Merge branch '1.2' into IconOverhaul

This commit is contained in:
W2.Wizard
2021-05-13 15:21:36 +02:00
committed by GitHub
577 changed files with 26583 additions and 26529 deletions

View File

@@ -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 />

View File

@@ -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>

View File

@@ -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();

View File

@@ -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);

View File

@@ -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 />

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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];

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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"

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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");
}
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -28,4 +28,7 @@ protected:
void OnEnable() override;
void OnDisable() override;
void OnTransformChanged() final override;
#if USE_EDITOR
void OnActiveInTreeChanged() override;
#endif
};

View File

@@ -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;
}
}