Legacy color table UI be gone

This commit is contained in:
Exter-N 2024-08-19 03:42:36 +02:00
parent 14ebde09d1
commit 040cd5c9db
3 changed files with 150 additions and 201 deletions

View file

@ -252,7 +252,8 @@ public partial class MtrlTab
return ret;
}
private static bool DrawColors(ColorTable table, ColorDyeTable? dyeTable, DyePack? dyePack, int rowIdx)
private static bool DrawColors<TRow, TDyeRow, TDyePack>(IColorTable<TRow> table, IColorDyeTable<TDyeRow>? dyeTable, TDyePack? dyePack, int rowIdx)
where TRow : unmanaged, IColorRow where TDyeRow : unmanaged, IColorDyeRow where TDyePack : unmanaged, IDyePack
{
var dyeOffset = ImGui.GetContentRegionAvail().X
+ ImGui.GetStyle().ItemSpacing.X

View file

@ -50,9 +50,9 @@ public partial class MtrlTab
ret |= Mtrl.Table switch
{
LegacyColorTable legacyTable => DrawLegacyColorTable(legacyTable, Mtrl.DyeTable as LegacyColorDyeTable, disabled),
LegacyColorTable legacyTable => DrawLegacyColorTable(legacyTable, Mtrl.DyeTable as LegacyColorDyeTable, disabled, uiState),
ColorTable table when Mtrl.ShaderPackage.Name is "characterlegacy.shpk" => DrawLegacyColorTable(table,
Mtrl.DyeTable as ColorDyeTable, disabled),
Mtrl.DyeTable as ColorDyeTable, disabled, uiState),
ColorTable table => DrawColorTable(table, Mtrl.DyeTable as ColorDyeTable, disabled, uiState),
_ => false,
};

View file

@ -1,7 +1,5 @@
using Dalamud.Interface;
using Dalamud.Interface.Utility.Raii;
using ImGuiNET;
using OtterGui;
using OtterGui.Text;
using Penumbra.GameData.Files.MaterialStructs;
using Penumbra.GameData.Files.StainMapStructs;
@ -11,247 +9,197 @@ namespace Penumbra.UI.AdvancedWindow.Materials;
public partial class MtrlTab
{
private const float LegacyColorTableFloatSize = 65.0f;
private const float LegacyColorTablePercentageSize = 50.0f;
private const float LegacyColorTableIntegerSize = 40.0f;
private const float LegacyColorTableByteSize = 25.0f;
private bool DrawLegacyColorTable<TRow, TDyeRow>(IColorTable<TRow> table, IColorDyeTable<TDyeRow>? dyeTable, bool disabled)
private bool DrawLegacyColorTable<TRow, TDyeRow>(IColorTable<TRow> table, IColorDyeTable<TDyeRow>? dyeTable, bool disabled, MtrlTabUiState uiState)
where TRow : unmanaged, ILegacyColorRow where TDyeRow : unmanaged, ILegacyColorDyeRow
{
using var imTable = ImUtf8.Table("##ColorTable"u8, dyeTable != null ? 10 : 8,
ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg | ImGuiTableFlags.BordersInnerV);
if (!imTable)
return false;
DrawColorTablePairSelector(table, disabled, uiState);
return DrawLegacyColorTablePairEditor(table, dyeTable, disabled, uiState);
}
DrawLegacyColorTableHeader(dyeTable != null);
var ret = false;
for (var i = 0; i < ColorTable.NumRows; ++i)
private bool DrawLegacyColorTablePairEditor<TRow, TDyeRow>(IColorTable<TRow> table, IColorDyeTable<TDyeRow>? dyeTable, bool disabled, MtrlTabUiState uiState)
where TRow : unmanaged, ILegacyColorRow where TDyeRow : unmanaged, ILegacyColorDyeRow
{
var retA = false;
var retB = false;
var rowAIdx = uiState.ColorTableSelectedPair << 1;
var rowBIdx = rowAIdx | 1;
var dyeA = dyeTable?[uiState.ColorTableSelectedPair << 1] ?? default;
var dyeB = dyeTable?[(uiState.ColorTableSelectedPair << 1) | 1] ?? default;
var previewDyeA = _stainService.GetStainCombo(dyeA.Channel).CurrentSelection.Key;
var previewDyeB = _stainService.GetStainCombo(dyeB.Channel).CurrentSelection.Key;
var dyePackA = _stainService.LegacyStmFile.GetValueOrNull(dyeA.Template, previewDyeA);
var dyePackB = _stainService.LegacyStmFile.GetValueOrNull(dyeB.Template, previewDyeB);
using (var columns = ImUtf8.Columns(2, "ColorTable"u8))
{
if (DrawLegacyColorTableRow(table, dyeTable, i, disabled))
using (ImUtf8.PushId("RowHeaderA"u8))
{
UpdateColorTableRowPreview(i);
ret = true;
retA |= DrawRowHeader(rowAIdx, disabled);
}
columns.Next();
using (ImUtf8.PushId("RowHeaderB"u8))
{
retB |= DrawRowHeader(rowBIdx, disabled);
}
}
DrawHeader(" Colors"u8);
using (var columns = ImUtf8.Columns(2, "ColorTable"u8))
{
using var dis = ImRaii.Disabled(disabled);
using (ImUtf8.PushId("ColorsA"u8))
{
retA |= DrawColors(table, dyeTable, dyePackA, rowAIdx);
}
ImGui.TableNextRow();
columns.Next();
using (ImUtf8.PushId("ColorsB"u8))
{
retB |= DrawColors(table, dyeTable, dyePackB, rowBIdx);
}
}
return ret;
}
private static void DrawLegacyColorTableHeader(bool hasDyeTable)
{
ImGui.TableNextColumn();
ImUtf8.TableHeader(default(ReadOnlySpan<byte>));
ImGui.TableNextColumn();
ImUtf8.TableHeader("Row"u8);
ImGui.TableNextColumn();
ImUtf8.TableHeader("Diffuse"u8);
ImGui.TableNextColumn();
ImUtf8.TableHeader("Specular"u8);
ImGui.TableNextColumn();
ImUtf8.TableHeader("Emissive"u8);
ImGui.TableNextColumn();
ImUtf8.TableHeader("Gloss"u8);
ImGui.TableNextColumn();
ImUtf8.TableHeader("Tile"u8);
ImGui.TableNextColumn();
ImUtf8.TableHeader("Repeat / Skew"u8);
if (hasDyeTable)
DrawHeader(" Specular Parameters"u8);
using (var columns = ImUtf8.Columns(2, "ColorTable"u8))
{
ImGui.TableNextColumn();
ImUtf8.TableHeader("Dye"u8);
ImGui.TableNextColumn();
ImUtf8.TableHeader("Dye Preview"u8);
using var dis = ImRaii.Disabled(disabled);
using (ImUtf8.PushId("SpecularA"u8))
{
retA |= DrawLegacySpecular(table, dyeTable, dyePackA, rowAIdx);
}
columns.Next();
using (ImUtf8.PushId("SpecularB"u8))
{
retB |= DrawLegacySpecular(table, dyeTable, dyePackB, rowBIdx);
}
}
DrawHeader(" Material Template"u8);
using (var columns = ImUtf8.Columns(2, "ColorTable"u8))
{
using var dis = ImRaii.Disabled(disabled);
using (ImUtf8.PushId("TemplateA"u8))
{
retA |= DrawTemplateTile(table, rowAIdx);
}
columns.Next();
using (ImUtf8.PushId("TemplateB"u8))
{
retB |= DrawTemplateTile(table, rowBIdx);
}
}
if (dyeTable != null)
{
DrawHeader(" Dye Properties"u8);
using var columns = ImUtf8.Columns(2, "ColorTable"u8);
using var dis = ImRaii.Disabled(disabled);
using (ImUtf8.PushId("DyeA"u8))
{
retA |= DrawLegacyDye(dyeTable, dyePackA, rowAIdx);
}
columns.Next();
using (ImUtf8.PushId("DyeB"u8))
{
retB |= DrawLegacyDye(dyeTable, dyePackB, rowBIdx);
}
}
if (retA)
UpdateColorTableRowPreview(rowAIdx);
if (retB)
UpdateColorTableRowPreview(rowBIdx);
return retA | retB;
}
private bool DrawLegacyColorTableRow<TRow, TDyeRow>(IColorTable<TRow> table, IColorDyeTable<TDyeRow>? dyeTable, int rowIdx, bool disabled)
private static bool DrawLegacySpecular<TRow, TDyeRow>(IColorTable<TRow> table, IColorDyeTable<TDyeRow>? dyeTable, LegacyDyePack? dyePack, int rowIdx)
where TRow : unmanaged, ILegacyColorRow where TDyeRow : unmanaged, ILegacyColorDyeRow
{
using var id = ImRaii.PushId(rowIdx);
ref var row = ref table[rowIdx];
var dye = dyeTable?[rowIdx] ?? default;
var floatSize = LegacyColorTableFloatSize * UiHelpers.Scale;
var pctSize = LegacyColorTablePercentageSize * UiHelpers.Scale;
var intSize = LegacyColorTableIntegerSize * UiHelpers.Scale;
var byteSize = LegacyColorTableByteSize * UiHelpers.Scale;
ImGui.TableNextColumn();
ColorTableCopyClipboardButton(rowIdx);
ImUtf8.SameLineInner();
var ret = ColorTablePasteFromClipboardButton(rowIdx, disabled);
ImUtf8.SameLineInner();
ColorTableRowHighlightButton(rowIdx, disabled);
var scalarSize = ColorTableScalarSize * UiHelpers.Scale;
var subColWidth = CalculateSubColumnWidth(2) + ImGui.GetStyle().ItemSpacing.X;
var dyeOffset = subColWidth
- ImGui.GetStyle().ItemSpacing.X * 2.0f
- ImGui.GetStyle().ItemInnerSpacing.X
- ImGui.GetFrameHeight()
- scalarSize;
ImGui.TableNextColumn();
using (ImRaii.PushFont(UiBuilder.MonoFont))
{
ImUtf8.Text($"{(rowIdx >> 1) + 1,2:D}{"AB"[rowIdx & 1]}");
}
var ret = false;
ref var row = ref table[rowIdx];
var dye = dyeTable?[rowIdx] ?? default;
ImGui.TableNextColumn();
using var dis = ImRaii.Disabled(disabled);
ret |= CtColorPicker("##Diffuse"u8, "Diffuse Color"u8, row.DiffuseColor,
c => table[rowIdx].DiffuseColor = c);
if (dyeTable != null)
{
ImUtf8.SameLineInner();
ret |= CtApplyStainCheckbox("##dyeDiffuse"u8, "Apply Diffuse Color on Dye"u8, dye.DiffuseColor,
b => dyeTable[rowIdx].DiffuseColor = b);
}
ImGui.TableNextColumn();
ret |= CtColorPicker("##Specular"u8, "Specular Color"u8, row.SpecularColor,
c => table[rowIdx].SpecularColor = c);
if (dyeTable != null)
{
ImUtf8.SameLineInner();
ret |= CtApplyStainCheckbox("##dyeSpecular"u8, "Apply Specular Color on Dye"u8, dye.SpecularColor,
b => dyeTable[rowIdx].SpecularColor = b);
}
ImGui.SameLine();
ImGui.SetNextItemWidth(pctSize);
ret |= CtDragScalar("##SpecularMask"u8, "Specular Strength"u8, (float)row.SpecularMask * 100.0f, "%.0f%%"u8, 0f, HalfMaxValue * 100.0f, 1.0f,
ImGui.SetNextItemWidth(scalarSize);
ret |= CtDragScalar("Specular Strength"u8, default, (float)row.SpecularMask * 100.0f, "%.0f%%"u8, 0.0f, HalfMaxValue * 100.0f,
1.0f,
v => table[rowIdx].SpecularMask = (Half)(v * 0.01f));
if (dyeTable != null)
{
ImUtf8.SameLineInner();
ImGui.SameLine(dyeOffset);
ret |= CtApplyStainCheckbox("##dyeSpecularMask"u8, "Apply Specular Strength on Dye"u8, dye.SpecularMask,
b => dyeTable[rowIdx].SpecularMask = b);
}
ImGui.TableNextColumn();
ret |= CtColorPicker("##Emissive"u8, "Emissive Color"u8, row.EmissiveColor,
c => table[rowIdx].EmissiveColor = c);
if (dyeTable != null)
{
ImUtf8.SameLineInner();
ret |= CtApplyStainCheckbox("##dyeEmissive"u8, "Apply Emissive Color on Dye"u8, dye.EmissiveColor,
b => dyeTable[rowIdx].EmissiveColor = b);
ImGui.SetNextItemWidth(scalarSize);
CtDragScalar("##dyePreviewSpecularMask"u8, "Dye Preview for Specular Strength"u8, (float?)dyePack?.SpecularMask * 100.0f, "%.0f%%"u8);
}
ImGui.TableNextColumn();
ImGui.SetNextItemWidth(floatSize);
var glossStrengthMin = ImGui.GetIO().KeyCtrl ? 0.0f : HalfEpsilon;
ret |= CtDragHalf("##Shininess"u8, "Gloss Strength"u8, row.Shininess, "%.1f"u8, glossStrengthMin, HalfMaxValue,
ImGui.SameLine(subColWidth);
ImGui.SetNextItemWidth(scalarSize);
var shininessMin = ImGui.GetIO().KeyCtrl ? 0.0f : HalfEpsilon;
ret |= CtDragHalf("Gloss"u8, default, row.Shininess, "%.1f"u8, shininessMin, HalfMaxValue,
Math.Max(0.1f, (float)row.Shininess * 0.025f),
v => table[rowIdx].Shininess = v);
if (dyeTable != null)
{
ImUtf8.SameLineInner();
ret |= CtApplyStainCheckbox("##dyeShininess"u8, "Apply Gloss Strength on Dye"u8, dye.Shininess,
ImGui.SameLine(subColWidth + dyeOffset);
ret |= CtApplyStainCheckbox("##dyeShininess"u8, "Apply Gloss on Dye"u8, dye.Shininess,
b => dyeTable[rowIdx].Shininess = b);
}
ImGui.TableNextColumn();
ImGui.SetNextItemWidth(intSize);
ret |= CtTileIndexPicker("##TileIndex"u8, "Tile Index"u8, row.TileIndex, true,
value => table[rowIdx].TileIndex = value);
ImUtf8.SameLineInner();
ImGui.SetNextItemWidth(pctSize);
if (table is ColorTable rwTable)
{
ret |= CtDragScalar("##TileAlpha"u8, "Tile Opacity"u8, (float)row.TileAlpha * 100.0f, "%.0f%%"u8, 0f, HalfMaxValue * 100.0f, 1.0f,
v => rwTable[rowIdx].TileAlpha = (Half)(v * 0.01f));
}
else
CtDragScalar<float>("##TileAlpha"u8, "Tile Opacity"u8, (float)row.TileAlpha * 100.0f, "%.0f%%"u8);
ImGui.TableNextColumn();
ret |= CtTileTransformMatrix(row.TileTransform, floatSize, false,
m => table[rowIdx].TileTransform = m);
if (dyeTable != null)
{
ImGui.TableNextColumn();
ImGui.SetNextItemWidth(byteSize);
if (dyeTable is ColorDyeTable rwDyeTable)
{
ret |= CtDragScalar("##DyeChannel"u8, "Dye Channel"u8, dye.Channel + 1, "%d"u8, 1, StainService.ChannelCount, 0.25f,
value => rwDyeTable[rowIdx].Channel = (byte)(Math.Clamp(value, 1, StainService.ChannelCount) - 1));
}
else
CtDragScalar<int>("##DyeChannel"u8, "Dye Channel"u8, dye.Channel + 1, "%d"u8);
ImUtf8.SameLineInner();
_stainService.LegacyTemplateCombo.CurrentDyeChannel = dye.Channel;
if (_stainService.LegacyTemplateCombo.Draw("##dyeTemplate", dye.Template.ToString(), string.Empty, intSize
+ ImGui.GetStyle().ScrollbarSize / 2, ImGui.GetTextLineHeightWithSpacing(), ImGuiComboFlags.NoArrowButton))
{
dyeTable[rowIdx].Template = _stainService.LegacyTemplateCombo.CurrentSelection;
ret = true;
}
ImGuiUtil.HoverTooltip("Dye Template", ImGuiHoveredFlags.AllowWhenDisabled);
ImGui.TableNextColumn();
ret |= DrawLegacyDyePreview(rowIdx, disabled, dye, floatSize);
ImGui.SetNextItemWidth(scalarSize);
CtDragHalf("##dyePreviewShininess"u8, "Dye Preview for Gloss"u8, dyePack?.Shininess, "%.1f"u8);
}
return ret;
}
private bool DrawLegacyDyePreview<TDyeRow>(int rowIdx, bool disabled, TDyeRow dye, float floatSize)
private bool DrawLegacyDye<TDyeRow>(IColorDyeTable<TDyeRow> dyeTable, LegacyDyePack? dyePack, int rowIdx)
where TDyeRow : unmanaged, ILegacyColorDyeRow
{
var stain = _stainService.StainCombo1.CurrentSelection.Key;
if (stain == 0 || !_stainService.LegacyStmFile.TryGetValue(dye.Template, stain, out var values))
return false;
var scalarSize = ColorTableScalarSize * UiHelpers.Scale;
var applyButtonWidth = ImUtf8.CalcTextSize("Apply Preview Dye"u8).X + ImGui.GetStyle().FramePadding.X * 2.0f;
var subColWidth = CalculateSubColumnWidth(2, applyButtonWidth);
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, ImGui.GetStyle().ItemSpacing / 2);
var ret = false;
ref var dye = ref dyeTable[rowIdx];
var ret = ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.PaintBrush.ToIconString(), new Vector2(ImGui.GetFrameHeight()),
"Apply the selected dye to this row.", disabled, true);
ImGui.SetNextItemWidth(scalarSize);
if (dyeTable is ColorDyeTable rwDyeTable)
{
ret |= CtDragScalar("Dye Channel"u8, default, dye.Channel + 1, "%d"u8, 1, StainService.ChannelCount, 0.1f,
value => rwDyeTable[rowIdx].Channel = (byte)(Math.Clamp(value, 1, StainService.ChannelCount) - 1));
}
else
CtDragScalar<int>("Dye Channel"u8, default, dye.Channel + 1, "%d"u8);
ImGui.SameLine(subColWidth);
ImGui.SetNextItemWidth(scalarSize);
if (_stainService.LegacyTemplateCombo.Draw("##dyeTemplate", dye.Template.ToString(), string.Empty,
scalarSize + ImGui.GetStyle().ScrollbarSize / 2, ImGui.GetTextLineHeightWithSpacing(), ImGuiComboFlags.NoArrowButton))
{
dye.Template = _stainService.LegacyTemplateCombo.CurrentSelection;
ret = true;
}
ret = ret && Mtrl.ApplyDyeToRow(_stainService.LegacyStmFile, [stain], rowIdx);
ImGui.SameLine();
DrawLegacyDyePreview(values, floatSize);
return ret;
}
private bool DrawLegacyDyePreview(int rowIdx, bool disabled, ColorDyeTableRow dye, float floatSize)
{
var stain = _stainService.GetStainCombo(dye.Channel).CurrentSelection.Key;
if (stain == 0 || !_stainService.LegacyStmFile.TryGetValue(dye.Template, stain, out var values))
return false;
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, ImGui.GetStyle().ItemSpacing / 2);
var ret = ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.PaintBrush.ToIconString(), new Vector2(ImGui.GetFrameHeight()),
"Apply the selected dye to this row.", disabled, true);
ret = ret
&& Mtrl.ApplyDyeToRow(_stainService.LegacyStmFile, [
ImUtf8.SameLineInner();
ImUtf8.Text("Dye Template"u8);
ImGui.SameLine(ImGui.GetContentRegionAvail().X - applyButtonWidth + ImGui.GetStyle().ItemSpacing.X);
using var dis = ImRaii.Disabled(!dyePack.HasValue);
if (ImUtf8.Button("Apply Preview Dye"u8))
ret |= Mtrl.ApplyDyeToRow(_stainService.LegacyStmFile, [
_stainService.StainCombo1.CurrentSelection.Key,
_stainService.StainCombo2.CurrentSelection.Key,
], rowIdx);
ImGui.SameLine();
DrawLegacyDyePreview(values, floatSize);
return ret;
}
private static void DrawLegacyDyePreview(LegacyDyePack values, float floatSize)
{
CtColorPicker("##diffusePreview"u8, default, values.DiffuseColor, "D"u8);
ImUtf8.SameLineInner();
CtColorPicker("##specularPreview"u8, default, values.SpecularColor, "S"u8);
ImUtf8.SameLineInner();
CtColorPicker("##emissivePreview"u8, default, values.EmissiveColor, "E"u8);
ImUtf8.SameLineInner();
using var dis = ImRaii.Disabled();
ImGui.SetNextItemWidth(floatSize);
var shininess = (float)values.Shininess;
ImGui.DragFloat("##shininessPreview", ref shininess, 0, shininess, shininess, "%.1f G");
ImUtf8.SameLineInner();
ImGui.SetNextItemWidth(floatSize);
var specularMask = (float)values.SpecularMask * 100.0f;
ImGui.DragFloat("##specularMaskPreview", ref specularMask, 0, specularMask, specularMask, "%.0f%% S");
}
}