380 lines
15 KiB
C#
380 lines
15 KiB
C#
// Copyright (c) 2015 - 2023 Doozy Entertainment. All Rights Reserved.
|
|
// This code can only be used under the standard Unity Asset Store End User License Agreement
|
|
// A Copy of the EULA APPENDIX 1 is available at http://unity3d.com/company/legal/as_terms
|
|
|
|
using System.Collections.Generic;
|
|
using Doozy.Editor.EditorUI;
|
|
using Doozy.Editor.EditorUI.Components;
|
|
using Doozy.Editor.EditorUI.Components.Internal;
|
|
using Doozy.Editor.EditorUI.Utils;
|
|
using Doozy.Editor.EditorUI.Windows.Internal;
|
|
using Doozy.Editor.UIDesigner.Utils;
|
|
using Doozy.Editor.UIElements;
|
|
using Doozy.Runtime.UIElements.Extensions;
|
|
using UnityEditor;
|
|
using UnityEditor.UIElements;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
// ReSharper disable MemberCanBePrivate.Global
|
|
|
|
namespace Doozy.Editor.UIDesigner.Windows
|
|
{
|
|
public class ScaleWindow : FluidWindow<ScaleWindow>
|
|
{
|
|
private const string WINDOW_TITLE = "Scale";
|
|
public const string k_WindowMenuPath = "Tools/Doozy/UI Designer/";
|
|
|
|
[MenuItem(k_WindowMenuPath + WINDOW_TITLE, priority = -800)]
|
|
public static void Open() => InternalOpenWindow(WINDOW_TITLE);
|
|
|
|
private FloatField snapIntervalFloatField { get; set; }
|
|
private FluidField optionsFluidField { get; set; }
|
|
private FluidField scaleIncreaseFluidField { get; set; }
|
|
private FluidField scaleDecreaseFluidField { get; set; }
|
|
|
|
private FluidRangeSlider scaleIncreaseSlider { get; set; }
|
|
private FluidRangeSlider scaleDecreaseSlider { get; set; }
|
|
|
|
private FluidToggleCheckbox relativeChangeCheckbox { get; set; }
|
|
private FluidToggleCheckbox snapToIntervalCheckbox { get; set; }
|
|
private FluidToggleCheckbox snapToValuesCheckbox { get; set; }
|
|
|
|
private FluidToggleButtonTab xTabButton { get; set; }
|
|
private FluidToggleButtonTab yTabButton { get; set; }
|
|
|
|
private bool scaleX
|
|
{
|
|
get => EditorPrefs.GetBool(EditorPrefsKey(nameof(scaleX)), true);
|
|
set => EditorPrefs.SetBool(EditorPrefsKey(nameof(scaleX)), value);
|
|
}
|
|
|
|
private bool scaleY
|
|
{
|
|
get => EditorPrefs.GetBool(EditorPrefsKey(nameof(scaleY)), true);
|
|
set => EditorPrefs.SetBool(EditorPrefsKey(nameof(scaleY)), value);
|
|
}
|
|
|
|
private float snapInterval
|
|
{
|
|
get => EditorPrefs.GetFloat(EditorPrefsKey(nameof(snapInterval)), 0.05f);
|
|
set => EditorPrefs.SetFloat(EditorPrefsKey(nameof(snapInterval)), value);
|
|
}
|
|
|
|
private bool snapToInterval
|
|
{
|
|
get => EditorPrefs.GetBool(EditorPrefsKey(nameof(snapToInterval)), true);
|
|
set => EditorPrefs.SetBool(EditorPrefsKey(nameof(snapToInterval)), value);
|
|
}
|
|
|
|
private bool snapToValues
|
|
{
|
|
get => EditorPrefs.GetBool(EditorPrefsKey(nameof(snapToValues)), true);
|
|
set => EditorPrefs.SetBool(EditorPrefsKey(nameof(snapToValues)), value);
|
|
}
|
|
|
|
private bool relativeChange
|
|
{
|
|
get => EditorPrefs.GetBool(EditorPrefsKey(nameof(relativeChange)), true);
|
|
set => EditorPrefs.SetBool(EditorPrefsKey(nameof(relativeChange)), value);
|
|
}
|
|
|
|
protected override void OnEnable()
|
|
{
|
|
base.OnEnable();
|
|
SceneView.duringSceneGui -= OnSceneGUI;
|
|
SceneView.duringSceneGui += OnSceneGUI;
|
|
OnSelectionChanged();
|
|
}
|
|
|
|
protected override void OnDisable()
|
|
{
|
|
base.OnDisable();
|
|
SceneView.duringSceneGui -= OnSceneGUI;
|
|
}
|
|
|
|
private void OnSceneGUI(SceneView sceneView)
|
|
{
|
|
if (selected.Count == 0)
|
|
return;
|
|
|
|
Handles.BeginGUI();
|
|
Color color = Handles.color;
|
|
Handles.color = EditorColors.EditorUI.Amber;
|
|
{
|
|
//ToDo SceneView visuals
|
|
}
|
|
Handles.color = color;
|
|
Handles.EndGUI();
|
|
}
|
|
|
|
protected override void CreateGUI()
|
|
{
|
|
Initialize();
|
|
Compose();
|
|
|
|
Selection.selectionChanged -= OnSelectionChanged;
|
|
Selection.selectionChanged += OnSelectionChanged;
|
|
}
|
|
|
|
private static HashSet<RectTransform> selected { get; set; } = new HashSet<RectTransform>();
|
|
|
|
private void OnSelectionChanged() =>
|
|
selected = DesignerEditorUtils.selected;
|
|
|
|
private void Initialize()
|
|
{
|
|
root
|
|
.RecycleAndClear()
|
|
.SetStylePadding(DesignUtils.k_Spacing2X);
|
|
|
|
#region Increase Scale
|
|
|
|
scaleIncreaseSlider =
|
|
new FluidRangeSlider(0, 2)
|
|
.SetTooltip("Increase the scale the selected objects by or to the specified value.")
|
|
.SetAccentColor(EditorColors.UIDesigner.Color)
|
|
.SetSnapInterval(snapInterval)
|
|
.SetSnapValues(0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2f)
|
|
.SetSnapDistanceForSnapValues(0.02f)
|
|
.SetAutoResetValue(0)
|
|
.SetSliderValue(0);
|
|
|
|
scaleIncreaseSlider.onStartValueChange.AddListener(DesignerEditorUtils.StartScale);
|
|
scaleIncreaseSlider.onEndValueChange.AddListener(DesignerEditorUtils.EndScale);
|
|
scaleIncreaseSlider.onValueChanged.AddListener(UpdateScale);
|
|
|
|
scaleIncreaseFluidField =
|
|
FluidField.Get()
|
|
.SetStyleFlexGrow(0)
|
|
.SetStyleFlexShrink(0)
|
|
// .SetLabelText("Increase Scale")
|
|
.SetIcon(EditorSpriteSheets.UIDesigner.Icons.ScaleIncrease)
|
|
.AddFieldContent(scaleIncreaseSlider);
|
|
|
|
#endregion
|
|
|
|
#region Decrease Scale
|
|
|
|
scaleDecreaseSlider =
|
|
new FluidRangeSlider(-2, 0)
|
|
.SetTooltip("Decrease the scale the selected objects by or to the specified value.")
|
|
.SetAccentColor(EditorColors.UIDesigner.Color)
|
|
.SetSnapInterval(snapInterval)
|
|
.SetSnapValues(0f, -0.1f, -0.2f, -0.3f, -0.4f, -0.5f, -0.6f, -0.7f, -0.8f, -0.9f, -1f, -1.1f, -1.2f, -1.3f, -1.4f, -1.5f, -1.6f, -1.7f, -1.8f, -1.9f, -2f)
|
|
.SetSnapDistanceForSnapValues(0.02f)
|
|
.SetAutoResetValue(0)
|
|
.SetSliderValue(0);
|
|
|
|
scaleDecreaseSlider.onStartValueChange.AddListener(DesignerEditorUtils.StartScale);
|
|
scaleDecreaseSlider.onEndValueChange.AddListener(DesignerEditorUtils.EndScale);
|
|
scaleDecreaseSlider.onValueChanged.AddListener(UpdateScale);
|
|
|
|
scaleDecreaseFluidField =
|
|
FluidField.Get()
|
|
.SetStyleFlexGrow(0)
|
|
.SetStyleFlexShrink(0)
|
|
// .SetLabelText("Decrease Scale")
|
|
.SetIcon(EditorSpriteSheets.UIDesigner.Icons.ScaleDecrease)
|
|
.AddFieldContent(scaleDecreaseSlider);
|
|
|
|
#endregion
|
|
|
|
#region Options
|
|
|
|
xTabButton =
|
|
GetToggleButton()
|
|
.SetLabelText("X")
|
|
.SetTooltip("Scale the selected objects along the X axis by or to the specified value.")
|
|
.SetOnValueChanged(evt => scaleX = evt.newValue)
|
|
.SetTabPosition(TabPosition.TabOnLeft);
|
|
|
|
yTabButton =
|
|
GetToggleButton()
|
|
.SetLabelText("Y")
|
|
.SetTooltip("Scale the selected objects along the Y axis by or to the specified value.")
|
|
.SetOnValueChanged(evt => scaleY = evt.newValue)
|
|
.SetTabPosition(TabPosition.TabOnRight);
|
|
|
|
xTabButton.SetIsOn(scaleX, false);
|
|
yTabButton.SetIsOn(scaleY, false);
|
|
|
|
if (!xTabButton.isOn & !yTabButton.isOn)
|
|
{
|
|
xTabButton.SetIsOn(true, false);
|
|
yTabButton.SetIsOn(true, false);
|
|
}
|
|
|
|
relativeChangeCheckbox =
|
|
FluidToggleCheckbox.Get()
|
|
.SetLabelText("Relative Change")
|
|
.SetTooltip
|
|
(
|
|
"If enabled, the scale will be relative to the current scale of the selected objects.\n" +
|
|
"If disabled, the scale will be absolute."
|
|
)
|
|
.SetToggleAccentColor(EditorSelectableColors.UIDesigner.Color)
|
|
.SetIsOn(relativeChange, false)
|
|
.SetOnValueChanged(evt => relativeChange = evt.newValue);
|
|
|
|
snapToIntervalCheckbox =
|
|
FluidToggleCheckbox.Get()
|
|
.SetLabelText("Snap to Interval")
|
|
.SetTooltip
|
|
(
|
|
"If enabled, the scale will snap to the nearest interval.\n" +
|
|
"If disabled, the scale will be continuous."
|
|
)
|
|
.SetToggleAccentColor(EditorSelectableColors.UIDesigner.Color)
|
|
.SetIsOn(snapToInterval, false)
|
|
.SetOnValueChanged(evt =>
|
|
{
|
|
snapToInterval = evt.newValue;
|
|
scaleIncreaseSlider.SnapToInterval(evt.newValue);
|
|
scaleDecreaseSlider.SnapToInterval(evt.newValue);
|
|
snapIntervalFloatField.SetEnabled(evt.newValue);
|
|
});
|
|
|
|
snapIntervalFloatField =
|
|
new FloatField()
|
|
.ResetLayout()
|
|
.SetStyleWidth(60)
|
|
.SetTooltip
|
|
(
|
|
"The interval to snap to.\n" +
|
|
"If Snap to Interval is disabled, this value will be ignored."
|
|
);
|
|
|
|
snapIntervalFloatField.value = snapInterval;
|
|
|
|
snapIntervalFloatField.RegisterValueChangedCallback(evt =>
|
|
{
|
|
if (evt?.newValue == null) return;
|
|
snapInterval = evt.newValue;
|
|
scaleIncreaseSlider.SetSnapInterval(evt.newValue);
|
|
scaleDecreaseSlider.SetSnapInterval(evt.newValue);
|
|
});
|
|
|
|
scaleIncreaseSlider.SetSnapInterval(snapIntervalFloatField.value);
|
|
scaleDecreaseSlider.SetSnapInterval(snapIntervalFloatField.value);
|
|
|
|
snapToValuesCheckbox =
|
|
FluidToggleCheckbox.Get()
|
|
.SetLabelText("Snap to Values")
|
|
.SetTooltip
|
|
(
|
|
"If enabled, the scale will snap to the marked predefined values."
|
|
)
|
|
.SetToggleAccentColor(EditorSelectableColors.UIDesigner.Color)
|
|
.SetIsOn(snapToValues, false)
|
|
.SetOnValueChanged(evt =>
|
|
{
|
|
snapToValues = evt.newValue;
|
|
scaleIncreaseSlider.SnapToValues(evt.newValue);
|
|
scaleDecreaseSlider.SnapToValues(evt.newValue);
|
|
});
|
|
|
|
scaleIncreaseSlider.SnapToValues(snapToValuesCheckbox.isOn);
|
|
scaleDecreaseSlider.SnapToValues(snapToValuesCheckbox.isOn);
|
|
|
|
optionsFluidField =
|
|
FluidField.Get()
|
|
.SetStyleFlexGrow(0)
|
|
.SetStyleFlexShrink(0)
|
|
.AddFieldContent
|
|
(
|
|
new VisualElement()
|
|
.SetName("XYZ - Space - Relative Change")
|
|
.SetStyleFlexShrink(0)
|
|
.SetStyleFlexWrap(Wrap.Wrap)
|
|
.SetStyleFlexDirection(FlexDirection.Row)
|
|
.AddChild
|
|
(
|
|
new VisualElement()
|
|
.SetName("XYZ")
|
|
.SetStyleFlexDirection(FlexDirection.Row)
|
|
.SetStylePadding(DesignUtils.k_Spacing2X)
|
|
.AddChild(xTabButton)
|
|
.AddSpace(1, 0)
|
|
.AddChild(yTabButton)
|
|
)
|
|
.AddChild
|
|
(
|
|
new VisualElement()
|
|
.SetName("Relative Change")
|
|
.SetStyleFlexDirection(FlexDirection.Row)
|
|
.SetStylePadding(DesignUtils.k_Spacing2X)
|
|
.AddChild(relativeChangeCheckbox)
|
|
)
|
|
)
|
|
.AddFieldContent
|
|
(
|
|
new VisualElement()
|
|
.SetName("Snap to Interval - Snap Values")
|
|
.SetStyleFlexShrink(0)
|
|
.SetStyleFlexWrap(Wrap.Wrap)
|
|
.SetStyleFlexDirection(FlexDirection.Row)
|
|
.AddChild
|
|
(
|
|
new VisualElement()
|
|
.SetName("Snap to Interval")
|
|
.SetStyleFlexDirection(FlexDirection.Row)
|
|
.SetStylePadding(DesignUtils.k_Spacing2X)
|
|
.AddChild(snapToIntervalCheckbox)
|
|
.AddSpaceBlock()
|
|
.AddChild(snapIntervalFloatField)
|
|
)
|
|
.AddChild
|
|
(
|
|
new VisualElement()
|
|
.SetName("Snap to Values")
|
|
.SetStyleFlexDirection(FlexDirection.Row)
|
|
.SetStylePadding(DesignUtils.k_Spacing2X)
|
|
.AddChild(snapToValuesCheckbox)
|
|
)
|
|
);
|
|
|
|
#endregion
|
|
}
|
|
|
|
private void Compose()
|
|
{
|
|
root
|
|
.AddChild(scaleIncreaseFluidField)
|
|
.AddSpaceBlock(2)
|
|
.AddChild(scaleDecreaseFluidField)
|
|
.AddSpaceBlock(2)
|
|
.AddChild(optionsFluidField);
|
|
}
|
|
|
|
private void UpdateScale(float value)
|
|
{
|
|
if (scaleX & scaleY)
|
|
{
|
|
DesignerEditorUtils.UpdateScaleXY(value, value, relativeChange);
|
|
return;
|
|
}
|
|
|
|
if (scaleX)
|
|
{
|
|
DesignerEditorUtils.UpdateScaleX(value, relativeChange);
|
|
return;
|
|
}
|
|
|
|
if (scaleY)
|
|
{
|
|
DesignerEditorUtils.UpdateScaleY(value, relativeChange);
|
|
return;
|
|
}
|
|
|
|
Debug.Log("UIDesigner - Unable to scale - No scale axis selected");
|
|
}
|
|
|
|
private FluidToggleButtonTab GetToggleButton() =>
|
|
FluidToggleButtonTab.Get()
|
|
.SetToggleAccentColor(EditorSelectableColors.UIDesigner.Color)
|
|
.SetStyleFlexShrink(0)
|
|
.SetElementSize(ElementSize.Normal)
|
|
.SetContainerColorOff(DesignUtils.tabButtonColorOff);
|
|
}
|
|
}
|