v1.0.8.23: Main Menu bar; Duty List transparent background
Made-with: Cursor
This commit is contained in:
@@ -32,7 +32,7 @@ namespace HSUI.Interface.GeneralElements
|
||||
|
||||
[ColorEdit4("Background Color")]
|
||||
[Order(31)]
|
||||
public PluginConfigColor BackgroundColor = new(new Vector4(0f, 0f, 0f, 0.5f));
|
||||
public PluginConfigColor BackgroundColor = new(new Vector4(0f, 0f, 0f, 0f));
|
||||
|
||||
[ColorEdit4("Divider Color")]
|
||||
[Order(32)]
|
||||
|
||||
@@ -57,7 +57,9 @@ namespace HSUI.Interface.GeneralElements
|
||||
{
|
||||
DrawHelper.DrawInWindow(ID, basePos, Config.Size, true, (drawList) =>
|
||||
{
|
||||
drawList.AddRectFilled(basePos, basePos + Config.Size, Config.BackgroundColor.Base, 4);
|
||||
uint bgColor = Config.BackgroundColor.Base;
|
||||
if ((bgColor & 0xFF000000) != 0)
|
||||
drawList.AddRectFilled(basePos, basePos + Config.Size, bgColor, 4);
|
||||
drawList.PushClipRect(basePos, basePos + Config.Size, true);
|
||||
|
||||
float y = basePos.Y + padding;
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using HSUI.Config;
|
||||
using HSUI.Config.Attributes;
|
||||
using HSUI.Enums;
|
||||
using System.Numerics;
|
||||
|
||||
namespace HSUI.Interface.GeneralElements
|
||||
{
|
||||
[Section("Other Elements")]
|
||||
[SubSection("Main Menu", 0)]
|
||||
public class MainMenuConfig : AnchorablePluginConfigObject
|
||||
{
|
||||
[Combo("Layout", new[] { "Horizontal", "Vertical" })]
|
||||
[Order(18)]
|
||||
public int LayoutDirection = 0; // 0 = horizontal, 1 = vertical
|
||||
|
||||
[DragInt("Icon Size", min = 16, max = 64)]
|
||||
[Order(20)]
|
||||
public int IconSize = 36;
|
||||
|
||||
[DragInt("Spacing", min = 0, max = 24)]
|
||||
[Order(21)]
|
||||
public int Spacing = 4;
|
||||
|
||||
[ColorEdit4("Background Color")]
|
||||
[Order(30)]
|
||||
public PluginConfigColor BackgroundColor = new(new Vector4(0f, 0f, 0f, 0.6f));
|
||||
|
||||
[ColorEdit4("Icon Tint")]
|
||||
[Order(31)]
|
||||
public PluginConfigColor IconTint = new(new Vector4(1f, 1f, 1f, 1f));
|
||||
|
||||
[ColorEdit4("Hover Tint")]
|
||||
[Order(32)]
|
||||
public PluginConfigColor HoverTint = new(new Vector4(1f, 1f, 1f, 1f));
|
||||
|
||||
[Checkbox("Show Labels")]
|
||||
[Order(35)]
|
||||
public bool ShowLabels = false;
|
||||
|
||||
[NestedConfig("Visibility", 70)]
|
||||
public VisibilityConfig VisibilityConfig = new();
|
||||
|
||||
public MainMenuConfig()
|
||||
{
|
||||
// Width fits 7 icons (36px) + 6 gaps (4px) + 8 margin = 284
|
||||
Size = new Vector2(284, 48);
|
||||
}
|
||||
|
||||
public new static MainMenuConfig DefaultConfig()
|
||||
{
|
||||
var viewport = ImGui.GetMainViewport().Size;
|
||||
return new MainMenuConfig
|
||||
{
|
||||
Position = new Vector2(0, viewport.Y * 0.5f - 24),
|
||||
Size = new Vector2(284, 48),
|
||||
Anchor = DrawAnchor.Bottom
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using HSUI.Config;
|
||||
using HSUI.Helpers;
|
||||
using HSUI.Interface;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
|
||||
namespace HSUI.Interface.GeneralElements
|
||||
{
|
||||
public class MainMenuHud : DraggableHudElement, IHudElementWithVisibilityConfig
|
||||
{
|
||||
private const float BarPadding = 0f;
|
||||
private const float BackgroundRounding = 6f;
|
||||
/// <summary>Extra padding around content when drawing the background so the bar doesn't extend past the icons.</summary>
|
||||
private const float BackgroundEdgePad = 2f;
|
||||
|
||||
private MainMenuConfig Config => (MainMenuConfig)_config;
|
||||
public VisibilityConfig VisibilityConfig => Config.VisibilityConfig;
|
||||
|
||||
/// <summary>When set, the context menu with these entries should be shown (same frame or next). Cleared when popup closes.</summary>
|
||||
private List<(uint CommandId, string Name)>? _contextMenuEntries = null;
|
||||
|
||||
public MainMenuHud(MainMenuConfig config, string displayName)
|
||||
: base(config, displayName) { }
|
||||
|
||||
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
|
||||
{
|
||||
return (new List<Vector2> { Config.Position }, new List<Vector2> { Config.Size });
|
||||
}
|
||||
|
||||
public override (Vector2 min, Vector2 max) GetScreenBounds(Vector2 origin)
|
||||
{
|
||||
Vector2 topLeft = Utils.GetAnchoredPosition(origin + ParentPos() + Config.Position, Config.Size, Config.Anchor);
|
||||
return (topLeft, topLeft + Config.Size);
|
||||
}
|
||||
|
||||
public override void DrawChildren(Vector2 origin)
|
||||
{
|
||||
if (!Config.Enabled)
|
||||
return;
|
||||
|
||||
var entries = MainMenuHelper.GetEnabledMainCommands();
|
||||
if (entries.Count == 0)
|
||||
return;
|
||||
|
||||
Vector2 basePos = Utils.GetAnchoredPosition(origin + Config.Position, Config.Size, Config.Anchor);
|
||||
Vector2 iconSize = new Vector2(Config.IconSize, Config.IconSize);
|
||||
bool horizontal = Config.LayoutDirection == 0;
|
||||
|
||||
AddDrawAction(Config.StrataLevel, () =>
|
||||
{
|
||||
DrawHelper.DrawInWindow(ID, basePos, Config.Size, true, (drawListParam) =>
|
||||
{
|
||||
var drawList = ImGui.GetWindowDrawList();
|
||||
|
||||
// Compute total content size and starting position so icons are centered in the bar
|
||||
int count = entries.Count;
|
||||
float contentW, contentH;
|
||||
if (horizontal)
|
||||
{
|
||||
contentW = count * iconSize.X + (count > 0 ? (count - 1) * Config.Spacing : 0);
|
||||
if (Config.ShowLabels)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
contentW += ImGui.CalcTextSize(entries[i].Name).X + Config.Spacing;
|
||||
}
|
||||
contentH = iconSize.Y;
|
||||
}
|
||||
else
|
||||
{
|
||||
contentW = iconSize.X;
|
||||
contentH = 0;
|
||||
foreach (var e in entries)
|
||||
{
|
||||
float h = iconSize.Y + Config.Spacing;
|
||||
if (Config.ShowLabels && !string.IsNullOrEmpty(e.Name))
|
||||
h += ImGui.CalcTextSize(e.Name).Y + 2;
|
||||
contentH += h;
|
||||
}
|
||||
if (contentH > 0) contentH -= Config.Spacing;
|
||||
}
|
||||
float startX = basePos.X + BarPadding + Math.Max(0, (Config.Size.X - 2f * BarPadding - contentW) / 2f);
|
||||
float startY = basePos.Y + BarPadding + Math.Max(0, (Config.Size.Y - 2f * BarPadding - contentH) / 2f);
|
||||
|
||||
// Draw background only over the content area so no gray bar shows on left/right
|
||||
Vector2 bgMin = new Vector2(startX - BackgroundEdgePad, basePos.Y);
|
||||
Vector2 bgMax = new Vector2(startX + contentW + BackgroundEdgePad, basePos.Y + Config.Size.Y);
|
||||
if (!horizontal)
|
||||
{
|
||||
bgMin = new Vector2(basePos.X, startY - BackgroundEdgePad);
|
||||
bgMax = new Vector2(basePos.X + Config.Size.X, startY + contentH + BackgroundEdgePad);
|
||||
}
|
||||
drawList.AddRectFilled(bgMin, bgMax, Config.BackgroundColor.Base, BackgroundRounding);
|
||||
drawList.PushClipRect(basePos, basePos + Config.Size, true);
|
||||
|
||||
float x = startX;
|
||||
float y = startY;
|
||||
int index = 0;
|
||||
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
Vector2 iconPos = horizontal
|
||||
? new Vector2(x, basePos.Y + (Config.Size.Y - iconSize.Y) / 2f)
|
||||
: new Vector2(basePos.X + (Config.Size.X - iconSize.X) / 2f, y);
|
||||
Vector2 iconEnd = iconPos + iconSize;
|
||||
|
||||
// Use InvisibleButton so ImGui tracks hover/click for this icon
|
||||
ImGui.SetCursorScreenPos(iconPos);
|
||||
ImGui.InvisibleButton($"##mainmenu_icon_{ID}_{index}", iconSize);
|
||||
bool hovered = ImGui.IsItemHovered();
|
||||
|
||||
uint tint = Config.IconTint.Base;
|
||||
if (hovered)
|
||||
{
|
||||
tint = Config.HoverTint.Base;
|
||||
TooltipsHelper.Instance.NotifyMouseOverHudElement();
|
||||
TooltipsHelper.Instance.ShowTooltipOnCursor(entry.Name);
|
||||
}
|
||||
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Left) || ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
||||
{
|
||||
var subEntries = MainMenuHelper.GetSubCommandEntries(entry.CommandId);
|
||||
if (subEntries != null && subEntries.Count > 0)
|
||||
{
|
||||
_contextMenuEntries = subEntries;
|
||||
ImGui.OpenPopup("HSUI_MainMenu_Context");
|
||||
ImGui.SetNextWindowPos(ImGui.GetMousePos());
|
||||
}
|
||||
else
|
||||
{
|
||||
MainMenuHelper.ExecuteMainCommand(entry.CommandId);
|
||||
}
|
||||
}
|
||||
|
||||
if (entry.IconId != 0)
|
||||
DrawHelper.DrawIcon(entry.IconId, iconPos, iconSize, false, tint, drawList);
|
||||
|
||||
float labelH = 0;
|
||||
if (Config.ShowLabels && !string.IsNullOrEmpty(entry.Name))
|
||||
{
|
||||
float labelW = ImGui.CalcTextSize(entry.Name).X;
|
||||
labelH = ImGui.CalcTextSize(entry.Name).Y;
|
||||
Vector2 labelPos = horizontal
|
||||
? new Vector2(iconPos.X + iconSize.X + Config.Spacing, basePos.Y + (Config.Size.Y - labelH) / 2f)
|
||||
: new Vector2(basePos.X + (Config.Size.X - labelW) / 2f, iconPos.Y + iconSize.Y + 2);
|
||||
drawList.AddText(labelPos, Config.IconTint.Base, entry.Name);
|
||||
}
|
||||
|
||||
if (horizontal)
|
||||
{
|
||||
float advance = iconSize.X + Config.Spacing;
|
||||
if (Config.ShowLabels) advance += ImGui.CalcTextSize(entry.Name).X + Config.Spacing;
|
||||
x += advance;
|
||||
}
|
||||
else
|
||||
{
|
||||
y += iconSize.Y + 2 + labelH + Config.Spacing;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
drawList.PopClipRect();
|
||||
|
||||
// Draw context menu popup (same options as default main menu bar)
|
||||
if (ImGui.BeginPopup("HSUI_MainMenu_Context", ImGuiWindowFlags.NoMove))
|
||||
{
|
||||
if (_contextMenuEntries != null)
|
||||
{
|
||||
foreach (var (cmdId, name) in _contextMenuEntries)
|
||||
{
|
||||
if (ImGui.Selectable(name))
|
||||
{
|
||||
uint commandId = cmdId;
|
||||
Plugin.Framework.RunOnFrameworkThread(() => MainMenuHelper.ExecuteMainCommand(commandId));
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
else
|
||||
{
|
||||
_contextMenuEntries = null;
|
||||
}
|
||||
}, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user