229 lines
7.4 KiB
C#
229 lines
7.4 KiB
C#
// Copyright (c) Wojciech Figat. All rights reserved.
|
|
|
|
using FlaxEditor.GUI.ContextMenu;
|
|
using FlaxEditor.Utilities;
|
|
using FlaxEngine;
|
|
using FlaxEngine.GUI;
|
|
|
|
namespace FlaxEditor.CustomEditors.GUI
|
|
{
|
|
/// <summary>
|
|
/// Displays custom editor property name.
|
|
/// </summary>
|
|
/// <seealso cref="FlaxEngine.GUI.Label" />
|
|
[HideInEditor]
|
|
public class PropertyNameLabel : Label
|
|
{
|
|
// TODO: if name is too long to show -> use tooltip to show it
|
|
|
|
/// <summary>
|
|
/// Custom event delegate that can be used to extend the property name label with an additional functionality.
|
|
/// </summary>
|
|
/// <param name="label">The label.</param>
|
|
/// <param name="menu">The menu.</param>
|
|
/// <param name="linkedEditor">The linked editor. Can be null.</param>
|
|
public delegate void SetupContextMenuDelegate(PropertyNameLabel label, ContextMenu menu, CustomEditor linkedEditor);
|
|
|
|
private bool _mouseDown;
|
|
|
|
/// <summary>
|
|
/// Helper value used by the <see cref="PropertiesList"/> to draw property names in a proper area.
|
|
/// </summary>
|
|
internal int FirstChildControlIndex;
|
|
|
|
/// <summary>
|
|
/// Helper value used by the <see cref="PropertiesList"/> to draw property names in a proper area.
|
|
/// </summary>
|
|
internal PropertiesList FirstChildControlContainer;
|
|
|
|
/// <summary>
|
|
/// The linked custom editor (shows the label property).
|
|
/// </summary>
|
|
internal CustomEditor LinkedEditor;
|
|
|
|
/// <summary>
|
|
/// The highlight strip color drawn on a side (transparent if skip rendering).
|
|
/// </summary>
|
|
public Color HighlightStripColor;
|
|
|
|
/// <summary>
|
|
/// The active search text query used to highlight matching parts of the label.
|
|
/// </summary>
|
|
public string SearchText = string.Empty;
|
|
|
|
private string _lastSearchText;
|
|
private string _lastText;
|
|
private QueryFilterHelper.Range[] _highlightRanges;
|
|
|
|
private void UpdateHighlights()
|
|
{
|
|
var text = Text?.ToString() ?? string.Empty;
|
|
if (_lastSearchText == SearchText && _lastText == text)
|
|
return;
|
|
|
|
_lastSearchText = SearchText;
|
|
_lastText = text;
|
|
|
|
if (!string.IsNullOrEmpty(SearchText))
|
|
{
|
|
QueryFilterHelper.Match(SearchText, text, out _highlightRanges);
|
|
}
|
|
else
|
|
{
|
|
_highlightRanges = null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Occurs when label creates the context menu popup for th property. Can be used to add some custom logic per property editor.
|
|
/// </summary>
|
|
public event SetupContextMenuDelegate SetupContextMenu;
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="PropertyNameLabel"/> class.
|
|
/// </summary>
|
|
/// <param name="name">The name.</param>
|
|
public PropertyNameLabel(string name)
|
|
{
|
|
Text = name;
|
|
HorizontalAlignment = TextAlignment.Near;
|
|
VerticalAlignment = TextAlignment.Center;
|
|
Margin = new Margin(4, 0, 0, 0);
|
|
ClipText = true;
|
|
|
|
HighlightStripColor = Color.Transparent;
|
|
}
|
|
|
|
internal void LinkEditor(CustomEditor editor)
|
|
{
|
|
if (LinkedEditor == null)
|
|
{
|
|
LinkedEditor = editor;
|
|
editor.LinkLabel(this);
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override void Draw()
|
|
{
|
|
base.Draw();
|
|
|
|
if (HighlightStripColor.A > 0.0f)
|
|
{
|
|
Render2D.FillRectangle(new Rectangle(0, 0, 2, Height), HighlightStripColor);
|
|
}
|
|
|
|
UpdateHighlights();
|
|
|
|
if (_highlightRanges != null && _highlightRanges.Length > 0)
|
|
{
|
|
var text = Text.ToString();
|
|
var font = Font?.GetFont();
|
|
if (font != null)
|
|
{
|
|
var style = Style.Current;
|
|
var color = style.ProgressNormal * 0.6f;
|
|
var margin = Margin;
|
|
var textSize = font.MeasureText(text);
|
|
var textX = margin.Left;
|
|
var textY = margin.Top + (Height - margin.Height - textSize.Y) * 0.5f;
|
|
|
|
for (int i = 0; i < _highlightRanges.Length; i++)
|
|
{
|
|
var start = font.GetCharPosition(text, _highlightRanges[i].StartIndex);
|
|
var end = font.GetCharPosition(text, _highlightRanges[i].EndIndex);
|
|
var highlightRect = new Rectangle(start.X + textX, textY, end.X - start.X, textSize.Y);
|
|
Render2D.FillRectangle(highlightRect, color);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override void OnMouseLeave()
|
|
{
|
|
_mouseDown = false;
|
|
|
|
base.OnMouseLeave();
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override bool OnMouseDown(Float2 location, MouseButton button)
|
|
{
|
|
if (button == MouseButton.Right)
|
|
{
|
|
_mouseDown = true;
|
|
}
|
|
|
|
return base.OnMouseDown(location, button);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override bool OnMouseUp(Float2 location, MouseButton button)
|
|
{
|
|
if (base.OnMouseUp(location, button))
|
|
return true;
|
|
|
|
if (_mouseDown && button == MouseButton.Right)
|
|
{
|
|
_mouseDown = false;
|
|
|
|
// Skip if is not extended
|
|
var linkedEditor = LinkedEditor;
|
|
if (linkedEditor == null && SetupContextMenu == null)
|
|
return false;
|
|
|
|
var menu = new ContextMenu();
|
|
|
|
if (linkedEditor != null)
|
|
{
|
|
var features = linkedEditor.Presenter.Features;
|
|
if ((features & (FeatureFlags.UseDefault | FeatureFlags.UsePrefab)) != 0)
|
|
{
|
|
if ((features & FeatureFlags.UsePrefab) != 0)
|
|
menu.AddButton("Revert to Prefab", linkedEditor.RevertToReferenceValue).Enabled = linkedEditor.CanRevertReferenceValue;
|
|
if ((features & FeatureFlags.UseDefault) != 0)
|
|
menu.AddButton("Reset to default", linkedEditor.RevertToDefaultValue).Enabled = linkedEditor.CanRevertDefaultValue;
|
|
menu.AddSeparator();
|
|
}
|
|
menu.AddButton("Copy", linkedEditor.Copy);
|
|
var paste = menu.AddButton("Paste", linkedEditor.Paste);
|
|
paste.Enabled = linkedEditor.CanPaste;
|
|
}
|
|
|
|
SetupContextMenu?.Invoke(this, menu, linkedEditor);
|
|
|
|
menu.Show(this, location);
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override void OnLostFocus()
|
|
{
|
|
_mouseDown = false;
|
|
|
|
base.OnLostFocus();
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override void OnDestroy()
|
|
{
|
|
SetupContextMenu = null;
|
|
LinkedEditor = null;
|
|
FirstChildControlContainer = null;
|
|
|
|
base.OnDestroy();
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override string ToString()
|
|
{
|
|
return Text.ToString();
|
|
}
|
|
}
|
|
}
|