@@ -323,6 +323,7 @@
|
|||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=reverb/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=reverb/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=rigidbodies/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=rigidbodies/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=rigidbody/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=rigidbody/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Scaler/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=scanline/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=scanline/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=scanlines/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=scanlines/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Scarlett/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Scarlett/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
|||||||
@@ -40,6 +40,11 @@ namespace FlaxEditor.CustomEditors
|
|||||||
[HideInEditor]
|
[HideInEditor]
|
||||||
public abstract class CustomEditor
|
public abstract class CustomEditor
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// True if Editor is during value setting (eg. by user or from copy/paste).
|
||||||
|
/// </summary>
|
||||||
|
public static bool IsSettingValue = false;
|
||||||
|
|
||||||
private LayoutElementsContainer _layout;
|
private LayoutElementsContainer _layout;
|
||||||
private CustomEditorPresenter _presenter;
|
private CustomEditorPresenter _presenter;
|
||||||
private CustomEditor _parent;
|
private CustomEditor _parent;
|
||||||
@@ -266,23 +271,30 @@ namespace FlaxEditor.CustomEditors
|
|||||||
// Check if need to update value
|
// Check if need to update value
|
||||||
if (_hasValueDirty)
|
if (_hasValueDirty)
|
||||||
{
|
{
|
||||||
// Cleanup (won't retry update in case of exception)
|
IsSettingValue = true;
|
||||||
object val = _valueToSet;
|
try
|
||||||
_hasValueDirty = false;
|
|
||||||
_valueToSet = null;
|
|
||||||
|
|
||||||
// Assign value
|
|
||||||
SynchronizeValue(val);
|
|
||||||
|
|
||||||
// Propagate values up (eg. when member of structure gets modified, also structure should be updated as a part of the other object)
|
|
||||||
var obj = _parent;
|
|
||||||
while (obj._parent != null && !(obj._parent is SyncPointEditor))
|
|
||||||
{
|
{
|
||||||
obj.Values.Set(obj._parent.Values, obj.Values);
|
// Cleanup (won't retry update in case of exception)
|
||||||
obj = obj._parent;
|
object val = _valueToSet;
|
||||||
}
|
_hasValueDirty = false;
|
||||||
|
_valueToSet = null;
|
||||||
|
|
||||||
OnUnDirty();
|
// Assign value
|
||||||
|
SynchronizeValue(val);
|
||||||
|
|
||||||
|
// Propagate values up (eg. when member of structure gets modified, also structure should be updated as a part of the other object)
|
||||||
|
var obj = _parent;
|
||||||
|
while (obj._parent != null && !(obj._parent is SyncPointEditor))
|
||||||
|
{
|
||||||
|
obj.Values.Set(obj._parent.Values, obj.Values);
|
||||||
|
obj = obj._parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
OnUnDirty();
|
||||||
|
IsSettingValue = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -817,6 +817,7 @@ namespace FlaxEditor.Windows
|
|||||||
|
|
||||||
// Selected UI controls outline
|
// Selected UI controls outline
|
||||||
bool drawAnySelectedControl = false;
|
bool drawAnySelectedControl = false;
|
||||||
|
// TODO: optimize this (eg. cache list of selected UIControl's when selection gets changed)
|
||||||
for (var i = 0; i < Editor.Instance.SceneEditing.Selection.Count; i++)
|
for (var i = 0; i < Editor.Instance.SceneEditing.Selection.Count; i++)
|
||||||
{
|
{
|
||||||
if (Editor.Instance.SceneEditing.Selection[i].EditableObject is UIControl controlActor && controlActor && controlActor.Control != null)
|
if (Editor.Instance.SceneEditing.Selection[i].EditableObject is UIControl controlActor && controlActor && controlActor.Control != null)
|
||||||
@@ -827,7 +828,8 @@ namespace FlaxEditor.Windows
|
|||||||
Render2D.PushTransform(ref _viewport._cachedTransform);
|
Render2D.PushTransform(ref _viewport._cachedTransform);
|
||||||
}
|
}
|
||||||
var control = controlActor.Control;
|
var control = controlActor.Control;
|
||||||
var bounds = Rectangle.FromPoints(control.PointToParent(_viewport, Float2.Zero), control.PointToParent(_viewport, control.Size));
|
var bounds = control.EditorBounds;
|
||||||
|
bounds = Rectangle.FromPoints(control.PointToParent(_viewport, bounds.Location), control.PointToParent(_viewport, bounds.Size));
|
||||||
Render2D.DrawRectangle(bounds, Editor.Instance.Options.Options.Visual.SelectionOutlineColor0, Editor.Instance.Options.Options.Visual.UISelectionOutlineSize);
|
Render2D.DrawRectangle(bounds, Editor.Instance.Options.Options.Visual.SelectionOutlineColor0, Editor.Instance.Options.Options.Visual.UISelectionOutlineSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
526
Source/Engine/UI/GUI/CanvasScaler.cs
Normal file
526
Source/Engine/UI/GUI/CanvasScaler.cs
Normal file
@@ -0,0 +1,526 @@
|
|||||||
|
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace FlaxEngine.GUI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// UI canvas scaling component for user interface that targets multiple different game resolutions (eg. mobile screens).
|
||||||
|
/// </summary>
|
||||||
|
public class CanvasScaler : ContainerControl
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Canvas scaling modes.
|
||||||
|
/// </summary>
|
||||||
|
public enum ScalingMode
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Applies constant scale to the whole UI in pixels.
|
||||||
|
/// </summary>
|
||||||
|
ConstantPixelSize,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Applies constant scale to the whole UI in physical units (depends on the screen DPI). Ensures the UI will have specific real-world size no matter the screen resolution.
|
||||||
|
/// </summary>
|
||||||
|
ConstantPhysicalSize,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Applies min/max scaling to the UI depending on the screen resolution. Ensures the UI size won't go below min or above max resolution to maintain it's readability.
|
||||||
|
/// </summary>
|
||||||
|
ScaleWithResolution,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Applies scaling curve to the UI depending on the screen DPI.
|
||||||
|
/// </summary>
|
||||||
|
ScaleWithDpi,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Physical unit types for canvas scaling.
|
||||||
|
/// </summary>
|
||||||
|
public enum PhysicalUnitMode
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Centimeters (0.01 meter).
|
||||||
|
/// </summary>
|
||||||
|
Centimeters,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Millimeters (0.1 centimeter, 0.001 meter).
|
||||||
|
/// </summary>
|
||||||
|
Millimeters,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Inches (2.54 centimeters).
|
||||||
|
/// </summary>
|
||||||
|
Inches,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Points (1/72 inch, 1/112 of pica).
|
||||||
|
/// </summary>
|
||||||
|
Points,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Pica (1/6 inch).
|
||||||
|
/// </summary>
|
||||||
|
Picas,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resolution scaling modes.
|
||||||
|
/// </summary>
|
||||||
|
public enum ResolutionScalingMode
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Uses the shortest side of the screen to scale the canvas for min/max rule.
|
||||||
|
/// </summary>
|
||||||
|
ShortestSide,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Uses the longest side of the screen to scale the canvas for min/max rule.
|
||||||
|
/// </summary>
|
||||||
|
LongestSide,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Uses the horizontal (X, width) side of the screen to scale the canvas for min/max rule.
|
||||||
|
/// </summary>
|
||||||
|
Horizontal,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Uses the vertical (Y, height) side of the screen to scale the canvas for min/max rule.
|
||||||
|
/// </summary>
|
||||||
|
Vertical,
|
||||||
|
}
|
||||||
|
|
||||||
|
private ScalingMode _scalingMode = ScalingMode.ConstantPixelSize;
|
||||||
|
private PhysicalUnitMode _physicalUnit = PhysicalUnitMode.Points;
|
||||||
|
private ResolutionScalingMode _resolutionMode = ResolutionScalingMode.ShortestSide;
|
||||||
|
private float _scale = 1.0f;
|
||||||
|
private float _scaleFactor = 1.0f;
|
||||||
|
private float _physicalUnitSize = 1.0f;
|
||||||
|
private Float2 _resolutionMin = new Float2(1, 1);
|
||||||
|
private Float2 _resolutionMax = new Float2(10000, 10000);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current UI scale. Computed based on the setup when performing layout.
|
||||||
|
/// </summary>
|
||||||
|
public float CurrentScale => _scale;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The UI Canvas scaling mode.
|
||||||
|
/// </summary>
|
||||||
|
[EditorOrder(0), EditorDisplay("Canvas Scaler"), ExpandGroups, DefaultValue(ScalingMode.ConstantPixelSize)]
|
||||||
|
public ScalingMode Scaling
|
||||||
|
{
|
||||||
|
get => _scalingMode;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_scalingMode == value)
|
||||||
|
return;
|
||||||
|
_scalingMode = value;
|
||||||
|
PerformLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The UI Canvas scale. Applied in all scaling modes for custom UI sizing.
|
||||||
|
/// </summary>
|
||||||
|
[EditorOrder(10), EditorDisplay("Canvas Scaler"), DefaultValue(1.0f), Limit(0.001f, 1000.0f, 0.01f)]
|
||||||
|
public float ScaleFactor
|
||||||
|
{
|
||||||
|
get => _scaleFactor;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (Mathf.NearEqual(_scaleFactor, value))
|
||||||
|
return;
|
||||||
|
_scaleFactor = value;
|
||||||
|
PerformLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The UI Canvas physical unit to use for scaling via PhysicalUnitSize. Used only in ConstantPhysicalSize mode.
|
||||||
|
/// </summary>
|
||||||
|
[EditorOrder(100), EditorDisplay("Canvas Scaler"), DefaultValue(PhysicalUnitMode.Points), VisibleIf(nameof(IsConstantPhysicalSize))]
|
||||||
|
public PhysicalUnitMode PhysicalUnit
|
||||||
|
{
|
||||||
|
get => _physicalUnit;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_physicalUnit == value)
|
||||||
|
return;
|
||||||
|
_physicalUnit = value;
|
||||||
|
#if FLAX_EDITOR
|
||||||
|
if (FlaxEditor.CustomEditors.CustomEditor.IsSettingValue)
|
||||||
|
{
|
||||||
|
// Set auto-default physical unit value for easier tweaking in Editor
|
||||||
|
_physicalUnitSize = GetUnitDpi(_physicalUnit) / Platform.Dpi;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
PerformLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The UI Canvas physical unit value. Used only in ConstantPhysicalSize mode.
|
||||||
|
/// </summary>
|
||||||
|
[EditorOrder(110), EditorDisplay("Canvas Scaler"), DefaultValue(1.0f), Limit(0.000001f, 1000000.0f, 0.0f), VisibleIf(nameof(IsConstantPhysicalSize))]
|
||||||
|
public float PhysicalUnitSize
|
||||||
|
{
|
||||||
|
get => _physicalUnitSize;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (Mathf.NearEqual(_physicalUnitSize, value))
|
||||||
|
return;
|
||||||
|
_physicalUnitSize = value;
|
||||||
|
PerformLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The UI Canvas resolution scaling mode. Controls min/max resolutions usage in relation to the current screen resolution to compute the UI scale. Used only in ScaleWithResolution mode.
|
||||||
|
/// </summary>
|
||||||
|
[EditorOrder(120), EditorDisplay("Canvas Scaler"), VisibleIf(nameof(IsScaleWithResolution))]
|
||||||
|
public ResolutionScalingMode ResolutionMode
|
||||||
|
{
|
||||||
|
get => _resolutionMode;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_resolutionMode == value)
|
||||||
|
return;
|
||||||
|
_resolutionMode = value;
|
||||||
|
PerformLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The UI Canvas minimum resolution. If the screen has lower size, then the interface will be scaled accordingly. Used only in ScaleWithResolution mode.
|
||||||
|
/// </summary>
|
||||||
|
[EditorOrder(120), EditorDisplay("Canvas Scaler"), VisibleIf(nameof(IsScaleWithResolution))]
|
||||||
|
public Float2 ResolutionMin
|
||||||
|
{
|
||||||
|
get => _resolutionMin;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
value = Float2.Max(value, Float2.One);
|
||||||
|
if (Float2.NearEqual(ref _resolutionMin, ref value))
|
||||||
|
return;
|
||||||
|
_resolutionMin = value;
|
||||||
|
PerformLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The UI Canvas maximum resolution. If the screen has higher size, then the interface will be scaled accordingly. Used only in ScaleWithResolution mode.
|
||||||
|
/// </summary>
|
||||||
|
[EditorOrder(130), EditorDisplay("Canvas Scaler"), VisibleIf(nameof(IsScaleWithResolution))]
|
||||||
|
public Float2 ResolutionMax
|
||||||
|
{
|
||||||
|
get => _resolutionMax;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
value = Float2.Max(value, Float2.One);
|
||||||
|
if (Float2.NearEqual(ref _resolutionMax, ref value))
|
||||||
|
return;
|
||||||
|
_resolutionMax = value;
|
||||||
|
PerformLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The UI Canvas scaling curve based on screen resolution - shortest/longest/vertical/horizontal (key is resolution, value is scale factor). Clear keyframes to skip using it and follow min/max rules only. Used only in ScaleWithResolution mode.
|
||||||
|
/// </summary>
|
||||||
|
[EditorOrder(140), EditorDisplay("Canvas Scaler"), VisibleIf(nameof(IsScaleWithResolution))]
|
||||||
|
public LinearCurve<float> ResolutionCurve = new LinearCurve<float>(new[]
|
||||||
|
{
|
||||||
|
new LinearCurve<float>.Keyframe(480, 0.444f), // 480p
|
||||||
|
new LinearCurve<float>.Keyframe(720, 0.666f), // 720p
|
||||||
|
new LinearCurve<float>.Keyframe(1080, 1.0f), // 1080p
|
||||||
|
new LinearCurve<float>.Keyframe(8640, 8.0f), // 8640p
|
||||||
|
});
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The UI Canvas scaling curve based on screen DPI (key is DPI, value is scale factor). Used only in ScaleWithDpi mode.
|
||||||
|
/// </summary>
|
||||||
|
[EditorOrder(150), EditorDisplay("Canvas Scaler"), VisibleIf(nameof(IsScaleWithDpi))]
|
||||||
|
public LinearCurve<float> DpiCurve = new LinearCurve<float>(new[]
|
||||||
|
{
|
||||||
|
new LinearCurve<float>.Keyframe(1.0f, 1.0f),
|
||||||
|
new LinearCurve<float>.Keyframe(96.0f, 1.0f),
|
||||||
|
new LinearCurve<float>.Keyframe(200.0f, 2.0f),
|
||||||
|
new LinearCurve<float>.Keyframe(400.0f, 4.0f),
|
||||||
|
});
|
||||||
|
|
||||||
|
#if FLAX_EDITOR
|
||||||
|
private bool IsConstantPhysicalSize => _scalingMode == ScalingMode.ConstantPhysicalSize;
|
||||||
|
private bool IsScaleWithResolution => _scalingMode == ScalingMode.ScaleWithResolution;
|
||||||
|
private bool IsScaleWithDpi => _scalingMode == ScalingMode.ScaleWithDpi;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="CanvasScaler"/> class.
|
||||||
|
/// </summary>
|
||||||
|
public CanvasScaler()
|
||||||
|
{
|
||||||
|
// Fill the canvas by default
|
||||||
|
Offsets = Margin.Zero;
|
||||||
|
AnchorPreset = AnchorPresets.StretchAll;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the scaler for the current setup.
|
||||||
|
/// </summary>
|
||||||
|
public void UpdateScale()
|
||||||
|
{
|
||||||
|
float scale = 1.0f;
|
||||||
|
if (Parent != null)
|
||||||
|
{
|
||||||
|
UICanvas canvas = (Root as CanvasRootControl)?.Canvas;
|
||||||
|
float dpi = Platform.Dpi;
|
||||||
|
switch (canvas?.RenderMode ?? CanvasRenderMode.ScreenSpace)
|
||||||
|
{
|
||||||
|
case CanvasRenderMode.WorldSpace:
|
||||||
|
case CanvasRenderMode.WorldSpaceFaceCamera:
|
||||||
|
scale = 1.0f;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
switch (_scalingMode)
|
||||||
|
{
|
||||||
|
case ScalingMode.ConstantPixelSize:
|
||||||
|
scale = 1.0f;
|
||||||
|
break;
|
||||||
|
case ScalingMode.ConstantPhysicalSize:
|
||||||
|
{
|
||||||
|
float targetDpi = GetUnitDpi(_physicalUnit);
|
||||||
|
scale = dpi / targetDpi * _physicalUnitSize;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ScalingMode.ScaleWithResolution:
|
||||||
|
{
|
||||||
|
Float2 resolution = Float2.Max(Size, Float2.One);
|
||||||
|
int axis = 0;
|
||||||
|
switch (_resolutionMode)
|
||||||
|
{
|
||||||
|
case ResolutionScalingMode.ShortestSide:
|
||||||
|
axis = resolution.X > resolution.Y ? 1 : 0;
|
||||||
|
break;
|
||||||
|
case ResolutionScalingMode.LongestSide:
|
||||||
|
axis = resolution.X > resolution.Y ? 0 : 1;
|
||||||
|
break;
|
||||||
|
case ResolutionScalingMode.Horizontal:
|
||||||
|
axis = 0;
|
||||||
|
break;
|
||||||
|
case ResolutionScalingMode.Vertical:
|
||||||
|
axis = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
float min = _resolutionMin[axis], max = _resolutionMax[axis], value = resolution[axis];
|
||||||
|
if (value < min)
|
||||||
|
scale = min / value;
|
||||||
|
else if (value > max)
|
||||||
|
scale = max / value;
|
||||||
|
if (ResolutionCurve != null && ResolutionCurve.Keyframes?.Length != 0)
|
||||||
|
{
|
||||||
|
ResolutionCurve.Evaluate(out var curveScale, value, false);
|
||||||
|
scale *= curveScale;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ScalingMode.ScaleWithDpi:
|
||||||
|
DpiCurve?.Evaluate(out scale, dpi, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_scale = Mathf.Max(scale * _scaleFactor, 0.01f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private float GetUnitDpi(PhysicalUnitMode unit)
|
||||||
|
{
|
||||||
|
float dpi = 1.0f;
|
||||||
|
switch (unit)
|
||||||
|
{
|
||||||
|
case PhysicalUnitMode.Centimeters:
|
||||||
|
dpi = 2.54f;
|
||||||
|
break;
|
||||||
|
case PhysicalUnitMode.Millimeters:
|
||||||
|
dpi = 25.4f;
|
||||||
|
break;
|
||||||
|
case PhysicalUnitMode.Inches:
|
||||||
|
dpi = 1;
|
||||||
|
break;
|
||||||
|
case PhysicalUnitMode.Points:
|
||||||
|
dpi = 72;
|
||||||
|
break;
|
||||||
|
case PhysicalUnitMode.Picas:
|
||||||
|
dpi = 6;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return dpi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void PerformLayoutBeforeChildren()
|
||||||
|
{
|
||||||
|
// Update current scaling before performing layout
|
||||||
|
UpdateScale();
|
||||||
|
|
||||||
|
base.PerformLayoutBeforeChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region UI Scale
|
||||||
|
|
||||||
|
#if FLAX_EDITOR
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override Rectangle EditorBounds => new Rectangle(Float2.Zero, Size / _scale);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void Draw()
|
||||||
|
{
|
||||||
|
DrawSelf();
|
||||||
|
|
||||||
|
// Draw children with scale
|
||||||
|
var scaling = new Float3(_scale, _scale, 1);
|
||||||
|
Matrix3x3.Scaling(ref scaling, out Matrix3x3 scale);
|
||||||
|
Render2D.PushTransform(scale);
|
||||||
|
if (ClipChildren)
|
||||||
|
{
|
||||||
|
GetDesireClientArea(out var clientArea);
|
||||||
|
Render2D.PushClip(ref clientArea);
|
||||||
|
DrawChildren();
|
||||||
|
Render2D.PopClip();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DrawChildren();
|
||||||
|
}
|
||||||
|
Render2D.PopTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void GetDesireClientArea(out Rectangle rect)
|
||||||
|
{
|
||||||
|
// Scale the area for the client controls
|
||||||
|
rect = new Rectangle(Float2.Zero, Size / _scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool IntersectsContent(ref Float2 locationParent, out Float2 location)
|
||||||
|
{
|
||||||
|
// Skip local PointFromParent but use base code
|
||||||
|
location = base.PointFromParent(ref locationParent);
|
||||||
|
return ContainsPoint(ref location);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override Float2 PointToParent(ref Float2 location)
|
||||||
|
{
|
||||||
|
var result = base.PointToParent(ref location);
|
||||||
|
result *= _scaleFactor;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override Float2 PointFromParent(ref Float2 location)
|
||||||
|
{
|
||||||
|
var result = base.PointFromParent(ref location);
|
||||||
|
result /= _scaleFactor;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override DragDropEffect OnDragEnter(ref Float2 location, DragData data)
|
||||||
|
{
|
||||||
|
location /= _scale;
|
||||||
|
return base.OnDragEnter(ref location, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override DragDropEffect OnDragMove(ref Float2 location, DragData data)
|
||||||
|
{
|
||||||
|
location /= _scale;
|
||||||
|
return base.OnDragMove(ref location, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override DragDropEffect OnDragDrop(ref Float2 location, DragData data)
|
||||||
|
{
|
||||||
|
location /= _scale;
|
||||||
|
return base.OnDragDrop(ref location, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnMouseEnter(Float2 location)
|
||||||
|
{
|
||||||
|
location /= _scale;
|
||||||
|
base.OnMouseEnter(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnMouseMove(Float2 location)
|
||||||
|
{
|
||||||
|
location /= _scale;
|
||||||
|
base.OnMouseMove(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool OnMouseDown(Float2 location, MouseButton button)
|
||||||
|
{
|
||||||
|
location /= _scale;
|
||||||
|
return base.OnMouseDown(location, button);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool OnMouseUp(Float2 location, MouseButton button)
|
||||||
|
{
|
||||||
|
location /= _scale;
|
||||||
|
return base.OnMouseUp(location, button);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool OnMouseDoubleClick(Float2 location, MouseButton button)
|
||||||
|
{
|
||||||
|
location /= _scale;
|
||||||
|
return base.OnMouseDoubleClick(location, button);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool OnMouseWheel(Float2 location, float delta)
|
||||||
|
{
|
||||||
|
location /= _scale;
|
||||||
|
return base.OnMouseWheel(location, delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnTouchEnter(Float2 location, int pointerId)
|
||||||
|
{
|
||||||
|
location /= _scale;
|
||||||
|
base.OnTouchEnter(location, pointerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnTouchMove(Float2 location, int pointerId)
|
||||||
|
{
|
||||||
|
location /= _scale;
|
||||||
|
base.OnTouchMove(location, pointerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool OnTouchDown(Float2 location, int pointerId)
|
||||||
|
{
|
||||||
|
location /= _scale;
|
||||||
|
return base.OnTouchDown(location, pointerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool OnTouchUp(Float2 location, int pointerId)
|
||||||
|
{
|
||||||
|
location /= _scale;
|
||||||
|
return base.OnTouchUp(location, pointerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1259,6 +1259,13 @@ namespace FlaxEngine.GUI
|
|||||||
return PointFromParent(ref location);
|
return PointFromParent(ref location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if FLAX_EDITOR
|
||||||
|
/// <summary>
|
||||||
|
/// Bounds rectangle for editor UI.
|
||||||
|
/// </summary>
|
||||||
|
public virtual Rectangle EditorBounds => new Rectangle(Float2.Zero, _bounds.Size);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Control Action
|
#region Control Action
|
||||||
|
|||||||
Reference in New Issue
Block a user