#nullable enable using ImGuiNET; using T3.Core.Operator; using T3.Editor.Gui.Styling; using T3.Editor.UiModel; namespace T3.Editor.Gui.Dialogs; internal sealed partial class DeleteSymbolDialog { /// /// Renders the main body of the delete confirmation dialog after symbol dependency analysis /// has completed successfully. /// /// The symbol currently selected for deletion. /// Detailed dependency and classification information about the symbol /// obtained from . private static void DrawAnalysisUi(Symbol symbol, LocalSymbolInfo info) { var isProtected = TryGetRestriction(symbol, info, out var restriction); var isNamespaceMain = IsNamespaceMainSymbol(symbol); var symbolName = symbol.Name; _allowDeletion = !isProtected && !symbol.SymbolPackage.IsReadOnly; ImGui.PushStyleColor(ImGuiCol.Text, UiColors.Text.Rgba); ImGui.TextWrapped(isProtected ? $"Can not delete [{symbolName}]" : $"Are you sure you want to delete [{symbolName}]?"); ImGui.PopStyleColor(); if (isProtected) { ImGui.PushFont(Fonts.FontBold); ImGui.TextColored(UiColors.StatusAttention, isNamespaceMain ? "This symbol is attached to the project namespace." : $"You can not delete symbols that are {restriction}"); ImGui.PopFont(); } if (isNamespaceMain) { ImGui.PushStyleColor(ImGuiCol.Text, UiColors.StatusAttention.Rgba); ImGui.TextWrapped($""" Symbol [{symbolName}] acts as the main symbol for namespace [{symbol.Namespace}]. Removing it directly can leave the project in a broken state. Use the namespace delete workflow (todo) instead of deleting this symbol. """); ImGui.PopStyleColor(); return; } if (!info.DependingSymbols.IsEmpty) { if (!_allowDeletion) { ImGui.PushStyleColor(ImGuiCol.Text, UiColors.StatusAttention.Rgba); ImGui.TextWrapped( $"Symbol [{symbolName}] is used by [{info.DependingSymbols.Count}] other projects/symbols, " + "but deletion is blocked because it belongs to a protected library or read-only package."); ImGui.PopStyleColor(); } else { ImGui.PushStyleColor(ImGuiCol.Text, UiColors.StatusAttention.Rgba); ImGui.TextWrapped($"[{symbolName}] is used in [{info.DependingSymbols.Count}] projects/symbols:"); ImGui.PopStyleColor(); ImGui.PushStyleColor(ImGuiCol.Text, UiColors.StatusAttention.Rgba); ListSymbolNames(info.DependingSymbols); ImGui.PopStyleColor(); ImGui.PushStyleColor(ImGuiCol.Text, UiColors.StatusAttention.Rgba); ImGui.TextWrapped("Clicking Force delete will automatically disconnect/clean all usages. " + "This may completely break these projects/symbols, and can *NOT* be undone."); ImGui.PopStyleColor(); } } else { if (!_allowDeletion) { ImGui.PushStyleColor(ImGuiCol.Text, UiColors.StatusAttention.Rgba); ImGui.TextWrapped($"Symbol [{symbolName}] is not used by other symbols, " + $"but deletion is blocked because it belongs to a protected library or read-only package."); ImGui.PopStyleColor(); } else { ImGui.PushStyleColor(ImGuiCol.Text, UiColors.Text.Rgba); ImGui.TextWrapped($"Symbol [{symbolName}] is not used by other symbols and can be safely deleted."); ImGui.PopStyleColor(); } } } /// /// Renders a scrollable list of symbol names and their project namespaces for all /// symbols that reference the symbol being deleted. /// /// /// The set of symbol IDs that depend on the symbol currently considered for deletion. /// private static void ListSymbolNames(IEnumerable symbolIds) { if (_cachedMatches == null) { var allSymbolUis = EditorSymbolPackage.AllSymbolUis; var idSet = symbolIds.ToHashSet(); _cachedMatches = allSymbolUis .Where(s => idSet.Contains(s.Symbol.Id)) .OrderBy(s => s.Symbol.Namespace) .ThenBy(s => s.Symbol.Name) .ToList(); } if (_cachedMatches.Count == 0) return; var fontSize = ImGui.GetFontSize(); // Current font size in pixels const int maxVisibleItems = 5; var itemHeight = fontSize + 4.0f; // Font size + small padding var scrollHeight = itemHeight * maxVisibleItems; if (ImGui.BeginChild("SymbolList", new Vector2(0, scrollHeight), ImGuiChildFlags.Borders)) { var lastGroupName = string.Empty; foreach (var symbolUi in _cachedMatches) { var projectName = symbolUi.Symbol.SymbolPackage.RootNamespace; if (projectName != lastGroupName) { lastGroupName = projectName; var avail = ImGui.GetContentRegionAvail(); var cursorPos = ImGui.GetCursorScreenPos(); var drawList = ImGui.GetWindowDrawList(); var rectMax = new Vector2(cursorPos.X + avail.X, cursorPos.Y + Fonts.FontSmall.FontSize + 4); drawList.AddRectFilled(cursorPos, rectMax, UiColors.BackgroundFull.Fade(0.3f), 0.0f); CustomComponents.StylizedText(projectName, Fonts.FontSmall, UiColors.Text); } var symbolLabel = " " + symbolUi.Symbol.Name; CustomComponents.StylizedText(symbolLabel, Fonts.FontSmall, UiColors.Text); } } ImGui.EndChild(); } }