507 lines
22 KiB
C#
507 lines
22 KiB
C#
using System;
|
|
using UnityEditor;
|
|
using UnityEditor.UI;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using Object = UnityEngine.Object;
|
|
|
|
namespace MPUIKIT.Editor {
|
|
[CustomEditor(typeof(MPImage), true)]
|
|
[CanEditMultipleObjects]
|
|
public class MPImageEditor : ImageEditor {
|
|
private SerializedProperty spSprite;
|
|
private SerializedProperty spCircle, spTriangle, spRectangle, spPentagon, spHexagon, spNStarPolygon;
|
|
private SerializedProperty spPreserveAspect;
|
|
private SerializedProperty spFillMethod, spFillOrigin, spFillAmount, spFillClockwise;
|
|
private SerializedProperty spShape;
|
|
private SerializedProperty spStrokeWidth, spOutlineWidth, spOutlineColor, spFalloffDistance;
|
|
private SerializedProperty spConstrainRotation, spShapeRotation, spFlipHorizontal, spFlipVertical;
|
|
private SerializedProperty spMaterialSettings, spMaterial, spImageType;
|
|
|
|
private SerializedProperty spGradient;
|
|
|
|
private bool gsInitialized, shaderChannelsNeedUpdate;
|
|
|
|
protected override void OnEnable() {
|
|
foreach (Object obj in serializedObject.targetObjects) {
|
|
((MPImage) obj).UpdateSerializedValuesFromSharedMaterial();
|
|
}
|
|
|
|
base.OnEnable();
|
|
|
|
spSprite = serializedObject.FindProperty("m_Sprite");
|
|
|
|
spShape = serializedObject.FindProperty("m_DrawShape");
|
|
|
|
spStrokeWidth = serializedObject.FindProperty("m_StrokeWidth");
|
|
spOutlineWidth = serializedObject.FindProperty("m_OutlineWidth");
|
|
spOutlineColor = serializedObject.FindProperty("m_OutlineColor");
|
|
spFalloffDistance = serializedObject.FindProperty("m_FalloffDistance");
|
|
|
|
spMaterialSettings = serializedObject.FindProperty("m_MaterialMode");
|
|
spMaterial = serializedObject.FindProperty("m_Material");
|
|
spImageType = serializedObject.FindProperty("m_ImageType");
|
|
|
|
spFillMethod = serializedObject.FindProperty("m_FillMethod");
|
|
spFillOrigin = serializedObject.FindProperty("m_FillOrigin");
|
|
spFillAmount = serializedObject.FindProperty("m_FillAmount");
|
|
spFillClockwise = serializedObject.FindProperty("m_FillClockwise");
|
|
|
|
spConstrainRotation = serializedObject.FindProperty("m_ConstrainRotation");
|
|
spShapeRotation = serializedObject.FindProperty("m_ShapeRotation");
|
|
spFlipHorizontal = serializedObject.FindProperty("m_FlipHorizontal");
|
|
spFlipVertical = serializedObject.FindProperty("m_FlipVertical");
|
|
|
|
|
|
spCircle = serializedObject.FindProperty("m_Circle");
|
|
spRectangle = serializedObject.FindProperty("m_Rectangle");
|
|
spTriangle = serializedObject.FindProperty("m_Triangle");
|
|
spPentagon = serializedObject.FindProperty("m_Pentagon");
|
|
spHexagon = serializedObject.FindProperty("m_Hexagon");
|
|
spNStarPolygon = serializedObject.FindProperty("m_NStarPolygon");
|
|
|
|
spPreserveAspect = serializedObject.FindProperty("m_PreserveAspect");
|
|
|
|
spGradient = serializedObject.FindProperty("m_GradientEffect");
|
|
}
|
|
|
|
|
|
|
|
public override void OnInspectorGUI() {
|
|
serializedObject.Update();
|
|
|
|
FixShaderChannelGUI();
|
|
|
|
RaycastControlsGUI();
|
|
EditorGUILayout.PropertyField(m_Color);
|
|
EditorGUILayout.Space();
|
|
EditorGUILayout.PropertyField(spShape);
|
|
|
|
if (spShape.enumValueIndex != (int) DrawShape.None) {
|
|
EditorGUILayout.BeginVertical("Box");
|
|
if (!spShape.hasMultipleDifferentValues) {
|
|
switch ((DrawShape) spShape.enumValueIndex) {
|
|
case DrawShape.Circle:
|
|
EditorGUILayout.PropertyField(spCircle);
|
|
break;
|
|
case DrawShape.Rectangle:
|
|
EditorGUILayout.PropertyField(spRectangle);
|
|
break;
|
|
case DrawShape.Pentagon:
|
|
EditorGUILayout.PropertyField(spPentagon);
|
|
break;
|
|
case DrawShape.Triangle:
|
|
EditorGUILayout.PropertyField(spTriangle);
|
|
break;
|
|
case DrawShape.Hexagon:
|
|
EditorGUILayout.PropertyField(spHexagon);
|
|
break;
|
|
case DrawShape.NStarPolygon:
|
|
EditorGUILayout.PropertyField(spNStarPolygon);
|
|
break;
|
|
default:
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
}
|
|
|
|
EditorGUILayout.Space();
|
|
|
|
if (spShape.enumValueIndex != (int) DrawShape.None) {
|
|
AdditionalShapeDataGUI();
|
|
}
|
|
EditorGUILayout.EndVertical();
|
|
}
|
|
|
|
|
|
|
|
EditorGUILayout.Space();
|
|
ImageTypeGUI();
|
|
|
|
SpriteGUI();
|
|
|
|
if (!spSprite.hasMultipleDifferentValues && spSprite.objectReferenceValue != null) {
|
|
EditorGUILayout.PropertyField(spPreserveAspect);
|
|
}
|
|
|
|
SetShowNativeSize(spSprite.objectReferenceValue != null, true);
|
|
NativeSizeButtonGUI();
|
|
|
|
EditorGUILayout.Space();
|
|
SharedMaterialGUI();
|
|
|
|
EditorGUILayout.Space();
|
|
EditorGUILayout.BeginVertical("Box");
|
|
{
|
|
EditorGUILayout.PropertyField(spGradient);
|
|
}
|
|
EditorGUILayout.EndVertical();
|
|
|
|
serializedObject.ApplyModifiedProperties();
|
|
serializedObject.Update();
|
|
Repaint();
|
|
}
|
|
|
|
private void AdditionalShapeDataGUI() {
|
|
EditorGUILayout.Space();
|
|
|
|
float strokeWidth = spStrokeWidth.floatValue;
|
|
float outlineWidth = spOutlineWidth.floatValue;
|
|
float falloff = spFalloffDistance.floatValue;
|
|
Color outlineColor = spOutlineColor.colorValue;
|
|
|
|
Rect r = EditorGUILayout.GetControlRect(true,
|
|
EditorGUIUtility.singleLineHeight * 2 + EditorGUIUtility.standardVerticalSpacing);
|
|
Rect line = r;
|
|
line.height = EditorGUIUtility.singleLineHeight;
|
|
float x = (line.width - 10f) / 2;
|
|
|
|
float fieldWidth = x / 2 - 10f;
|
|
float labelWidth = x - fieldWidth;
|
|
|
|
line.width = labelWidth;
|
|
EditorGUI.LabelField(line, "Stroke");
|
|
Rect dragZone = line;
|
|
line.x += labelWidth;
|
|
line.width = fieldWidth;
|
|
EditorGUI.BeginChangeCheck();
|
|
{
|
|
EditorGUI.showMixedValue = spStrokeWidth.hasMultipleDifferentValues;
|
|
strokeWidth =
|
|
EditorGUILayoutExtended.FloatFieldExtended(line, spStrokeWidth.floatValue, dragZone);
|
|
EditorGUI.showMixedValue = false;
|
|
}
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
spStrokeWidth.floatValue = strokeWidth;
|
|
}
|
|
line.x += fieldWidth + 10;
|
|
line.width = labelWidth;
|
|
EditorGUI.LabelField(line, "Falloff");
|
|
dragZone = line;
|
|
line.x += labelWidth;
|
|
line.width = fieldWidth;
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
{
|
|
EditorGUI.showMixedValue = spFalloffDistance.hasMultipleDifferentValues;
|
|
falloff =
|
|
EditorGUILayoutExtended.FloatFieldExtended(line, spFalloffDistance.floatValue, dragZone);
|
|
EditorGUI.showMixedValue = false;
|
|
}
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
spFalloffDistance.floatValue = falloff;
|
|
}
|
|
line.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
|
line.x = r.x;
|
|
line.width = labelWidth;
|
|
EditorGUI.LabelField(line, "Outline Width");
|
|
dragZone = line;
|
|
line.x += labelWidth;
|
|
line.width = fieldWidth;
|
|
EditorGUI.BeginChangeCheck();
|
|
{
|
|
EditorGUI.showMixedValue = spOutlineWidth.hasMultipleDifferentValues;
|
|
outlineWidth =
|
|
EditorGUILayoutExtended.FloatFieldExtended(line, spOutlineWidth.floatValue, dragZone);
|
|
EditorGUI.showMixedValue = false;
|
|
}
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
spOutlineWidth.floatValue = outlineWidth;
|
|
}
|
|
line.x += fieldWidth + 10;
|
|
line.width = labelWidth;
|
|
EditorGUI.LabelField(line, "Outline Color");
|
|
dragZone = line;
|
|
line.width = fieldWidth;
|
|
line.x += labelWidth;
|
|
EditorGUI.BeginChangeCheck();
|
|
{
|
|
EditorGUI.showMixedValue = spOutlineColor.hasMultipleDifferentValues;
|
|
outlineColor = EditorGUI.ColorField(line, spOutlineColor.colorValue);
|
|
EditorGUI.showMixedValue = false;
|
|
}
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
spOutlineColor.colorValue = outlineColor;
|
|
}
|
|
|
|
EditorGUILayout.Space();
|
|
|
|
RotationGUI();
|
|
}
|
|
|
|
private void RotationGUI() {
|
|
Rect r =EditorGUILayout.GetControlRect(true,
|
|
EditorGUIUtility.singleLineHeight + 24 + EditorGUIUtility.standardVerticalSpacing);
|
|
Rect line = r;
|
|
line.height = EditorGUIUtility.singleLineHeight;
|
|
float x = (line.width - 10f) / 2;
|
|
|
|
float fieldWidth = x / 2 - 10f;
|
|
float labelWidth = x - fieldWidth;
|
|
|
|
line.width = labelWidth;
|
|
EditorGUI.LabelField(line, "Rotation");
|
|
line.x += labelWidth;
|
|
line.width = r.width - labelWidth - 78;
|
|
|
|
string[] options = spConstrainRotation.hasMultipleDifferentValues? new []{ "---", "---" } : new []{"Free", "Constrained"};
|
|
bool boolVal = spConstrainRotation.boolValue;
|
|
EditorGUI.BeginChangeCheck();
|
|
{
|
|
boolVal = GUI.Toolbar(line, boolVal ? 1 : 0, options) == 1;
|
|
}
|
|
if (EditorGUI.EndChangeCheck()) {
|
|
spConstrainRotation.boolValue = boolVal;
|
|
GUI.FocusControl(null);
|
|
}
|
|
|
|
line.x += line.width + 14;
|
|
line.width = 64;
|
|
EditorGUI.LabelField(line, "Flip");
|
|
|
|
line.y += EditorGUIUtility.standardVerticalSpacing + EditorGUIUtility.singleLineHeight;
|
|
line.x = r.x + 10;
|
|
line.height = EditorGUIUtility.singleLineHeight;
|
|
line.width = labelWidth - 10;
|
|
EditorGUI.BeginDisabledGroup(spConstrainRotation.boolValue);
|
|
{
|
|
Rect dragZone = line;
|
|
EditorGUI.LabelField(line, "Angle");
|
|
line.x = r.x + labelWidth;
|
|
line.width = r.width - labelWidth - 148;
|
|
|
|
float rotationValue = spShapeRotation.floatValue;
|
|
EditorGUI.BeginChangeCheck();
|
|
{
|
|
EditorGUI.showMixedValue = spShapeRotation.hasMultipleDifferentValues;
|
|
rotationValue = EditorGUILayoutExtended.FloatFieldExtended(line, spShapeRotation.floatValue, dragZone);
|
|
EditorGUI.showMixedValue = false;
|
|
}
|
|
if (EditorGUI.EndChangeCheck()) {
|
|
spShapeRotation.floatValue = rotationValue;
|
|
}
|
|
}
|
|
EditorGUI.EndDisabledGroup();
|
|
|
|
EditorGUI.BeginDisabledGroup(!spConstrainRotation.boolValue);
|
|
{
|
|
line.x += line.width + 4;
|
|
line.width = 30;
|
|
line.height = 24;
|
|
if (GUI.Button(line, MPEditorContents.RotateLeftNormal)) {
|
|
float rotation = spShapeRotation.floatValue;
|
|
float remainder = rotation % 90;
|
|
if (Mathf.Abs(remainder) <= 0) {
|
|
rotation += 90;
|
|
}
|
|
else {
|
|
rotation = rotation - remainder + 90;
|
|
}
|
|
if (Math.Abs(rotation) >= 360) rotation = 0;
|
|
spShapeRotation.floatValue = rotation;
|
|
}
|
|
|
|
line.x += 34;
|
|
if (GUI.Button(line, MPEditorContents.RotateRightNormal)) {
|
|
float rotation = spShapeRotation.floatValue;
|
|
float remainder = rotation % 90;
|
|
if (Mathf.Abs(remainder) <= 0) {
|
|
rotation -= 90;
|
|
}
|
|
else {
|
|
rotation -= remainder;
|
|
}
|
|
|
|
if (Math.Abs(rotation) >= 360) rotation = 0;
|
|
spShapeRotation.floatValue = rotation;
|
|
}
|
|
}
|
|
EditorGUI.EndDisabledGroup();
|
|
|
|
line.x += 46;
|
|
bool flipH = spFlipHorizontal.boolValue;
|
|
bool flipV = spFlipVertical.boolValue;
|
|
EditorGUI.BeginChangeCheck();
|
|
{
|
|
EditorGUI.BeginDisabledGroup(spFlipHorizontal.hasMultipleDifferentValues || spFlipVertical.hasMultipleDifferentValues);
|
|
flipH = GUI.Toggle(line, spFlipHorizontal.boolValue, spFlipHorizontal.boolValue ? MPEditorContents.FlipHorizontalActive:MPEditorContents.FlipHorizontalNormal, "button");
|
|
line.x += 34;
|
|
flipV = GUI.Toggle(line, spFlipVertical.boolValue, spFlipVertical.boolValue?MPEditorContents.FlipVerticalActive:MPEditorContents.FlipVerticalNormal, "button");
|
|
EditorGUI.EndDisabledGroup();
|
|
}
|
|
if (EditorGUI.EndChangeCheck()) {
|
|
spFlipHorizontal.boolValue = flipH;
|
|
spFlipVertical.boolValue = flipV;
|
|
}
|
|
|
|
}
|
|
|
|
private void FixShaderChannelGUI() {
|
|
if (!shaderChannelsNeedUpdate) return;
|
|
EditorGUILayout.HelpBox(
|
|
"Parent Canvas needs to have these additional shader channels : Texcoord1, Texcoord2",
|
|
MessageType.Error);
|
|
EditorGUILayout.BeginHorizontal();
|
|
{
|
|
GUILayout.FlexibleSpace();
|
|
if (GUILayout.Button("Fix", GUILayout.Width(100))) {
|
|
Canvas canvas = (target as MPImage)?.GetComponentInParent<Canvas>();
|
|
if (canvas != null) {
|
|
MPEditorUtility.AddAdditionalShaderChannelsToCanvas(canvas);
|
|
shaderChannelsNeedUpdate = false;
|
|
}
|
|
}
|
|
}
|
|
EditorGUILayout.EndHorizontal();
|
|
}
|
|
|
|
private new void SpriteGUI() {
|
|
EditorGUI.BeginChangeCheck();
|
|
EditorGUILayout.PropertyField(spSprite, new GUIContent("Sprite"));
|
|
if (EditorGUI.EndChangeCheck()) {
|
|
Sprite newSprite = spSprite.objectReferenceValue as Sprite;
|
|
if (newSprite) {
|
|
Image.Type oldType = (Image.Type) spImageType.enumValueIndex;
|
|
if (newSprite.border.SqrMagnitude() > 0) {
|
|
spImageType.enumValueIndex = (int) Image.Type.Sliced;
|
|
}
|
|
else if (oldType == Image.Type.Sliced) {
|
|
spImageType.enumValueIndex = (int) Image.Type.Simple;
|
|
}
|
|
}
|
|
|
|
(serializedObject.targetObject as Image)?.DisableSpriteOptimizations();
|
|
}
|
|
}
|
|
|
|
private void ImageTypeGUI() {
|
|
int selectedIndex = spImageType.enumValueIndex == (int) Image.Type.Simple ? 0 : 1;
|
|
Rect imageTypeRect = EditorGUILayout.GetControlRect();
|
|
EditorGUI.BeginChangeCheck();
|
|
{
|
|
EditorGUI.LabelField(
|
|
new Rect(imageTypeRect.x, imageTypeRect.y, EditorGUIUtility.labelWidth, imageTypeRect.height),
|
|
"Type");
|
|
imageTypeRect.x += EditorGUIUtility.labelWidth + 2;
|
|
imageTypeRect.width -= EditorGUIUtility.labelWidth + 2;
|
|
selectedIndex = EditorGUI.Popup(imageTypeRect, selectedIndex, new[] {"Simple", "Filled"});
|
|
}
|
|
if (EditorGUI.EndChangeCheck()) {
|
|
spImageType.enumValueIndex = (int) (selectedIndex == 0 ? Image.Type.Simple : Image.Type.Filled);
|
|
}
|
|
|
|
if (!spImageType.hasMultipleDifferentValues && spImageType.enumValueIndex == (int) Image.Type.Filled) {
|
|
++EditorGUI.indentLevel;
|
|
EditorGUI.BeginChangeCheck();
|
|
EditorGUILayout.PropertyField(spFillMethod);
|
|
if (EditorGUI.EndChangeCheck()) {
|
|
spFillOrigin.intValue = 0;
|
|
}
|
|
|
|
switch ((Image.FillMethod) spFillMethod.enumValueIndex) {
|
|
case Image.FillMethod.Horizontal:
|
|
spFillOrigin.intValue = (int) (Image.OriginHorizontal) EditorGUILayout.EnumPopup("Fill Origin",
|
|
(Image.OriginHorizontal) spFillOrigin.intValue);
|
|
break;
|
|
case Image.FillMethod.Vertical:
|
|
spFillOrigin.intValue = (int) (Image.OriginVertical) EditorGUILayout.EnumPopup("Fill Origin",
|
|
(Image.OriginVertical) spFillOrigin.intValue);
|
|
break;
|
|
case Image.FillMethod.Radial90:
|
|
spFillOrigin.intValue =
|
|
(int) (Image.Origin90) EditorGUILayout.EnumPopup("Fill Origin",
|
|
(Image.Origin90) spFillOrigin.intValue);
|
|
break;
|
|
case Image.FillMethod.Radial180:
|
|
spFillOrigin.intValue =
|
|
(int) (Image.Origin180) EditorGUILayout.EnumPopup("Fill Origin",
|
|
(Image.Origin180) spFillOrigin.intValue);
|
|
break;
|
|
case Image.FillMethod.Radial360:
|
|
spFillOrigin.intValue =
|
|
(int) (Image.Origin360) EditorGUILayout.EnumPopup("Fill Origin",
|
|
(Image.Origin360) spFillOrigin.intValue);
|
|
break;
|
|
}
|
|
|
|
EditorGUILayout.PropertyField(spFillAmount);
|
|
if ((Image.FillMethod) spFillMethod.enumValueIndex > Image.FillMethod.Vertical) {
|
|
EditorGUILayout.PropertyField(spFillClockwise, new GUIContent("Clockwise"));
|
|
}
|
|
|
|
--EditorGUI.indentLevel;
|
|
}
|
|
}
|
|
|
|
private void SharedMaterialGUI() {
|
|
Rect rect = EditorGUILayout.GetControlRect(true,
|
|
EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing);
|
|
int matSett = spMaterialSettings.enumValueIndex;
|
|
Rect labelRect = rect;
|
|
labelRect.width = EditorGUIUtility.labelWidth;
|
|
EditorGUI.LabelField(labelRect, "Material Mode");
|
|
rect.x += labelRect.width;
|
|
rect.width -= labelRect.width;
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
EditorGUI.showMixedValue = spMaterialSettings.hasMultipleDifferentValues;
|
|
string[] options = new[] {"Dynamic", "Shared"};
|
|
if (EditorGUI.showMixedValue) options = new[] {"---", "---"};
|
|
matSett = GUI.Toolbar(rect, matSett, options);
|
|
|
|
if (EditorGUI.EndChangeCheck()) {
|
|
spMaterialSettings.enumValueIndex = matSett;
|
|
foreach (Object obj in targets) {
|
|
((MPImage) obj).MaterialMode = (MaterialMode) matSett;
|
|
EditorUtility.SetDirty(obj);
|
|
}
|
|
}
|
|
|
|
EditorGUI.showMixedValue = false;
|
|
|
|
|
|
EditorGUI.BeginDisabledGroup(spMaterialSettings.enumValueIndex == (int) MaterialMode.Dynamic);
|
|
{
|
|
rect = EditorGUILayout.GetControlRect(true,
|
|
EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing);
|
|
|
|
Object matObj = spMaterial.objectReferenceValue;
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
{
|
|
EditorGUI.showMixedValue = spMaterialSettings.hasMultipleDifferentValues;
|
|
matObj = (Material) EditorGUI.ObjectField(
|
|
new Rect(rect.x, rect.y, rect.width - 60, EditorGUIUtility.singleLineHeight),
|
|
matObj, typeof(Material), false);
|
|
EditorGUI.showMixedValue = false;
|
|
}
|
|
if (EditorGUI.EndChangeCheck()) {
|
|
spMaterial.objectReferenceValue = matObj;
|
|
foreach (Object obj in targets) {
|
|
((MPImage) obj).material = (Material) matObj;
|
|
EditorUtility.SetDirty(obj);
|
|
}
|
|
}
|
|
|
|
EditorGUI.BeginDisabledGroup(spMaterial.objectReferenceValue != null);
|
|
{
|
|
if (GUI.Button(new Rect(rect.x + rect.width - 55, rect.y, 55, EditorGUIUtility.singleLineHeight),
|
|
"Create")) {
|
|
Material mat = ((MPImage) target).CreateMaterialAssetFromComponentSettings();
|
|
spMaterial.objectReferenceValue = mat;
|
|
foreach (Object obj in targets) {
|
|
((MPImage) obj).material = mat;
|
|
EditorUtility.SetDirty(obj);
|
|
}
|
|
}
|
|
}
|
|
EditorGUI.EndDisabledGroup();
|
|
}
|
|
EditorGUI.EndDisabledGroup();
|
|
}
|
|
}
|
|
}
|