Make colors favoritable.

This commit is contained in:
Ottermandias 2023-11-10 17:30:27 +01:00
parent 6ad9b56239
commit 4328f5d680
5 changed files with 161 additions and 23 deletions

View file

@ -14,7 +14,6 @@ using Glamourer.Unlocks;
using ImGuiNET; using ImGuiNET;
using OtterGui; using OtterGui;
using OtterGui.Raii; using OtterGui.Raii;
using OtterGui.Widgets;
using Penumbra.GameData.Data; using Penumbra.GameData.Data;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
@ -26,7 +25,7 @@ public class EquipmentDrawer
private const float DefaultWidth = 280; private const float DefaultWidth = 280;
private readonly ItemManager _items; private readonly ItemManager _items;
private readonly FilterComboColors _stainCombo; private readonly GlamourerColorCombo _stainCombo;
private readonly StainData _stainData; private readonly StainData _stainData;
private readonly ItemCombo[] _itemCombo; private readonly ItemCombo[] _itemCombo;
private readonly Dictionary<FullEquipType, WeaponCombo> _weaponCombo; private readonly Dictionary<FullEquipType, WeaponCombo> _weaponCombo;
@ -39,8 +38,7 @@ public class EquipmentDrawer
private float _requiredComboWidth; private float _requiredComboWidth;
public EquipmentDrawer(FavoriteManager favorites, IDataManager gameData, ItemManager items, CodeService codes, TextureService textures, public EquipmentDrawer(FavoriteManager favorites, IDataManager gameData, ItemManager items, CodeService codes, TextureService textures,
Configuration config, Configuration config, GPoseService gPose)
GPoseService gPose)
{ {
_items = items; _items = items;
_codes = codes; _codes = codes;
@ -48,8 +46,7 @@ public class EquipmentDrawer
_config = config; _config = config;
_gPose = gPose; _gPose = gPose;
_stainData = items.Stains; _stainData = items.Stains;
_stainCombo = new FilterComboColors(DefaultWidth - 20, _stainCombo = new GlamourerColorCombo(DefaultWidth - 20, _stainData, favorites);
_stainData.Data.Prepend(new KeyValuePair<byte, (string Name, uint Dye, bool Gloss)>(0, ("None", 0, false))), Glamourer.Log);
_itemCombo = EquipSlotExtensions.EqdpSlots.Select(e => new ItemCombo(gameData, items, e, Glamourer.Log, favorites)).ToArray(); _itemCombo = EquipSlotExtensions.EqdpSlots.Select(e => new ItemCombo(gameData, items, e, Glamourer.Log, favorites)).ToArray();
_weaponCombo = new Dictionary<FullEquipType, WeaponCombo>(FullEquipTypeExtensions.WeaponTypes.Count * 2); _weaponCombo = new Dictionary<FullEquipType, WeaponCombo>(FullEquipTypeExtensions.WeaponTypes.Count * 2);
foreach (var type in Enum.GetValues<FullEquipType>()) foreach (var type in Enum.GetValues<FullEquipType>())

View file

@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Dalamud.Interface;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Glamourer.Unlocks;
using ImGuiNET;
using OtterGui.Widgets;
using Penumbra.GameData.Data;
using Penumbra.GameData.Structs;
namespace Glamourer.Gui.Equipment;
public sealed class GlamourerColorCombo : FilterComboColors
{
private readonly FavoriteManager _favorites;
public GlamourerColorCombo(float comboWidth, StainData stains, FavoriteManager favorites)
: base(comboWidth, CreateFunc(stains, favorites), Glamourer.Log)
=> _favorites = favorites;
protected override bool DrawSelectable(int globalIdx, bool selected)
{
using (var space = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, ImGuiHelpers.ScaledVector2(4, 0)))
{
if (globalIdx == 0)
{
using var font = ImRaii.PushFont(UiBuilder.IconFont);
ImGui.Dummy(ImGui.CalcTextSize(FontAwesomeIcon.Star.ToIconString()));
}
else
{
UiHelpers.DrawFavoriteStar(_favorites, (StainId)Items[globalIdx].Key);
}
ImGui.SameLine();
}
var buttonWidth = ImGui.GetContentRegionAvail().X;
var totalWidth = ImGui.GetContentRegionMax().X;
using var style = ImRaii.PushStyle(ImGuiStyleVar.ButtonTextAlign, new Vector2(buttonWidth / 2 / totalWidth, 0.5f));
return base.DrawSelectable(globalIdx, selected);
}
private static Func<IReadOnlyList<KeyValuePair<byte, (string Name, uint Color, bool Gloss)>>> CreateFunc(StainData stains,
FavoriteManager favorites)
=> () => stains.Data.Select(kvp => (kvp, favorites.Contains((StainId)kvp.Key))).OrderBy(p => !p.Item2).Select(p => p.kvp)
.Prepend(new KeyValuePair<byte, (string Name, uint Dye, bool Gloss)>(0, ("None", 0, false))).ToList();
}

View file

@ -143,4 +143,27 @@ public static class UiHelpers
return false; return false;
} }
public static bool DrawFavoriteStar(FavoriteManager favorites, StainId stain)
{
var favorite = favorites.Contains(stain);
var hovering = ImGui.IsMouseHoveringRect(ImGui.GetCursorScreenPos(),
ImGui.GetCursorScreenPos() + new Vector2(ImGui.GetFrameHeight()));
using var font = ImRaii.PushFont(UiBuilder.IconFont);
using var c = ImRaii.PushColor(ImGuiCol.Text,
hovering ? ColorId.FavoriteStarHovered.Value() : favorite ? ColorId.FavoriteStarOn.Value() : ColorId.FavoriteStarOff.Value());
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted(FontAwesomeIcon.Star.ToIconString());
if (ImGui.IsItemClicked())
{
if (favorite)
favorites.Remove(stain);
else
favorites.TryAdd(stain);
return true;
}
return false;
}
} }

View file

@ -5,7 +5,6 @@ using System.Linq;
using Dalamud.Interface.Internal.Notifications; using Dalamud.Interface.Internal.Notifications;
using Glamourer.Services; using Glamourer.Services;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OtterGui.Classes; using OtterGui.Classes;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
@ -13,8 +12,10 @@ namespace Glamourer.Unlocks;
public class FavoriteManager : ISavable public class FavoriteManager : ISavable
{ {
private const int CurrentVersion = 1;
private readonly SaveService _saveService; private readonly SaveService _saveService;
private readonly HashSet<ItemId> _favorites = new(); private readonly HashSet<ItemId> _favorites = new();
private readonly HashSet<StainId> _favoriteColors = new();
public FavoriteManager(SaveService saveService) public FavoriteManager(SaveService saveService)
{ {
@ -31,8 +32,22 @@ public class FavoriteManager : ISavable
try try
{ {
var text = File.ReadAllText(file); var text = File.ReadAllText(file);
var array = JsonConvert.DeserializeObject<uint[]>(text) ?? Array.Empty<uint>(); if (text.StartsWith('['))
_favorites.UnionWith(array.Select(i => (ItemId)i)); {
LoadV0(text);
}
else
{
var load = JsonConvert.DeserializeObject<LoadStruct>(text);
switch (load.Version)
{
case 1:
_favorites.UnionWith(load.FavoriteItems.Select(i => (ItemId)i));
_favoriteColors.UnionWith(load.FavoriteColors.Select(i => (StainId)i));
break;
default: throw new Exception($"Unknown Version {load.Version}");
}
}
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -40,6 +55,13 @@ public class FavoriteManager : ISavable
} }
} }
private void LoadV0(string text)
{
var array = JsonConvert.DeserializeObject<uint[]>(text) ?? Array.Empty<uint>();
_favorites.UnionWith(array.Select(i => (ItemId)i));
Save();
}
public string ToFilename(FilenameService fileNames) public string ToFilename(FilenameService fileNames)
=> fileNames.FavoriteFile; => fileNames.FavoriteFile;
@ -52,10 +74,20 @@ public class FavoriteManager : ISavable
{ {
Formatting = Formatting.Indented, Formatting = Formatting.Indented,
}; };
j.WriteStartObject();
j.WritePropertyName(nameof(LoadStruct.Version));
j.WriteValue(CurrentVersion);
j.WritePropertyName(nameof(LoadStruct.FavoriteItems));
j.WriteStartArray(); j.WriteStartArray();
foreach (var item in _favorites) foreach (var item in _favorites)
j.WriteValue(item.Id); j.WriteValue(item.Id);
j.WriteEndArray(); j.WriteEndArray();
j.WritePropertyName(nameof(LoadStruct.FavoriteColors));
j.WriteStartArray();
foreach (var stain in _favoriteColors)
j.WriteValue(stain.Id);
j.WriteEndArray();
j.WriteEndObject();
} }
public bool TryAdd(EquipItem item) public bool TryAdd(EquipItem item)
@ -70,6 +102,18 @@ public class FavoriteManager : ISavable
return true; return true;
} }
public bool TryAdd(Stain stain)
=> TryAdd(stain.RowIndex);
public bool TryAdd(StainId stain)
{
if (stain.Id == 0 || !_favoriteColors.Add(stain))
return false;
Save();
return true;
}
public bool Remove(EquipItem item) public bool Remove(EquipItem item)
=> Remove(item.ItemId); => Remove(item.ItemId);
@ -82,15 +126,37 @@ public class FavoriteManager : ISavable
return true; return true;
} }
public IEnumerator<ItemId> GetEnumerator() public bool Remove(Stain stain)
=> _favorites.GetEnumerator(); => Remove(stain.RowIndex);
public int Count public bool Remove(StainId stain)
=> _favorites.Count; {
if (!_favoriteColors.Remove(stain))
return false;
Save();
return true;
}
public bool Contains(EquipItem item) public bool Contains(EquipItem item)
=> _favorites.Contains(item.ItemId); => _favorites.Contains(item.ItemId);
public bool Contains(Stain stain)
=> _favoriteColors.Contains(stain.RowIndex);
public bool Contains(ItemId item) public bool Contains(ItemId item)
=> _favorites.Contains(item); => _favorites.Contains(item);
public bool Contains(StainId stain)
=> _favoriteColors.Contains(stain);
private struct LoadStruct
{
public int Version = CurrentVersion;
public uint[] FavoriteItems = Array.Empty<uint>();
public byte[] FavoriteColors = Array.Empty<byte>();
public LoadStruct()
{ }
}
} }

@ -1 +1 @@
Subproject commit a4f9b285c82f84ff0841695c0787dbba93afc59b Subproject commit b09bbcc276363bc994d90b641871e6280898b6e5