f37369cdda
Co-authored-by: Cursor <cursoragent@cursor.com>
258 lines
10 KiB
C#
258 lines
10 KiB
C#
using HSUI.Config;
|
|
using HSUI.Enums;
|
|
using HSUI.Interface;
|
|
using HSUI.Interface.GeneralElements;
|
|
using HSUI.Interface.Jobs;
|
|
using HSUI.Interface.StatusEffects;
|
|
using Dalamud.Bindings.ImGui;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Numerics;
|
|
|
|
namespace HSUI.Helpers
|
|
{
|
|
public static class DraggablesHelper
|
|
{
|
|
public static void DrawGrid(GridConfig config, HUDOptionsConfig? hudConfig, DraggableHudElement? selectedElement)
|
|
{
|
|
ImGui.SetNextWindowPos(Vector2.Zero);
|
|
ImGui.SetNextWindowSize(ImGui.GetMainViewport().Size);
|
|
|
|
ImGui.SetNextWindowBgAlpha(config.BackgroundAlpha);
|
|
|
|
ImGui.Begin("DelvUI_grid",
|
|
ImGuiWindowFlags.NoTitleBar
|
|
| ImGuiWindowFlags.NoScrollbar
|
|
| ImGuiWindowFlags.AlwaysAutoResize
|
|
| ImGuiWindowFlags.NoInputs
|
|
| ImGuiWindowFlags.NoDecoration
|
|
| ImGuiWindowFlags.NoBringToFrontOnFocus
|
|
| ImGuiWindowFlags.NoFocusOnAppearing
|
|
);
|
|
|
|
ImDrawListPtr drawList = ImGui.GetWindowDrawList();
|
|
Vector2 screenSize = ImGui.GetMainViewport().Size;
|
|
Vector2 offset = hudConfig != null && hudConfig.UseGlobalHudShift ? hudConfig.HudOffset : Vector2.Zero;
|
|
Vector2 center = screenSize / 2f + offset;
|
|
|
|
// grid
|
|
if (config.ShowGrid)
|
|
{
|
|
int count = (int)(Math.Max(screenSize.X, screenSize.Y) / config.GridDivisionsDistance) / 2 + 1;
|
|
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
var step = i * config.GridDivisionsDistance;
|
|
|
|
drawList.AddLine(new Vector2(center.X + step, 0), new Vector2(center.X + step, screenSize.Y), 0x88888888);
|
|
drawList.AddLine(new Vector2(center.X - step, 0), new Vector2(center.X - step, screenSize.Y), 0x88888888);
|
|
|
|
drawList.AddLine(new Vector2(0, center.Y + step), new Vector2(screenSize.X, center.Y + step), 0x88888888);
|
|
drawList.AddLine(new Vector2(0, center.Y - step), new Vector2(screenSize.X, center.Y - step), 0x88888888);
|
|
|
|
if (config.GridSubdivisionCount > 1)
|
|
{
|
|
for (int j = 1; j < config.GridSubdivisionCount; j++)
|
|
{
|
|
var subStep = j * (config.GridDivisionsDistance / config.GridSubdivisionCount);
|
|
|
|
drawList.AddLine(new Vector2(center.X + step + subStep, 0), new Vector2(center.X + step + subStep, screenSize.Y), 0x44888888);
|
|
drawList.AddLine(new Vector2(center.X - step - subStep, 0), new Vector2(center.X - step - subStep, screenSize.Y), 0x44888888);
|
|
|
|
drawList.AddLine(new Vector2(0, center.Y + step + subStep), new Vector2(screenSize.X, center.Y + step + subStep), 0x44888888);
|
|
drawList.AddLine(new Vector2(0, center.Y - step - subStep), new Vector2(screenSize.X, center.Y - step - subStep), 0x44888888);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// center lines
|
|
if (config.ShowCenterLines)
|
|
{
|
|
drawList.AddLine(new Vector2(center.X, 0), new Vector2(center.X, screenSize.Y), 0xAAFFFFFF);
|
|
drawList.AddLine(new Vector2(0, center.Y), new Vector2(screenSize.X, center.Y), 0xAAFFFFFF);
|
|
}
|
|
|
|
if (config.ShowAnchorPoints && selectedElement != null)
|
|
{
|
|
Vector2 parentAnchorPos = center + selectedElement.ParentPos();
|
|
Vector2 anchorPos = parentAnchorPos + selectedElement.GetConfig().Position;
|
|
|
|
drawList.AddLine(parentAnchorPos, anchorPos, 0xAA0000FF, 2);
|
|
|
|
var anchorSize = new Vector2(10, 10);
|
|
drawList.AddRectFilled(anchorPos - anchorSize / 2f, anchorPos + anchorSize / 2f, 0xAA0000FF);
|
|
}
|
|
|
|
ImGui.End();
|
|
}
|
|
|
|
public static void DrawElements(
|
|
Vector2 origin,
|
|
HudHelper hudHelper,
|
|
IList<DraggableHudElement> elements,
|
|
JobHud? jobHud,
|
|
DraggableHudElement? selectedElement)
|
|
{
|
|
foreach (DraggableHudElement element in elements)
|
|
{
|
|
if (!hudHelper.IsElementHidden(element))
|
|
{
|
|
element.PrepareForDraw(origin);
|
|
}
|
|
}
|
|
|
|
jobHud?.PrepareForDraw(origin);
|
|
|
|
bool clip = ConfigurationManager.Instance?.LockHUD == true &&
|
|
ClipRectsHelper.Instance?.Enabled == true &&
|
|
ClipRectsHelper.Instance?.Mode == WindowClippingMode.Performance;
|
|
|
|
bool needsDraw = true;
|
|
|
|
if (clip)
|
|
{
|
|
ClipRect? clipRect = ClipRectsHelper.Instance?.GetClipRectForArea(Vector2.Zero, ImGui.GetMainViewport().Size);
|
|
if (clipRect.HasValue)
|
|
{
|
|
needsDraw = false;
|
|
|
|
ClipRect[] invertedClipRects = ClipRectsHelper.GetInvertedClipRects(clipRect.Value);
|
|
for (int i = 0; i < invertedClipRects.Length; i++)
|
|
{
|
|
ImGui.PushClipRect(invertedClipRects[i].Min, invertedClipRects[i].Max, false);
|
|
Draw(origin, hudHelper, elements, jobHud, selectedElement);
|
|
ImGui.PopClipRect();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (needsDraw)
|
|
{
|
|
Draw(origin, hudHelper, elements, jobHud, selectedElement);
|
|
}
|
|
}
|
|
|
|
private static void Draw(
|
|
Vector2 origin,
|
|
HudHelper hudHelper,
|
|
IList<DraggableHudElement> elements,
|
|
JobHud? jobHud,
|
|
DraggableHudElement? selectedElement)
|
|
{
|
|
bool canTakeInput = true;
|
|
bool jobHudNeedsDraw = jobHud != null && jobHud != selectedElement && !hudHelper.IsElementHidden(jobHud);
|
|
|
|
// selected
|
|
if (selectedElement != null)
|
|
{
|
|
if (!hudHelper.IsElementHidden(selectedElement))
|
|
{
|
|
selectedElement.CanTakeInputForDrag = true;
|
|
selectedElement.Draw(origin);
|
|
canTakeInput = !selectedElement.NeedsInputForDrag;
|
|
}
|
|
else if (selectedElement is IHudElementWithMouseOver elementWithMouseOver)
|
|
{
|
|
elementWithMouseOver.StopMouseover();
|
|
}
|
|
}
|
|
|
|
// all
|
|
foreach (DraggableHudElement element in elements)
|
|
{
|
|
if (element == selectedElement) { continue; }
|
|
|
|
if (jobHudNeedsDraw && jobHud != null && element.GetConfig().StrataLevel > jobHud.GetConfig().StrataLevel)
|
|
{
|
|
jobHud.CanTakeInputForDrag = canTakeInput;
|
|
jobHud.Draw(origin);
|
|
jobHudNeedsDraw = false;
|
|
}
|
|
|
|
if (!hudHelper.IsElementHidden(element))
|
|
{
|
|
element.CanTakeInputForDrag = canTakeInput;
|
|
element.Draw(origin);
|
|
canTakeInput = !canTakeInput ? false : !element.NeedsInputForDrag;
|
|
}
|
|
else if (element is IHudElementWithMouseOver elementWithMouseOver)
|
|
{
|
|
elementWithMouseOver.StopMouseover();
|
|
}
|
|
}
|
|
}
|
|
|
|
public static bool DrawArrows(Vector2 position, Vector2 size, string tooltipText, out Vector2 offset)
|
|
{
|
|
offset = Vector2.Zero;
|
|
|
|
var windowFlags = ImGuiWindowFlags.NoScrollbar
|
|
| ImGuiWindowFlags.NoTitleBar
|
|
| ImGuiWindowFlags.NoResize
|
|
| ImGuiWindowFlags.NoBackground
|
|
| ImGuiWindowFlags.NoDecoration
|
|
| ImGuiWindowFlags.NoSavedSettings;
|
|
|
|
var margin = new Vector2(4, 0);
|
|
var windowSize = ArrowSize + margin * 2;
|
|
|
|
// left, right, up, down
|
|
var positions = GetArrowPositions(position, size);
|
|
var offsets = new Vector2[]
|
|
{
|
|
new Vector2(-1, 0),
|
|
new Vector2(1, 0),
|
|
new Vector2(0, -1),
|
|
new Vector2(0, 1)
|
|
};
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
var pos = positions[i] - margin;
|
|
|
|
ImGui.SetNextWindowSize(windowSize, ImGuiCond.Always);
|
|
ImGui.SetNextWindowPos(pos);
|
|
|
|
ImGui.Begin("DelvUI_draggablesArrow " + i.ToString(), windowFlags);
|
|
|
|
// fake button
|
|
ImGuiP.ArrowButtonEx($"arrow button {i}", (ImGuiDir)i, new Vector2(ArrowSize.X, ArrowSize.Y));
|
|
if (ImGui.IsMouseHoveringRect(pos, pos + windowSize))
|
|
{
|
|
// track click manually to not deal with window focus stuff
|
|
if (ImGui.IsMouseClicked(ImGuiMouseButton.Left))
|
|
{
|
|
offset = offsets[i];
|
|
}
|
|
|
|
// tooltip
|
|
TooltipsHelper.Instance.ShowTooltipOnCursor(tooltipText);
|
|
}
|
|
|
|
ImGui.End();
|
|
}
|
|
|
|
return offset != Vector2.Zero;
|
|
}
|
|
|
|
public static Vector2 ArrowSize = new Vector2(40, 40);
|
|
|
|
public static Vector2[] GetArrowPositions(Vector2 position, Vector2 size)
|
|
{
|
|
return GetArrowPositions(position, size, ArrowSize);
|
|
}
|
|
|
|
public static Vector2[] GetArrowPositions(Vector2 position, Vector2 size, Vector2 arrowSize)
|
|
{
|
|
return new Vector2[]
|
|
{
|
|
new Vector2(position.X - arrowSize.X + 10, position.Y + size.Y / 2f - arrowSize.Y / 2f - 2),
|
|
new Vector2(position.X + size.X - 8, position.Y + size.Y / 2f - arrowSize.Y / 2f - 2),
|
|
new Vector2(position.X + size.X / 2f - arrowSize.X / 2f + 2, position.Y - arrowSize.Y + 1),
|
|
new Vector2(position.X + size.X / 2f - arrowSize.X / 2f + 2, position.Y + size.Y - 7)
|
|
};
|
|
}
|
|
}
|
|
}
|