using ImGuiNET;
using T3.Core.SystemUi;
using T3.Editor.Gui.Help;
using T3.Editor.Gui.Input;
using T3.Editor.Gui.Interaction.Variations;
using T3.Editor.Gui.Interaction.Variations.Model;
using T3.Editor.Gui.Styling;
using T3.Editor.Gui.UiHelpers;
using T3.Editor.UiModel;
using T3.Editor.UiModel.ProjectHandling;
namespace T3.Editor.Gui.Windows.Variations;
[HelpUiID("VariationWindow")]
internal sealed class VariationsWindow : Window
{
public VariationsWindow()
{
_presetCanvas = new PresetCanvas();
_snapshotCanvas = new SnapshotCanvas();
Config.Title = "Variations";
MenuTitle = "Presets";
WindowFlags = ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse;
}
protected override void DrawContent()
{
DrawWindowContent();
}
private InteractionModes _interactionMode = InteractionModes.Presets;
private int _selectedNodeCount;
public void DrawWindowContent(bool hideHeader = false)
{
// Delete actions need be deferred to prevent collection modification during iteration
if (_variationsToBeDeletedNextFrame.Count > 0)
{
_poolWithVariationToBeDeleted.DeleteVariations(_variationsToBeDeletedNextFrame);
_variationsToBeDeletedNextFrame.Clear();
}
var components = ProjectView.Focused;
if (components == null)
return;
var nodeSelection = components.NodeSelection;
var compositionHasVariations = VariationHandling.ActivePoolForSnapshots != null && VariationHandling.ActivePoolForSnapshots.AllVariations.Count > 0;
var oneChildSelected = nodeSelection.Selection.Count == 1;
if (FrameStats.SelectionChanged)
{
_selectedNodeCount = nodeSelection.Selection.Count;
if (oneChildSelected)
{
_interactionMode = InteractionModes.Presets;
}
else if (compositionHasVariations && _selectedNodeCount == 0)
{
_interactionMode = InteractionModes.Snapshots;
}
}
if (FrameStats.SelectionChanged || FrameStats.WindowLayoutChanged)
{
_presetCanvas.RefreshView();
_snapshotCanvas.RefreshView();
}
var drawList = ImGui.GetWindowDrawList();
var topLeftCorner = ImGui.GetCursorScreenPos();
drawList.ChannelsSplit(2);
drawList.ChannelsSetCurrent(1);
{
if (!hideHeader)
{
ImGui.BeginChild("header",
new Vector2(ImGui.GetContentRegionAvail().X, ImGui.GetFrameHeight()),
ImGuiChildFlags.None,
ImGuiWindowFlags.NoScrollbar);
if (FormInputs.SegmentedButton(ref _interactionMode))
{
// _interactionMode = (InteractionModes)viewModeIndex;
//_presetCanvas.RefreshView();
//_snapshotCanvas.RefreshView();
}
ImGui.SameLine();
ImGui.Dummy(new Vector2(10, 10));
ImGui.SameLine();
switch (_interactionMode)
{
case InteractionModes.Presets:
_presetCanvas.DrawToolbarFunctions();
break;
case InteractionModes.Snapshots:
_snapshotCanvas.DrawToolbarFunctions();
break;
}
DrawHeaderIcons();
ImGui.EndChild();
}
}
drawList.ChannelsSetCurrent(0);
{
switch (_interactionMode)
{
case InteractionModes.Presets:
ImGui.SetCursorScreenPos(topLeftCorner);
if (VariationHandling.ActivePoolForPresets == null
|| VariationHandling.ActiveInstanceForPresets == null
|| VariationHandling.ActivePoolForPresets.AllVariations.Count == 0)
{
CustomComponents.EmptyWindowMessage("No presets yet.");
}
else
{
_presetCanvas.DrawBaseCanvas(drawList, hideHeader);
}
break;
case InteractionModes.Snapshots:
ImGui.SetCursorScreenPos(topLeftCorner);
if (VariationHandling.ActivePoolForSnapshots == null
|| VariationHandling.ActiveInstanceForSnapshots == null
|| VariationHandling.ActivePoolForSnapshots.AllVariations.Count == 0)
{
var additionalHint = "";
if (VariationHandling.ActiveInstanceForSnapshots != null
&& SymbolUiRegistry.TryGetSymbolUi(VariationHandling.ActiveInstanceForSnapshots.Symbol.Id, out var childUi)
&& !childUi.ChildUis.Values.Any(s => s.SnapshotGroupIndex > 0))
{
additionalHint = "Use the graph window context menu\nto activate snapshots for operators.";
}
if (CustomComponents
.EmptyWindowMessage("No Snapshots yet.\n\nWith snapshots you can switch or blend\nbetween parameter sets in your composition.\n\n"
+ additionalHint, "Learn More"))
{
var url = "https://github.com/tixl3d/tixl/wiki/help.PresetsAndSnapshots";
CoreUi.Instance.OpenWithDefaultApplication(url);
}
// }
}
else
{
_snapshotCanvas.DrawBaseCanvas(drawList);
}
break;
}
}
drawList.ChannelsMerge();
}
///
/// Right-aligned cluster with the preview mode toggles and the documentation button.
///
private void DrawHeaderIcons()
{
var iconSize = new Vector2(ImGui.GetFrameHeight(), ImGui.GetFrameHeight());
var spacing = ImGui.GetStyle().ItemSpacing.X;
CustomComponents.RightAlign(iconSize.X * 3 + spacing * 2);
CustomComponents.ToggleTwoIconsButton(ref UserSettings.Config.VariationHoverPreview,
iconOff:Icon.HoverScrub,
iconOn:Icon.HoverScrub,
CustomComponents.ButtonStates.Activated,
CustomComponents.ButtonStates.Default,
noBackground:true);
CustomComponents.TooltipForLastItem("Preview on hover",
"Hovering a thumbnail temporarily applies the variation to the output.");
ImGui.SameLine();
var liveThumbnails = UserSettings.Config.VariationLiveThumbnails;
if (CustomComponents.ToggleTwoIconsButton(ref liveThumbnails,
iconOff:Icon.AutoRefresh,
iconOn:Icon.AutoRefresh,
CustomComponents.ButtonStates.Activated,
CustomComponents.ButtonStates.Default,
noBackground:true))
{
_presetCanvas.EnableLiveThumbnails(liveThumbnails);
_snapshotCanvas.EnableLiveThumbnails(liveThumbnails);
}
CustomComponents.TooltipForLastItem("Live render previews",
"Continuously renders thumbnails for the pinned output.\nDisabling restores the default thumbnails.");
ImGui.SameLine();
DocumentationButton.Draw("Variations", DocumentationWikiUrl, iconSize);
}
private const string DocumentationWikiUrl = "https://github.com/tixl3d/tixl/wiki/help.PresetsAndSnapshots";
private enum InteractionModes
{
Presets,
Snapshots,
}
private static readonly List _options = new() { "Presets", "Snapshots" };
internal override List GetInstances()
{
return new List();
}
public static void DeleteVariationsFromPool(SymbolVariationPool pool, IEnumerable selectionSelection)
{
_poolWithVariationToBeDeleted = pool;
_variationsToBeDeletedNextFrame.AddRange(selectionSelection); // TODO: mixing Snapshots and variations in same list is dangerous
pool.StopHover();
pool.SaveVariationsToFile();
}
private static readonly List _variationsToBeDeletedNextFrame = new(20);
private static SymbolVariationPool _poolWithVariationToBeDeleted;
private readonly PresetCanvas _presetCanvas;
private readonly SnapshotCanvas _snapshotCanvas;
}