mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2026-02-21 23:17:43 +01:00
blep
This commit is contained in:
parent
cb2e2f0128
commit
941bba1518
39 changed files with 2569 additions and 1579 deletions
|
|
@ -1,12 +1,14 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Dalamud.Interface;
|
||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using Glamourer.Interop;
|
||||
using Glamourer.State;
|
||||
using ImGuiNET;
|
||||
using OtterGui;
|
||||
using OtterGui.Classes;
|
||||
using OtterGui.Raii;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
|
||||
namespace Glamourer.Gui;
|
||||
|
||||
|
|
@ -14,8 +16,15 @@ internal partial class Interface
|
|||
{
|
||||
private class ActorTab
|
||||
{
|
||||
private ObjectManager.ActorData _data = new(string.Empty, new Actor.InvalidIdentifier(), Actor.Null, false, Actor.Null);
|
||||
private Actor _nextSelect = Actor.Null;
|
||||
private readonly CurrentManipulations _manipulations;
|
||||
|
||||
public ActorTab(CurrentManipulations manipulations)
|
||||
=> _manipulations = manipulations;
|
||||
|
||||
private Actor.IIdentifier _identifier = Actor.IIdentifier.Invalid;
|
||||
private ObjectManager.ActorData _currentData = ObjectManager.ActorData.Invalid;
|
||||
private string _currentLabel = string.Empty;
|
||||
private CurrentDesign? _currentSave;
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
|
|
@ -24,62 +33,107 @@ internal partial class Interface
|
|||
return;
|
||||
|
||||
DrawActorSelector();
|
||||
if (_data.Label.Length == 0)
|
||||
return;
|
||||
if (!ObjectManager.Actors.TryGetValue(_identifier, out _currentData))
|
||||
_currentData = ObjectManager.ActorData.Invalid;
|
||||
else
|
||||
_currentLabel = _currentData.Label;
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
if (_data.Actor.IsHuman)
|
||||
DrawActorPanel();
|
||||
else
|
||||
DrawMonsterPanel();
|
||||
DrawPanel();
|
||||
}
|
||||
|
||||
private void DrawActorPanel()
|
||||
private unsafe void DrawPanel()
|
||||
{
|
||||
if (_identifier == Actor.IIdentifier.Invalid)
|
||||
return;
|
||||
|
||||
|
||||
using var group = ImRaii.Group();
|
||||
if (!Glamourer.RedrawManager.CurrentManipulations.GetSave(_data.Actor, out var save))
|
||||
DrawPanelHeader();
|
||||
using var child = ImRaii.Child("##ActorPanel", -Vector2.One, true);
|
||||
if (!child || _currentSave == null)
|
||||
return;
|
||||
|
||||
if (DrawCustomization(save.Customize, save.Equipment, !_data.Modifiable))
|
||||
{
|
||||
//Glamourer.RedrawManager.Set(_data.Actor.Address, _character);
|
||||
Glamourer.Penumbra.RedrawObject(_data.Actor.Character, RedrawType.Redraw, true);
|
||||
}
|
||||
if (_currentData.Valid)
|
||||
_currentSave.Update(_currentData.Objects[0]);
|
||||
|
||||
if (ImGui.Button("Set Machinist Goggles"))
|
||||
{
|
||||
Glamourer.RedrawManager.ChangeEquip(_data.Actor.Address, EquipSlot.Head, new CharacterArmor(265, 1, 0));
|
||||
}
|
||||
|
||||
if (ImGui.Button("Set Weapon"))
|
||||
{
|
||||
Glamourer.RedrawManager.LoadWeapon(_data.Actor.Address, new CharacterWeapon(0x00C9, 0x004E, 0x0001, 0x00), new CharacterWeapon(0x0065, 0x003D, 0x0001, 0x00));
|
||||
}
|
||||
var d = _currentData.Objects[0].DrawObject.Pointer;
|
||||
var x = (*(delegate* unmanaged<Human*, byte>**)d)[50](d);
|
||||
ImGui.Text($"{x} {_currentData.Objects[0].ModelId}");
|
||||
if (x == 1)
|
||||
CustomizationDrawer.Draw(_currentSave.Data.Customize, _currentSave.Data.Equipment, _currentData.Objects,
|
||||
_identifier is Actor.SpecialIdentifier);
|
||||
}
|
||||
|
||||
private void DrawMonsterPanel()
|
||||
private const uint RedHeaderColor = 0xFF1818C0;
|
||||
private const uint GreenHeaderColor = 0xFF18C018;
|
||||
|
||||
private void DrawPanelHeader()
|
||||
{
|
||||
using var group = ImRaii.Group();
|
||||
var currentModel = (uint)_data.Actor.ModelId;
|
||||
var models = GameData.Models(Dalamud.GameData);
|
||||
var currentData = models.Models.TryGetValue(currentModel, out var c) ? c.FirstName : $"#{currentModel}";
|
||||
using var combo = ImRaii.Combo("Model Id", currentData);
|
||||
if (!combo)
|
||||
return;
|
||||
|
||||
foreach (var (id, data) in models.Models)
|
||||
{
|
||||
if (ImGui.Selectable(data.FirstName, id == currentModel) && id != currentModel)
|
||||
{
|
||||
_data.Actor.SetModelId((int)id);
|
||||
_data.Actor.ObjectKind =
|
||||
Glamourer.Penumbra.RedrawObject(_data.Actor.Character, RedrawType.Redraw, true);
|
||||
}
|
||||
ImGuiUtil.HoverTooltip(data.AllNames);
|
||||
}
|
||||
var color = _currentData.Valid ? GreenHeaderColor : RedHeaderColor;
|
||||
var buttonColor = ImGui.GetColorU32(ImGuiCol.FrameBg);
|
||||
using var c = ImRaii.PushColor(ImGuiCol.Text, color)
|
||||
.Push(ImGuiCol.Button, buttonColor)
|
||||
.Push(ImGuiCol.ButtonHovered, buttonColor)
|
||||
.Push(ImGuiCol.ButtonActive, buttonColor);
|
||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero)
|
||||
.Push(ImGuiStyleVar.FrameRounding, 0);
|
||||
ImGui.Button($"{_currentLabel}##playerHeader", -Vector2.UnitX);
|
||||
}
|
||||
|
||||
//private void DrawActorPanel()
|
||||
//{
|
||||
// using var group = ImRaii.Group();
|
||||
// if (!_data.Identifier.IsValid)
|
||||
// return;
|
||||
//
|
||||
// if (DrawCustomization(_currentSave.Customize, _currentSave.Equipment, !_data.Modifiable))
|
||||
// //Glamourer.RedrawManager.Set(_data.Actor.Address, _character);
|
||||
// Glamourer.Penumbra.RedrawObject(_data.Actor.Character, RedrawType.Redraw, true);
|
||||
//
|
||||
// if (ImGui.Button("Set Machinist Goggles"))
|
||||
// Glamourer.RedrawManager.ChangeEquip(_data.Actor, EquipSlot.Head, new CharacterArmor(265, 1, 0));
|
||||
//
|
||||
// if (ImGui.Button("Set Weapon"))
|
||||
// Glamourer.RedrawManager.LoadWeapon(_data.Actor.Address, new CharacterWeapon(0x00C9, 0x004E, 0x0001, 0x00),
|
||||
// new CharacterWeapon(0x0065, 0x003D, 0x0001, 0x00));
|
||||
//
|
||||
// if (ImGui.Button("Set Customize"))
|
||||
// {
|
||||
// unsafe
|
||||
// {
|
||||
// var data = _data.Actor.Customize.Data->Clone();
|
||||
// Glamourer.RedrawManager.UpdateCustomize(_data.Actor.DrawObject, new Customize(&data)
|
||||
// {
|
||||
// SkinColor = 154,
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//private void DrawMonsterPanel()
|
||||
//{
|
||||
// using var group = ImRaii.Group();
|
||||
// var currentModel = (uint)_data.Actor.ModelId;
|
||||
// var models = GameData.Models(Dalamud.GameData);
|
||||
// var currentData = models.Models.TryGetValue(currentModel, out var c) ? c.FirstName : $"#{currentModel}";
|
||||
// using var combo = ImRaii.Combo("Model Id", currentData);
|
||||
// if (!combo)
|
||||
// return;
|
||||
//
|
||||
// foreach (var (id, data) in models.Models)
|
||||
// {
|
||||
// if (ImGui.Selectable(data.FirstName, id == currentModel) && id != currentModel)
|
||||
// {
|
||||
// _data.Actor.SetModelId((int)id);
|
||||
// Glamourer.Penumbra.RedrawObject(_data.Actor.Character, RedrawType.Redraw, true);
|
||||
// }
|
||||
//
|
||||
// ImGuiUtil.HoverTooltip(data.AllNames);
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
private LowerString _actorFilter = LowerString.Empty;
|
||||
|
||||
|
|
@ -91,63 +145,55 @@ internal partial class Interface
|
|||
.Push(ImGuiStyleVar.FrameRounding, 0);
|
||||
ImGui.SetNextItemWidth(_actorSelectorWidth);
|
||||
LowerString.InputWithHint("##actorFilter", "Filter...", ref _actorFilter, 64);
|
||||
using (var child = ImRaii.Child("##actorSelector", new Vector2(_actorSelectorWidth, -ImGui.GetFrameHeight()), true))
|
||||
{
|
||||
if (!child)
|
||||
return;
|
||||
|
||||
_data.Actor = Actor.Null;
|
||||
_data.GPose = Actor.Null;
|
||||
_data.Modifiable = false;
|
||||
|
||||
style.Push(ImGuiStyleVar.ItemSpacing, oldSpacing);
|
||||
var skips = ImGuiClip.GetNecessarySkips(ImGui.GetTextLineHeight());
|
||||
var remainder = ImGuiClip.FilteredClippedDraw(ObjectManager.GetEnumerator(), skips, CheckFilter, DrawSelectable);
|
||||
ImGuiClip.DrawEndDummy(remainder, ImGui.GetTextLineHeight());
|
||||
style.Pop();
|
||||
}
|
||||
|
||||
DrawSelector(oldSpacing);
|
||||
DrawSelectionButtons();
|
||||
}
|
||||
|
||||
private void UpdateSelection(ObjectManager.ActorData data)
|
||||
private void DrawSelector(Vector2 oldSpacing)
|
||||
{
|
||||
_data = data;
|
||||
//_character.Load(_data.Actor);
|
||||
using var child = ImRaii.Child("##actorSelector", new Vector2(_actorSelectorWidth, -ImGui.GetFrameHeight()), true);
|
||||
if (!child)
|
||||
return;
|
||||
|
||||
ObjectManager.Update();
|
||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, oldSpacing);
|
||||
var skips = ImGuiClip.GetNecessarySkips(ImGui.GetTextLineHeight());
|
||||
var remainder = ImGuiClip.FilteredClippedDraw(ObjectManager.List, skips, CheckFilter, DrawSelectable);
|
||||
ImGuiClip.DrawEndDummy(remainder, ImGui.GetTextLineHeight());
|
||||
}
|
||||
|
||||
private bool CheckFilter(ObjectManager.ActorData data)
|
||||
{
|
||||
if (_nextSelect && _nextSelect == data.Actor || data.Label == _data.Label)
|
||||
UpdateSelection(data);
|
||||
return data.Label.Contains(_actorFilter.Lower, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
private bool CheckFilter((Actor.IIdentifier, ObjectManager.ActorData) pair)
|
||||
=> _actorFilter.IsEmpty || pair.Item2.Label.Contains(_actorFilter.Lower, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
private void DrawSelectable(ObjectManager.ActorData data)
|
||||
private void DrawSelectable((Actor.IIdentifier, ObjectManager.ActorData) pair)
|
||||
{
|
||||
var equal = data.Label == _data.Label;
|
||||
if (ImGui.Selectable(data.Label, equal) && !equal)
|
||||
UpdateSelection(data);
|
||||
var equal = pair.Item1.Equals(_identifier);
|
||||
if (ImGui.Selectable(pair.Item2.Label, equal) && !equal)
|
||||
{
|
||||
_identifier = pair.Item1.CreatePermanent();
|
||||
_currentData = pair.Item2;
|
||||
_currentSave = _currentData.Valid ? _manipulations.GetOrCreateSave(_currentData.Objects[0]) : null;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawSelectionButtons()
|
||||
{
|
||||
_nextSelect = Actor.Null;
|
||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero)
|
||||
.Push(ImGuiStyleVar.FrameRounding, 0);
|
||||
var buttonWidth = new Vector2(_actorSelectorWidth / 2, 0);
|
||||
|
||||
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.UserCircle.ToIconString(), buttonWidth
|
||||
, "Select the local player character.", !ObjectManager.Player, true))
|
||||
_nextSelect = _inGPose ? ObjectManager.GPosePlayer : ObjectManager.Player;
|
||||
_identifier = ObjectManager.Player.GetIdentifier();
|
||||
|
||||
ImGui.SameLine();
|
||||
Actor targetActor = Dalamud.Targets.Target?.Address;
|
||||
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.HandPointer.ToIconString(), buttonWidth,
|
||||
"Select the current target, if it is in the list.", _inGPose || !targetActor, true))
|
||||
_nextSelect = targetActor;
|
||||
"Select the current target, if it is in the list.", ObjectManager.IsInGPose || !targetActor, true))
|
||||
_identifier = targetActor.GetIdentifier();
|
||||
}
|
||||
}
|
||||
|
||||
private readonly ActorTab _actorTab = new();
|
||||
}
|
||||
|
||||
//internal partial class Interface
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Logging;
|
||||
using Glamourer.Customization;
|
||||
using Glamourer.Interop;
|
||||
using Glamourer.Util;
|
||||
using ImGuiNET;
|
||||
using OtterGui;
|
||||
using OtterGui.Raii;
|
||||
|
|
@ -15,405 +18,385 @@ namespace Glamourer.Gui;
|
|||
|
||||
internal partial class Interface
|
||||
{
|
||||
private static byte _tempStorage;
|
||||
private static CustomizationId _tempType;
|
||||
|
||||
private static bool DrawCustomization(Customize customize, CharacterEquip equip, bool locked)
|
||||
private class CustomizationDrawer
|
||||
{
|
||||
if (!ImGui.CollapsingHeader("Character Customization"))
|
||||
return false;
|
||||
private Customize _customize;
|
||||
private CharacterEquip _equip;
|
||||
private IReadOnlyCollection<Actor> _actors = Array.Empty<Actor>();
|
||||
private CustomizationSet _set = null!;
|
||||
|
||||
var ret = DrawRaceGenderSelector(customize, equip, locked);
|
||||
var set = Glamourer.Customization.GetList(customize.Clan, customize.Gender);
|
||||
|
||||
foreach (var id in set.Order[CharaMakeParams.MenuType.Percentage])
|
||||
ret |= PercentageSelector(set, id, customize, locked);
|
||||
|
||||
Functions.IteratePairwise(set.Order[CharaMakeParams.MenuType.IconSelector], c => DrawIconSelector(set, c, customize, locked),
|
||||
ImGui.SameLine);
|
||||
|
||||
ret |= DrawMultiIconSelector(set, customize, locked);
|
||||
|
||||
foreach (var id in set.Order[CharaMakeParams.MenuType.ListSelector])
|
||||
ret |= DrawListSelector(set, id, customize, locked);
|
||||
|
||||
Functions.IteratePairwise(set.Order[CharaMakeParams.MenuType.ColorPicker], c => DrawColorPicker(set, c, customize, locked),
|
||||
ImGui.SameLine);
|
||||
|
||||
ret |= Checkbox(set.Option(CustomizationId.HighlightsOnFlag), customize.HighlightsOn, b => customize.HighlightsOn = b, locked);
|
||||
var xPos = _inputIntSize + _framedIconSize.X + 3 * ImGui.GetStyle().ItemSpacing.X;
|
||||
ImGui.SameLine(xPos);
|
||||
ret |= Checkbox($"{Glamourer.Customization.GetName(CustomName.Reverse)} {set.Option(CustomizationId.FacePaint)}",
|
||||
customize.FacePaintReversed, b => customize.FacePaintReversed = b, locked);
|
||||
ret |= Checkbox($"{Glamourer.Customization.GetName(CustomName.IrisSmall)} {Glamourer.Customization.GetName(CustomName.IrisSize)}",
|
||||
customize.SmallIris, b => customize.SmallIris = b, locked);
|
||||
|
||||
if (customize.Race != Race.Hrothgar)
|
||||
public static void Draw(Customize customize, CharacterEquip equip, IReadOnlyCollection<Actor> actors, bool locked)
|
||||
{
|
||||
var d = new CustomizationDrawer()
|
||||
{
|
||||
_customize = customize,
|
||||
_equip = equip,
|
||||
_actors = actors,
|
||||
};
|
||||
|
||||
|
||||
if (!ImGui.CollapsingHeader("Character Customization"))
|
||||
return;
|
||||
|
||||
using var disabled = ImRaii.Disabled(locked);
|
||||
|
||||
d.DrawRaceGenderSelector();
|
||||
|
||||
d._set = Glamourer.Customization.GetList(customize.Clan, customize.Gender);
|
||||
|
||||
foreach (var id in d._set.Order[CharaMakeParams.MenuType.Percentage])
|
||||
d.PercentageSelector(id);
|
||||
|
||||
Functions.IteratePairwise(d._set.Order[CharaMakeParams.MenuType.IconSelector], d.DrawIconSelector, ImGui.SameLine);
|
||||
|
||||
d.DrawMultiIconSelector();
|
||||
|
||||
foreach (var id in d._set.Order[CharaMakeParams.MenuType.ListSelector])
|
||||
d.DrawListSelector(id);
|
||||
|
||||
Functions.IteratePairwise(d._set.Order[CharaMakeParams.MenuType.ColorPicker], d.DrawColorPicker, ImGui.SameLine);
|
||||
|
||||
d.Checkbox(d._set.Option(CustomizationId.HighlightsOnFlag), customize.HighlightsOn, b => customize.HighlightsOn = b);
|
||||
var xPos = _inputIntSize + _framedIconSize.X + 3 * ImGui.GetStyle().ItemSpacing.X;
|
||||
ImGui.SameLine(xPos);
|
||||
ret |= Checkbox(set.Option(CustomizationId.LipColor), customize.Lipstick, b => customize.Lipstick = b, locked);
|
||||
}
|
||||
d.Checkbox($"{Glamourer.Customization.GetName(CustomName.Reverse)} {d._set.Option(CustomizationId.FacePaint)}",
|
||||
customize.FacePaintReversed, b => customize.FacePaintReversed = b);
|
||||
d.Checkbox($"{Glamourer.Customization.GetName(CustomName.IrisSmall)} {Glamourer.Customization.GetName(CustomName.IrisSize)}",
|
||||
customize.SmallIris, b => customize.SmallIris = b);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static bool DrawRaceGenderSelector(Customize customize, CharacterEquip equip, bool locked)
|
||||
{
|
||||
var ret = DrawGenderSelector(customize, equip, locked);
|
||||
ImGui.SameLine();
|
||||
using var group = ImRaii.Group();
|
||||
ret |= DrawRaceCombo(customize, equip, locked);
|
||||
var gender = Glamourer.Customization.GetName(CustomName.Gender);
|
||||
var clan = Glamourer.Customization.GetName(CustomName.Clan);
|
||||
ImGui.TextUnformatted($"{gender} & {clan}");
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static bool DrawGenderSelector(Customize customize, CharacterEquip equip, bool locked)
|
||||
{
|
||||
using var font = ImRaii.PushFont(UiBuilder.IconFont);
|
||||
var icon = customize.Gender == Gender.Male ? FontAwesomeIcon.Mars : FontAwesomeIcon.Venus;
|
||||
var restricted = customize.Race == Race.Hrothgar;
|
||||
if (restricted)
|
||||
icon = FontAwesomeIcon.MarsDouble;
|
||||
|
||||
if (!ImGuiUtil.DrawDisabledButton(icon.ToIconString(), _framedIconSize, string.Empty, restricted || locked, true))
|
||||
return false;
|
||||
|
||||
var gender = customize.Gender == Gender.Male ? Gender.Female : Gender.Male;
|
||||
return false; //customize.ChangeGender(gender, locked ? CharacterEquip.Null : equip);
|
||||
}
|
||||
|
||||
private static bool DrawRaceCombo(Customize customize, CharacterEquip equip, bool locked)
|
||||
{
|
||||
using var alpha = ImRaii.PushStyle(ImGuiStyleVar.Alpha, 0.5f, locked);
|
||||
ImGui.SetNextItemWidth(_raceSelectorWidth);
|
||||
using var combo = ImRaii.Combo("##subRaceCombo", customize.ClanName());
|
||||
if (!combo)
|
||||
return false;
|
||||
|
||||
if (locked)
|
||||
ImGui.CloseCurrentPopup();
|
||||
|
||||
var ret = false;
|
||||
foreach (var subRace in Enum.GetValues<SubRace>().Skip(1)) // Skip Unknown
|
||||
{
|
||||
if (ImGui.Selectable(CustomizeExtensions.ClanName(subRace, customize.Gender), subRace == customize.Clan))
|
||||
ret |= false; //customize.ChangeRace(subRace, equip);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static bool Checkbox(string label, bool current, Action<bool> setter, bool locked)
|
||||
{
|
||||
var tmp = current;
|
||||
var ret = false;
|
||||
using var alpha = ImRaii.PushStyle(ImGuiStyleVar.Alpha, 0.5f, locked);
|
||||
if (ImGui.Checkbox($"##{label}", ref tmp) && tmp == current && !locked)
|
||||
{
|
||||
setter(tmp);
|
||||
ret = true;
|
||||
}
|
||||
|
||||
alpha.Pop();
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.TextUnformatted(label);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static bool PercentageSelector(CustomizationSet set, CustomizationId id, Customize customization, bool locked)
|
||||
{
|
||||
using var bigGroup = ImRaii.Group();
|
||||
using var _ = ImRaii.PushId((int)id);
|
||||
int value = id == _tempType ? _tempStorage : customization[id];
|
||||
var count = set.Count(id);
|
||||
ImGui.SetNextItemWidth(_comboSelectorSize);
|
||||
|
||||
var (min, max) = locked ? (value, value) : (0, count - 1);
|
||||
using var alpha = ImRaii.PushStyle(ImGuiStyleVar.Alpha, 0.5f, locked);
|
||||
if (ImGui.SliderInt("##slider", ref value, min, max, string.Empty, ImGuiSliderFlags.AlwaysClamp) && !locked)
|
||||
{
|
||||
_tempStorage = (byte)value;
|
||||
_tempType = id;
|
||||
}
|
||||
|
||||
var ret = ImGui.IsItemDeactivatedAfterEdit();
|
||||
|
||||
ImGui.SameLine();
|
||||
ret |= InputInt("##input", id, --value, min, max, locked);
|
||||
|
||||
alpha.Pop();
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.TextUnformatted(set.OptionName[(int)id]);
|
||||
|
||||
if (ret)
|
||||
customization[id] = _tempStorage;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static bool InputInt(string label, CustomizationId id, int startValue, int minValue, int maxValue, bool locked)
|
||||
{
|
||||
var tmp = startValue + 1;
|
||||
ImGui.SetNextItemWidth(_inputIntSize);
|
||||
if (ImGui.InputInt(label, ref tmp, 1, 1, ImGuiInputTextFlags.EnterReturnsTrue)
|
||||
&& !locked
|
||||
&& tmp != startValue + 1
|
||||
&& tmp >= minValue
|
||||
&& tmp <= maxValue)
|
||||
{
|
||||
_tempType = id;
|
||||
_tempStorage = (byte)(tmp - 1);
|
||||
}
|
||||
|
||||
var ret = ImGui.IsItemDeactivatedAfterEdit() && !locked;
|
||||
if (!locked)
|
||||
ImGuiUtil.HoverTooltip($"Input Range: [{minValue}, {maxValue}]");
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static bool DrawIconSelector(CustomizationSet set, CustomizationId id, Customize customize, bool locked)
|
||||
{
|
||||
const string popupName = "Style Picker";
|
||||
|
||||
using var bigGroup = ImRaii.Group();
|
||||
using var _ = ImRaii.PushId((int)id);
|
||||
var count = set.Count(id);
|
||||
var label = set.Option(id);
|
||||
|
||||
var current = set.DataByValue(id, _tempType == id ? _tempStorage : customize[id], out var custom);
|
||||
if (current < 0)
|
||||
{
|
||||
label = $"{label} (Custom #{customize[id]})";
|
||||
current = 0;
|
||||
custom = set.Data(id, 0);
|
||||
}
|
||||
|
||||
var icon = Glamourer.Customization.GetIcon(custom!.Value.IconId);
|
||||
using var alpha = ImRaii.PushStyle(ImGuiStyleVar.Alpha, 0.5f, locked);
|
||||
if (ImGui.ImageButton(icon.ImGuiHandle, _iconSize) && !locked)
|
||||
ImGui.OpenPopup(popupName);
|
||||
|
||||
ImGuiUtil.HoverIconTooltip(icon, _iconSize);
|
||||
|
||||
ImGui.SameLine();
|
||||
using var group = ImRaii.Group();
|
||||
var (min, max) = locked ? (current, current) : (1, count);
|
||||
var ret = InputInt("##text", id, current, min, max, locked);
|
||||
if (ret)
|
||||
customize[id] = set.Data(id, _tempStorage).Value;
|
||||
|
||||
ImGui.TextUnformatted($"{label} ({custom.Value.Value})");
|
||||
|
||||
ret |= DrawIconPickerPopup(popupName, set, id, customize);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static bool DrawIconPickerPopup(string label, CustomizationSet set, CustomizationId id, Customize customize)
|
||||
{
|
||||
using var popup = ImRaii.Popup(label, ImGuiWindowFlags.AlwaysAutoResize);
|
||||
if (!popup)
|
||||
return false;
|
||||
|
||||
var ret = false;
|
||||
var count = set.Count(id);
|
||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero)
|
||||
.Push(ImGuiStyleVar.FrameRounding, 0);
|
||||
for (var i = 0; i < count; ++i)
|
||||
{
|
||||
var custom = set.Data(id, i);
|
||||
var icon = Glamourer.Customization.GetIcon(custom.IconId);
|
||||
using var group = ImRaii.Group();
|
||||
if (ImGui.ImageButton(icon.ImGuiHandle, _iconSize))
|
||||
if (customize.Race != Race.Hrothgar)
|
||||
{
|
||||
customize[id] = custom.Value;
|
||||
ret = true;
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGuiUtil.HoverIconTooltip(icon, _iconSize);
|
||||
|
||||
var text = custom.Value.ToString();
|
||||
var textWidth = ImGui.CalcTextSize(text).X;
|
||||
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + (_iconSize.X - textWidth + 2 * ImGui.GetStyle().FramePadding.X) / 2);
|
||||
ImGui.TextUnformatted(text);
|
||||
group.Dispose();
|
||||
|
||||
if (i % 8 != 7)
|
||||
ImGui.SameLine();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static bool DrawColorPicker(CustomizationSet set, CustomizationId id, Customize customize, bool locked)
|
||||
{
|
||||
const string popupName = "Color Picker";
|
||||
using var _ = ImRaii.PushId((int)id);
|
||||
var ret = false;
|
||||
var count = set.Count(id);
|
||||
var label = set.Option(id);
|
||||
var (current, custom) = GetCurrentCustomization(set, id, customize);
|
||||
|
||||
using var alpha = ImRaii.PushStyle(ImGuiStyleVar.Alpha, 0.5f, locked);
|
||||
if (ImGui.ColorButton($"{current + 1}##color", ImGui.ColorConvertU32ToFloat4(custom.Color), ImGuiColorEditFlags.None, _framedIconSize)
|
||||
&& !locked)
|
||||
ImGui.OpenPopup(popupName);
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
using (var group = ImRaii.Group())
|
||||
{
|
||||
var (min, max) = locked ? (current, current) : (1, count);
|
||||
if (InputInt("##text", id, current, min, max, locked))
|
||||
{
|
||||
customize[id] = set.Data(id, current).Value;
|
||||
ret = true;
|
||||
ImGui.SameLine(xPos);
|
||||
d.Checkbox(d._set.Option(CustomizationId.LipColor), customize.Lipstick, b => customize.Lipstick = b);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawRaceGenderSelector()
|
||||
{
|
||||
DrawGenderSelector();
|
||||
ImGui.SameLine();
|
||||
using var group = ImRaii.Group();
|
||||
DrawRaceCombo();
|
||||
var gender = Glamourer.Customization.GetName(CustomName.Gender);
|
||||
var clan = Glamourer.Customization.GetName(CustomName.Clan);
|
||||
ImGui.TextUnformatted($"{gender} & {clan}");
|
||||
}
|
||||
|
||||
private void DrawGenderSelector()
|
||||
{
|
||||
using var font = ImRaii.PushFont(UiBuilder.IconFont);
|
||||
var icon = _customize.Gender == Gender.Male ? FontAwesomeIcon.Mars : FontAwesomeIcon.Venus;
|
||||
var restricted = _customize.Race == Race.Hrothgar;
|
||||
if (restricted)
|
||||
icon = FontAwesomeIcon.MarsDouble;
|
||||
|
||||
if (!ImGuiUtil.DrawDisabledButton(icon.ToIconString(), _framedIconSize, string.Empty, restricted, true))
|
||||
return;
|
||||
|
||||
var gender = _customize.Gender == Gender.Male ? Gender.Female : Gender.Male;
|
||||
if (!_customize.ChangeGender(_equip, gender))
|
||||
return;
|
||||
|
||||
foreach (var actor in _actors.Where(a => a))
|
||||
Glamourer.Penumbra.RedrawObject(actor.Character, RedrawType.Redraw, false);
|
||||
}
|
||||
|
||||
private void DrawRaceCombo()
|
||||
{
|
||||
ImGui.SetNextItemWidth(_raceSelectorWidth);
|
||||
using var combo = ImRaii.Combo("##subRaceCombo", _customize.ClanName());
|
||||
if (!combo)
|
||||
return;
|
||||
|
||||
foreach (var subRace in Enum.GetValues<SubRace>().Skip(1)) // Skip Unknown
|
||||
{
|
||||
if (ImGui.Selectable(CustomizeExtensions.ClanName(subRace, _customize.Gender), subRace == _customize.Clan)
|
||||
&& _customize.ChangeRace(_equip, subRace))
|
||||
foreach (var actor in _actors.Where(a => a && a.DrawObject))
|
||||
Glamourer.Penumbra.RedrawObject(actor.Character, RedrawType.Redraw, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void Checkbox(string label, bool current, Action<bool> setter)
|
||||
{
|
||||
var tmp = current;
|
||||
if (ImGui.Checkbox($"##{label}", ref tmp) && tmp != current)
|
||||
{
|
||||
setter(tmp);
|
||||
foreach (var actor in _actors.Where(a => a && a.DrawObject))
|
||||
Glamourer.RedrawManager.UpdateCustomize(actor.DrawObject, _customize);
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.TextUnformatted(label);
|
||||
}
|
||||
|
||||
return ret | DrawColorPickerPopup(popupName, set, id, customize);
|
||||
}
|
||||
|
||||
private static (int, Customization.Customization) GetCurrentCustomization(CustomizationSet set, CustomizationId id,
|
||||
Customize customize)
|
||||
{
|
||||
var current = set.DataByValue(id, customize[id], out var custom);
|
||||
if (set.IsAvailable(id) && current < 0)
|
||||
private void PercentageSelector(CustomizationId id)
|
||||
{
|
||||
PluginLog.Warning($"Read invalid customization value {customize[id]} for {id}.");
|
||||
current = 0;
|
||||
custom = set.Data(id, 0);
|
||||
}
|
||||
using var bigGroup = ImRaii.Group();
|
||||
using var _ = ImRaii.PushId((int)id);
|
||||
int value = _customize[id];
|
||||
var count = _set.Count(id);
|
||||
ImGui.SetNextItemWidth(_comboSelectorSize);
|
||||
|
||||
return (current, custom!.Value);
|
||||
}
|
||||
|
||||
private static bool DrawColorPickerPopup(string label, CustomizationSet set, CustomizationId id, Customize customize)
|
||||
{
|
||||
using var popup = ImRaii.Popup(label, ImGuiWindowFlags.AlwaysAutoResize);
|
||||
if (!popup)
|
||||
return false;
|
||||
|
||||
var ret = false;
|
||||
var count = set.Count(id);
|
||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero)
|
||||
.Push(ImGuiStyleVar.FrameRounding, 0);
|
||||
for (var i = 0; i < count; ++i)
|
||||
{
|
||||
var custom = set.Data(id, i);
|
||||
if (ImGui.ColorButton((i + 1).ToString(), ImGui.ColorConvertU32ToFloat4(custom.Color)))
|
||||
void OnChange(int v)
|
||||
{
|
||||
customize[id] = custom.Value;
|
||||
ret = true;
|
||||
ImGui.CloseCurrentPopup();
|
||||
_customize[id] = (byte)v;
|
||||
foreach (var actor in _actors.Where(a => a && a.DrawObject))
|
||||
Glamourer.RedrawManager.UpdateCustomize(actor.DrawObject, _customize);
|
||||
}
|
||||
|
||||
if (i % 8 != 7)
|
||||
ImGui.SameLine();
|
||||
if (ImGui.SliderInt("##slider", ref value, 0, count - 1, "%i", ImGuiSliderFlags.AlwaysClamp))
|
||||
OnChange(value);
|
||||
|
||||
ImGui.SameLine();
|
||||
InputInt("##input", --value, 0, count - 1, OnChange);
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.TextUnformatted(_set.OptionName[(int)id]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static bool DrawMultiIconSelector(CustomizationSet set, Customize customize, bool locked)
|
||||
{
|
||||
using var bigGroup = ImRaii.Group();
|
||||
using var _ = ImRaii.PushId((int)CustomizationId.FacialFeaturesTattoos);
|
||||
using var alpha = ImRaii.PushStyle(ImGuiStyleVar.Alpha, 0.5f, locked);
|
||||
var ret = DrawMultiIcons(set, customize, locked);
|
||||
ImGui.SameLine();
|
||||
using var group = ImRaii.Group();
|
||||
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + ImGui.GetTextLineHeightWithSpacing() + 3 * ImGui.GetStyle().ItemSpacing.Y / 2);
|
||||
int value = customize[CustomizationId.FacialFeaturesTattoos];
|
||||
var (min, max) = locked ? (value, value) : (1, 256);
|
||||
if (InputInt(string.Empty, CustomizationId.FacialFeaturesTattoos, value, min, max, locked))
|
||||
private static void InputInt(string label, int startValue, int minValue, int maxValue, Action<int> setter)
|
||||
{
|
||||
customize[CustomizationId.FacialFeaturesTattoos] = (byte)value;
|
||||
ret = true;
|
||||
var tmp = startValue + 1;
|
||||
ImGui.SetNextItemWidth(_inputIntSize);
|
||||
if (ImGui.InputInt(label, ref tmp, 1, 1, ImGuiInputTextFlags.EnterReturnsTrue)
|
||||
&& tmp != startValue + 1
|
||||
&& tmp >= minValue
|
||||
&& tmp <= maxValue)
|
||||
setter(tmp);
|
||||
|
||||
ImGuiUtil.HoverTooltip($"Input Range: [{minValue}, {maxValue}]");
|
||||
}
|
||||
|
||||
ImGui.TextUnformatted(set.Option(CustomizationId.FacialFeaturesTattoos));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static bool DrawMultiIcons(CustomizationSet set, Customize customize, bool locked)
|
||||
{
|
||||
using var _ = ImRaii.Group();
|
||||
var face = customize.Face;
|
||||
if (set.Faces.Count < face)
|
||||
face = 1;
|
||||
|
||||
var ret = false;
|
||||
var count = set.Count(CustomizationId.FacialFeaturesTattoos);
|
||||
for (var i = 0; i < count; ++i)
|
||||
private void DrawIconSelector(CustomizationId id)
|
||||
{
|
||||
var enabled = customize.FacialFeatures[i];
|
||||
var feature = set.FacialFeature(face, i);
|
||||
var icon = i == count - 1
|
||||
? LegacyTattoo ?? Glamourer.Customization.GetIcon(feature.IconId)
|
||||
: Glamourer.Customization.GetIcon(feature.IconId);
|
||||
if (ImGui.ImageButton(icon.ImGuiHandle, _iconSize, Vector2.Zero, Vector2.One, (int)ImGui.GetStyle().FramePadding.X,
|
||||
Vector4.Zero, enabled ? Vector4.One : RedTint)
|
||||
&& !locked)
|
||||
const string popupName = "Style Picker";
|
||||
|
||||
using var bigGroup = ImRaii.Group();
|
||||
using var _ = ImRaii.PushId((int)id);
|
||||
var count = _set.Count(id, _customize.Face);
|
||||
var label = _set.Option(id);
|
||||
|
||||
var current = _set.DataByValue(id, _customize[id], out var custom);
|
||||
if (current < 0)
|
||||
{
|
||||
customize.FacialFeatures.Set(i, !enabled);
|
||||
ret = true;
|
||||
label = $"{label} (Custom #{_customize[id]})";
|
||||
current = 0;
|
||||
custom = _set.Data(id, 0);
|
||||
}
|
||||
|
||||
using var alpha = ImRaii.PushStyle(ImGuiStyleVar.Alpha, 1f, !locked);
|
||||
var icon = Glamourer.Customization.GetIcon(custom!.Value.IconId);
|
||||
if (ImGui.ImageButton(icon.ImGuiHandle, _iconSize))
|
||||
ImGui.OpenPopup(popupName);
|
||||
|
||||
ImGuiUtil.HoverIconTooltip(icon, _iconSize);
|
||||
|
||||
if (i % 4 != 3)
|
||||
ImGui.SameLine();
|
||||
void OnChange(int v)
|
||||
{
|
||||
var value = _set.Data(id, v - 1).Value;
|
||||
// Hrothgar hack
|
||||
if (_set.Race == Race.Hrothgar && id == CustomizationId.Face)
|
||||
value += 4;
|
||||
|
||||
if (_customize[id] == value)
|
||||
return;
|
||||
|
||||
_customize[id] = value;
|
||||
foreach (var actor in _actors.Where(a => a && a.DrawObject))
|
||||
Glamourer.RedrawManager.UpdateCustomize(actor.DrawObject, _customize);
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
using var group = ImRaii.Group();
|
||||
InputInt("##text", current, 1, count, OnChange);
|
||||
|
||||
ImGui.TextUnformatted($"{label} ({custom.Value.Value})");
|
||||
|
||||
DrawIconPickerPopup(popupName, id, OnChange);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static bool DrawListSelector(CustomizationSet set, CustomizationId id, Customize customize, bool locked)
|
||||
{
|
||||
using var _ = ImRaii.PushId((int)id);
|
||||
using var bigGroup = ImRaii.Group();
|
||||
var ret = false;
|
||||
int current = customize[id];
|
||||
var count = set.Count(id);
|
||||
|
||||
ImGui.SetNextItemWidth(_comboSelectorSize * ImGui.GetIO().FontGlobalScale);
|
||||
using var alpha = ImRaii.PushStyle(ImGuiStyleVar.Alpha, 0.5f, locked);
|
||||
using (var combo = ImRaii.Combo("##combo", $"{set.Option(id)} #{current + 1}"))
|
||||
private void DrawIconPickerPopup(string label, CustomizationId id, Action<int> setter)
|
||||
{
|
||||
if (combo)
|
||||
for (var i = 0; i < count; ++i)
|
||||
using var popup = ImRaii.Popup(label, ImGuiWindowFlags.AlwaysAutoResize);
|
||||
if (!popup)
|
||||
return;
|
||||
|
||||
var count = _set.Count(id, _customize.Face);
|
||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero)
|
||||
.Push(ImGuiStyleVar.FrameRounding, 0);
|
||||
for (var i = 0; i < count; ++i)
|
||||
{
|
||||
var custom = _set.Data(id, i, _customize.Face);
|
||||
var icon = Glamourer.Customization.GetIcon(custom.IconId);
|
||||
using var group = ImRaii.Group();
|
||||
if (ImGui.ImageButton(icon.ImGuiHandle, _iconSize))
|
||||
{
|
||||
if (!ImGui.Selectable($"{set.Option(id)} #{i + 1}##combo", i == current) || i == current || locked)
|
||||
continue;
|
||||
|
||||
customize[id] = (byte)i;
|
||||
ret = true;
|
||||
setter(custom.Value);
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGuiUtil.HoverIconTooltip(icon, _iconSize);
|
||||
|
||||
var text = custom.Value.ToString();
|
||||
var textWidth = ImGui.CalcTextSize(text).X;
|
||||
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + (_iconSize.X - textWidth + 2 * ImGui.GetStyle().FramePadding.X) / 2);
|
||||
ImGui.TextUnformatted(text);
|
||||
group.Dispose();
|
||||
|
||||
if (i % 8 != 7)
|
||||
ImGui.SameLine();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
var (min, max) = locked ? (current, current) : (1, count);
|
||||
if (InputInt("##text", id, current, min, max, locked))
|
||||
private void DrawColorPicker(CustomizationId id)
|
||||
{
|
||||
customize[id] = (byte)current;
|
||||
ret = true;
|
||||
const string popupName = "Color Picker";
|
||||
using var _ = ImRaii.PushId((int)id);
|
||||
var count = _set.Count(id);
|
||||
var label = _set.Option(id);
|
||||
var (current, custom) = GetCurrentCustomization(id);
|
||||
|
||||
if (ImGui.ColorButton($"{current + 1}##color", ImGui.ColorConvertU32ToFloat4(custom.Color), ImGuiColorEditFlags.None,
|
||||
_framedIconSize))
|
||||
ImGui.OpenPopup(popupName);
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
void OnChange(int v)
|
||||
{
|
||||
_customize[id] = _set.Data(id, v).Value;
|
||||
foreach (var actor in _actors.Where(a => a && a.DrawObject))
|
||||
Glamourer.RedrawManager.UpdateCustomize(actor.DrawObject, _customize);
|
||||
}
|
||||
|
||||
using (var group = ImRaii.Group())
|
||||
{
|
||||
InputInt("##text", current, 1, count, OnChange);
|
||||
ImGui.TextUnformatted(label);
|
||||
}
|
||||
|
||||
DrawColorPickerPopup(popupName, id, OnChange);
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
alpha.Pop();
|
||||
ImGui.TextUnformatted(set.Option(id));
|
||||
private (int, Customization.Customization) GetCurrentCustomization(CustomizationId id)
|
||||
{
|
||||
var current = _set.DataByValue(id, _customize[id], out var custom);
|
||||
if (_set.IsAvailable(id) && current < 0)
|
||||
{
|
||||
PluginLog.Warning($"Read invalid customization value {_customize[id]} for {id}.");
|
||||
current = 0;
|
||||
custom = _set.Data(id, 0);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return (current, custom!.Value);
|
||||
}
|
||||
|
||||
private void DrawColorPickerPopup(string label, CustomizationId id, Action<int> setter)
|
||||
{
|
||||
using var popup = ImRaii.Popup(label, ImGuiWindowFlags.AlwaysAutoResize);
|
||||
if (!popup)
|
||||
return;
|
||||
|
||||
var count = _set.Count(id);
|
||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero)
|
||||
.Push(ImGuiStyleVar.FrameRounding, 0);
|
||||
for (var i = 0; i < count; ++i)
|
||||
{
|
||||
var custom = _set.Data(id, i);
|
||||
if (ImGui.ColorButton((i + 1).ToString(), ImGui.ColorConvertU32ToFloat4(custom.Color)))
|
||||
{
|
||||
setter(custom.Value);
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
if (i % 8 != 7)
|
||||
ImGui.SameLine();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawMultiIconSelector()
|
||||
{
|
||||
using var bigGroup = ImRaii.Group();
|
||||
using var _ = ImRaii.PushId((int)CustomizationId.FacialFeaturesTattoos);
|
||||
|
||||
void OnChange(int v)
|
||||
{
|
||||
_customize[CustomizationId.FacialFeaturesTattoos] = (byte)v;
|
||||
foreach (var actor in _actors.Where(a => a && a.DrawObject))
|
||||
Glamourer.RedrawManager.UpdateCustomize(actor.DrawObject, _customize);
|
||||
}
|
||||
|
||||
DrawMultiIcons();
|
||||
ImGui.SameLine();
|
||||
int value = _customize[CustomizationId.FacialFeaturesTattoos];
|
||||
using var group = ImRaii.Group();
|
||||
ImGui.Dummy(new Vector2(0, ImGui.GetTextLineHeightWithSpacing() + ImGui.GetStyle().ItemSpacing.Y / 2));
|
||||
InputInt(string.Empty, --value, 0, 255, OnChange);
|
||||
|
||||
ImGui.TextUnformatted(_set.Option(CustomizationId.FacialFeaturesTattoos));
|
||||
}
|
||||
|
||||
private void DrawMultiIcons()
|
||||
{
|
||||
using var _ = ImRaii.Group();
|
||||
var face = _customize.Face;
|
||||
|
||||
var ret = false;
|
||||
var count = _set.Count(CustomizationId.FacialFeaturesTattoos);
|
||||
for (var i = 0; i < count; ++i)
|
||||
{
|
||||
var enabled = _customize.FacialFeatures[i];
|
||||
var feature = _set.FacialFeature(face, i);
|
||||
var icon = i == count - 1
|
||||
? LegacyTattoo ?? Glamourer.Customization.GetIcon(feature.IconId)
|
||||
: Glamourer.Customization.GetIcon(feature.IconId);
|
||||
if (ImGui.ImageButton(icon.ImGuiHandle, _iconSize, Vector2.Zero, Vector2.One, (int)ImGui.GetStyle().FramePadding.X,
|
||||
Vector4.Zero, enabled ? Vector4.One : RedTint))
|
||||
{
|
||||
_customize.FacialFeatures.Set(i, !enabled);
|
||||
foreach (var actor in _actors.Where(a => a && a.DrawObject))
|
||||
Glamourer.RedrawManager.UpdateCustomize(actor.DrawObject, _customize);
|
||||
}
|
||||
|
||||
ImGuiUtil.HoverIconTooltip(icon, _iconSize);
|
||||
if (i % 4 != 3)
|
||||
ImGui.SameLine();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawListSelector(CustomizationId id)
|
||||
{
|
||||
using var _ = ImRaii.PushId((int)id);
|
||||
using var bigGroup = ImRaii.Group();
|
||||
int current = _customize[id];
|
||||
var count = _set.Count(id);
|
||||
|
||||
void OnChange(int v)
|
||||
{
|
||||
_customize[id] = (byte)v;
|
||||
foreach (var actor in _actors.Where(a => a && a.DrawObject))
|
||||
Glamourer.RedrawManager.UpdateCustomize(actor.DrawObject, _customize);
|
||||
}
|
||||
|
||||
ImGui.SetNextItemWidth(_comboSelectorSize * ImGui.GetIO().FontGlobalScale);
|
||||
using (var combo = ImRaii.Combo("##combo", $"{_set.Option(id)} #{current + 1}"))
|
||||
{
|
||||
if (combo)
|
||||
for (var i = 0; i < count; ++i)
|
||||
{
|
||||
if (!ImGui.Selectable($"{_set.Option(id)} #{i + 1}##combo", i == current) || i == current)
|
||||
continue;
|
||||
|
||||
OnChange(i);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
InputInt("##text", current, 1, count, OnChange);
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.TextUnformatted(_set.Option(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
using Glamourer.State;
|
||||
using ImGuiNET;
|
||||
using OtterGui;
|
||||
using OtterGui.Raii;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using System.Numerics;
|
|||
using System.Reflection;
|
||||
using Dalamud.Interface;
|
||||
using Glamourer.Customization;
|
||||
using Glamourer.Interop;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Glamourer.Gui;
|
||||
|
|
@ -20,13 +21,11 @@ internal partial class Interface
|
|||
private static float _inputIntSize;
|
||||
private static float _comboSelectorSize;
|
||||
private static float _raceSelectorWidth;
|
||||
private static bool _inGPose;
|
||||
|
||||
|
||||
private static void UpdateState()
|
||||
{
|
||||
// General
|
||||
_inGPose = ObjectManager.IsInGPose();
|
||||
_spacing = _spacing with { Y = ImGui.GetTextLineHeightWithSpacing() / 2 };
|
||||
_actorSelectorWidth = 200 * ImGuiHelpers.GlobalScale;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,108 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using Dalamud.Logging;
|
||||
using Glamourer.Interop;
|
||||
using Glamourer.State;
|
||||
using ImGuiNET;
|
||||
using OtterGui;
|
||||
using OtterGui.Classes;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Widgets;
|
||||
|
||||
namespace Glamourer.Gui;
|
||||
|
||||
internal partial class Interface : Window, IDisposable
|
||||
{
|
||||
private class DebugStateTab
|
||||
{
|
||||
private readonly CurrentManipulations _currentManipulations;
|
||||
|
||||
private LowerString _manipulationFilter = LowerString.Empty;
|
||||
private Actor.IIdentifier _selection = Actor.IIdentifier.Invalid;
|
||||
private CurrentDesign? _save = null;
|
||||
private bool _delete = false;
|
||||
|
||||
public DebugStateTab(CurrentManipulations currentManipulations)
|
||||
=> _currentManipulations = currentManipulations;
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
using var tab = ImRaii.TabItem("Current Manipulations");
|
||||
if (!tab)
|
||||
return;
|
||||
|
||||
DrawManipulationSelector();
|
||||
if (_save == null)
|
||||
return;
|
||||
|
||||
ImGui.SameLine();
|
||||
DrawActorPanel();
|
||||
if (_delete)
|
||||
{
|
||||
_delete = false;
|
||||
_currentManipulations.DeleteSave(_selection);
|
||||
_selection = Actor.IIdentifier.Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawSelector(Vector2 oldSpacing)
|
||||
{
|
||||
using var child = ImRaii.Child("##actorSelector", new Vector2(_actorSelectorWidth, -1), true);
|
||||
if (!child)
|
||||
return;
|
||||
|
||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, oldSpacing);
|
||||
var skips = ImGuiClip.GetNecessarySkips(ImGui.GetTextLineHeight());
|
||||
var remainder = ImGuiClip.FilteredClippedDraw(_currentManipulations, skips, CheckFilter, DrawSelectable);
|
||||
ImGuiClip.DrawEndDummy(remainder, ImGui.GetTextLineHeight());
|
||||
}
|
||||
|
||||
private void DrawManipulationSelector()
|
||||
{
|
||||
using var group = ImRaii.Group();
|
||||
var oldSpacing = ImGui.GetStyle().ItemSpacing;
|
||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero)
|
||||
.Push(ImGuiStyleVar.FrameRounding, 0);
|
||||
ImGui.SetNextItemWidth(_actorSelectorWidth);
|
||||
LowerString.InputWithHint("##actorFilter", "Filter...", ref _manipulationFilter, 64);
|
||||
|
||||
_save = null;
|
||||
DrawSelector(oldSpacing);
|
||||
}
|
||||
|
||||
private bool CheckFilter(KeyValuePair<Actor.IIdentifier, 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)
|
||||
{
|
||||
var equal = data.Key.Equals(_selection);
|
||||
if (ImGui.Selectable(data.Key.ToString(), equal))
|
||||
{
|
||||
_selection = data.Key;
|
||||
_save = data.Value;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawActorPanel()
|
||||
{
|
||||
using var group = ImRaii.Group();
|
||||
if (ImGui.Button("Delete"))
|
||||
_delete = true;
|
||||
CustomizationDrawer.Draw(_save!.Data.Customize, _save.Data.Equipment, Array.Empty<Actor>(), false);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Glamourer _plugin;
|
||||
|
||||
private readonly ActorTab _actorTab;
|
||||
private readonly DebugStateTab _debugStateTab;
|
||||
|
||||
public Interface(Glamourer plugin)
|
||||
: base(GetLabel())
|
||||
{
|
||||
|
|
@ -23,6 +114,8 @@ internal partial class Interface : Window, IDisposable
|
|||
MinimumSize = new Vector2(675, 675),
|
||||
MaximumSize = ImGui.GetIO().DisplaySize,
|
||||
};
|
||||
_actorTab = new ActorTab(_plugin.CurrentManipulations);
|
||||
_debugStateTab = new DebugStateTab(_plugin.CurrentManipulations);
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
|
|
@ -31,13 +124,21 @@ internal partial class Interface : Window, IDisposable
|
|||
if (!tabBar)
|
||||
return;
|
||||
|
||||
UpdateState();
|
||||
try
|
||||
{
|
||||
UpdateState();
|
||||
|
||||
_actorTab.Draw();
|
||||
DrawSettingsTab();
|
||||
// DrawSaves();
|
||||
// DrawFixedDesignsTab();
|
||||
// DrawRevertablesTab();
|
||||
_actorTab.Draw();
|
||||
DrawSettingsTab();
|
||||
_debugStateTab.Draw();
|
||||
// DrawSaves();
|
||||
// DrawFixedDesignsTab();
|
||||
// DrawRevertablesTab();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
PluginLog.Error($"Unexpected Error during Draw:\n{e}");
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ internal partial class Interface
|
|||
//private bool _holdShift;
|
||||
//private bool _holdCtrl;
|
||||
//private const string DesignNamePopupLabel = "Save Design As...";
|
||||
//private const uint RedHeaderColor = 0xFF1818C0;
|
||||
//private const uint GreenHeaderColor = 0xFF18C018;
|
||||
|
||||
//
|
||||
//private void DrawPlayerHeader()
|
||||
//{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue