using System; using System.Drawing; using System.Linq; using System.Numerics; using Dalamud.Bindings.ImGui; using Dalamud.Interface; using Dalamud.Interface.Components; using Dalamud.Interface.Utility; using Dalamud.Interface.Utility.Raii; using KamiLib.Classes; using KamiLib.CommandManager; using KamiLib.Extensions; using KamiLib.Window; using Mappy.Classes; using Mappy.Data; namespace Mappy.Windows; public class ConfigurationWindow : Window { private readonly TabBar tabBar = new("mappy_tab_bar", [ new IconConfigurationTab(), new MapFunctionsTab(), new StyleOptionsTab(), new MinimapOptionsTab(), new PlayerOptionsTab(), ]); public ConfigurationWindow() : base("HSMappy Configuration Window", new Vector2(500.0f, 580.0f)) { System.CommandManager.RegisterCommand(new CommandHandler { Delegate = _ => System.ConfigWindow.Toggle(), ActivationPath = "/", }); } protected override void DrawContents() => tabBar.Draw(); } public class MapFunctionsTab : ITabItem { public string Name => "Map Functions"; public bool Disabled => false; public void Draw() { var configChanged = false; ImGuiTweaks.Header("Zoom Options"); using (ImRaii.PushIndent()) { configChanged |= ImGui.Checkbox("Use Linear Zoom", ref System.SystemConfig.UseLinearZoom); configChanged |= ImGui.Checkbox("Scale icons with zoom", ref System.SystemConfig.ScaleWithZoom); configChanged |= ImGui.Checkbox("Scale text labels with zoom", ref System.SystemConfig.ScaleTextWithZoom); ImGuiHelpers.ScaledDummy(5.0f); configChanged |= ImGuiTweaks.Checkbox("Auto Zoom", ref System.SystemConfig.AutoZoom, "Automatically sets zoom to a reasonable value relative to the map size."); configChanged |= ImGui.SliderFloat("Auto Zoom Scale Factor", ref System.SystemConfig.AutoZoomScaleFactor, 0.20f, 1.00f); ImGuiHelpers.ScaledDummy(5.0f); configChanged |= ImGui.SliderFloat("Zoom Speed", ref System.SystemConfig.ZoomSpeed, 0.001f, 0.500f); configChanged |= ImGui.SliderFloat("Icon Scale", ref System.SystemConfig.IconScale, 0.10f, 3.0f); } ImGuiTweaks.Header("When Opening Map"); using (ImRaii.PushIndent()) { configChanged |= ImGui.Checkbox("Follow On Open", ref System.SystemConfig.FollowOnOpen); ImGuiHelpers.ScaledDummy(5.0f); DrawCenterModeRadio(); } ImGuiTweaks.Header("Link Behaviors"); using (ImRaii.PushIndent()) { configChanged |= ImGui.Checkbox("Center on Flags", ref System.SystemConfig.CenterOnFlag); configChanged |= ImGui.Checkbox("Center on Gathering Areas", ref System.SystemConfig.CenterOnGathering); configChanged |= ImGui.Checkbox("Center on Quest", ref System.SystemConfig.CenterOnQuest); } ImGuiTweaks.Header("Misc Options"); using (ImRaii.PushIndent()) { configChanged |= ImGui.Checkbox("Show Misc Tooltips", ref System.SystemConfig.ShowMiscTooltips); configChanged |= ImGui.Checkbox("Lock Map on Center", ref System.SystemConfig.LockCenterOnMap); configChanged |= ImGui.Checkbox("Show Other Players", ref System.SystemConfig.ShowPlayers); configChanged |= ImGui.Checkbox("Disable Map Focus on Appear", ref System.SystemConfig.NoFocusOnAppear); configChanged |= ImGui.Checkbox("Suppress the native map's open/close sound effect.", ref System.SystemConfig.SuppressNativeMapOpenSound); ImGuiHelpers.ScaledDummy(5.0f); configChanged |= ImGui.Checkbox("Show Text Labels", ref System.SystemConfig.ShowTextLabels); configChanged |= ImGui.DragFloat("Large Label Scale", ref System.SystemConfig.LargeAreaTextScale, 0.01f, 1.0f, 4.0f); configChanged |= ImGui.DragFloat("Small Label Scale", ref System.SystemConfig.SmallAreaTextScale, 0.01f, 0.5f, 3.0f); ImGuiHelpers.ScaledDummy(5.0f); configChanged |= ImGui.Checkbox("Show Fog of War", ref System.SystemConfig.ShowFogOfWar); ImGuiHelpers.ScaledDummy(5.0f); configChanged |= ImGui.Checkbox("Debug Mode", ref System.SystemConfig.DebugMode); } ImGuiTweaks.Header("Toolbar"); using (ImRaii.PushIndent()) { configChanged |= ImGui.Checkbox("Always Show", ref System.SystemConfig.AlwaysShowToolbar); configChanged |= ImGui.Checkbox("Show On Hover", ref System.SystemConfig.ShowToolbarOnHover); ImGuiHelpers.ScaledDummy(5.0f); configChanged |= ImGui.DragFloat("Opacity##toolbar", ref System.SystemConfig.ToolbarFade, 0.01f, 0.0f, 1.0f); } ImGuiTweaks.Header("Coordinates"); using (ImRaii.PushIndent()) { configChanged |= ImGui.Checkbox("Show Coordinate Bar", ref System.SystemConfig.ShowCoordinateBar); ImGuiHelpers.ScaledDummy(5.0f); configChanged |= ImGuiTweaks.ColorEditWithDefault("Text Color", ref System.SystemConfig.CoordinateTextColor, KnownColor.White.Vector()); ImGuiHelpers.ScaledDummy(5.0f); configChanged |= ImGui.DragFloat("Opacity##coordinatebar", ref System.SystemConfig.CoordinateBarFade, 0.01f, 0.0f, 1.0f); } if (configChanged) { SystemConfig.Save(); } } private void DrawCenterModeRadio() { var enumObject = System.SystemConfig.CenterOnOpen; var firstLine = true; foreach (Enum enumValue in Enum.GetValues(enumObject.GetType())) { if (!firstLine) ImGui.SameLine(); if (ImGui.RadioButton(enumValue.GetDescription(), enumValue.Equals(enumObject))) { System.SystemConfig.CenterOnOpen = (CenterTarget)enumValue; SystemConfig.Save(); } firstLine = false; } ImGui.SameLine(); ImGui.Text("\t\tCenter on Open"); } } public class StyleOptionsTab : ITabItem { public string Name => "Style"; public bool Disabled => false; public void Draw() { var configChanged = false; ImGuiTweaks.Header("Window Options"); using (ImRaii.PushIndent()) { configChanged |= ImGui.Checkbox("Keep Open", ref System.SystemConfig.KeepOpen); configChanged |= ImGui.Checkbox("Lock Window Position", ref System.SystemConfig.LockWindow); configChanged |= ImGui.Checkbox("Hide Window Frame", ref System.SystemConfig.HideWindowFrame); configChanged |= ImGui.Checkbox("Hide Window Background", ref System.SystemConfig.HideWindowBackground); configChanged |= ImGui.Checkbox("Enable Shift + Drag to Move Window Frame", ref System.SystemConfig.EnableShiftDragMove); } ImGuiTweaks.Header("Window Hiding"); using (ImRaii.PushIndent()) { configChanged |= ImGui.Checkbox("Hide With Game GUI", ref System.SystemConfig.HideWithGameGui); configChanged |= ImGui.Checkbox("Hide Between Areas", ref System.SystemConfig.HideBetweenAreas); configChanged |= ImGui.Checkbox("Hide in Combat", ref System.SystemConfig.HideInCombat); } ImGuiTweaks.Header("Window Title"); using (ImRaii.PushIndent()) { configChanged |= ImGui.Checkbox("Show Region Text", ref System.SystemConfig.ShowRegionLabel); configChanged |= ImGui.Checkbox("Show Map Text", ref System.SystemConfig.ShowMapLabel); configChanged |= ImGui.Checkbox("Show Area Text", ref System.SystemConfig.ShowAreaLabel); configChanged |= ImGui.Checkbox("Show Sub-Area Text", ref System.SystemConfig.ShowSubAreaLabel); } ImGuiTweaks.Header("Window Location"); using (ImRaii.PushIndent()) { configChanged |= ImGui.DragFloat2("Window Position", ref System.SystemConfig.WindowPosition); configChanged |= ImGui.DragFloat2("Window Size", ref System.SystemConfig.WindowSize); } ImGuiTweaks.Header("Fade Options"); using (ImRaii.PushIndent()) { using (var columns = ImRaii.Table("fade_options_toggles", 2)) { if (!columns) return; var value = System.SystemConfig.FadeMode; ImGui.TableNextColumn(); foreach (Enum enumValue in Enum.GetValues(value.GetType())) { var isFlagSet = value.HasFlag(enumValue); if (ImGuiComponents.ToggleButton(enumValue.ToString(), ref isFlagSet)) { var sourceValue = Convert.ToInt32(value); var targetValue = Convert.ToInt32(enumValue); if (value.HasFlag(enumValue)) { System.SystemConfig.FadeMode = (FadeMode)Enum.ToObject(value.GetType(), sourceValue & ~targetValue); } else { System.SystemConfig.FadeMode = (FadeMode)Enum.ToObject(value.GetType(), sourceValue | targetValue); } configChanged = true; } ImGui.SameLine(); ImGui.TextUnformatted(enumValue.GetDescription()); ImGui.TableNextColumn(); } } configChanged |= ImGui.DragFloat("Fade Opacity", ref System.SystemConfig.FadePercent, 0.01f, 0.05f, 1.0f); } ImGuiTweaks.Header("Area Style"); using (ImRaii.PushIndent()) { configChanged |= ImGuiTweaks.ColorEditWithDefault("Area Color", ref System.SystemConfig.AreaColor, KnownColor.CornflowerBlue.Vector() with { W = 0.33f }); configChanged |= ImGuiTweaks.ColorEditWithDefault("Area Outline Color", ref System.SystemConfig.AreaOutlineColor, KnownColor.CornflowerBlue.Vector() with { W = 0.30f }); } if (configChanged) { if (System.MapWindow.SizeConstraints is { } constraints) { System.SystemConfig.WindowSize.X = MathF.Max(System.SystemConfig.WindowSize.X, constraints.MinimumSize.X); System.SystemConfig.WindowSize.Y = MathF.Max(System.SystemConfig.WindowSize.Y, constraints.MinimumSize.Y); } System.MapWindow.RefreshTitle(); SystemConfig.Save(); } } } public class MinimapOptionsTab : ITabItem { public string Name => "Minimap"; public bool Disabled => false; public void Draw() { var configChanged = false; ImGuiTweaks.Header("Minimap"); using (ImRaii.PushIndent()) { var showMinimap = System.SystemConfig.ShowMinimap; if (ImGui.Checkbox("Show Minimap", ref showMinimap)) { System.SystemConfig.ShowMinimap = showMinimap; configChanged = true; if (showMinimap) System.MinimapWindow?.UnCollapseOrShow(); } ImGuiHelpers.ScaledDummy(5.0f); configChanged |= ImGui.DragFloat("Size", ref System.SystemConfig.MinimapSize, 5.0f, 80.0f, 400.0f, "%.0f"); if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)) ImGui.SetTooltip("Minimap size. Resize only via this setting (no corner grip)."); configChanged |= ImGui.DragFloat2("Position", ref System.SystemConfig.MinimapPosition); configChanged |= ImGui.DragFloat("Opacity", ref System.SystemConfig.MinimapOpacity, 0.01f, 0.2f, 1.0f); configChanged |= ImGui.SliderFloat("Zoom Level", ref System.SystemConfig.MinimapZoom, 0.03f, 0.112f, "%.2f (0.1 = zoomed out, lower = zoomed in)"); configChanged |= ImGui.Checkbox("Show Player Cone", ref System.SystemConfig.MinimapShowPlayerCone); configChanged |= ImGui.Checkbox("Show Quest Direction Arrow", ref System.SystemConfig.MinimapShowQuestDirectionArrow); if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)) ImGui.SetTooltip("Show an arrow at the edge of the minimap pointing toward your quest objective or waymark (like the default game minimap)."); configChanged |= ImGui.Checkbox("Show FATE Direction Arrows", ref System.SystemConfig.MinimapShowFateDirectionArrows); if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)) ImGui.SetTooltip("Show purple arrows at the edge of the minimap pointing toward nearby FATEs."); configChanged |= ImGui.Checkbox("Show Flag Direction Arrow", ref System.SystemConfig.MinimapShowFlagDirectionArrow); if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)) ImGui.SetTooltip("Show a red arrow at the edge of the minimap pointing toward your placed flag."); configChanged |= ImGui.Checkbox("Show Quest Area Radius", ref System.SystemConfig.MinimapShowQuestAreaRadius); if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)) ImGui.SetTooltip("Show quest objective area circles on the minimap (same as on the Area Map)."); configChanged |= ImGui.Checkbox("Show Players and NPCs", ref System.SystemConfig.MinimapShowPlayersAndNpcs); if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)) ImGui.SetTooltip("Show Player/NPC tracking on the minimap (other players, enemies, bosses, etc.), matching the main map display."); var otherPlayerIcon = (int)System.SystemConfig.MinimapOtherPlayerIconId; if (ImGui.DragInt("Other Player Icon (minimap)", ref otherPlayerIcon, 1.0f, 60000, 61000, "%d")) { System.SystemConfig.MinimapOtherPlayerIconId = (uint)Math.Clamp(otherPlayerIcon, 60000, 61000); configChanged = true; } if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)) ImGui.SetTooltip("Icon ID for other players on the minimap (default 60403). Must be distinct from party marker (60421)."); configChanged |= ImGui.Checkbox("Hide Minimap With Game GUI", ref System.SystemConfig.MinimapHideWithGameGui); if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)) ImGui.SetTooltip("When enabled, the minimap hides during NPC dialogue, object interaction, and when the game hides nameplates (same as the main map). When disabled, the minimap stays visible in those situations."); configChanged |= ImGui.Checkbox("Lock Position", ref System.SystemConfig.MinimapLockPosition); } if (configChanged) { SystemConfig.Save(); } } } public class PlayerOptionsTab : ITabItem { public string Name => "Player"; public bool Disabled => false; public void Draw() { var configChanged = false; ImGuiTweaks.Header("Cone Options"); using (ImRaii.PushIndent()) { configChanged |= ImGui.Checkbox("Scale Player Cone", ref System.SystemConfig.ScalePlayerCone); ImGuiHelpers.ScaledDummy(5.0f); configChanged |= ImGui.DragFloat("Cone Size", ref System.SystemConfig.ConeSize, 0.25f); ImGuiHelpers.ScaledDummy(5.0f); configChanged |= ImGuiTweaks.ColorEditWithDefault("Cone Color", ref System.SystemConfig.PlayerConeColor, KnownColor.CornflowerBlue.Vector() with { W = 0.33f }); configChanged |= ImGuiTweaks.ColorEditWithDefault("Cone Outline Color", ref System.SystemConfig.PlayerConeOutlineColor, KnownColor.CornflowerBlue.Vector() with { W = 1.00f }); } ImGuiTweaks.Header("Radar Options"); using (ImRaii.PushIndent()) { configChanged |= ImGui.Checkbox("Show Radar Radius", ref System.SystemConfig.ShowRadar); configChanged |= ImGui.Checkbox("Show in Duties", ref System.SystemConfig.ShowRadarInDuties); ImGuiHelpers.ScaledDummy(5.0f); configChanged |= ImGuiTweaks.ColorEditWithDefault("Radar Area Color", ref System.SystemConfig.RadarColor, KnownColor.Gray.Vector() with { W = 0.10f }); configChanged |= ImGuiTweaks.ColorEditWithDefault("Radar Outline Color", ref System.SystemConfig.RadarOutlineColor, KnownColor.Gray.Vector() with { W = 0.30f }); } ImGuiTweaks.Header("Player Icon Options"); using (ImRaii.PushIndent()) { configChanged |= ImGui.Checkbox("Show Player Icon", ref System.SystemConfig.ShowPlayerIcon); ImGuiHelpers.ScaledDummy(5.0f); configChanged |= ImGui.DragFloat("Player Icon Size", ref System.SystemConfig.PlayerIconScale, 0.05f); } if (configChanged) { SystemConfig.Save(); } } } public class IconConfigurationTab : ITabItem { public string Name => "Icon Settings"; public bool Disabled => false; private IconSetting? currentSetting; public void Draw() { using (var leftChild = ImRaii.Child("left_child", new Vector2(48.0f * ImGuiHelpers.GlobalScale + ImGui.GetStyle().ItemSpacing.X, ImGui.GetContentRegionAvail().Y))) { if (leftChild) { using var selectionList = ImRaii.ListBox("iconSelection", ImGui.GetContentRegionAvail()); foreach (var (iconId, settings) in System.IconConfig.IconSettingMap.OrderBy(pairData => pairData.Key)) { if (iconId is 0) continue; if (DrawHelpers.IsDisallowedIcon(iconId)) continue; var texture = Service.TextureProvider.GetFromGameIcon(iconId).GetWrapOrEmpty(); var cursorStart = ImGui.GetCursorScreenPos(); if (ImGui.Selectable($"##iconSelect{iconId}", currentSetting == settings, ImGuiSelectableFlags.None, ImGuiHelpers.ScaledVector2(32.0f, 32.0f))) { currentSetting = currentSetting == settings ? null : settings; } ImGui.SetCursorScreenPos(cursorStart); ImGui.Image(texture.Handle, texture.Size / 2.0f * ImGuiHelpers.GlobalScale); } } } ImGui.SameLine(); using (var rightChild = ImRaii.Child("right_child", ImGui.GetContentRegionAvail(), false, ImGuiWindowFlags.NoScrollbar)) { if (rightChild) { if (currentSetting is null) { using var textColor = ImRaii.PushColor(ImGuiCol.Text, KnownColor.Orange.Vector()); ImGui.SetCursorPosY(ImGui.GetContentRegionAvail().Y / 2.0f); ImGuiHelpers.CenteredText("Select an Icon to Edit Settings"); } else { // Draw background texture var settingsChanged = false; var texture = Service.TextureProvider.GetFromGameIcon(currentSetting.IconId).GetWrapOrEmpty(); var smallestAxis = MathF.Min(ImGui.GetContentRegionAvail().X, ImGui.GetContentRegionAvail().Y); if (ImGui.GetContentRegionAvail().X > ImGui.GetContentRegionAvail().Y) { var remainingSpace = ImGui.GetContentRegionAvail().X - smallestAxis; ImGui.SetCursorPosX(remainingSpace / 2.0f); } ImGui.Image(texture.Handle, new Vector2(smallestAxis, smallestAxis), Vector2.Zero, Vector2.One, new Vector4(1.0f, 1.0f, 1.0f, 0.20f)); ImGui.SetCursorPos(Vector2.Zero); // Draw settings ImGuiTweaks.Header($"Configure Marker #{currentSetting.IconId}"); using (ImRaii.PushIndent()) { settingsChanged |= ImGui.Checkbox("Hide Icon", ref currentSetting.Hide); settingsChanged |= ImGui.Checkbox("Allow Tooltip", ref currentSetting.AllowTooltip); settingsChanged |= ImGui.Checkbox("Allow Click Interaction", ref currentSetting.AllowClick); ImGuiHelpers.ScaledDummy(5.0f); settingsChanged |= ImGuiTweaks.ColorEditWithDefault("Color", ref currentSetting.Color, KnownColor.White.Vector()); ImGuiHelpers.ScaledDummy(5.0f); settingsChanged |= ImGui.DragFloat("Icon Scale", ref currentSetting.Scale, 0.01f, 0.05f, 20.0f); } ImGui.SetCursorPosY(ImGui.GetContentRegionMax().Y - 25.0f * ImGuiHelpers.GlobalScale); if (ImGui.Button("Reset to Default", new Vector2(ImGui.GetContentRegionAvail().X, 25.0f * ImGuiHelpers.GlobalScale))) { currentSetting.Reset(); System.IconConfig.Save(); } if (settingsChanged) { System.IconConfig.Save(); } } } } } }