Files
2026-07-13 13:13:17 +08:00

186 lines
6.0 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#nullable enable
using System.Diagnostics;
using ImGuiNET;
using SharpDX.DXGI;
using T3.Core.DataTypes;
using T3.Core.Resource;
using T3.Editor.Gui.Interaction;
using T3.Editor.Gui.OutputUi;
using T3.Editor.Gui.Styling;
using T3.Editor.Gui.UiHelpers;
using T3.SystemUi;
namespace T3.Editor.Gui.Windows;
internal sealed class ImageOutputCanvas : ScalableCanvas
{
public void Update(T3Ui.EditingFlags editingFlags = T3Ui.EditingFlags.None)
{
UpdateCanvas(out var interactionState, editingFlags);
UpdateViewMode(interactionState);
}
public void SetAsCurrent()
{
Current = this;
}
public static void Deactivate()
{
Current = null;
}
/// <summary>
/// The image canvas that is currently being drawn from the UI.
/// Note that <see cref="ImageOutputCanvas"/> is NOT a singleton so you can't rely on this to be valid outside of the Draw()ing context.
/// It is used by <see cref="Texture2dOutputUi"/> to draw its content.
/// </summary>
public static ImageOutputCanvas? Current;
protected override ScalableCanvas? Parent => null;
public Texture2D? LastTexture;
public void DrawTexture(Texture2D? texture)
{
CustomComponents.FillWithStripes(ImGui.GetWindowDrawList(), DrawUtils.GetContentRegionArea(), Scale.X);
LastTexture = texture;
Debug.Assert(Current != null);
if (texture == null || texture.IsDisposed)
return;
var size = new Vector2(texture.Description.Width, texture.Description.Height);
var area = new ImRect(0, 0, size.X, size.Y);
if (_viewMode == Modes.Fitted)
{
Current.FitAreaOnCanvas(area);
if (DisableDamping)
{
Scale = ScaleTarget;
}
}
var topLeft = Vector2.Zero;
var topLeftOnScreen = Current.TransformPosition(topLeft);
ImGui.SetCursorScreenPos(topLeftOnScreen);
var sizeOnScreen = Current.TransformDirection(size);
var srv = SrvManager.GetSrvForTexture(texture);
ImGui.Image((IntPtr)srv, sizeOnScreen);
if (ImGui.IsMouseHoveringRect(topLeftOnScreen, topLeftOnScreen + sizeOnScreen))
{
var relativePosition = (ImGui.GetMousePos() - topLeftOnScreen) / sizeOnScreen;
MouseInput.Set(relativePosition, ImGui.IsMouseDown(ImGuiMouseButton.Left));
}
if (UserSettings.Config.ShowToolbar)
{
string format;
if (srv == null || srv.IsDisposed)
{
format = "null?";
}
else if (UserSettings.Config.ShowExplicitTextureFormatInOutputWindow)
{
format = srv.Description.Format.ToString();
}
else
{
switch (srv.Description.Format)
{
case Format.R16G16B16A16_Float:
format = "RGBA:16";
break;
case Format.R8G8B8A8_SNorm:
format = "RGBA:8";
break;
default:
format = srv.Description.Format.ToString();
break;
}
}
ImGui.PushFont(Fonts.FontSmall);
var zoom = Math.Abs(Scale.X) < 0.001f ? "" : $" ×{Scale.X:G2}";
var description = $"{size.X}x{size.Y} {format} {zoom}";
var descriptionWidth = ImGui.CalcTextSize(description).X;
var textPos = new Vector2(WindowPos.X + (WindowSize.X - descriptionWidth) / 2,
WindowPos.Y + WindowSize.Y - 14 * T3Ui.UiScaleFactor);
var drawList = ImGui.GetWindowDrawList();
var shadowColor = UiColors.BackgroundFull.Fade(0.5f);
drawList.AddText(textPos + new Vector2(1,0), shadowColor, description );
drawList.AddText(textPos + new Vector2(-1,0), shadowColor, description );
drawList.AddText(textPos + new Vector2(0,1), shadowColor, description );
drawList.AddText(textPos + new Vector2(0,-1), shadowColor, description );
drawList.AddText(textPos, UiColors.ForegroundFull, description );
ImGui.PopFont();
}
}
//private static readonly Color ShadowColor = new Color(0.0f, 0.0f, 0.0f, 0.6f);
public void SetViewMode(Modes newMode)
{
_viewMode = newMode;
switch (newMode)
{
case Modes.Pixel:
SetScaleToMatchPixels();
// UserZoomedView = false;
break;
case Modes.Fitted:
// UserZoomedView = false;
// UserPannedView = false;
break;
}
}
/// <summary>
/// Updated the view mode if user interacted
/// </summary>
private void UpdateViewMode(InteractionState interactionState)
{
// UserZoomedView |= interactionState.UserZoomedCanvas;
// UserPannedView |= interactionState.UserPannedCanvas;
switch (_viewMode)
{
case Modes.Fitted:
if (interactionState.UserPannedCanvas || interactionState.UserZoomedCanvas)
{
_viewMode = Modes.Custom;
}
break;
case Modes.Pixel:
if (interactionState.UserZoomedCanvas)
_viewMode = Modes.Custom;
break;
}
}
public enum Modes
{
Fitted,
Pixel,
Custom,
}
public Modes ViewMode => _viewMode;
private Modes _viewMode = Modes.Fitted;
public bool DisableDamping = false;
// public bool UserPannedView;
// public bool UserZoomedView;
}