From ee62e50390b6b816322e43cf8f3ecf2b00ee5a35 Mon Sep 17 00:00:00 2001 From: Anna Date: Sun, 27 Jun 2021 18:56:44 -0400 Subject: [PATCH] feat(housing): add bookmarks --- RoleplayersToolbox/Tools/Housing/Bookmark.cs | 25 +++ .../Tools/Housing/BookmarksUi.cs | 180 ++++++++++++++++++ .../Tools/Housing/HousingConfig.cs | 2 + .../Tools/Housing/HousingTool.cs | 32 +++- RoleplayersToolbox/Util.cs | 25 +++ 5 files changed, 258 insertions(+), 6 deletions(-) create mode 100755 RoleplayersToolbox/Tools/Housing/Bookmark.cs create mode 100755 RoleplayersToolbox/Tools/Housing/BookmarksUi.cs diff --git a/RoleplayersToolbox/Tools/Housing/Bookmark.cs b/RoleplayersToolbox/Tools/Housing/Bookmark.cs new file mode 100755 index 0000000..3d9fca2 --- /dev/null +++ b/RoleplayersToolbox/Tools/Housing/Bookmark.cs @@ -0,0 +1,25 @@ +using System; + +namespace RoleplayersToolbox.Tools.Housing { + [Serializable] + internal class Bookmark { + public string Name; + public uint WorldId; + public HousingArea Area; + public uint Ward; + public uint Plot; + + public Bookmark(string name) { + this.Name = name; + } + + internal Bookmark Clone() { + return new(this.Name) { + WorldId = this.WorldId, + Area = this.Area, + Ward = this.Ward, + Plot = this.Plot, + }; + } + } +} diff --git a/RoleplayersToolbox/Tools/Housing/BookmarksUi.cs b/RoleplayersToolbox/Tools/Housing/BookmarksUi.cs new file mode 100755 index 0000000..b36b0ce --- /dev/null +++ b/RoleplayersToolbox/Tools/Housing/BookmarksUi.cs @@ -0,0 +1,180 @@ +using System; +using System.Numerics; +using Dalamud.Interface; +using ImGuiNET; +using Lumina.Excel.GeneratedSheets; + +namespace RoleplayersToolbox.Tools.Housing { + internal class BookmarksUi { + private Plugin Plugin { get; } + private HousingTool Tool { get; } + private HousingConfig Config { get; } + private (Bookmark editing, int index)? _editing; + + internal bool ShouldDraw; + + internal BookmarksUi(Plugin plugin, HousingTool tool, HousingConfig config) { + this.Plugin = plugin; + this.Tool = tool; + this.Config = config; + } + + internal void Draw() { + if (!this.ShouldDraw) { + return; + } + + this.AddEditWindow(); + + if (!ImGui.Begin("Housing Bookmarks", ref this.ShouldDraw)) { + ImGui.End(); + return; + } + + if (Util.IconButton(FontAwesomeIcon.Plus)) { + this._editing = (new Bookmark(string.Empty), -1); + } + + var toDelete = -1; + + if (ImGui.BeginChild("bookmark-list", new Vector2(-1, -1))) { + for (var i = 0; i < this.Config.Bookmarks.Count; i++) { + var bookmark = this.Config.Bookmarks[i]; + var hash = bookmark.GetHashCode().ToString(); + + if (ImGui.TreeNode($"{bookmark.Name}##{hash}")) { + var worldName = this.Plugin.Interface.Data.GetExcelSheet().GetRow(bookmark.WorldId)?.Name; + ImGui.TextUnformatted($"{worldName}/{bookmark.Area.Name()}/W{bookmark.Ward}/P{bookmark.Plot}"); + + if (Util.IconButton(FontAwesomeIcon.MapMarkerAlt, hash)) { + this.Tool.FlagHouseOnMap(bookmark.Area, bookmark.Plot); + } + + Util.Tooltip("Show on map"); + + ImGui.SameLine(); + + if (Util.IconButton(FontAwesomeIcon.Route, hash)) { + this.Tool.Destination = new DestinationInfo( + this.Tool.Info, + this.Plugin.Interface.Data.GetExcelSheet().GetRow(bookmark.WorldId), + bookmark.Area, + bookmark.Ward, + bookmark.Plot + ); + } + + Util.Tooltip("Open routing window"); + + ImGui.SameLine(); + + if (Util.IconButton(FontAwesomeIcon.PencilAlt, hash)) { + this._editing = (bookmark.Clone(), i); + } + + Util.Tooltip("Edit"); + + ImGui.SameLine(); + + if (Util.IconButton(FontAwesomeIcon.Trash, hash)) { + toDelete = i; + } + + Util.Tooltip("Delete"); + + ImGui.TreePop(); + } + + ImGui.Separator(); + } + + ImGui.EndChild(); + } + + if (toDelete > -1) { + this.Config.Bookmarks.RemoveAt(toDelete); + this.Plugin.SaveConfig(); + } + + ImGui.End(); + } + + private void AddEditWindow() { + if (this._editing == null) { + return; + } + + if (!ImGui.Begin("Edit bookmark", ImGuiWindowFlags.AlwaysAutoResize)) { + ImGui.End(); + return; + } + + var (bookmark, index) = this._editing.Value; + + ImGui.InputText("Name", ref bookmark.Name, 255); + + var world = bookmark.WorldId == 0 + ? null + : this.Plugin.Interface.Data.GetExcelSheet().GetRow(bookmark.WorldId); + if (ImGui.BeginCombo("World", world?.Name?.ToString() ?? string.Empty)) { + var dataCentre = this.Plugin.Interface.ClientState.LocalPlayer?.HomeWorld?.GameData?.DataCenter?.Row; + + foreach (var availWorld in this.Plugin.Interface.Data.GetExcelSheet()) { + if (availWorld.DataCenter.Row != dataCentre || !availWorld.IsPublic) { + continue; + } + + if (!ImGui.Selectable(availWorld.Name.ToString())) { + continue; + } + + bookmark.WorldId = availWorld.RowId; + } + + ImGui.EndCombo(); + } + + var area = bookmark.Area; + if (ImGui.BeginCombo("Housing area", area != 0 ? area.Name() : string.Empty)) { + foreach (var housingArea in (HousingArea[]) Enum.GetValues(typeof(HousingArea))) { + if (!ImGui.Selectable(housingArea.Name(), area == housingArea)) { + continue; + } + + bookmark.Area = housingArea; + } + + ImGui.EndCombo(); + } + + var ward = (int) bookmark.Ward; + if (ImGui.InputInt("Ward", ref ward)) { + bookmark.Ward = (uint) Math.Max(1, Math.Min(24, ward)); + } + + var plot = (int) bookmark.Plot; + if (ImGui.InputInt("Plot", ref plot)) { + bookmark.Plot = (uint) Math.Max(1, Math.Min(60, plot)); + } + + if (ImGui.Button("Save")) { + if (index < 0) { + this.Config.Bookmarks.Add(bookmark); + } else if (index < this.Config.Bookmarks.Count) { + this.Config.Bookmarks[index] = bookmark; + } + + this.Plugin.SaveConfig(); + this._editing = null; + } + + ImGui.SameLine(); + + if (ImGui.Button("Cancel")) { + this._editing = null; + } + + ImGui.End(); + } + } +} diff --git a/RoleplayersToolbox/Tools/Housing/HousingConfig.cs b/RoleplayersToolbox/Tools/Housing/HousingConfig.cs index 4cfcc72..0d5d725 100755 --- a/RoleplayersToolbox/Tools/Housing/HousingConfig.cs +++ b/RoleplayersToolbox/Tools/Housing/HousingConfig.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using RoleplayersToolbox.Tools.Housing; namespace RoleplayersToolbox.Tools { @@ -13,5 +14,6 @@ namespace RoleplayersToolbox.Tools.Housing { public bool PlaceFlagOnSelect = true; public bool CloseMapOnApproach = true; public bool ClearFlagOnApproach = true; + public List Bookmarks = new(); } } diff --git a/RoleplayersToolbox/Tools/Housing/HousingTool.cs b/RoleplayersToolbox/Tools/Housing/HousingTool.cs index 230d4dd..57daf3d 100755 --- a/RoleplayersToolbox/Tools/Housing/HousingTool.cs +++ b/RoleplayersToolbox/Tools/Housing/HousingTool.cs @@ -31,12 +31,13 @@ namespace RoleplayersToolbox.Tools.Housing { public override string Name => "Housing"; private Plugin Plugin { get; } private HousingConfig Config { get; } - private HousingInfo Info { get; } + internal HousingInfo Info { get; } + private BookmarksUi BookmarksUi { get; } private Teleport Teleport { get; } private DestinationInfo? _destination; - private DestinationInfo? Destination { + internal DestinationInfo? Destination { get => this._destination; set { this._destination = value; @@ -69,6 +70,7 @@ namespace RoleplayersToolbox.Tools.Housing { this.Plugin = plugin; this.Config = plugin.Config.Tools.Housing; this.Info = new HousingInfo(plugin); + this.BookmarksUi = new BookmarksUi(plugin, this, this.Config); this.Teleport = new Teleport(plugin); if (this.Plugin.Interface.TargetModuleScanner.TryScanText(Signatures.AddonMapHide, out var addonMapHidePtr)) { @@ -79,12 +81,16 @@ namespace RoleplayersToolbox.Tools.Housing { this.Plugin.Common.Functions.ContextMenu.OpenContextMenu += this.OnContextMenu; this.Plugin.Interface.Framework.OnUpdateEvent += this.OnFramework; - this.Plugin.Interface.CommandManager.AddHandler("/route", new CommandInfo(this.OnCommand) { + this.Plugin.Interface.CommandManager.AddHandler("/route", new CommandInfo(this.OnRouteCommand) { HelpMessage = "Extract housing information from the given text and open the routing window", }); + this.Plugin.Interface.CommandManager.AddHandler("/bookmarks", new CommandInfo(this.OnBookmarksCommand) { + HelpMessage = "Toggles the housing bookmarks window", + }); } public void Dispose() { + this.Plugin.Interface.CommandManager.RemoveHandler("/bookmarks"); this.Plugin.Interface.CommandManager.RemoveHandler("/route"); this.Plugin.Interface.Framework.OnUpdateEvent -= this.OnFramework; this.Plugin.Common.Functions.ContextMenu.OpenContextMenu -= this.OnContextMenu; @@ -103,9 +109,19 @@ namespace RoleplayersToolbox.Tools.Housing { ImGui.TextUnformatted("You can also use the /route command for this."); ImGui.TextUnformatted("Ex: /route jen lb w5 p3"); + + ImGui.Separator(); + + if (ImGui.Button("Open housing bookmarks")) { + this.BookmarksUi.ShouldDraw = true; + } + + ImGui.TextUnformatted("You can also use the /bookmarks command for this."); } public override void DrawAlways() { + this.BookmarksUi.Draw(); + if (this.Destination == null) { return; } @@ -155,7 +171,7 @@ namespace RoleplayersToolbox.Tools.Housing { var ward = (int) (this.Destination.Ward ?? 0); if (ImGui.InputInt("Ward", ref ward)) { - this.Destination.Ward = (uint) Math.Max(1, Math.Min(60, ward)); + this.Destination.Ward = (uint) Math.Max(1, Math.Min(24, ward)); anyChanged = true; } @@ -190,7 +206,7 @@ namespace RoleplayersToolbox.Tools.Housing { ImGui.End(); } - private void OnCommand(string command, string arguments) { + private void OnRouteCommand(string command, string arguments) { var player = this.Plugin.Interface.ClientState.LocalPlayer; if (player == null) { return; @@ -199,6 +215,10 @@ namespace RoleplayersToolbox.Tools.Housing { this.Destination = InfoExtractor.Extract(arguments, player.HomeWorld.GameData.DataCenter.Row, this.Plugin.Interface.Data, this.Info); } + private void OnBookmarksCommand(string command, string arguments) { + this.BookmarksUi.ShouldDraw ^= true; + } + private void OnContextMenu(ContextMenuOpenArgs args) { if (args.ParentAddonName != "LookingForGroup" || args.ContentIdLower == 0) { return; @@ -301,7 +321,7 @@ namespace RoleplayersToolbox.Tools.Housing { this.FlagHouseOnMap(this.Destination.Area.Value, this.Destination.Plot.Value); } - private void FlagHouseOnMap(HousingArea area, uint plot) { + internal void FlagHouseOnMap(HousingArea area, uint plot) { var info = this.Plugin.Interface.Data.GetExcelSheet().GetRow((uint) area, plot - 1); if (info == null) { return; diff --git a/RoleplayersToolbox/Util.cs b/RoleplayersToolbox/Util.cs index e5a15de..b5b7495 100755 --- a/RoleplayersToolbox/Util.cs +++ b/RoleplayersToolbox/Util.cs @@ -5,6 +5,8 @@ using System.Runtime.InteropServices; using System.Text; using Dalamud.Game; using Dalamud.Game.Text.SeStringHandling; +using Dalamud.Interface; +using ImGuiNET; namespace RoleplayersToolbox { internal static class Util { @@ -76,5 +78,28 @@ namespace RoleplayersToolbox { return start; } + + internal static bool IconButton(FontAwesomeIcon icon, string? id = null) { + var label = icon.ToIconString(); + if (id != null) { + label += $"##{id}"; + } + + ImGui.PushFont(UiBuilder.IconFont); + var ret = ImGui.Button(label); + ImGui.PopFont(); + + return ret; + } + + internal static void Tooltip(string tooltip) { + if (!ImGui.IsItemHovered()) { + return; + } + + ImGui.BeginTooltip(); + ImGui.TextUnformatted(tooltip); + ImGui.EndTooltip(); + } } }