Merge branch '1.2' into IconOverhaul
This commit is contained in:
@@ -24,11 +24,20 @@ namespace FlaxEngine.GUI
|
||||
/// </summary>
|
||||
protected FontReference _font;
|
||||
|
||||
/// <summary>
|
||||
/// The text.
|
||||
/// </summary>
|
||||
protected LocalizedString _text = new LocalizedString();
|
||||
|
||||
/// <summary>
|
||||
/// Button text property.
|
||||
/// </summary>
|
||||
[EditorOrder(10), Tooltip("The button label text.")]
|
||||
public string Text { get; set; }
|
||||
public LocalizedString Text
|
||||
{
|
||||
get => _text;
|
||||
set => _text = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the font used to draw button text.
|
||||
@@ -201,7 +210,7 @@ namespace FlaxEngine.GUI
|
||||
Render2D.DrawRectangle(clientRect, borderColor);
|
||||
|
||||
// Draw text
|
||||
Render2D.DrawText(_font.GetFont(), TextMaterial, Text, clientRect, textColor, TextAlignment.Center, TextAlignment.Center);
|
||||
Render2D.DrawText(_font.GetFont(), TextMaterial, _text, clientRect, textColor, TextAlignment.Center, TextAlignment.Center);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace FlaxEngine.GUI
|
||||
/// <summary>
|
||||
/// The items.
|
||||
/// </summary>
|
||||
protected List<string> _items = new List<string>();
|
||||
protected List<LocalizedString> _items = new List<LocalizedString>();
|
||||
|
||||
/// <summary>
|
||||
/// The popup menu. May be null if has not been used yet.
|
||||
@@ -95,7 +95,7 @@ namespace FlaxEngine.GUI
|
||||
/// Gets or sets the items collection.
|
||||
/// </summary>
|
||||
[EditorOrder(1), Tooltip("The items collection.")]
|
||||
public List<string> Items
|
||||
public List<LocalizedString> Items
|
||||
{
|
||||
get => _items;
|
||||
set => _items = value;
|
||||
@@ -107,7 +107,17 @@ namespace FlaxEngine.GUI
|
||||
[HideInEditor, NoSerialize]
|
||||
public string SelectedItem
|
||||
{
|
||||
get => _selectedIndex != -1 ? _items[_selectedIndex] : string.Empty;
|
||||
get => _selectedIndex != -1 ? _items[_selectedIndex].ToString() : string.Empty;
|
||||
set => SelectedIndex = _items.IndexOf(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the selected item (returns <see cref="LocalizedString.Empty"/> if no item is being selected).
|
||||
/// </summary>
|
||||
[HideInEditor, NoSerialize]
|
||||
public LocalizedString SelectedItemLocalized
|
||||
{
|
||||
get => _selectedIndex != -1 ? _items[_selectedIndex] : LocalizedString.Empty;
|
||||
set => SelectedIndex = _items.IndexOf(value);
|
||||
}
|
||||
|
||||
@@ -265,7 +275,8 @@ namespace FlaxEngine.GUI
|
||||
/// <param name="items">The items.</param>
|
||||
public void AddItems(IEnumerable<string> items)
|
||||
{
|
||||
_items.AddRange(items);
|
||||
foreach (var item in items)
|
||||
_items.Add(item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -276,7 +287,8 @@ namespace FlaxEngine.GUI
|
||||
{
|
||||
SelectedIndex = -1;
|
||||
_items.Clear();
|
||||
_items.AddRange(items);
|
||||
foreach (var item in items)
|
||||
_items.Add(item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -10,7 +10,11 @@ namespace FlaxEngine.GUI
|
||||
/// <seealso cref="FlaxEngine.GUI.ContainerControl" />
|
||||
public class Label : ContainerControl
|
||||
{
|
||||
private string _text;
|
||||
/// <summary>
|
||||
/// The text.
|
||||
/// </summary>
|
||||
protected LocalizedString _text = new LocalizedString();
|
||||
|
||||
private bool _autoWidth;
|
||||
private bool _autoHeight;
|
||||
private bool _autoFitText;
|
||||
@@ -26,7 +30,7 @@ namespace FlaxEngine.GUI
|
||||
/// Gets or sets the text.
|
||||
/// </summary>
|
||||
[EditorOrder(10), MultilineText, Tooltip("The label text.")]
|
||||
public string Text
|
||||
public LocalizedString Text
|
||||
{
|
||||
get => _text;
|
||||
set
|
||||
@@ -225,18 +229,7 @@ namespace FlaxEngine.GUI
|
||||
}
|
||||
}
|
||||
|
||||
Render2D.DrawText(
|
||||
_font.GetFont(),
|
||||
Material,
|
||||
Text,
|
||||
rect,
|
||||
color,
|
||||
hAlignment,
|
||||
wAlignment,
|
||||
Wrapping,
|
||||
1.0f,
|
||||
scale
|
||||
);
|
||||
Render2D.DrawText(_font.GetFont(), Material, _text, rect, color, hAlignment, wAlignment, Wrapping, 1.0f, scale);
|
||||
|
||||
if (ClipText)
|
||||
Render2D.PopClip();
|
||||
|
||||
@@ -39,9 +39,6 @@ namespace FlaxEngine.GUI
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether use progress value smoothing.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if use progress value smoothing; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool UseSmoothing => !Mathf.IsZero(SmoothingScale);
|
||||
|
||||
/// <summary>
|
||||
@@ -91,8 +88,6 @@ namespace FlaxEngine.GUI
|
||||
if (!Mathf.NearEqual(value, _value))
|
||||
{
|
||||
_value = value;
|
||||
|
||||
// Check if skip smoothing
|
||||
if (!UseSmoothing)
|
||||
{
|
||||
_current = _value;
|
||||
@@ -138,22 +133,22 @@ namespace FlaxEngine.GUI
|
||||
/// <inheritdoc />
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
bool isDeltaSlow = deltaTime > (1 / 20.0f);
|
||||
|
||||
// Ensure progress bar is visible
|
||||
if (Visible)
|
||||
{
|
||||
// Value smoothing
|
||||
var value = _value;
|
||||
if (Mathf.Abs(_current - _value) > 0.01f)
|
||||
{
|
||||
// Lerp or not if running slow
|
||||
float value;
|
||||
bool isDeltaSlow = deltaTime > (1 / 20.0f);
|
||||
if (!isDeltaSlow && UseSmoothing)
|
||||
value = Mathf.Lerp(_current, _value, Mathf.Saturate(deltaTime * 5.0f * SmoothingScale));
|
||||
else
|
||||
value = _value;
|
||||
_current = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
_current = _value;
|
||||
}
|
||||
}
|
||||
|
||||
base.Update(deltaTime);
|
||||
|
||||
@@ -55,8 +55,9 @@ namespace FlaxEngine.GUI
|
||||
/// </summary>
|
||||
public bool AutomaticInvalidate { get; set; } = true;
|
||||
|
||||
#if FLAX_EDITOR
|
||||
private bool CanEditTextureSize => !_autoSize;
|
||||
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Invalidates the cached image of children controls and invokes the redraw to the texture.
|
||||
/// </summary>
|
||||
@@ -105,7 +106,7 @@ namespace FlaxEngine.GUI
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void DrawSelf()
|
||||
public override void Draw()
|
||||
{
|
||||
// Draw cached texture
|
||||
if (_texture && !_invalid && !_isDuringTextureDraw)
|
||||
@@ -119,7 +120,7 @@ namespace FlaxEngine.GUI
|
||||
}
|
||||
|
||||
// Draw default UI directly
|
||||
base.DrawSelf();
|
||||
base.Draw();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -9,11 +9,20 @@ namespace FlaxEngine.GUI
|
||||
{
|
||||
private TextLayoutOptions _layout;
|
||||
|
||||
/// <summary>
|
||||
/// The watermark text.
|
||||
/// </summary>
|
||||
protected LocalizedString _watermarkText;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the watermark text to show grayed when textbox is empty.
|
||||
/// </summary>
|
||||
[EditorOrder(20), Tooltip("The watermark text to show grayed when textbox is empty.")]
|
||||
public string WatermarkText { get; set; }
|
||||
public LocalizedString WatermarkText
|
||||
{
|
||||
get => _watermarkText;
|
||||
set => _watermarkText = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the text wrapping within the control bounds.
|
||||
@@ -201,9 +210,9 @@ namespace FlaxEngine.GUI
|
||||
color *= 0.6f;
|
||||
Render2D.DrawText(font, _text, color, ref _layout, TextMaterial);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(WatermarkText) && !IsFocused)
|
||||
else if (!string.IsNullOrEmpty(_watermarkText) && !IsFocused)
|
||||
{
|
||||
Render2D.DrawText(font, WatermarkText, WatermarkTextColor, ref _layout, TextMaterial);
|
||||
Render2D.DrawText(font, _watermarkText, WatermarkTextColor, ref _layout, TextMaterial);
|
||||
}
|
||||
|
||||
// Caret
|
||||
|
||||
@@ -261,6 +261,11 @@ namespace FlaxEngine.GUI
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether user is editing the text.
|
||||
/// </summary>
|
||||
public bool IsEditing => _isEditing;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets text property.
|
||||
/// </summary>
|
||||
@@ -279,10 +284,11 @@ namespace FlaxEngine.GUI
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the text.
|
||||
/// Sets the text (forced, even if user is editing it).
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
protected void SetText(string value)
|
||||
[NoAnimate]
|
||||
public void SetText(string value)
|
||||
{
|
||||
// Prevent from null problems
|
||||
if (value == null)
|
||||
@@ -314,6 +320,18 @@ namespace FlaxEngine.GUI
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the text as it was entered by user (focus, change value, defocus).
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
[NoAnimate]
|
||||
public void SetTextAsUser(string value)
|
||||
{
|
||||
Focus();
|
||||
SetText(value);
|
||||
Defocus();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets length of the text
|
||||
/// </summary>
|
||||
@@ -504,9 +522,7 @@ namespace FlaxEngine.GUI
|
||||
if (string.IsNullOrEmpty(clipboardText))
|
||||
return;
|
||||
|
||||
var right = SelectionRight;
|
||||
Insert(clipboardText);
|
||||
SetSelection(Mathf.Max(right, 0) + clipboardText.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -622,11 +638,13 @@ namespace FlaxEngine.GUI
|
||||
{
|
||||
var left = SelectionLeft >= 0 ? SelectionLeft : 0;
|
||||
if (HasSelection)
|
||||
{
|
||||
_text = _text.Remove(left, selectionLength);
|
||||
|
||||
SetSelection(left);
|
||||
}
|
||||
_text = _text.Insert(left, str);
|
||||
|
||||
SetSelection(left + 1);
|
||||
SetSelection(left + str.Length);
|
||||
}
|
||||
|
||||
OnTextChanged();
|
||||
@@ -1000,7 +1018,8 @@ namespace FlaxEngine.GUI
|
||||
/// <inheritdoc />
|
||||
public override void OnMouseMove(Vector2 location)
|
||||
{
|
||||
// Check if user is selecting
|
||||
base.OnMouseMove(location);
|
||||
|
||||
if (_isSelecting)
|
||||
{
|
||||
// Find char index at current mouse location
|
||||
@@ -1014,6 +1033,9 @@ namespace FlaxEngine.GUI
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseDown(Vector2 location, MouseButton button)
|
||||
{
|
||||
if (base.OnMouseDown(location, button))
|
||||
return true;
|
||||
|
||||
if (button == MouseButton.Left && _text.Length > 0)
|
||||
{
|
||||
Focus();
|
||||
@@ -1050,6 +1072,9 @@ namespace FlaxEngine.GUI
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseUp(Vector2 location, MouseButton button)
|
||||
{
|
||||
if (base.OnMouseUp(location, button))
|
||||
return true;
|
||||
|
||||
if (button == MouseButton.Left)
|
||||
{
|
||||
OnSelectingEnd();
|
||||
@@ -1079,6 +1104,8 @@ namespace FlaxEngine.GUI
|
||||
/// <inheritdoc />
|
||||
public override bool OnCharInput(char c)
|
||||
{
|
||||
if (base.OnCharInput(c))
|
||||
return true;
|
||||
Insert(c);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -249,6 +249,8 @@ namespace FlaxEngine.GUI
|
||||
internal void ChangeChildIndex(Control child, int newIndex)
|
||||
{
|
||||
int oldIndex = _children.IndexOf(child);
|
||||
if (oldIndex == newIndex)
|
||||
return;
|
||||
_children.RemoveAt(oldIndex);
|
||||
|
||||
// Check if index is invalid
|
||||
@@ -274,7 +276,7 @@ namespace FlaxEngine.GUI
|
||||
public int GetChildIndexAt(Vector2 point)
|
||||
{
|
||||
int result = -1;
|
||||
for (int i = 0; i < _children.Count; i++)
|
||||
for (int i = _children.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var child = _children[i];
|
||||
|
||||
@@ -296,7 +298,7 @@ namespace FlaxEngine.GUI
|
||||
public Control GetChildAt(Vector2 point)
|
||||
{
|
||||
Control result = null;
|
||||
for (int i = 0; i < _children.Count; i++)
|
||||
for (int i = _children.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var child = _children[i];
|
||||
|
||||
@@ -322,7 +324,7 @@ namespace FlaxEngine.GUI
|
||||
throw new ArgumentNullException(nameof(isValid));
|
||||
|
||||
Control result = null;
|
||||
for (int i = 0; i < _children.Count; i++)
|
||||
for (int i = _children.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var child = _children[i];
|
||||
|
||||
@@ -344,7 +346,7 @@ namespace FlaxEngine.GUI
|
||||
public Control GetChildAtRecursive(Vector2 point)
|
||||
{
|
||||
Control result = null;
|
||||
for (int i = 0; i < _children.Count; i++)
|
||||
for (int i = _children.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var child = _children[i];
|
||||
|
||||
|
||||
@@ -26,11 +26,30 @@ namespace FlaxEngine.GUI
|
||||
set => Bounds = new Rectangle(X, value, _bounds.Size);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the local X coordinate of the pivot of the control relative to the anchor in parent of its container.
|
||||
/// </summary>
|
||||
[HideInEditor, NoSerialize]
|
||||
public float LocalX
|
||||
{
|
||||
get => LocalLocation.X;
|
||||
set => LocalLocation = new Vector2(value, LocalLocation.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the local Y coordinate of the pivot of the control relative to the anchor in parent of its container.
|
||||
/// </summary>
|
||||
[HideInEditor, NoSerialize]
|
||||
public float LocalY
|
||||
{
|
||||
get => LocalLocation.Y;
|
||||
set => LocalLocation = new Vector2(LocalLocation.X, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the normalized position in the parent control that the upper left corner is anchored to (range 0-1).
|
||||
/// </summary>
|
||||
[Serialize]
|
||||
[HideInEditor, ExpandGroups, Limit(0.0f, 1.0f, 0.01f), EditorDisplay("Transform"), EditorOrder(990), Tooltip("The normalized position in the parent control that the upper left corner is anchored to (range 0-1).")]
|
||||
[Serialize, HideInEditor]
|
||||
public Vector2 AnchorMin
|
||||
{
|
||||
get => _anchorMin;
|
||||
@@ -49,8 +68,7 @@ namespace FlaxEngine.GUI
|
||||
/// <summary>
|
||||
/// Gets or sets the normalized position in the parent control that the bottom right corner is anchored to (range 0-1).
|
||||
/// </summary>
|
||||
[Serialize]
|
||||
[HideInEditor, ExpandGroups, Limit(0.0f, 1.0f, 0.01f), EditorDisplay("Transform"), EditorOrder(991), Tooltip("The normalized position in the parent control that the bottom right corner is anchored to (range 0-1).")]
|
||||
[Serialize, HideInEditor]
|
||||
public Vector2 AnchorMax
|
||||
{
|
||||
get => _anchorMax;
|
||||
@@ -69,8 +87,7 @@ namespace FlaxEngine.GUI
|
||||
/// <summary>
|
||||
/// Gets or sets the offsets of the corners of the control relative to its anchors.
|
||||
/// </summary>
|
||||
[Serialize]
|
||||
[HideInEditor, ExpandGroups, EditorDisplay("Transform"), EditorOrder(992), Tooltip("The offsets of the corners of the control relative to its anchors.")]
|
||||
[Serialize, HideInEditor]
|
||||
public Margin Offsets
|
||||
{
|
||||
get => _offsets;
|
||||
@@ -91,8 +108,8 @@ namespace FlaxEngine.GUI
|
||||
[NoSerialize, HideInEditor]
|
||||
internal float Proxy_Offset_Left
|
||||
{
|
||||
get => Offsets.Left;
|
||||
set => Offsets = new Margin(value, Offsets.Right, Offsets.Top, Offsets.Bottom);
|
||||
get => _offsets.Left;
|
||||
set => Offsets = new Margin(value, _offsets.Right, _offsets.Top, _offsets.Bottom);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -101,8 +118,8 @@ namespace FlaxEngine.GUI
|
||||
[NoSerialize, HideInEditor]
|
||||
internal float Proxy_Offset_Right
|
||||
{
|
||||
get => Offsets.Right;
|
||||
set => Offsets = new Margin(Offsets.Left, value, Offsets.Top, Offsets.Bottom);
|
||||
get => _offsets.Right;
|
||||
set => Offsets = new Margin(_offsets.Left, value, _offsets.Top, _offsets.Bottom);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -111,8 +128,8 @@ namespace FlaxEngine.GUI
|
||||
[NoSerialize, HideInEditor]
|
||||
internal float Proxy_Offset_Top
|
||||
{
|
||||
get => Offsets.Top;
|
||||
set => Offsets = new Margin(Offsets.Left, Offsets.Right, value, Offsets.Bottom);
|
||||
get => _offsets.Top;
|
||||
set => Offsets = new Margin(_offsets.Left, _offsets.Right, value, _offsets.Bottom);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -121,22 +138,31 @@ namespace FlaxEngine.GUI
|
||||
[NoSerialize, HideInEditor]
|
||||
internal float Proxy_Offset_Bottom
|
||||
{
|
||||
get => Offsets.Bottom;
|
||||
set => Offsets = new Margin(Offsets.Left, Offsets.Right, Offsets.Top, value);
|
||||
get => _offsets.Bottom;
|
||||
set => Offsets = new Margin(_offsets.Left, _offsets.Right, _offsets.Top, value);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets coordinates of the upper-left corner of the control relative to the upper-left corner of its container.
|
||||
/// </summary>
|
||||
[NoSerialize]
|
||||
[HideInEditor, ExpandGroups, EditorDisplay("Transform"), EditorOrder(1000), Tooltip("The location of the upper-left corner of the control relative to he upper-left corner of its container.")]
|
||||
[NoSerialize, HideInEditor]
|
||||
public Vector2 Location
|
||||
{
|
||||
get => _bounds.Location;
|
||||
set => Bounds = new Rectangle(value, _bounds.Size);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the local position of the pivot of the control relative to the anchor in parent of its container.
|
||||
/// </summary>
|
||||
[NoSerialize, HideInEditor]
|
||||
public Vector2 LocalLocation
|
||||
{
|
||||
get => _bounds.Location - (_parent != null ? _parent._bounds.Size * (_anchorMax + _anchorMin) * 0.5f : Vector2.Zero) + _bounds.Size * _pivot;
|
||||
set => Bounds = new Rectangle(value + (_parent != null ? _parent.Bounds.Size * (_anchorMax + _anchorMin) * 0.5f : Vector2.Zero) - _bounds.Size * _pivot, _bounds.Size);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets width of the control.
|
||||
/// </summary>
|
||||
@@ -160,8 +186,7 @@ namespace FlaxEngine.GUI
|
||||
/// <summary>
|
||||
/// Gets or sets control's size.
|
||||
/// </summary>
|
||||
[NoSerialize]
|
||||
[HideInEditor, EditorDisplay("Transform"), EditorOrder(1010), Tooltip("The size of the control bounds.")]
|
||||
[NoSerialize, HideInEditor]
|
||||
public Vector2 Size
|
||||
{
|
||||
get => _bounds.Size;
|
||||
@@ -466,7 +491,8 @@ namespace FlaxEngine.GUI
|
||||
/// </summary>
|
||||
/// <param name="anchorPreset">The anchor preset to set.</param>
|
||||
/// <param name="preserveBounds">True if preserve current control bounds, otherwise will align control position accordingly to the anchor location.</param>
|
||||
public void SetAnchorPreset(AnchorPresets anchorPreset, bool preserveBounds)
|
||||
/// <param name="setPivotToo">Whether or not we should set the pivot too, eg left-top 0,0, bottom-right 1,1</param>
|
||||
public void SetAnchorPreset(AnchorPresets anchorPreset, bool preserveBounds, bool setPivotToo = false)
|
||||
{
|
||||
for (int i = 0; i < AnchorPresetsData.Length; i++)
|
||||
{
|
||||
@@ -558,6 +584,10 @@ namespace FlaxEngine.GUI
|
||||
}
|
||||
SetBounds(ref bounds);
|
||||
}
|
||||
if (setPivotToo)
|
||||
{
|
||||
Pivot = (anchorMin + anchorMax) / 2;
|
||||
}
|
||||
_parent?.PerformLayout();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -73,13 +73,18 @@ namespace FlaxEngine.GUI
|
||||
Vector2 locationWS = target.PointToWindow(location);
|
||||
Vector2 locationSS = parentWin.PointToScreen(locationWS);
|
||||
Vector2 screenSize = Platform.VirtualDesktopSize;
|
||||
Vector2 parentWinLocationSS = parentWin.PointToScreen(Vector2.Zero);
|
||||
float parentWinRightSS = parentWinLocationSS.Y + parentWin.Size.Y;
|
||||
float parentWinBottomSS = parentWinLocationSS.X + parentWin.Size.X;
|
||||
Vector2 rightBottomLocationSS = locationSS + dpiSize;
|
||||
if (screenSize.Y < rightBottomLocationSS.Y)
|
||||
|
||||
// Prioritize tooltip placement within parent window, fall back to virtual desktop
|
||||
if (parentWinRightSS < rightBottomLocationSS.Y || screenSize.Y < rightBottomLocationSS.Y)
|
||||
{
|
||||
// Direction: up
|
||||
locationSS.Y -= dpiSize.Y;
|
||||
}
|
||||
if (screenSize.X < rightBottomLocationSS.X)
|
||||
if (parentWinBottomSS < rightBottomLocationSS.X || screenSize.X < rightBottomLocationSS.X)
|
||||
{
|
||||
// Direction: left
|
||||
locationSS.X -= dpiSize.X;
|
||||
@@ -155,7 +160,7 @@ namespace FlaxEngine.GUI
|
||||
/// <param name="dt">The delta time.</param>
|
||||
public void OnMouseOverControl(Control target, float dt)
|
||||
{
|
||||
if (!Visible)
|
||||
if (!Visible && _timeToPopupLeft > 0.0f)
|
||||
{
|
||||
_lastTarget = target;
|
||||
_timeToPopupLeft -= dt;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Content/Assets/Model.h"
|
||||
#include "Engine/Content/Assets/MaterialInstance.h"
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
#include "Engine/Level/Actors/Camera.h"
|
||||
#include "Engine/Serialization/Serialization.h"
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
#include "Engine/Graphics/Models/Types.h"
|
||||
#include "Engine/Graphics/RenderView.h"
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
#include "Engine/Level/Scene/SceneRendering.h"
|
||||
#include "Engine/Render2D/Font.h"
|
||||
#include "Engine/Render2D/FontAsset.h"
|
||||
@@ -16,7 +17,7 @@
|
||||
#include "Engine/Content/Assets/MaterialInstance.h"
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Core/Types/Variant.h"
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
#include "Engine/Localization/Localization.h"
|
||||
#if USE_EDITOR
|
||||
#include "Editor/Editor.h"
|
||||
#endif
|
||||
@@ -45,7 +46,12 @@ TextRender::TextRender(const SpawnParams& params)
|
||||
Material.Changed.Bind<TextRender, &TextRender::Invalidate>(this);
|
||||
}
|
||||
|
||||
void TextRender::SetText(const StringView& value)
|
||||
const LocalizedString& TextRender::GetText() const
|
||||
{
|
||||
return _text;
|
||||
}
|
||||
|
||||
void TextRender::SetText(const LocalizedString& value)
|
||||
{
|
||||
if (_text != value)
|
||||
{
|
||||
@@ -54,6 +60,11 @@ void TextRender::SetText(const StringView& value)
|
||||
}
|
||||
}
|
||||
|
||||
Color TextRender::GetColor() const
|
||||
{
|
||||
return _color;
|
||||
}
|
||||
|
||||
void TextRender::SetColor(const Color& value)
|
||||
{
|
||||
if (_color != value)
|
||||
@@ -63,6 +74,11 @@ void TextRender::SetColor(const Color& value)
|
||||
}
|
||||
}
|
||||
|
||||
int32 TextRender::GetFontSize() const
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
void TextRender::SetFontSize(int32 value)
|
||||
{
|
||||
value = Math::Clamp(value, 1, 1024);
|
||||
@@ -84,9 +100,6 @@ void TextRender::SetLayoutOptions(TextLayoutOptions& value)
|
||||
|
||||
void TextRender::UpdateLayout()
|
||||
{
|
||||
if (!_isDirty)
|
||||
return;
|
||||
|
||||
// Clear
|
||||
_ib.Clear();
|
||||
_vb0.Clear();
|
||||
@@ -111,8 +124,28 @@ void TextRender::UpdateLayout()
|
||||
_isDirty = false;
|
||||
|
||||
// Skip if no need to calculate the layout
|
||||
if (_text.IsEmpty())
|
||||
return;
|
||||
String textData;
|
||||
String* textPtr = &_text.Value;
|
||||
if (textPtr->IsEmpty())
|
||||
{
|
||||
if (_text.Id.IsEmpty())
|
||||
return;
|
||||
textData = Localization::GetString(_text.Id);
|
||||
textPtr = &textData;
|
||||
if (!_isLocalized)
|
||||
{
|
||||
_isLocalized = true;
|
||||
Localization::LocalizationChanged.Bind<TextRender, &TextRender::UpdateLayout>(this);
|
||||
}
|
||||
if (textPtr->IsEmpty())
|
||||
return;
|
||||
}
|
||||
else if (_isLocalized)
|
||||
{
|
||||
_isLocalized = false;
|
||||
Localization::LocalizationChanged.Unbind<TextRender, &TextRender::UpdateLayout>(this);
|
||||
}
|
||||
const String& text = *textPtr;
|
||||
|
||||
// Pick a font (remove DPI text scale as the text is being placed in the world)
|
||||
auto font = Font->CreateFont(_size);
|
||||
@@ -126,13 +159,13 @@ void TextRender::UpdateLayout()
|
||||
|
||||
// Perform layout
|
||||
Array<FontLineCache> lines;
|
||||
font->ProcessText(_text, lines, _layoutOptions);
|
||||
font->ProcessText(text, lines, _layoutOptions);
|
||||
|
||||
// Prepare buffers capacity
|
||||
_ib.Data.EnsureCapacity(_text.Length() * 6 * sizeof(uint16));
|
||||
_vb0.Data.EnsureCapacity(_text.Length() * 4 * sizeof(VB0ElementType));
|
||||
_vb1.Data.EnsureCapacity(_text.Length() * 4 * sizeof(VB1ElementType));
|
||||
_vb2.Data.EnsureCapacity(_text.Length() * 4 * sizeof(VB2ElementType));
|
||||
_ib.Data.EnsureCapacity(text.Length() * 6 * sizeof(uint16));
|
||||
_vb0.Data.EnsureCapacity(text.Length() * 4 * sizeof(VB0ElementType));
|
||||
_vb1.Data.EnsureCapacity(text.Length() * 4 * sizeof(VB1ElementType));
|
||||
_vb2.Data.EnsureCapacity(text.Length() * 4 * sizeof(VB2ElementType));
|
||||
_buffersDirty = true;
|
||||
|
||||
// Init draw chunks data
|
||||
@@ -155,7 +188,7 @@ void TextRender::UpdateLayout()
|
||||
// Render all characters from the line
|
||||
for (int32 charIndex = line.FirstCharIndex; charIndex <= line.LastCharIndex; charIndex++)
|
||||
{
|
||||
const Char c = _text[charIndex];
|
||||
const Char c = text[charIndex];
|
||||
if (c != '\n')
|
||||
{
|
||||
font->GetCharacter(c, entry);
|
||||
@@ -198,7 +231,7 @@ void TextRender::UpdateLayout()
|
||||
const auto param = drawChunk.Material->Params.Get(FontParamName);
|
||||
if (param && param->GetParameterType() == MaterialParameterType::Texture)
|
||||
{
|
||||
param->SetValue(fontAtlas);
|
||||
param->SetValue(Variant(fontAtlas));
|
||||
param->SetIsOverride(true);
|
||||
}
|
||||
}
|
||||
@@ -305,7 +338,10 @@ bool TextRender::HasContentLoaded() const
|
||||
|
||||
void TextRender::Draw(RenderContext& renderContext)
|
||||
{
|
||||
UpdateLayout();
|
||||
if (_isDirty)
|
||||
{
|
||||
UpdateLayout();
|
||||
}
|
||||
|
||||
GEOMETRY_DRAW_STATE_EVENT_BEGIN(_drawState, _world);
|
||||
|
||||
@@ -449,11 +485,19 @@ void TextRender::OnEnable()
|
||||
// Base
|
||||
Actor::OnEnable();
|
||||
|
||||
UpdateLayout();
|
||||
if (_isDirty)
|
||||
{
|
||||
UpdateLayout();
|
||||
}
|
||||
}
|
||||
|
||||
void TextRender::OnDisable()
|
||||
{
|
||||
if (_isLocalized)
|
||||
{
|
||||
_isLocalized = false;
|
||||
Localization::LocalizationChanged.Unbind<TextRender, &TextRender::UpdateLayout>(this);
|
||||
}
|
||||
GetSceneRendering()->RemoveGeometry(this);
|
||||
|
||||
// Base
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "Engine/Content/Assets/MaterialInstance.h"
|
||||
#include "Engine/Graphics/DynamicBuffer.h"
|
||||
#include "Engine/Graphics/Models/Config.h"
|
||||
#include "Engine/Localization/LocalizedString.h"
|
||||
#if USE_PRECISE_MESH_INTERSECTS
|
||||
#include "Engine/Graphics/Models/CollisionProxy.h"
|
||||
#endif
|
||||
@@ -34,7 +35,8 @@ private:
|
||||
|
||||
bool _isDirty = false;
|
||||
bool _buffersDirty = false;
|
||||
String _text;
|
||||
bool _isLocalized = false;
|
||||
LocalizedString _text;
|
||||
Color _color;
|
||||
TextLayoutOptions _layoutOptions;
|
||||
int32 _size;
|
||||
@@ -56,25 +58,19 @@ public:
|
||||
/// <summary>
|
||||
/// Gets the text.
|
||||
/// </summary>
|
||||
API_PROPERTY(Attributes="EditorOrder(0), DefaultValue(\"\"), MultilineText, EditorDisplay(\"Text\")")
|
||||
FORCE_INLINE const String& GetText() const
|
||||
{
|
||||
return _text;
|
||||
}
|
||||
API_PROPERTY(Attributes="EditorOrder(0), EditorDisplay(\"Text\")")
|
||||
const LocalizedString& GetText() const;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the text.
|
||||
/// </summary>
|
||||
API_PROPERTY() void SetText(const StringView& value);
|
||||
API_PROPERTY() void SetText(const LocalizedString& value);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the color of the text.
|
||||
/// </summary>
|
||||
API_PROPERTY(Attributes="EditorOrder(10), DefaultValue(typeof(Color), \"1,1,1,1\"), EditorDisplay(\"Text\")")
|
||||
FORCE_INLINE Color GetColor() const
|
||||
{
|
||||
return _color;
|
||||
}
|
||||
Color GetColor() const;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the color of the text.
|
||||
@@ -97,10 +93,7 @@ public:
|
||||
/// Gets the font characters size.
|
||||
/// </summary>
|
||||
API_PROPERTY(Attributes="EditorOrder(40), DefaultValue(32), Limit(1, 1000), EditorDisplay(\"Text\")")
|
||||
FORCE_INLINE int32 GetFontSize() const
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
int32 GetFontSize() const;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the font characters size.
|
||||
@@ -123,7 +116,7 @@ public:
|
||||
/// Gets the layout options. Layout is defined in local space of the object (on XY plane).
|
||||
/// </summary>
|
||||
API_PROPERTY(Attributes="EditorOrder(100), EditorDisplay(\"Text\")")
|
||||
FORCE_INLINE TextLayoutOptions GetLayoutOptions() const
|
||||
FORCE_INLINE const TextLayoutOptions& GetLayoutOptions() const
|
||||
{
|
||||
return _layoutOptions;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
using Flax.Build;
|
||||
using Flax.Build.NativeCpp;
|
||||
|
||||
/// <summary>
|
||||
/// User Interface module.
|
||||
/// </summary>
|
||||
public class UI : EngineModule
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void Setup(BuildOptions options)
|
||||
{
|
||||
base.Setup(options);
|
||||
|
||||
options.PublicDependencies.Add("Localization");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,9 @@ MMethod* UICanvas_Deserialize = nullptr;
|
||||
MMethod* UICanvas_PostDeserialize = nullptr;
|
||||
MMethod* UICanvas_OnEnable = nullptr;
|
||||
MMethod* UICanvas_OnDisable = nullptr;
|
||||
#if USE_EDITOR
|
||||
MMethod* UICanvas_OnActiveInTreeChanged = nullptr;
|
||||
#endif
|
||||
MMethod* UICanvas_EndPlay = nullptr;
|
||||
MMethod* UICanvas_ParentChanged = nullptr;
|
||||
|
||||
@@ -43,6 +46,9 @@ UICanvas::UICanvas(const SpawnParams& params)
|
||||
UICanvas_PostDeserialize = mclass->GetMethod("PostDeserialize");
|
||||
UICanvas_OnEnable = mclass->GetMethod("OnEnable");
|
||||
UICanvas_OnDisable = mclass->GetMethod("OnDisable");
|
||||
#if USE_EDITOR
|
||||
UICanvas_OnActiveInTreeChanged = mclass->GetMethod("OnActiveInTreeChanged");
|
||||
#endif
|
||||
UICanvas_EndPlay = mclass->GetMethod("EndPlay");
|
||||
UICanvas_ParentChanged = mclass->GetMethod("ParentChanged");
|
||||
}
|
||||
@@ -167,3 +173,15 @@ void UICanvas::OnTransformChanged()
|
||||
_box = BoundingBox(_transform.Translation);
|
||||
_sphere = BoundingSphere(_transform.Translation, 0.0f);
|
||||
}
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
void UICanvas::OnActiveInTreeChanged()
|
||||
{
|
||||
UICANVAS_INVOKE(OnActiveInTreeChanged);
|
||||
|
||||
// Base
|
||||
Actor::OnActiveInTreeChanged();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -428,7 +428,10 @@ namespace FlaxEngine
|
||||
}
|
||||
#if FLAX_EDITOR
|
||||
if (_editorRoot != null && IsActiveInHierarchy)
|
||||
{
|
||||
_guiRoot.Parent = _editorRoot;
|
||||
_guiRoot.IndexInParent = 0;
|
||||
}
|
||||
#endif
|
||||
if (_isRegisteredForTick)
|
||||
{
|
||||
@@ -637,6 +640,7 @@ namespace FlaxEngine
|
||||
if (RenderMode == CanvasRenderMode.ScreenSpace && _editorRoot != null && _guiRoot != null)
|
||||
{
|
||||
_guiRoot.Parent = HasParent && IsActiveInHierarchy ? _editorRoot : null;
|
||||
_guiRoot.IndexInParent = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -644,7 +648,15 @@ namespace FlaxEngine
|
||||
internal void OnEnable()
|
||||
{
|
||||
#if FLAX_EDITOR
|
||||
_guiRoot.Parent = _editorRoot ?? RootControl.CanvasRoot;
|
||||
if (_editorRoot != null)
|
||||
{
|
||||
_guiRoot.Parent = _editorRoot;
|
||||
_guiRoot.IndexInParent = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_guiRoot.Parent = RootControl.CanvasRoot;
|
||||
}
|
||||
#else
|
||||
_guiRoot.Parent = RootControl.CanvasRoot;
|
||||
#endif
|
||||
@@ -672,6 +684,17 @@ namespace FlaxEngine
|
||||
}
|
||||
}
|
||||
|
||||
#if FLAX_EDITOR
|
||||
internal void OnActiveInTreeChanged()
|
||||
{
|
||||
if (RenderMode == CanvasRenderMode.ScreenSpace && _editorRoot != null && _guiRoot != null)
|
||||
{
|
||||
_guiRoot.Parent = HasParent && IsActiveInHierarchy ? _editorRoot : null;
|
||||
_guiRoot.IndexInParent = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
internal void EndPlay()
|
||||
{
|
||||
if (_isRegisteredForTick)
|
||||
@@ -707,7 +730,10 @@ namespace FlaxEngine
|
||||
Setup();
|
||||
|
||||
if (RenderMode == CanvasRenderMode.ScreenSpace && _editorRoot != null && _guiRoot != null && IsActiveInHierarchy)
|
||||
{
|
||||
_guiRoot.Parent = _editorRoot;
|
||||
_guiRoot.IndexInParent = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -28,4 +28,7 @@ protected:
|
||||
void OnEnable() override;
|
||||
void OnDisable() override;
|
||||
void OnTransformChanged() final override;
|
||||
#if USE_EDITOR
|
||||
void OnActiveInTreeChanged() override;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -52,7 +52,6 @@ namespace FlaxEngine
|
||||
_control.Parent = GetParent();
|
||||
_control.IndexInParent = OrderInParent;
|
||||
_control.Location = new Vector2(LocalPosition);
|
||||
// TODO: sync control order in parent with actor order in parent (think about special cases like Panel with scroll bars used as internal controls)
|
||||
_control.LocationChanged += OnControlLocationChanged;
|
||||
|
||||
// Link children UI controls
|
||||
@@ -353,6 +352,7 @@ namespace FlaxEngine
|
||||
if (_control != null)
|
||||
{
|
||||
_control.Parent = GetParent();
|
||||
_control.IndexInParent = OrderInParent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user