Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ME] Add Category attribute, SortPropertiesByType, SortPropertiesByAlphabet config and color work #302

Merged
merged 13 commits into from
Jan 25, 2025
Merged
16 changes: 16 additions & 0 deletions Guides/Material Editor Guide/shader_manifest_template.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
<!-- Optional `Hidden` attribute -->
<Property Name="{{PropertyName}}" Type="Float" Hidden="{{boolean}}"/>
<!-- Example: <Property Name="PropertyName" Type="Float" Hidden="True"/> -->
<!-- -->
<!-- Optional `Category` attribute -->
<Property Name="{{PropertyName}}" Type="Float" Category="{{category_name}}"/>
<!-- Example: <Property Name="PropertyName" Type="Float" Category="Category Name"/> -->

<!-- Color or vector property -->
<Property Name="{{PropertyName}}" Type="Color"/>
Expand All @@ -47,6 +51,10 @@
<!-- Optional `Hidden` attribute -->
<Property Name="{{PropertyName}}" Type="Color" Hidden="{{boolean}}"/>
<!-- Example: <Property Name="PropertyName" Type="Color" Hidden="True"/> -->
<!-- -->
<!-- Optional `Category` attribute -->
<Property Name="{{PropertyName}}" Type="Color" Category="{{category_name}}"/>
<!-- Example: <Property Name="PropertyName" Type="Color" Category="Category Name"/> -->

<!-- Texture property -->
<Property Name="{{PropertyName}}" Type="Texture"/>
Expand All @@ -58,6 +66,10 @@
<!-- Optional `Hidden` attribute -->
<Property Name="{{PropertyName}}" Type="Texture" Hidden="{{boolean}}"/>
<!-- Example: <Property Name="PropertyName" Type="Texture" Hidden="True"/> -->
<!-- -->
<!-- Optional `Category` attribute -->
<Property Name="{{PropertyName}}" Type="Texture" Category="{{category_name}}"/>
<!-- Example: <Property Name="PropertyName" Type="Texture" Category="Category Name"/> -->

<!-- Keyword -->
<Property Name="{{KEYWORD_NAME}}" Type="Keyword"/>
Expand All @@ -69,6 +81,10 @@
<!-- Optional `Hidden` attribute -->
<Property Name="{{KEYWORD_NAME}}" Type="Keyword" Hidden="{{boolean}}"/>
<!-- Example: <Property Name="KEYWORD_NAME" Type="Keyword" Hidden="True"/> -->
<!-- -->
<!-- Optional `Category` attribute -->
<Property Name="{{PropertyName}}" Type="Keyword" Category="{{category_name}}"/>
<!-- Example: <Property Name="PropertyName" Type="Keyword" Category="Category Name"/> -->


<!-- Notes -->
Expand Down
1 change: 1 addition & 0 deletions src/MaterialEditor.Base/MaterialEditor.Base.projitems
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Export.UV.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)PluginBase.cs" />
<Compile Include="$(MSBuildThisFileDirectory)UI\UI.PropertyOrganizer.cs" />
<Compile Include="$(MSBuildThisFileDirectory)UI\UI.cs" />
<Compile Include="$(MSBuildThisFileDirectory)UI\UI.AutoScrollToCenter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)UI\UI.FloatLabelDragTrigger.cs" />
Expand Down
21 changes: 18 additions & 3 deletions src/MaterialEditor.Base/PluginBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public partial class MaterialEditorPluginBase : BaseUnityPlugin
internal static ConfigEntry<string> ConfigExportPath { get; private set; }
public static ConfigEntry<bool> PersistFilter { get; set; }
public static ConfigEntry<bool> Showtooltips { get; set; }
public static ConfigEntry<bool> SortPropertiesByType { get; set; }
public static ConfigEntry<bool> SortPropertiesByName { get; set; }
public static ConfigEntry<float> ProjectorNearClipPlaneMax { get; set; }
public static ConfigEntry<float> ProjectorFarClipPlaneMax { get; set; }
public static ConfigEntry<float> ProjectorFieldOfViewMax { get; set; }
Expand All @@ -73,6 +75,8 @@ public virtual void Awake()
ConfigExportPath = Config.Bind("Config", "Export Path Override", "", new ConfigDescription($"Textures and models will be exported to this folder. If empty, exports to {ExportPathDefault}", null, new ConfigurationManagerAttributes { Order = 1 }));
PersistFilter = Config.Bind("Config", "Persist Filter", false, "Persist search filter across editor windows");
Showtooltips = Config.Bind("Config", "Show Tooltips", true, "Whether to show tooltips or not");
SortPropertiesByType = Config.Bind("Config", "Sort Properties by Type", true, "Whether to sort shader properties by their types.");
SortPropertiesByName = Config.Bind("Config", "Sort Properties by Name", true, "Whether to sort shader properties by their names.");

//Everything in these games is 10x the size of KK/KKS
#if AI || HS2 || PH
Expand All @@ -94,6 +98,9 @@ public virtual void Awake()
WatchTexChanges.SettingChanged += WatchTexChanges_SettingChanged;
ShaderOptimization.SettingChanged += ShaderOptimization_SettingChanged;
ConfigExportPath.SettingChanged += ConfigExportPath_SettingChanged;
SortPropertiesByType.SettingChanged += (object sender, EventArgs e) => PropertyOrganizer.Refresh();
SortPropertiesByName.SettingChanged += (object sender, EventArgs e) => PropertyOrganizer.Refresh();

SetExportPath();

ResourceRedirection.RegisterAssetLoadedHook(HookBehaviour.OneCallbackPerResourceLoaded, AssetLoadedHook);
Expand Down Expand Up @@ -180,6 +187,7 @@ private static void LoadXML()
string range = shaderPropertyElement.GetAttribute("Range");
string min = null;
string max = null;
string category = shaderPropertyElement.GetAttribute("Category");
if (!range.IsNullOrWhiteSpace())
{
var rangeSplit = range.Split(',');
Expand All @@ -189,7 +197,7 @@ private static void LoadXML()
max = rangeSplit[1];
}
}
ShaderPropertyData shaderPropertyData = new ShaderPropertyData(propertyName, propertyType, defaultValue, defaultValueAB, hidden, min, max);
ShaderPropertyData shaderPropertyData = new ShaderPropertyData(propertyName, propertyType, defaultValue, defaultValueAB, hidden, min, max, category);

XMLShaderProperties["default"][propertyName] = shaderPropertyData;
}
Expand Down Expand Up @@ -258,6 +266,11 @@ internal static void SaveTex(Texture tex, string path, RenderTextureFormat rtf =
RenderTexture.active = currentActiveRT;
RenderTexture.ReleaseTemporary(tmp);
}

protected static void RefreshPropertyOrganization()
{
PropertyOrganizer.Refresh();
}

public class ShaderData
{
Expand Down Expand Up @@ -294,8 +307,9 @@ public class ShaderPropertyData
public bool Hidden;
public float? MinValue;
public float? MaxValue;
public string Category;

public ShaderPropertyData(string name, ShaderPropertyType type, string defaultValue = null, string defaultValueAB = null, string hidden = null, string minValue = null, string maxValue = null)
public ShaderPropertyData(string name, ShaderPropertyType type, string defaultValue = null, string defaultValueAB = null, string hidden = null, string minValue = null, string maxValue = null, string category = null)
{
Name = name;
Type = type;
Expand All @@ -309,7 +323,8 @@ public ShaderPropertyData(string name, ShaderPropertyType type, string defaultVa
MinValue = min;
MaxValue = max;
}
}
}
Category = category;
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/MaterialEditor.Base/UI/UI.ItemInfo.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using UnityEngine;

namespace MaterialEditorAPI
Expand Down Expand Up @@ -99,6 +99,6 @@ public ItemInfo(RowItemType itemType, string labelText = "")
LabelText = labelText;
}

public enum RowItemType { Renderer, RendererEnabled, RendererShadowCastingMode, RendererReceiveShadows, RendererUpdateWhenOffscreen, RendererRecalculateNormals, Material, Shader, ShaderRenderQueue, TextureProperty, TextureOffsetScale, ColorProperty, FloatProperty, KeywordProperty }
public enum RowItemType { Renderer, RendererEnabled, RendererShadowCastingMode, RendererReceiveShadows, RendererUpdateWhenOffscreen, RendererRecalculateNormals, Material, Shader, ShaderRenderQueue, PropertyCategory, TextureProperty, TextureOffsetScale, ColorProperty, FloatProperty, KeywordProperty }
}
}
}
19 changes: 17 additions & 2 deletions src/MaterialEditor.Base/UI/UI.ItemTemplate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ internal static GameObject CreateTemplate(Transform parent)
var itemPanel = UIUtility.CreatePanel("RendererPanel", contentList.transform);
itemPanel.gameObject.AddComponent<CanvasGroup>();
itemPanel.gameObject.AddComponent<HorizontalLayoutGroup>().padding = Padding;
itemPanel.color = SeparatorItemColor;
itemPanel.color = RendererColor;

var label = UIUtility.CreateText("RendererLabel", itemPanel.transform, "");
label.alignment = TextAnchor.MiddleLeft;
Expand Down Expand Up @@ -192,7 +192,7 @@ internal static GameObject CreateTemplate(Transform parent)
var itemPanel = UIUtility.CreatePanel("MaterialPanel", contentList.transform);
itemPanel.gameObject.AddComponent<CanvasGroup>();
itemPanel.gameObject.AddComponent<HorizontalLayoutGroup>().padding = Padding;
itemPanel.color = SeparatorItemColor;
itemPanel.color = MaterialColor;

var label = UIUtility.CreateText("MaterialLabel", itemPanel.transform, "");
label.alignment = TextAnchor.MiddleLeft;
Expand Down Expand Up @@ -290,6 +290,21 @@ internal static GameObject CreateTemplate(Transform parent)
resetLE.flexibleWidth = 0;
}

// Property Category
{
var itemPanel = UIUtility.CreatePanel("PropertyCategoryPanel", contentList.transform);
itemPanel.gameObject.AddComponent<CanvasGroup>();
itemPanel.gameObject.AddComponent<HorizontalLayoutGroup>().padding = Padding;
itemPanel.color = CategoryColor;

var label = UIUtility.CreateText("PropertyCategoryLabel", itemPanel.transform, "");
label.alignment = TextAnchor.MiddleLeft;
label.color = Color.black;
var labelLE = label.gameObject.AddComponent<LayoutElement>();
labelLE.preferredWidth = LabelWidth;
labelLE.flexibleWidth = LabelWidth;
}

//Texture properties
{
var itemPanel = UIUtility.CreatePanel("TexturePanel", contentList.transform);
Expand Down
23 changes: 20 additions & 3 deletions src/MaterialEditor.Base/UI/UI.ListEntry.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using UnityEngine;
using UnityEngine.UI;
using static UILib.Extensions;
Expand Down Expand Up @@ -59,6 +59,9 @@ internal class ListEntry : MonoBehaviour
public InputField ShaderRenderQueueInput;
public Button ShaderRenderQueueResetButton;

public CanvasGroup PropertyCategoryPanel;
public Text PropertyCategoryLabel;

public CanvasGroup TexturePanel;
public Text TextureLabel;
public Button SelectInterpolableTextureButton;
Expand Down Expand Up @@ -125,7 +128,7 @@ public void SetItem(ItemInfo item, bool force)
{
case ItemInfo.RowItemType.Renderer:
ShowRenderer();
SetLabelText(RendererLabel, item.LabelText, false, null, RendererPanel);
SetLabelText(RendererLabel, item.LabelText);
ExportUVButton.onClick.RemoveAllListeners();
ExportUVButton.onClick.AddListener(() => item.ExportUVOnClick());
TooltipManager.AddTooltip(ExportUVButton.gameObject, "Export the UV map of this renderer.\n\nThe UV map is the 2d projection of the renderer with which to map textures to the 3d model. You can use this UV map as a guide to drawing on textures");
Expand Down Expand Up @@ -247,7 +250,7 @@ public void SetItem(ItemInfo item, bool force)
break;
case ItemInfo.RowItemType.Material:
ShowMaterial();
SetLabelText(MaterialLabel, item.LabelText, false, null, MaterialPanel);
SetLabelText(MaterialLabel, item.LabelText);
MaterialText.text = item.MaterialName;
MaterialCopyButton.onClick.RemoveAllListeners();
MaterialCopyButton.onClick.AddListener(() => item.MaterialOnCopy.Invoke());
Expand Down Expand Up @@ -363,6 +366,10 @@ public void SetItem(ItemInfo item, bool force)
});
TooltipManager.AddTooltip(ShaderRenderQueueResetButton.gameObject, "Reset this property to its original value");

break;
case ItemInfo.RowItemType.PropertyCategory:
ShowPropertyCategory();
SetLabelText(PropertyCategoryLabel, item.LabelText);
break;
case ItemInfo.RowItemType.TextureProperty:
ShowTexture();
Expand Down Expand Up @@ -762,6 +769,10 @@ public void SetVisible(bool visible)
gameObject.SetActive(visible);
}

private static void SetLabelText(Text label, string text) {
label.text = text ?? "";
}

private static void SetLabelText(Text label, string text, bool valueChanged, Button resetBtn, CanvasGroup panel)
{
label.text = text ?? "";
Expand Down Expand Up @@ -790,6 +801,7 @@ private void HideAll()
ShowMaterial(false);
ShowShader(false);
ShowShaderRenderQueue(false);
ShowPropertyCategory(false);
ShowTexture(false);
ShowOffsetScale(false);
ShowColor(false);
Expand Down Expand Up @@ -844,6 +856,11 @@ private void ShowShaderRenderQueue(bool visible = true)
ShaderRenderQueuePanel.blocksRaycasts = visible;
}

private void ShowPropertyCategory(bool visible = true) {
PropertyCategoryPanel.alpha = visible ? 1 : 0;
PropertyCategoryPanel.blocksRaycasts = visible;
}

private void ShowTexture(bool visible = true)
{
TexturePanel.alpha = visible ? 1 : 0;
Expand Down
46 changes: 46 additions & 0 deletions src/MaterialEditor.Base/UI/UI.PropertyOrganizer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using System.Linq;
using static MaterialEditorAPI.MaterialEditorPluginBase;

namespace MaterialEditorAPI
{
internal class PropertyOrganizer
{
// Shader, category, property
internal static Dictionary<string, Dictionary<string, List<ShaderPropertyData>>> PropertyOrganization = new Dictionary<string, Dictionary<string, List<ShaderPropertyData>>>();
internal static string UncategorizedName = "Uncategorized";
internal static void Refresh() {
foreach (var shader in XMLShaderProperties)
{
PropertyOrganization[shader.Key] = shader.Value
.Where(kv => !kv.Value.Hidden)
.GroupBy(kv => string.IsNullOrEmpty(kv.Value.Category) ? UncategorizedName : char.ToUpper(kv.Value.Category[0]) + kv.Value.Category.Substring(1))
.OrderBy(g => g.Key == UncategorizedName ? 1 : 0) // Ensure "Uncategorized" goes to the end
.ToDictionary(
g => g.Key,
g =>
{
var kvs = g.AsEnumerable();
if (SortPropertiesByType.Value && SortPropertiesByName.Value)
{
kvs = kvs.OrderBy(kv => kv.Value.Type).ThenBy(kv => kv.Value.Name);
}
else if (SortPropertiesByType.Value)
{
kvs = kvs.OrderBy(kv => kv.Value.Type);
}
else if (SortPropertiesByName.Value)
{
kvs = kvs.OrderBy(kv => kv.Value.Name);
}
return kvs.Select(kv=>kv.Value).ToList();
}
);

}
}
}
}
3 changes: 3 additions & 0 deletions src/MaterialEditor.Base/UI/UI.VirtualList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ private void SetupEntryTemplate()
listEntry.ShaderRenderQueueInput = listEntry.GetUIComponent<InputField>("ShaderRenderQueueInput");
listEntry.ShaderRenderQueueResetButton = listEntry.GetUIComponent<Button>("ShaderRenderQueueResetButton");

listEntry.PropertyCategoryPanel = listEntry.GetUIComponent<CanvasGroup>("PropertyCategoryPanel");
listEntry.PropertyCategoryLabel = listEntry.GetUIComponent<Text>("PropertyCategoryLabel");

listEntry.TexturePanel = listEntry.GetUIComponent<CanvasGroup>("TexturePanel");
listEntry.TextureLabel = listEntry.GetUIComponent<Text>("TextureLabel");
listEntry.SelectInterpolableTextureButton = listEntry.GetUIComponent<Button>("SelectInterpolableTextureButton");
Expand Down
Loading