Files
FlaxEngine/Source/Editor/GUI/Row.cs
Luke Schneider ad28a3fdbf Better light theme (Style) support, and a Default light theme (as a secondary option)
1) Added ForegroundViewport as a new color.  It is used in the main game viewport (ViewportWidgetButton), and the viewport for rendering of particles and materials.  It is needed because the default foreground in a Light theme is black, but black does not work well in a viewport.  A new color seemed appropriate.

2) Fixed the profiler window to use the Foreground color in multiple text elements, instead of Color.White (or no default TitleColor).  This includes  the Row class, Asset class, SingleChart class, Timeline Class, and more.

3) Added a second theme/Style (DefaultLight) to include with the engine.  It uses RGB float values because those were easier to transfer from the saved values that I had created (and they're easier for me to edit if necessary).  I tried to emulate how the Default theme is created/loaded/etc as closely as possible.
2023-09-27 21:54:34 -05:00

285 lines
8.9 KiB
C#

// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
using System;
using FlaxEngine;
using FlaxEngine.GUI;
namespace FlaxEditor.GUI
{
/// <summary>
/// Single row control for <see cref="Table"/>.
/// </summary>
/// <seealso cref="FlaxEngine.GUI.Control" />
public class Row : Control
{
private Table _table;
/// <summary>
/// Gets the parent table that owns this row.
/// </summary>
public Table Table => _table;
/// <summary>
/// Gets or sets the cell values.
/// </summary>
public object[] Values { get; set; }
/// <summary>
/// Gets or sets the row depth level.
/// </summary>
public int Depth { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="Row"/> class.
/// </summary>
/// <param name="height">The height.</param>
public Row(float height = 16)
: base(0, 0, 100, height)
{
Depth = -1;
}
/// <inheritdoc />
public override void Draw()
{
base.Draw();
var style = Style.Current;
if (IsMouseOver)
{
Render2D.FillRectangle(new Rectangle(Float2.Zero, Size), style.BackgroundHighlighted * 0.7f);
}
if (Values != null && _table?.Columns != null)
{
float x = 0;
int end = Mathf.Min(Values.Length, _table.Columns.Length);
for (int i = 0; i < end; i++)
{
var column = _table.Columns[i];
var value = Values[i];
var width = _table.GetColumnWidth(i);
string text;
if (value == null)
text = string.Empty;
else if (column.FormatValue != null)
text = column.FormatValue(value);
else
text = value.ToString();
var rect = new Rectangle(x, 0, width, Height);
rect.Expand(-4);
float leftDepthMargin = 0;
if (column.UseExpandCollapseMode)
{
float arrowSize = 12.0f;
leftDepthMargin = arrowSize * (Depth + 1);
// Check if has any child events (next row should be it)
int nextIndex = IndexInParent + 1;
if (nextIndex < _table.ChildrenCount)
{
if (_table.Children[nextIndex] is Row row && row.Depth == Depth + 1)
{
// Tree node arrow
var arrowRect = new Rectangle(x + leftDepthMargin - arrowSize, (Height - arrowSize) * 0.5f, arrowSize, arrowSize);
Render2D.DrawSprite(row.Visible ? style.ArrowDown : style.ArrowRight, arrowRect, IsMouseOver ? style.Foreground : style.ForegroundGrey);
}
}
}
rect.X += leftDepthMargin;
rect.Width -= leftDepthMargin;
Render2D.PushClip(rect);
Render2D.DrawText(style.FontMedium, text, rect, Style.Current.Foreground, column.CellAlignment, TextAlignment.Center);
Render2D.PopClip();
x += width;
}
}
}
/// <inheritdoc />
protected override void OnParentChangedInternal()
{
base.OnParentChangedInternal();
_table = Parent as Table;
}
/// <inheritdoc />
public override bool OnMouseUp(Float2 location, MouseButton button)
{
if (button == MouseButton.Left && Values != null && _table?.Columns != null)
{
float x = 0;
int end = Mathf.Min(Values.Length, _table.Columns.Length);
for (int i = 0; i < end; i++)
{
var column = _table.Columns[i];
var width = _table.GetColumnWidth(i);
if (column.UseExpandCollapseMode)
{
float arrowSize = 12.0f;
float leftDepthMargin = arrowSize * (Depth + 1);
int nextIndex = IndexInParent + 1;
if (nextIndex < _table.ChildrenCount)
{
if (_table.Children[nextIndex] is Row row && row.Depth == Depth + 1)
{
var arrowRect = new Rectangle(x + leftDepthMargin - arrowSize, (Height - arrowSize) * 0.5f, arrowSize, arrowSize);
if (arrowRect.Contains(location))
{
// Collapse/expand
SetSubRowsVisible(!GetSubRowsVisible());
return true;
}
}
}
}
x += width;
}
}
return base.OnMouseUp(location, button);
}
/// <inheritdoc />
protected override void OnVisibleChanged()
{
base.OnVisibleChanged();
// Hide child events (only if using depth mode)
if (HasParent && Depth != -1 && !Visible)
{
SetSubRowsVisible(Visible);
}
}
private bool GetSubRowsVisible()
{
for (int i = Parent.GetChildIndex(this) + 1; i < Parent.ChildrenCount; i++)
{
if (Parent.Children[i] is Row child)
{
if (child.Depth == Depth + 1)
return child.Visible;
if (child.Depth <= Depth)
break;
}
}
return true;
}
private void SetSubRowsVisible(bool visible)
{
for (int i = Parent.GetChildIndex(this) + 1; i < Parent.ChildrenCount; i++)
{
if (Parent.Children[i] is Row child)
{
if (child.Depth == Depth + 1)
child.Visible = visible;
else if (child.Depth <= Depth)
break;
}
}
}
}
/// <summary>
/// The table row that contains events for mouse interaction.
/// </summary>
[HideInEditor]
public class ClickableRow : Row
{
private bool _leftClick;
private bool _isRightDown;
/// <summary>
/// The double click event.
/// </summary>
public Action DoubleClick;
/// <summary>
/// The left mouse button click event.
/// </summary>
public Action LeftClick;
/// <summary>
/// The right mouse button click event.
/// </summary>
public Action RightClick;
/// <summary>
/// The double click event.
/// </summary>
public Action<ClickableRow> RowDoubleClick;
/// <summary>
/// The left mouse button click event.
/// </summary>
public Action<ClickableRow> RowLeftClick;
/// <summary>
/// The right mouse button click event.
/// </summary>
public Action<ClickableRow> RowRightClick;
/// <inheritdoc />
public override bool OnMouseDoubleClick(Float2 location, MouseButton button)
{
DoubleClick?.Invoke();
RowDoubleClick?.Invoke(this);
return base.OnMouseDoubleClick(location, button);
}
/// <inheritdoc />
public override bool OnMouseDown(Float2 location, MouseButton button)
{
if (button == MouseButton.Left)
_leftClick = true;
else if (button == MouseButton.Right)
_isRightDown = true;
return base.OnMouseDown(location, button);
}
/// <inheritdoc />
public override bool OnMouseUp(Float2 location, MouseButton button)
{
if (button == MouseButton.Left && _leftClick)
{
_leftClick = false;
LeftClick?.Invoke();
RowLeftClick?.Invoke(this);
}
else if (button == MouseButton.Right && _isRightDown)
{
_isRightDown = false;
RightClick?.Invoke();
RowRightClick?.Invoke(this);
}
return base.OnMouseUp(location, button);
}
/// <inheritdoc />
public override void OnMouseLeave()
{
_leftClick = false;
_isRightDown = false;
base.OnMouseLeave();
}
}
}