9659f7a7d1
Made-with: Cursor
128 lines
5.3 KiB
C#
128 lines
5.3 KiB
C#
using System;
|
|
using System.Numerics;
|
|
using Dalamud.Bindings.ImGui;
|
|
using Dalamud.Interface.Utility.Raii;
|
|
using KamiLib.Window;
|
|
using Mappy.Controllers;
|
|
using Mappy.Data;
|
|
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
|
|
|
namespace Mappy.Windows;
|
|
|
|
public class MinimapWindow : Window
|
|
{
|
|
public MinimapWindow() : base("HSMappy Minimap###HSMappyMinimap", new Vector2(200.0f, 200.0f))
|
|
{
|
|
DisableWindowSounds = true;
|
|
Flags |= ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoScrollWithMouse;
|
|
}
|
|
|
|
public override bool DrawConditions() =>
|
|
IntegrationsController.ShouldShowMinimap() && System.SystemConfig.ShowMinimap;
|
|
|
|
public override void PreOpenCheck()
|
|
{
|
|
if (Service.ClientState is { IsLoggedIn: false } or { IsPvP: true })
|
|
IsOpen = false;
|
|
}
|
|
|
|
protected override unsafe void DrawContents()
|
|
{
|
|
var agent = AgentMap.Instance();
|
|
// Try loading from Lumina first so minimap can show without ever opening the area map
|
|
if (!System.MapRenderer.HasMinimapCacheFor(agent->CurrentMapId) && agent->SelectedMapId != agent->CurrentMapId)
|
|
System.MapRenderer.TryEnsureLuminaCacheFor(agent->CurrentMapId);
|
|
|
|
var mapLoaded = agent->SelectedMapId == agent->CurrentMapId || System.MapRenderer.HasMinimapCacheFor(agent->CurrentMapId);
|
|
|
|
if (!mapLoaded)
|
|
{
|
|
// Map data could not be loaded for this area (no Lumina path matched). Minimap shows automatically when data is available.
|
|
const string hint = "Map unavailable for this area.";
|
|
var textSize = ImGui.CalcTextSize(hint);
|
|
var pos = (ImGui.GetWindowSize() - textSize) * 0.5f;
|
|
ImGui.SetCursorPos(new Vector2(Math.Max(0, pos.X), Math.Max(20, pos.Y)));
|
|
ImGui.TextColored(new Vector4(0.7f, 0.7f, 0.7f, 0.9f), hint);
|
|
UpdateStyle();
|
|
UpdateSizePosition();
|
|
return;
|
|
}
|
|
|
|
UpdateStyle();
|
|
UpdateSizePosition();
|
|
|
|
// Compensate for window padding: draw the minimap child so it fills the full window (no black bands).
|
|
var padding = ImGui.GetStyle().WindowPadding;
|
|
var winSize = ImGui.GetWindowSize();
|
|
ImGui.SetCursorPos(new Vector2(-padding.X, -padding.Y));
|
|
var contentSize = winSize;
|
|
|
|
if (contentSize.X <= 0 || contentSize.Y <= 0) return;
|
|
|
|
using (ImRaii.PushStyle(ImGuiStyleVar.Alpha, System.SystemConfig.MinimapOpacity))
|
|
using (ImRaii.PushStyle(ImGuiStyleVar.ChildBorderSize, 0f))
|
|
using (ImRaii.PushStyle(ImGuiStyleVar.WindowPadding, Vector2.Zero))
|
|
using (var child = ImRaii.Child("minimap_render", contentSize, false, ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse))
|
|
{
|
|
if (child) {
|
|
// Use window size so map fills the full window; renderer clamps draw position so map always covers the view.
|
|
System.MapRenderer.DrawMinimapContents(contentSize);
|
|
// Mouse wheel over minimap: zoom in/out, and consume wheel so the window doesn't scroll
|
|
if (ImGui.IsItemHovered()) {
|
|
var io = ImGui.GetIO();
|
|
var wheel = io.MouseWheel;
|
|
if (wheel != 0) {
|
|
var zoom = System.SystemConfig.MinimapZoom;
|
|
zoom -= wheel * 0.012f; // Small step so zoom is incremental between max out (0.1) and max in (0.03)
|
|
System.SystemConfig.MinimapZoom = Math.Clamp(zoom, 0.03f, 0.112f);
|
|
SystemConfig.Save();
|
|
}
|
|
// Consume wheel so the window doesn't scroll when at min/max zoom or when we handled it
|
|
io.MouseWheel = 0f;
|
|
io.MouseWheelH = 0f;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Restore default padding for the next window is done in plugin Draw callback (PopStyleVar after all windows).
|
|
}
|
|
|
|
public override void OnOpen()
|
|
{
|
|
ImGui.SetWindowPos(System.SystemConfig.MinimapPosition);
|
|
ImGui.SetWindowSize(new Vector2(System.SystemConfig.MinimapSize, System.SystemConfig.MinimapSize));
|
|
}
|
|
|
|
private void UpdateStyle()
|
|
{
|
|
if (System.SystemConfig.MinimapLockPosition)
|
|
Flags |= ImGuiWindowFlags.NoMove;
|
|
else
|
|
Flags &= ~ImGuiWindowFlags.NoMove;
|
|
}
|
|
|
|
private void UpdateSizePosition()
|
|
{
|
|
var config = System.SystemConfig;
|
|
var windowPosition = ImGui.GetWindowPos();
|
|
var windowSize = ImGui.GetWindowSize();
|
|
var configSize = config.MinimapSize;
|
|
|
|
// Size is config-only (set in Mappy settings); always apply config size to window.
|
|
if (Math.Abs(windowSize.X - configSize) > 0.1f || Math.Abs(windowSize.Y - configSize) > 0.1f)
|
|
ImGui.SetWindowSize(new Vector2(configSize, configSize));
|
|
|
|
if (!ImGui.IsWindowFocused(ImGuiFocusedFlags.RootAndChildWindows)) {
|
|
// Not focused: apply config position to window
|
|
if (windowPosition != config.MinimapPosition)
|
|
ImGui.SetWindowPos(config.MinimapPosition);
|
|
} else {
|
|
// Focused: save window position to config (size is changed only via settings)
|
|
if (config.MinimapPosition != windowPosition) {
|
|
config.MinimapPosition = windowPosition;
|
|
SystemConfig.Save();
|
|
}
|
|
}
|
|
}
|
|
}
|