using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Numerics; using System.Runtime.CompilerServices; using Dalamud.Interface; using Dalamud.Interface.Windowing; using ImGuiNET; using IG = ImGuiNET.ImGui; namespace LLib.ImGui; [SuppressMessage("ReSharper", "SuspiciousTypeConversion.Global")] public abstract class LWindow : Window { private bool _initializedConfig; protected LWindow(string name, ImGuiWindowFlags flags = ImGuiWindowFlags.None, bool forceMainWindow = false) : base(name, flags, forceMainWindow) { TitleBarButtons.Add(new TitleBarButton { Icon = FontAwesomeIcon.Heart, ShowTooltip = () => { IG.BeginTooltip(); IG.Text("Go to patreon.com/lizac"); IG.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, }); } protected bool ClickedHeaderLastFrame { get; private set; } protected bool ClickedHeaderCurrentFrame { get; private set; } protected bool IsPinned { get => InternalIsPinned(this); set => InternalIsPinned(this) = value; } protected bool IsClickthrough { get => InternalIsClickthrough(this); set => InternalIsClickthrough(this) = value; } protected int? Alpha { get { float? value = InternalAlpha(this); return (int?)(10_0000 * value); } set => InternalAlpha(this) = value / 10_0000f; } private void LoadWindowConfig() { if (this is IPersistableWindowConfig pwc) { WindowConfig? config = pwc.WindowConfig; if (config != null) { if (AllowPinning) IsPinned = config.IsPinned; if (AllowClickthrough) IsClickthrough = config.IsClickthrough; Alpha = config.Alpha; } _initializedConfig = true; } } private void UpdateWindowConfig() { if (this is IPersistableWindowConfig pwc && !IG.IsAnyMouseDown()) { WindowConfig? config = pwc.WindowConfig; if (config != null) { bool changed = false; if (AllowPinning && config.IsPinned != IsPinned) { config.IsPinned = IsPinned; changed = true; } if (AllowClickthrough && config.IsClickthrough != IsClickthrough) { config.IsClickthrough = IsClickthrough; changed = true; } if (config.Alpha != Alpha) { config.Alpha = Alpha; changed = true; } if (changed) { pwc.SaveWindowConfig(); } } } } public override void PreDraw() { if (!_initializedConfig) LoadWindowConfig(); base.PreDraw(); ClickedHeaderLastFrame = ClickedHeaderCurrentFrame; ClickedHeaderCurrentFrame = false; } public override void PostDraw() { base.PostDraw(); if (_initializedConfig) UpdateWindowConfig(); } [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "internalIsPinned")] private static extern ref bool InternalIsPinned(Window @this); [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "internalIsClickthrough")] private static extern ref bool InternalIsClickthrough(Window @this); [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "internalAlpha")] private static extern ref float? InternalAlpha(Window @this); }