From 865a6080319f8ccbcd5fd5b0004404822b6e60d4 Mon Sep 17 00:00:00 2001 From: Liza Carvelli Date: Thu, 9 Nov 2023 10:47:42 +0100 Subject: [PATCH] Update header icon logic for Dalamud changes --- LImGui.HeaderIcon.cs | 109 ------------------------------------------- LImGui.cs | 67 ++++++++++++++++++-------- 2 files changed, 48 insertions(+), 128 deletions(-) delete mode 100644 LImGui.HeaderIcon.cs diff --git a/LImGui.HeaderIcon.cs b/LImGui.HeaderIcon.cs deleted file mode 100644 index 81cab68..0000000 --- a/LImGui.HeaderIcon.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System.Numerics; -using System.Runtime.InteropServices; -using Dalamud.Interface; -using Dalamud.Interface.Utility; -using Dalamud.Plugin; -using ImGuiNET; - -namespace LLib; - -/// -/// Originally part of ECommons by NightmareXIV. -/// -/// https://github.com/NightmareXIV/ECommons/blob/master/ECommons/ImGuiMethods/ImGuiEx.cs -/// -partial class LImGui -{ - public sealed record HeaderIconOptions - { - public Vector2 Offset { get; init; } = Vector2.Zero; - public ImGuiMouseButton MouseButton { get; init; } = ImGuiMouseButton.Left; - public string Tooltip { get; init; } = string.Empty; - public uint Color { get; init; } = 0xFFFFFFFF; - } - - private static uint _headerLastWindowId = 0; - private static ulong _headerLastFrame = 0; - private static float _headerCurrentPos = 0; - private static float _headerImGuiButtonWidth = 0; - - public static bool AddHeaderIcon(DalamudPluginInterface pluginInterface, string id, FontAwesomeIcon icon, HeaderIconOptions? options = null) - { - if (ImGui.IsWindowCollapsed()) return false; - - var scale = ImGuiHelpers.GlobalScale; - var currentID = ImGui.GetID(0); - if (currentID != _headerLastWindowId || _headerLastFrame != pluginInterface.UiBuilder.FrameCount) - { - _headerLastWindowId = currentID; - _headerLastFrame = pluginInterface.UiBuilder.FrameCount; - _headerCurrentPos = 0.25f * ImGui.GetStyle().FramePadding.Length(); - if (!GetCurrentWindowFlags().HasFlag(ImGuiWindowFlags.NoTitleBar)) - _headerCurrentPos = 1; - _headerImGuiButtonWidth = 0f; - if (CurrentWindowHasCloseButton()) - _headerImGuiButtonWidth += 17 * scale; - if (!GetCurrentWindowFlags().HasFlag(ImGuiWindowFlags.NoCollapse)) - _headerImGuiButtonWidth += 17 * scale; - - if (!CurrentWindowHasCloseButton() && - GetCurrentWindowFlags().HasFlag(ImGuiWindowFlags.NoCollapse) && - GetCurrentWindowFlags().HasFlag(ImGuiWindowFlags.AlwaysAutoResize)) - _headerImGuiButtonWidth += 5 * scale; - else - _headerImGuiButtonWidth += 10 * scale; - } - - options ??= new(); - var prevCursorPos = ImGui.GetCursorPos(); - var buttonSize = new Vector2(20 * scale); - var buttonPos = new Vector2((ImGui.GetWindowWidth() - buttonSize.X - _headerImGuiButtonWidth * scale * _headerCurrentPos) - (ImGui.GetStyle().FramePadding.X * scale), ImGui.GetScrollY() + 1); - ImGui.SetCursorPos(buttonPos); - var drawList = ImGui.GetWindowDrawList(); - drawList.PushClipRectFullScreen(); - - var pressed = false; - ImGui.InvisibleButton(id, buttonSize); - var itemMin = ImGui.GetItemRectMin(); - var itemMax = ImGui.GetItemRectMax(); - var halfSize = ImGui.GetItemRectSize() / 2; - var center = itemMin + halfSize; - if (ImGui.IsWindowHovered() && ImGui.IsMouseHoveringRect(itemMin, itemMax, false)) - { - if (!string.IsNullOrEmpty(options.Tooltip)) - ImGui.SetTooltip(options.Tooltip); - ImGui.GetWindowDrawList().AddCircleFilled(center, halfSize.X, ImGui.GetColorU32(ImGui.IsMouseDown(ImGuiMouseButton.Left) ? ImGuiCol.ButtonActive : ImGuiCol.ButtonHovered)); - if (ImGui.IsMouseReleased(options.MouseButton)) - pressed = true; - } - - ImGui.SetCursorPos(buttonPos); - ImGui.PushFont(UiBuilder.IconFont); - var iconString = icon.ToIconString(); - drawList.AddText(UiBuilder.IconFont, ImGui.GetFontSize(), itemMin + halfSize - ImGui.CalcTextSize(iconString) / 2 + options.Offset, options.Color, iconString); - ImGui.PopFont(); - - ImGui.PopClipRect(); - ImGui.SetCursorPos(prevCursorPos); - - return pressed; - } - - [LibraryImport("cimgui")] - [UnmanagedCallConv(CallConvs = new[] { typeof(System.Runtime.CompilerServices.CallConvCdecl) })] - private static partial nint igGetCurrentWindow(); - private static unsafe ImGuiWindow* GetCurrentWindow() => (ImGuiWindow*)igGetCurrentWindow(); - private static unsafe ImGuiWindowFlags GetCurrentWindowFlags() => GetCurrentWindow()->Flags; - private static unsafe bool CurrentWindowHasCloseButton() => GetCurrentWindow()->HasCloseButton != 0; - - [StructLayout(LayoutKind.Explicit)] - private struct ImGuiWindow - { - [FieldOffset(0xC)] public ImGuiWindowFlags Flags; - - [FieldOffset(0xD5)] public byte HasCloseButton; - - // 0x118 is the start of ImGuiWindowTempData - [FieldOffset(0x130)] public Vector2 CursorMaxPos; - } -} diff --git a/LImGui.cs b/LImGui.cs index ed53332..3582b02 100644 --- a/LImGui.cs +++ b/LImGui.cs @@ -1,34 +1,63 @@ using System.Diagnostics; using System.Numerics; using Dalamud.Interface; -using Dalamud.Plugin; +using Dalamud.Interface.Windowing; using ImGuiNET; namespace LLib; -public static partial class LImGui +public static class LImGui { - public static void AddPatreonIcon(DalamudPluginInterface pluginInterface) + public abstract class LWindow : Window { - if (AddHeaderIcon(pluginInterface, "##Patreon", FontAwesomeIcon.Heart, new HeaderIconOptions - { - Tooltip = "Go to patreon.com/lizac", - Color = 0xFF3030D0, - })) + protected bool ClickedHeaderLastFrame; + protected bool ClickedHeaderCurrentFrame; + + protected LWindow(string name, ImGuiWindowFlags flags = ImGuiWindowFlags.None, bool forceMainWindow = false) + : base(name, flags, forceMainWindow) { - try + TitleBarButtons.Add(new TitleBarButton { - Process.Start(new ProcessStartInfo + Icon = FontAwesomeIcon.Heart, + ShowTooltip = () => { - FileName = "https://www.patreon.com/lizac", - UseShellExecute = true, - Verb = string.Empty, - }); - } - catch - { - // not sure what to do anyway - } + ImGui.BeginTooltip(); + ImGui.Text("Go to patreon.com/lizac"); + ImGui.EndTooltip(); + }, + Priority = int.MinValue, + IconOffset = new Vector2(1.5f, 1), + Click = _ => + { + // when you make a window click-through, `Click` is triggered on each individual frame the mouse button is held down. + ClickedHeaderCurrentFrame = true; + if (ClickedHeaderLastFrame) + return; + + try + { + Process.Start(new ProcessStartInfo + { + FileName = "https://www.patreon.com/lizac", + UseShellExecute = true, + Verb = string.Empty, + }); + } + catch + { + // not sure what to do anyway + } + }, + AvailableClickthrough = true, + }); + } + + public override void PreDraw() + { + base.PreDraw(); + + ClickedHeaderLastFrame = ClickedHeaderCurrentFrame; + ClickedHeaderCurrentFrame = false; } } }