diff --git a/Glamourer/GameData/CustomizeParameterValue.cs b/Glamourer/GameData/CustomizeParameterValue.cs index 0e22d18..0e2df8e 100644 --- a/Glamourer/GameData/CustomizeParameterValue.cs +++ b/Glamourer/GameData/CustomizeParameterValue.cs @@ -1,4 +1,6 @@ -namespace Glamourer.GameData; +using Newtonsoft.Json; + +namespace Glamourer.GameData; public readonly struct CustomizeParameterValue { @@ -47,4 +49,30 @@ public readonly struct CustomizeParameterValue public override string ToString() => _data.ToString(); + + public string ToJson() + { + try + { + return JsonConvert.SerializeObject(_data, Formatting.None); + } + catch + { + return string.Empty; + } + } + + public static bool FromJson(string input, out CustomizeParameterValue value) + { + try + { + value = new CustomizeParameterValue(JsonConvert.DeserializeObject(input)); + return true; + } + catch + { + value = default; + return false; + } + } } diff --git a/Glamourer/Gui/Customization/CustomizeParameterDrawer.cs b/Glamourer/Gui/Customization/CustomizeParameterDrawer.cs index 28f3d3c..62f46a2 100644 --- a/Glamourer/Gui/Customization/CustomizeParameterDrawer.cs +++ b/Glamourer/Gui/Customization/CustomizeParameterDrawer.cs @@ -1,4 +1,5 @@ -using Glamourer.Designs; +using Dalamud.Interface; +using Glamourer.Designs; using Glamourer.GameData; using Glamourer.Interop.PalettePlus; using Glamourer.State; @@ -17,17 +18,20 @@ public class CustomizeParameterDrawer(Configuration config, PaletteImport import private CustomizeParameterFlag _flags; private float _width; - public void Draw(DesignManager designManager, Design design) { - using var _ = EnsureSize(); + using var generalSize = EnsureSize(); DrawPaletteImport(designManager, design); DrawConfig(true); - foreach (var flag in CustomizeParameterExtensions.RgbFlags) - DrawColorInput3(CustomizeParameterDrawData.FromDesign(designManager, design, flag)); - foreach (var flag in CustomizeParameterExtensions.RgbaFlags) - DrawColorInput4(CustomizeParameterDrawData.FromDesign(designManager, design, flag)); + using (_ = ImRaii.ItemWidth(_width - 2 * ImGui.GetFrameHeight() - 2 * ImGui.GetStyle().ItemInnerSpacing.X)) + { + foreach (var flag in CustomizeParameterExtensions.RgbFlags) + DrawColorInput3(CustomizeParameterDrawData.FromDesign(designManager, design, flag), true); + + foreach (var flag in CustomizeParameterExtensions.RgbaFlags) + DrawColorInput4(CustomizeParameterDrawData.FromDesign(designManager, design, flag)); + } foreach (var flag in CustomizeParameterExtensions.PercentageFlags) DrawPercentageInput(CustomizeParameterDrawData.FromDesign(designManager, design, flag)); @@ -36,6 +40,26 @@ public class CustomizeParameterDrawer(Configuration config, PaletteImport import DrawValueInput(CustomizeParameterDrawData.FromDesign(designManager, design, flag)); } + public void Draw(StateManager stateManager, ActorState state) + { + using var _ = EnsureSize(); + DrawConfig(false); + using (_ = ImRaii.ItemWidth(_width - 2 * ImGui.GetFrameHeight() - 2 * ImGui.GetStyle().ItemInnerSpacing.X)) + { + foreach (var flag in CustomizeParameterExtensions.RgbFlags) + DrawColorInput3(CustomizeParameterDrawData.FromState(stateManager, state, flag), state.ModelData.Customize.Highlights); + + foreach (var flag in CustomizeParameterExtensions.RgbaFlags) + DrawColorInput4(CustomizeParameterDrawData.FromState(stateManager, state, flag)); + } + + foreach (var flag in CustomizeParameterExtensions.PercentageFlags) + DrawPercentageInput(CustomizeParameterDrawData.FromState(stateManager, state, flag)); + + foreach (var flag in CustomizeParameterExtensions.ValueFlags) + DrawValueInput(CustomizeParameterDrawData.FromState(stateManager, state, flag)); + } + private void DrawPaletteCombo() { using var id = ImRaii.PushId("Palettes"); @@ -97,24 +121,8 @@ public class CustomizeParameterDrawer(Configuration config, PaletteImport import } } - public void Draw(StateManager stateManager, ActorState state) - { - using var _ = EnsureSize(); - DrawConfig(false); - foreach (var flag in CustomizeParameterExtensions.RgbFlags) - DrawColorInput3(CustomizeParameterDrawData.FromState(stateManager, state, flag)); - foreach (var flag in CustomizeParameterExtensions.RgbaFlags) - DrawColorInput4(CustomizeParameterDrawData.FromState(stateManager, state, flag)); - - foreach (var flag in CustomizeParameterExtensions.PercentageFlags) - DrawPercentageInput(CustomizeParameterDrawData.FromState(stateManager, state, flag)); - - foreach (var flag in CustomizeParameterExtensions.ValueFlags) - DrawValueInput(CustomizeParameterDrawData.FromState(stateManager, state, flag)); - } - - public void DrawConfig(bool withApply) + private void DrawConfig(bool withApply) { if (!config.ShowColorConfig) return; @@ -133,7 +141,7 @@ public class CustomizeParameterDrawer(Configuration config, PaletteImport import "Hide the color configuration options from the Advanced Customization panel. You can re-enable it in Glamourers interface settings."); } - public void DrawColorDisplayOptions() + private void DrawColorDisplayOptions() { using var group = ImRaii.Group(); if (ImGui.RadioButton("RGB", config.UseRgbForColors) && !config.UseRgbForColors) @@ -150,7 +158,7 @@ public class CustomizeParameterDrawer(Configuration config, PaletteImport import } } - public void DrawColorFormatOptions(bool withApply) + private void DrawColorFormatOptions(bool withApply) { var width = _width - (ImGui.CalcTextSize("Float").X @@ -176,16 +184,22 @@ public class CustomizeParameterDrawer(Configuration config, PaletteImport import } } - private void DrawColorInput3(in CustomizeParameterDrawData data) + private void DrawColorInput3(in CustomizeParameterDrawData data, bool allowHighlights) { - using var id = ImRaii.PushId((int)data.Flag); - var value = data.CurrentValue.InternalTriple; - using (_ = ImRaii.Disabled(data.Locked)) + using var id = ImRaii.PushId((int)data.Flag); + var value = data.CurrentValue.InternalTriple; + var noHighlights = !allowHighlights && data.Flag is CustomizeParameterFlag.HairHighlight; + DrawCopyPasteButtons(data, data.Locked || noHighlights); + ImGui.SameLine(0, ImGui.GetStyle().ItemInnerSpacing.X); + using (_ = ImRaii.Disabled(data.Locked || noHighlights)) { if (ImGui.ColorEdit3("##value", ref value, GetFlags())) data.ValueSetter(new CustomizeParameterValue(value)); } + if (noHighlights) + ImGuiUtil.HoverTooltip("Highlights are disabled in your regular customizations.", ImGuiHoveredFlags.AllowWhenDisabled); + DrawRevert(data); DrawApplyAndLabel(data); @@ -195,6 +209,8 @@ public class CustomizeParameterDrawer(Configuration config, PaletteImport import { using var id = ImRaii.PushId((int)data.Flag); var value = data.CurrentValue.InternalQuadruple; + DrawCopyPasteButtons(data, data.Locked); + ImGui.SameLine(0, ImGui.GetStyle().ItemInnerSpacing.X); using (_ = ImRaii.Disabled(data.Locked)) { if (ImGui.ColorEdit4("##value", ref value, GetFlags() | ImGuiColorEditFlags.AlphaPreviewHalf)) @@ -229,7 +245,7 @@ public class CustomizeParameterDrawer(Configuration config, PaletteImport import using (_ = ImRaii.Disabled(data.Locked)) { - if (ImGui.SliderFloat("##value", ref value, -100f, 200f, "%.2f")) + if (ImGui.SliderFloat("##value", ref value, -100f, 300, "%.2f")) data.ValueSetter(new CustomizeParameterValue(value / 100f)); ImGuiUtil.HoverTooltip("You can control-click this to enter arbitrary values by hand instead of dragging."); } @@ -281,7 +297,29 @@ public class CustomizeParameterDrawer(Configuration config, PaletteImport import private ImRaii.IEndObject EnsureSize() { var iconSize = ImGui.GetTextLineHeight() * 2 + ImGui.GetStyle().ItemSpacing.Y + 4 * ImGui.GetStyle().FramePadding.Y; - _width = 6 * iconSize + 4 * ImGui.GetStyle().ItemInnerSpacing.X; + _width = 7 * iconSize + 4 * ImGui.GetStyle().ItemInnerSpacing.X; return ImRaii.ItemWidth(_width); } + + private static void DrawCopyPasteButtons(in CustomizeParameterDrawData data, bool locked) + { + if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Copy.ToIconString(), new Vector2(ImGui.GetFrameHeight()), + "Copy this color to clipboard.", false, true)) + ImGui.SetClipboardText(data.CurrentValue.ToJson()); + ImGui.SameLine(0, ImGui.GetStyle().ItemInnerSpacing.X); + if (!ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Paste.ToIconString(), new Vector2(ImGui.GetFrameHeight()), + "Try to paste this color from clipboard", locked, true)) + return; + + try + { + var text = ImGui.GetClipboardText(); + if (CustomizeParameterValue.FromJson(text, out var v)) + data.ValueSetter(v); + } + catch + { + // ignored + } + } } diff --git a/Glamourer/State/StateEditor.cs b/Glamourer/State/StateEditor.cs index 1d5048e..9dc8418 100644 --- a/Glamourer/State/StateEditor.cs +++ b/Glamourer/State/StateEditor.cs @@ -210,8 +210,8 @@ public class StateEditor } /// Change the customize flags of a character. - public bool ChangeParameter(ActorState state, CustomizeParameterFlag flag, CustomizeParameterValue value, StateChanged.Source source, out CustomizeParameterValue oldValue, - uint key = 0) + public bool ChangeParameter(ActorState state, CustomizeParameterFlag flag, CustomizeParameterValue value, StateChanged.Source source, + out CustomizeParameterValue oldValue, uint key = 0) { oldValue = state.ModelData.Parameters[flag]; if (!state.CanUnlock(key)) @@ -219,6 +219,7 @@ public class StateEditor state.ModelData.Parameters.Set(flag, value); state[flag] = source; + return true; } diff --git a/Glamourer/State/StateManager.cs b/Glamourer/State/StateManager.cs index 4f683b8..0286e73 100644 --- a/Glamourer/State/StateManager.cs +++ b/Glamourer/State/StateManager.cs @@ -312,6 +312,10 @@ public class StateManager( public void ChangeCustomizeParameter(ActorState state, CustomizeParameterFlag flag, CustomizeParameterValue value, StateChanged.Source source, uint key = 0) { + // Also apply main color to highlights when highlights is off. + if (!state.ModelData.Customize.Highlights && flag is CustomizeParameterFlag.HairDiffuse) + ChangeCustomizeParameter(state, CustomizeParameterFlag.HairHighlight, value, source, key); + if (!_editor.ChangeParameter(state, flag, value, source, out var old, key)) return; @@ -410,6 +414,12 @@ public class StateManager( foreach (var flag in CustomizeParameterExtensions.AllFlags.Where(design.DoApplyParameter)) _editor.ChangeParameter(state, flag, design.DesignData.Parameters[flag], paramSource, out _, key); + + // Do not apply highlights from a design if highlights is unchecked. + if (!state.ModelData.Customize.Highlights) + _editor.ChangeParameter(state, CustomizeParameterFlag.HairHighlight, + state.ModelData.Parameters[CustomizeParameterFlag.HairDiffuse], + state[CustomizeParameterFlag.HairDiffuse], out _, key); } var actors = ApplyAll(state, redraw, false); diff --git a/Penumbra.GameData b/Penumbra.GameData index afc0345..1ebaf1d 160000 --- a/Penumbra.GameData +++ b/Penumbra.GameData @@ -1 +1 @@ -Subproject commit afc0345819ca64ec08432e0011b65ff9880c2967 +Subproject commit 1ebaf1d209b7edc783896b3a6af4907c91bb302e