mirror of
https://github.com/goatcorp/Dalamud.git
synced 2026-02-22 15:57:44 +01:00
feat: MVP pinning, clickthrough, alpha menu for Window System windows
Needs saving, an actual button in the title bar
This commit is contained in:
parent
e30c904ad6
commit
36364576a8
1 changed files with 128 additions and 2 deletions
|
|
@ -1,7 +1,10 @@
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using CheapLoc;
|
||||||
using Dalamud.Configuration.Internal;
|
using Dalamud.Configuration.Internal;
|
||||||
using Dalamud.Game.ClientState.Keys;
|
using Dalamud.Game.ClientState.Keys;
|
||||||
|
using Dalamud.Interface.Colors;
|
||||||
using Dalamud.Interface.Utility;
|
using Dalamud.Interface.Utility;
|
||||||
using Dalamud.Logging.Internal;
|
using Dalamud.Logging.Internal;
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI;
|
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||||
|
|
@ -20,6 +23,11 @@ public abstract class Window
|
||||||
|
|
||||||
private bool internalLastIsOpen = false;
|
private bool internalLastIsOpen = false;
|
||||||
private bool internalIsOpen = false;
|
private bool internalIsOpen = false;
|
||||||
|
private bool internalIsPinned = false;
|
||||||
|
private bool internalIsClickthrough = false;
|
||||||
|
private DateTimeOffset internalLastDisableClick = DateTimeOffset.MinValue;
|
||||||
|
private bool didPushInternalAlpha = false;
|
||||||
|
private float? internalAlpha = null;
|
||||||
private bool nextFrameBringToFront = false;
|
private bool nextFrameBringToFront = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -130,6 +138,16 @@ public abstract class Window
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ShowCloseButton { get; set; } = true;
|
public bool ShowCloseButton { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether or not this window should offer to be pinned via the window's titlebar context menu.
|
||||||
|
/// </summary>
|
||||||
|
public bool AllowPinning { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether or not this window should offer to be made click-through via the window's titlebar context menu.
|
||||||
|
/// </summary>
|
||||||
|
public bool AllowClickthrough { get; set; } = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether or not this window will stay open.
|
/// Gets or sets a value indicating whether or not this window will stay open.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -185,6 +203,11 @@ public abstract class Window
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void PreDraw()
|
public virtual void PreDraw()
|
||||||
{
|
{
|
||||||
|
if (this.internalAlpha.HasValue)
|
||||||
|
{
|
||||||
|
ImGui.PushStyleVar(ImGuiStyleVar.Alpha, this.internalAlpha.Value);
|
||||||
|
this.didPushInternalAlpha = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -192,6 +215,11 @@ public abstract class Window
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void PostDraw()
|
public virtual void PostDraw()
|
||||||
{
|
{
|
||||||
|
if (this.didPushInternalAlpha)
|
||||||
|
{
|
||||||
|
ImGui.PopStyleVar();
|
||||||
|
this.didPushInternalAlpha = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -286,7 +314,15 @@ public abstract class Window
|
||||||
this.nextFrameBringToFront = false;
|
this.nextFrameBringToFront = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.ShowCloseButton ? ImGui.Begin(this.WindowName, ref this.internalIsOpen, this.Flags) : ImGui.Begin(this.WindowName, this.Flags))
|
var flags = this.Flags;
|
||||||
|
|
||||||
|
if (this.internalIsPinned)
|
||||||
|
flags |= ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoResize;
|
||||||
|
|
||||||
|
if (this.internalIsClickthrough)
|
||||||
|
flags |= ImGuiWindowFlags.NoInputs | ImGuiWindowFlags.NoNav | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoScrollWithMouse | ImGuiWindowFlags.NoMouseInputs;
|
||||||
|
|
||||||
|
if (this.ShowCloseButton ? ImGui.Begin(this.WindowName, ref this.internalIsOpen, flags) : ImGui.Begin(this.WindowName, flags))
|
||||||
{
|
{
|
||||||
// Draw the actual window contents
|
// Draw the actual window contents
|
||||||
try
|
try
|
||||||
|
|
@ -297,6 +333,80 @@ public abstract class Window
|
||||||
{
|
{
|
||||||
Log.Error(ex, $"Error during Draw(): {this.WindowName}");
|
Log.Error(ex, $"Error during Draw(): {this.WindowName}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.AllowPinning || this.AllowClickthrough)
|
||||||
|
{
|
||||||
|
ImGui.PushStyleVar(ImGuiStyleVar.Alpha, 1f);
|
||||||
|
|
||||||
|
var popupName = "WindowSystemContextActions";
|
||||||
|
if (ImGui.BeginPopup(popupName))
|
||||||
|
{
|
||||||
|
if (this.internalIsClickthrough)
|
||||||
|
ImGui.BeginDisabled();
|
||||||
|
|
||||||
|
if (this.AllowPinning)
|
||||||
|
ImGui.Checkbox(Loc.Localize("WindowSystemContextActionPin", "Pin Window"), ref this.internalIsPinned);
|
||||||
|
|
||||||
|
if (this.internalIsClickthrough)
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
|
||||||
|
if (this.AllowClickthrough)
|
||||||
|
{
|
||||||
|
if (ImGui.Checkbox(Loc.Localize("WindowSystemContextActionClickthrough", "Make clickthrough"),
|
||||||
|
ref this.internalIsClickthrough))
|
||||||
|
{
|
||||||
|
if (this.internalIsClickthrough)
|
||||||
|
this.internalIsPinned = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var alpha = (this.internalAlpha ?? ImGui.GetStyle().Alpha) * 100f;
|
||||||
|
if (ImGui.SliderFloat(Loc.Localize("WindowSystemContextActionAlpha", "Opacity"), ref alpha, 20f,
|
||||||
|
100f))
|
||||||
|
{
|
||||||
|
this.internalAlpha = alpha / 100f;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (ImGui.Button(Loc.Localize("WindowSystemContextActionReset", "Reset")))
|
||||||
|
{
|
||||||
|
this.internalAlpha = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.TextColored(ImGuiColors.DalamudGrey, Loc.Localize("WindowSystemContextActionDoubleClick", "Double click the title bar to disable clickthrough."));
|
||||||
|
ImGui.TextColored(ImGuiColors.DalamudGrey, Loc.Localize("WindowSystemContextActionDisclaimer", "These options may not work for all plugins at the moment."));
|
||||||
|
|
||||||
|
ImGui.EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.PopStyleVar();
|
||||||
|
|
||||||
|
var titleBarRect = Vector4.Zero;
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
var window = ImGuiNativeAdditions.igGetCurrentWindow();
|
||||||
|
ImGuiNativeAdditions.ImGuiWindow_TitleBarRect(&titleBarRect, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.IsMouseHoveringRect(new Vector2(titleBarRect.X, titleBarRect.Y), new Vector2(titleBarRect.Z, titleBarRect.W), false))
|
||||||
|
{
|
||||||
|
if (ImGui.IsWindowHovered() && ImGui.IsMouseClicked(ImGuiMouseButton.Right))
|
||||||
|
{
|
||||||
|
ImGui.OpenPopup(popupName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.IsMouseDown(ImGuiMouseButton.Left))
|
||||||
|
{
|
||||||
|
if (DateTime.Now - this.internalLastDisableClick < TimeSpan.FromMilliseconds(100))
|
||||||
|
{
|
||||||
|
this.internalIsPinned = false;
|
||||||
|
this.internalIsClickthrough = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.internalLastDisableClick = DateTime.Now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wasFocused)
|
if (wasFocused)
|
||||||
|
|
@ -375,6 +485,12 @@ public abstract class Window
|
||||||
{
|
{
|
||||||
ImGui.SetNextWindowBgAlpha(this.BgAlpha.Value);
|
ImGui.SetNextWindowBgAlpha(this.BgAlpha.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Manually set alpha takes precedence, if devs don't want that, they should turn it off
|
||||||
|
if (this.internalAlpha.HasValue)
|
||||||
|
{
|
||||||
|
ImGui.SetNextWindowBgAlpha(this.internalAlpha.Value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -392,4 +508,14 @@ public abstract class Window
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Vector2 MaximumSize { get; set; }
|
public Vector2 MaximumSize { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1300:Element should begin with upper-case letter", Justification = "imports")]
|
||||||
|
private static unsafe class ImGuiNativeAdditions
|
||||||
|
{
|
||||||
|
[DllImport("cimgui", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern unsafe void* igGetCurrentWindow();
|
||||||
|
|
||||||
|
[DllImport("cimgui", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern unsafe void ImGuiWindow_TitleBarRect(Vector4* pOut, void* window);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue