using UnityEditor;
|
|
using UnityEngine;
|
|
using static UnityEditor.EditorGUI;
|
|
|
|
namespace LeTai.TrueShadow.Editor
|
|
{
|
|
[CustomPropertyDrawer(typeof(SpreadSliderAttribute))]
|
|
public class SpreadSliderDrawer : PropertyDrawer
|
|
{
|
|
const float SLIDER_SPACING = 5;
|
|
const float MARKER_HEIGHT = 6;
|
|
const float MARKER_ALPHA = .75f;
|
|
const float MARKER_FILLET = 2;
|
|
|
|
static readonly Vector4 START_RADII = new Vector4(MARKER_FILLET, 0, 0, MARKER_FILLET);
|
|
static readonly Vector4 END_RADII = new Vector4(0, MARKER_FILLET, MARKER_FILLET, 0);
|
|
|
|
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
|
{
|
|
using (var propScope = new PropertyScope(position, label, property))
|
|
using (var changeScope = new ChangeCheckScope())
|
|
{
|
|
var controlPosition = PrefixLabel(position, propScope.content);
|
|
|
|
var floatFieldWidth = Mathf.Min(EditorGUIUtility.fieldWidth, controlPosition.width);
|
|
var sliderPosition = new Rect(controlPosition)
|
|
{width = controlPosition.width - floatFieldWidth - SLIDER_SPACING};
|
|
|
|
const float marker1 = .8f;
|
|
const float marker2 = .95f;
|
|
|
|
DrawMarkers(sliderPosition,
|
|
(marker1, new Color(1.00000f, 0.60392f, 0.01961f, MARKER_ALPHA)),
|
|
(marker2, new Color(1.00000f, 0.25490f, 0.20784f, MARKER_ALPHA)));
|
|
|
|
var newVal = Slider(controlPosition,
|
|
GUIContent.none,
|
|
property.floatValue,
|
|
0, 1);
|
|
|
|
if (!Event.current.control && !Event.current.alt)
|
|
{
|
|
var dist1 = (newVal - marker1) * sliderPosition.width;
|
|
var dist2 = (newVal - marker2) * sliderPosition.width;
|
|
if (0 < dist1 && dist1 < 4)
|
|
newVal = marker1;
|
|
if (0 < dist2 && dist2 < 4)
|
|
newVal = marker2;
|
|
}
|
|
|
|
if (changeScope.changed)
|
|
property.floatValue = newVal;
|
|
}
|
|
}
|
|
|
|
void DrawMarkers(Rect sliderPosition, params (float, Color)[] markers)
|
|
{
|
|
var hPad = GUI.skin.horizontalSliderThumb.fixedWidth / 2f;
|
|
var markerXStart = sliderPosition.x + hPad;
|
|
var markerXEnd = sliderPosition.width - hPad * 2;
|
|
var vPad = (sliderPosition.height - MARKER_HEIGHT) / 2f;
|
|
var markerYStart = sliderPosition.y + vPad;
|
|
var markerHeight = sliderPosition.height - vPad * 2;
|
|
for (var i = 0; i < markers.Length; i++)
|
|
{
|
|
var (offset, color) = markers[i];
|
|
|
|
var x = markerXStart + markerXEnd * offset;
|
|
var width = i < markers.Length - 1
|
|
? sliderPosition.width * (markers[i + 1].Item1 - offset) - 1
|
|
: sliderPosition.xMax - x;
|
|
var position = new Rect {
|
|
x = x,
|
|
y = markerYStart,
|
|
width = width,
|
|
height = markerHeight
|
|
};
|
|
|
|
var radii = i == 0 ? START_RADII : END_RADII;
|
|
|
|
GUI.DrawTexture(position,
|
|
Texture2D.whiteTexture, ScaleMode.StretchToFill, true, 0, color,
|
|
Vector4.zero, radii);
|
|
}
|
|
}
|
|
}
|
|
}
|