mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2026-02-18 13:37:44 +01:00
More stuff.
This commit is contained in:
parent
dad146d043
commit
1a4672a901
23 changed files with 616 additions and 1005 deletions
|
|
@ -1,207 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Glamourer.Gui;
|
||||
|
||||
public class ComboWithFilter<T>
|
||||
{
|
||||
private readonly string _label;
|
||||
private readonly string _filterLabel;
|
||||
private readonly string _listLabel;
|
||||
private string _currentFilter = string.Empty;
|
||||
private string _currentFilterLower = string.Empty;
|
||||
private bool _focus;
|
||||
private readonly float _size;
|
||||
private float _previewSize;
|
||||
private readonly IReadOnlyList<T> _items;
|
||||
private readonly IReadOnlyList<(string, int)> _itemNamesLower;
|
||||
private readonly Func<T, string> _itemToName;
|
||||
private IReadOnlyList<(string, int)> _currentItemNames;
|
||||
private bool _needsClear;
|
||||
|
||||
public Action? PrePreview;
|
||||
public Action? PostPreview;
|
||||
public Func<T, bool>? CreateSelectable;
|
||||
public Action? PreList;
|
||||
public Action? PostList;
|
||||
public float? HeightPerItem;
|
||||
|
||||
private float _heightPerItem;
|
||||
|
||||
public ImGuiComboFlags Flags { get; set; } = ImGuiComboFlags.None;
|
||||
public int ItemsAtOnce { get; set; } = 12;
|
||||
|
||||
private void UpdateFilter(string newFilter)
|
||||
{
|
||||
if (newFilter == _currentFilter)
|
||||
return;
|
||||
|
||||
var lower = newFilter.ToLowerInvariant();
|
||||
if (_currentFilterLower.Any() && lower.Contains(_currentFilterLower))
|
||||
_currentItemNames = _currentItemNames.Where(p => p.Item1.Contains(lower)).ToArray();
|
||||
else if (lower.Any())
|
||||
_currentItemNames = _itemNamesLower.Where(p => p.Item1.Contains(lower)).ToArray();
|
||||
else
|
||||
_currentItemNames = _itemNamesLower;
|
||||
_currentFilter = newFilter;
|
||||
_currentFilterLower = lower;
|
||||
}
|
||||
|
||||
public ComboWithFilter(string label, float size, float previewSize, IReadOnlyList<T> items, Func<T, string> itemToName)
|
||||
{
|
||||
_label = label;
|
||||
_filterLabel = $"##_{label}_filter";
|
||||
_listLabel = $"##_{label}_list";
|
||||
_itemToName = itemToName;
|
||||
_items = items;
|
||||
_size = size;
|
||||
_previewSize = previewSize;
|
||||
|
||||
_itemNamesLower = _items.Select((i, idx) => (_itemToName(i).ToLowerInvariant(), idx)).ToArray();
|
||||
_currentItemNames = _itemNamesLower;
|
||||
}
|
||||
|
||||
public ComboWithFilter(string label, ComboWithFilter<T> other)
|
||||
{
|
||||
_label = label;
|
||||
_filterLabel = $"##_{label}_filter";
|
||||
_listLabel = $"##_{label}_list";
|
||||
_itemToName = other._itemToName;
|
||||
_items = other._items;
|
||||
_itemNamesLower = other._itemNamesLower;
|
||||
_currentItemNames = other._currentItemNames;
|
||||
_size = other._size;
|
||||
_previewSize = other._previewSize;
|
||||
PrePreview = other.PrePreview;
|
||||
PostPreview = other.PostPreview;
|
||||
CreateSelectable = other.CreateSelectable;
|
||||
PreList = other.PreList;
|
||||
PostList = other.PostList;
|
||||
HeightPerItem = other.HeightPerItem;
|
||||
Flags = other.Flags;
|
||||
}
|
||||
|
||||
private bool DrawList(string currentName, out int numItems, out int nodeIdx, ref T? value)
|
||||
{
|
||||
numItems = ItemsAtOnce;
|
||||
nodeIdx = -1;
|
||||
if (!ImGui.BeginChild(_listLabel, new Vector2(_size, ItemsAtOnce * _heightPerItem)))
|
||||
{
|
||||
ImGui.EndChild();
|
||||
return false;
|
||||
}
|
||||
|
||||
var ret = false;
|
||||
try
|
||||
{
|
||||
if (!_focus)
|
||||
{
|
||||
ImGui.SetScrollY(0);
|
||||
_focus = true;
|
||||
}
|
||||
|
||||
var scrollY = Math.Max((int)(ImGui.GetScrollY() / _heightPerItem) - 1, 0);
|
||||
var restHeight = scrollY * _heightPerItem;
|
||||
numItems = 0;
|
||||
nodeIdx = 0;
|
||||
|
||||
if (restHeight > 0)
|
||||
ImGui.Dummy(Vector2.UnitY * restHeight);
|
||||
|
||||
for (var i = scrollY; i < _currentItemNames.Count; ++i)
|
||||
{
|
||||
if (++numItems > ItemsAtOnce + 2)
|
||||
continue;
|
||||
|
||||
nodeIdx = _currentItemNames[i].Item2;
|
||||
var item = _items[nodeIdx]!;
|
||||
bool success;
|
||||
if (CreateSelectable != null)
|
||||
{
|
||||
success = CreateSelectable(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
var name = _itemToName(item);
|
||||
success = ImGui.Selectable(name, name == currentName);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
value = item;
|
||||
ImGui.CloseCurrentPopup();
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (_currentItemNames.Count > ItemsAtOnce + 2)
|
||||
ImGui.Dummy(Vector2.UnitY * (_currentItemNames.Count - ItemsAtOnce - 2 - scrollY) * _heightPerItem);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ImGui.EndChild();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public bool Draw(string currentName, out T? value, float? size = null)
|
||||
{
|
||||
if (size.HasValue)
|
||||
_previewSize = size.Value;
|
||||
|
||||
value = default;
|
||||
ImGui.SetNextItemWidth(_previewSize);
|
||||
PrePreview?.Invoke();
|
||||
if (!ImGui.BeginCombo(_label, currentName, Flags))
|
||||
{
|
||||
if (_needsClear)
|
||||
{
|
||||
_needsClear = false;
|
||||
_focus = false;
|
||||
UpdateFilter(string.Empty);
|
||||
}
|
||||
|
||||
PostPreview?.Invoke();
|
||||
return false;
|
||||
}
|
||||
|
||||
_needsClear = true;
|
||||
PostPreview?.Invoke();
|
||||
|
||||
_heightPerItem = HeightPerItem ?? ImGui.GetTextLineHeightWithSpacing();
|
||||
|
||||
bool ret;
|
||||
try
|
||||
{
|
||||
ImGui.SetNextItemWidth(-1);
|
||||
var tmp = _currentFilter;
|
||||
if (ImGui.InputTextWithHint(_filterLabel, "Filter...", ref tmp, 255))
|
||||
UpdateFilter(tmp);
|
||||
|
||||
var isFocused = ImGui.IsItemActive();
|
||||
if (!_focus)
|
||||
ImGui.SetKeyboardFocusHere();
|
||||
|
||||
PreList?.Invoke();
|
||||
ret = DrawList(currentName, out var numItems, out var nodeIdx, ref value);
|
||||
PostList?.Invoke();
|
||||
|
||||
if (!isFocused && numItems <= 1 && nodeIdx >= 0)
|
||||
{
|
||||
value = _items[nodeIdx];
|
||||
ret = true;
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
ImGui.EndCombo();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Dalamud.Interface;
|
||||
using ImGuiNET;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
|
|
@ -354,7 +355,7 @@ public partial class EquipmentDrawer
|
|||
{
|
||||
0 => SmallClothes,
|
||||
9903 => SmallClothesNpc,
|
||||
_ => Identifier.Identify(set, weapon, variant, slot) ?? Unknown,
|
||||
_ => Identifier.Identify(set, weapon, variant, slot).FirstOrDefault(Unknown),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using Glamourer.Customization;
|
||||
using Glamourer.Interop;
|
||||
using Glamourer.State;
|
||||
using ImGuiNET;
|
||||
using OtterGui.Raii;
|
||||
using Penumbra.GameData.Enums;
|
||||
|
|
@ -11,6 +10,11 @@ using Penumbra.GameData.Structs;
|
|||
|
||||
namespace Glamourer.Gui.Equipment;
|
||||
|
||||
public enum ApplicationFlags
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public partial class EquipmentDrawer
|
||||
{
|
||||
private Race _race;
|
||||
|
|
@ -26,7 +30,7 @@ public partial class EquipmentDrawer
|
|||
{
|
||||
Stains = GameData.Stains(Dalamud.GameData);
|
||||
StainCombo = new FilterStainCombo(140);
|
||||
Identifier = Penumbra.GameData.GameData.GetIdentifier(Dalamud.GameData);
|
||||
Identifier = Glamourer.Identifier;
|
||||
ItemCombos = EquipSlotExtensions.EqdpSlots.Select(s => new ItemCombo(s)).ToArray();
|
||||
MainHandCombo = new WeaponCombo(EquipSlot.MainHand);
|
||||
OffHandCombo = new WeaponCombo(EquipSlot.OffHand);
|
||||
|
|
|
|||
|
|
@ -20,15 +20,20 @@ public partial class EquipmentDrawer
|
|||
|
||||
private sealed class FilterStainCombo : FilterComboBase<Stain>
|
||||
{
|
||||
private readonly float _comboWidth;
|
||||
private Vector2 _buttonSize;
|
||||
private readonly float _comboWidth;
|
||||
private Vector2 _buttonSize;
|
||||
public ImRaii.Color Color = new();
|
||||
|
||||
public FilterStainCombo(float comboWidth)
|
||||
: base(Stains.Values.ToArray(), false)
|
||||
=> _comboWidth = comboWidth;
|
||||
|
||||
protected override float GetFilterWidth()
|
||||
=> _buttonSize.X + ImGui.GetStyle().ScrollbarSize;
|
||||
{
|
||||
// Hack to not color the filter frame.
|
||||
Color.Pop();
|
||||
return _buttonSize.X + ImGui.GetStyle().ScrollbarSize;
|
||||
}
|
||||
|
||||
protected override void DrawList(float width, float itemHeight)
|
||||
{
|
||||
|
|
@ -58,11 +63,12 @@ public partial class EquipmentDrawer
|
|||
|
||||
private void DrawStainSelector()
|
||||
{
|
||||
var foundIdx = StainCombo.Items.IndexOf(s => s.RowIndex.Equals(_currentArmor.Stain));
|
||||
var stain = foundIdx >= 0 ? StainCombo.Items[foundIdx] : default;
|
||||
using var color = ImRaii.PushColor(ImGuiCol.FrameBg, stain.RgbaColor, foundIdx >= 0);
|
||||
var foundIdx = StainCombo.Items.IndexOf(s => s.RowIndex.Equals(_currentArmor.Stain));
|
||||
var stain = foundIdx >= 0 ? StainCombo.Items[foundIdx] : default;
|
||||
StainCombo.Color.Push(ImGuiCol.FrameBg, stain.RgbaColor, foundIdx >= 0);
|
||||
var change = StainCombo.Draw("##stainSelector", string.Empty, ref foundIdx, ImGui.GetFrameHeight(), ImGui.GetFrameHeight(),
|
||||
ImGuiComboFlags.NoArrowButton);
|
||||
StainCombo.Color.Pop();
|
||||
if (!change && (byte)_currentArmor.Stain != 0)
|
||||
{
|
||||
ImGuiUtil.HoverTooltip($"{stain.Name}\nRight-click to clear.");
|
||||
|
|
@ -82,7 +88,7 @@ public partial class EquipmentDrawer
|
|||
}
|
||||
|
||||
private void DrawCheckbox(ref ApplicationFlags flags)
|
||||
=> DrawCheckbox("##checkbox", "Enable writing this slot in this save.", ref flags, _currentSlot.ToApplicationFlag());
|
||||
=> DrawCheckbox("##checkbox", "Enable writing this slot in this save.", ref flags, 0);
|
||||
|
||||
private static void DrawCheckbox(string label, string tooltip, ref ApplicationFlags flags, ApplicationFlags flag)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ using ImGuiNET;
|
|||
using OtterGui;
|
||||
using OtterGui.Classes;
|
||||
using OtterGui.Raii;
|
||||
using Penumbra.GameData.Actors;
|
||||
using Penumbra.GameData.Enums;
|
||||
using ImGui = ImGuiNET.ImGui;
|
||||
|
||||
|
|
@ -26,7 +27,7 @@ internal partial class Interface
|
|||
public ActorTab(CurrentManipulations manipulations)
|
||||
=> _manipulations = manipulations;
|
||||
|
||||
private Actor.IIdentifier _identifier = Actor.IIdentifier.Invalid;
|
||||
private ActorIdentifier _identifier = ActorIdentifier.Invalid;
|
||||
private ObjectManager.ActorData _currentData = ObjectManager.ActorData.Invalid;
|
||||
private string _currentLabel = string.Empty;
|
||||
private CurrentDesign? _currentSave;
|
||||
|
|
@ -50,7 +51,7 @@ internal partial class Interface
|
|||
|
||||
private unsafe void DrawPanel()
|
||||
{
|
||||
if (_identifier == Actor.IIdentifier.Invalid)
|
||||
if (_identifier == ActorIdentifier.Invalid)
|
||||
return;
|
||||
|
||||
|
||||
|
|
@ -65,15 +66,16 @@ internal partial class Interface
|
|||
|
||||
RevertButton();
|
||||
CustomizationDrawer.Draw(_currentSave.Data.Customize, _currentSave.Data.Equipment, _currentData.Objects,
|
||||
_identifier is Actor.SpecialIdentifier);
|
||||
_identifier.Type == IdentifierType.Special);
|
||||
|
||||
EquipmentDrawer.Draw(_currentSave.Data.Customize, _currentSave.Data.Equipment, ref _currentSave.Data.MainHand, ref _currentSave.Data.OffHand, _currentData.Objects, _identifier is Actor.SpecialIdentifier);
|
||||
EquipmentDrawer.Draw(_currentSave.Data.Customize, _currentSave.Data.Equipment, ref _currentSave.Data.MainHand,
|
||||
ref _currentSave.Data.OffHand, _currentData.Objects, _identifier.Type == IdentifierType.Special);
|
||||
}
|
||||
|
||||
private const uint RedHeaderColor = 0xFF1818C0;
|
||||
private const uint GreenHeaderColor = 0xFF18C018;
|
||||
|
||||
private void RevertButton()
|
||||
private unsafe void RevertButton()
|
||||
{
|
||||
if (ImGui.Button("Revert"))
|
||||
{
|
||||
|
|
@ -84,40 +86,42 @@ internal partial class Interface
|
|||
|
||||
if (_currentData.Objects.Count > 0)
|
||||
_currentSave = _manipulations.GetOrCreateSave(_currentData.Objects[0]);
|
||||
|
||||
|
||||
_currentSave!.Reset();
|
||||
}
|
||||
|
||||
VisorBox();
|
||||
if (_currentData.Objects.Count > 0)
|
||||
ImGui.TextUnformatted(_currentData.Objects[0].Pointer->GameObject.DataID.ToString());
|
||||
//VisorBox();
|
||||
}
|
||||
|
||||
private unsafe void VisorBox()
|
||||
{
|
||||
var (flags, mask) = (_currentSave!.Data.Flags & (ApplicationFlags.SetVisor | ApplicationFlags.Visor)) switch
|
||||
{
|
||||
ApplicationFlags.SetVisor => (0u, 3u),
|
||||
ApplicationFlags.Visor => (1u, 3u),
|
||||
ApplicationFlags.SetVisor | ApplicationFlags.Visor => (3u, 3u),
|
||||
_ => (2u, 3u),
|
||||
};
|
||||
var tmp = flags;
|
||||
if (ImGui.CheckboxFlags("Visor Toggled", ref tmp, mask))
|
||||
{
|
||||
_currentSave.Data.Flags = flags switch
|
||||
{
|
||||
0 => (_currentSave.Data.Flags | ApplicationFlags.Visor) & ~ApplicationFlags.SetVisor,
|
||||
1 => _currentSave.Data.Flags | ApplicationFlags.SetVisor,
|
||||
2 => _currentSave.Data.Flags | ApplicationFlags.SetVisor,
|
||||
_ => _currentSave.Data.Flags & ~(ApplicationFlags.SetVisor | ApplicationFlags.Visor),
|
||||
};
|
||||
if (_currentSave.Data.Flags.HasFlag(ApplicationFlags.SetVisor))
|
||||
{
|
||||
var on = _currentSave.Data.Flags.HasFlag(ApplicationFlags.Visor);
|
||||
foreach (var actor in _currentData.Objects.Where(a => a.IsHuman && a.DrawObject))
|
||||
RedrawManager.SetVisor(actor.DrawObject.Pointer, on);
|
||||
}
|
||||
}
|
||||
}
|
||||
//private unsafe void VisorBox()
|
||||
//{
|
||||
// var (flags, mask) = (_currentSave!.Data.Flags & (ApplicationFlags.SetVisor | ApplicationFlags.Visor)) switch
|
||||
// {
|
||||
// ApplicationFlags.SetVisor => (0u, 3u),
|
||||
// ApplicationFlags.Visor => (1u, 3u),
|
||||
// ApplicationFlags.SetVisor | ApplicationFlags.Visor => (3u, 3u),
|
||||
// _ => (2u, 3u),
|
||||
// };
|
||||
// var tmp = flags;
|
||||
// if (ImGui.CheckboxFlags("Visor Toggled", ref tmp, mask))
|
||||
// {
|
||||
// _currentSave.Data.Flags = flags switch
|
||||
// {
|
||||
// 0 => (_currentSave.Data.Flags | ApplicationFlags.Visor) & ~ApplicationFlags.SetVisor,
|
||||
// 1 => _currentSave.Data.Flags | ApplicationFlags.SetVisor,
|
||||
// 2 => _currentSave.Data.Flags | ApplicationFlags.SetVisor,
|
||||
// _ => _currentSave.Data.Flags & ~(ApplicationFlags.SetVisor | ApplicationFlags.Visor),
|
||||
// };
|
||||
// if (_currentSave.Data.Flags.HasFlag(ApplicationFlags.SetVisor))
|
||||
// {
|
||||
// var on = _currentSave.Data.Flags.HasFlag(ApplicationFlags.Visor);
|
||||
// foreach (var actor in _currentData.Objects.Where(a => a.IsHuman && a.DrawObject))
|
||||
// RedrawManager.SetVisor(actor.DrawObject.Pointer, on);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
private void DrawPanelHeader()
|
||||
{
|
||||
|
|
@ -213,10 +217,10 @@ internal partial class Interface
|
|||
ImGuiClip.DrawEndDummy(remainder, ImGui.GetTextLineHeight());
|
||||
}
|
||||
|
||||
private bool CheckFilter((Actor.IIdentifier, ObjectManager.ActorData) pair)
|
||||
private bool CheckFilter((ActorIdentifier, ObjectManager.ActorData) pair)
|
||||
=> _actorFilter.IsEmpty || pair.Item2.Label.Contains(_actorFilter.Lower, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
private void DrawSelectable((Actor.IIdentifier, ObjectManager.ActorData) pair)
|
||||
private void DrawSelectable((ActorIdentifier, ObjectManager.ActorData) pair)
|
||||
{
|
||||
var equal = pair.Item1.Equals(_identifier);
|
||||
if (ImGui.Selectable(pair.Item2.Label, equal) && !equal)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ using ImGuiNET;
|
|||
using OtterGui;
|
||||
using OtterGui.Classes;
|
||||
using OtterGui.Raii;
|
||||
using Penumbra.GameData.Actors;
|
||||
|
||||
namespace Glamourer.Gui;
|
||||
|
||||
|
|
@ -18,10 +19,10 @@ internal partial class Interface
|
|||
{
|
||||
private readonly CurrentManipulations _currentManipulations;
|
||||
|
||||
private LowerString _manipulationFilter = LowerString.Empty;
|
||||
private Actor.IIdentifier _selection = Actor.IIdentifier.Invalid;
|
||||
private CurrentDesign? _save = null;
|
||||
private bool _delete = false;
|
||||
private LowerString _manipulationFilter = LowerString.Empty;
|
||||
private ActorIdentifier _selection = ActorIdentifier.Invalid;
|
||||
private CurrentDesign? _save = null;
|
||||
private bool _delete = false;
|
||||
|
||||
public DebugStateTab(CurrentManipulations currentManipulations)
|
||||
=> _currentManipulations = currentManipulations;
|
||||
|
|
@ -43,7 +44,7 @@ internal partial class Interface
|
|||
{
|
||||
_delete = false;
|
||||
_currentManipulations.DeleteSave(_selection);
|
||||
_selection = Actor.IIdentifier.Invalid;
|
||||
_selection = ActorIdentifier.Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -72,14 +73,14 @@ internal partial class Interface
|
|||
DrawSelector(oldSpacing);
|
||||
}
|
||||
|
||||
private bool CheckFilter(KeyValuePair<Actor.IIdentifier, CurrentDesign> data)
|
||||
private bool CheckFilter(KeyValuePair<ActorIdentifier, CurrentDesign> data)
|
||||
{
|
||||
if (data.Key.Equals(_selection))
|
||||
_save = data.Value;
|
||||
return _manipulationFilter.Length == 0 || _manipulationFilter.IsContained(data.Key.ToString()!);
|
||||
}
|
||||
|
||||
private void DrawSelectable(KeyValuePair<Actor.IIdentifier, CurrentDesign> data)
|
||||
private void DrawSelectable(KeyValuePair<ActorIdentifier, CurrentDesign> data)
|
||||
{
|
||||
var equal = data.Key.Equals(_selection);
|
||||
if (ImGui.Selectable(data.Key.ToString(), equal))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue