293f83dc36
Made-with: Cursor
191 lines
8.9 KiB
C#
191 lines
8.9 KiB
C#
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);
|
|
});
|
|
}
|
|
}
|
|
}
|