Files
HSUI/Helpers/DraggablesHelper.cs

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)
};
}
}
}