Initial HSMappy release (fork of Mappy)
Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user