Merge remote-tracking branch 'origin/master' into 1.10

# Conflicts:
#	Source/Engine/Graphics/Materials/MaterialShader.h
This commit is contained in:
Wojtek Figat
2025-02-18 09:19:59 +01:00
133 changed files with 2253 additions and 654 deletions

View File

@@ -48,6 +48,11 @@ namespace FlaxEditor.GUI
/// </summary>
public bool CanEdit = true;
/// <summary>
/// Utility flag used to indicate that there are different values assigned to this reference editor and user should be informed about it.
/// </summary>
public bool DifferentValues;
/// <summary>
/// Initializes a new instance of the <see cref="AssetPicker"/> class.
/// </summary>
@@ -121,7 +126,13 @@ namespace FlaxEditor.GUI
if (CanEdit)
Render2D.DrawSprite(style.ArrowDown, button1Rect, button1Rect.Contains(_mousePos) ? style.Foreground : style.ForegroundGrey);
if (Validator.SelectedItem != null)
if (DifferentValues)
{
// No element selected
Render2D.FillRectangle(iconRect, style.BackgroundNormal);
Render2D.DrawText(style.FontMedium, "Multiple\nValues", iconRect, style.Foreground, TextAlignment.Center, TextAlignment.Center, TextWrapping.NoWrap, 1.0f, Height / DefaultIconSize);
}
else if (Validator.SelectedItem != null)
{
// Draw item preview
Validator.SelectedItem.DrawThumbnail(ref iconRect);

View File

@@ -30,8 +30,10 @@ namespace FlaxEditor.GUI
internal bool _isMovingTangent;
internal bool _movedView;
internal bool _movedKeyframes;
internal bool _toggledSelection;
private TangentPoint _movingTangent;
private Float2 _movingSelectionStart;
private Float2 _movingSelectionStartPosLock;
private Float2[] _movingSelectionOffsets;
private Float2 _cmShowPos;
@@ -56,12 +58,11 @@ namespace FlaxEditor.GUI
internal void UpdateSelection(ref Rectangle selectionRect)
{
// Find controls to select
for (int i = 0; i < Children.Count; i++)
var children = _children;
for (int i = 0; i < children.Count; i++)
{
if (Children[i] is KeyframePoint p)
{
if (children[i] is KeyframePoint p)
p.IsSelected = p.Bounds.Intersects(ref selectionRect);
}
}
_editor.UpdateTangents();
}
@@ -72,6 +73,7 @@ namespace FlaxEditor.GUI
_isMovingSelection = true;
_movedKeyframes = false;
var viewRect = _editor._mainPanel.GetClientArea();
_movingSelectionStartPosLock = location;
_movingSelectionStart = PointToKeyframes(location, ref viewRect);
if (_movingSelectionOffsets == null || _movingSelectionOffsets.Length != _editor._points.Count)
_movingSelectionOffsets = new Float2[_editor._points.Count];
@@ -82,10 +84,17 @@ namespace FlaxEditor.GUI
internal void OnMove(Float2 location)
{
// Skip updating keyframes until move actual starts to be meaningful
if (Float2.Distance(ref _movingSelectionStartPosLock, ref location) < 1.5f)
return;
_movingSelectionStartPosLock = Float2.Minimum;
var viewRect = _editor._mainPanel.GetClientArea();
var locationKeyframes = PointToKeyframes(location, ref viewRect);
var accessor = _editor.Accessor;
var components = accessor.GetCurveComponents();
var snapEnabled = Root.GetKey(KeyboardKeys.Control);
var snapGrid = snapEnabled ? _editor.GetGridSnap() : Float2.One;
for (var i = 0; i < _editor._points.Count; i++)
{
var p = _editor._points[i];
@@ -122,7 +131,20 @@ namespace FlaxEditor.GUI
if (isFirstSelected)
{
time = locationKeyframes.X + offset.X;
}
if (snapEnabled)
{
// Snap to the grid
var key = new Float2(time, value);
key = Float2.SnapToGrid(key, snapGrid);
time = key.X;
value = key.Y;
}
// Clamp and snap time to the valid range
if (isFirstSelected)
{
if (_editor.FPS.HasValue)
{
float fps = _editor.FPS.Value;
@@ -131,8 +153,6 @@ namespace FlaxEditor.GUI
time = Mathf.Clamp(time, minTime, maxTime);
}
// TODO: snapping keyframes to grid when moving
_editor.SetKeyframeInternal(p.Index, time, value, p.Component);
}
_editor.UpdateKeyframes();
@@ -234,7 +254,11 @@ namespace FlaxEditor.GUI
var k = _editor.GetKeyframe(_movingTangent.Index);
var kv = _editor.GetKeyframeValue(k);
var value = _editor.Accessor.GetCurveValue(ref kv, _movingTangent.Component);
_movingTangent.TangentValue = PointToKeyframes(location, ref viewRect).Y - value;
var tangent = PointToKeyframes(location, ref viewRect).Y - value;
if (Root.GetKey(KeyboardKeys.Control))
tangent = Float2.SnapToGrid(new Float2(0, tangent), _editor.GetGridSnap()).Y; // Snap tangent over Y axis
tangent = tangent * _editor.ViewScale.X * 2;
_movingTangent.TangentValue = tangent;
_editor.UpdateTangents();
Cursor = CursorType.SizeNS;
_movedKeyframes = true;
@@ -283,6 +307,7 @@ namespace FlaxEditor.GUI
}
// Cache data
_toggledSelection = false;
_isMovingSelection = false;
_isMovingTangent = false;
_mousePos = location;
@@ -305,13 +330,7 @@ namespace FlaxEditor.GUI
{
if (_leftMouseDown)
{
if (Root.GetKey(KeyboardKeys.Control))
{
// Toggle selection
keyframe.IsSelected = !keyframe.IsSelected;
_editor.UpdateTangents();
}
else if (Root.GetKey(KeyboardKeys.Shift))
if (Root.GetKey(KeyboardKeys.Shift))
{
// Select range
keyframe.IsSelected = true;
@@ -335,10 +354,14 @@ namespace FlaxEditor.GUI
else if (!keyframe.IsSelected)
{
// Select node
if (_editor.KeyframesEditorContext != null)
_editor.KeyframesEditorContext.OnKeyframesDeselect(_editor);
else
_editor.ClearSelection();
if (!Root.GetKey(KeyboardKeys.Control))
{
if (_editor.KeyframesEditorContext != null)
_editor.KeyframesEditorContext.OnKeyframesDeselect(_editor);
else
_editor.ClearSelection();
}
_toggledSelection = true;
keyframe.IsSelected = true;
_editor.UpdateTangents();
}
@@ -429,6 +452,12 @@ namespace FlaxEditor.GUI
else
OnMoveEnd(location);
}
// Toggle selection
else if (!_toggledSelection && Root.GetKey(KeyboardKeys.Control) && GetChildAt(location) is KeyframePoint keyframe)
{
keyframe.IsSelected = !keyframe.IsSelected;
_editor.UpdateTangents();
}
_isMovingSelection = false;
_isMovingTangent = false;
@@ -514,11 +543,11 @@ namespace FlaxEditor.GUI
{
if (base.OnMouseDoubleClick(location, button))
return true;
// Add keyframe on double click
var child = GetChildAt(location);
if (child is not KeyframePoint &&
child is not TangentPoint &&
if (child is not KeyframePoint &&
child is not TangentPoint &&
_editor.KeyframesCount < _editor.MaxKeyframes)
{
var viewRect = _editor._mainPanel.GetClientArea();
@@ -545,7 +574,7 @@ namespace FlaxEditor.GUI
var viewRect = _editor._mainPanel.GetClientArea();
var locationInKeyframes = PointToKeyframes(location, ref viewRect);
var locationInEditorBefore = _editor.PointFromKeyframes(locationInKeyframes, ref viewRect);
// Scale relative to the curve size
var scale = new Float2(delta * 0.1f);
_editor._mainPanel.GetDesireClientArea(out var mainPanelArea);

View File

@@ -163,10 +163,11 @@ namespace FlaxEditor.GUI
/// <inheritdoc />
public override void Draw()
{
var style = Style.Current;
var rect = new Rectangle(Float2.Zero, Size);
var color = Editor.ShowCollapsed ? Color.Gray : Editor.Colors[Component];
var color = Editor.ShowCollapsed ? style.ForegroundDisabled : Editor.Colors[Component];
if (IsSelected)
color = Editor.ContainsFocus ? Color.YellowGreen : Color.Lerp(Color.Gray, Color.YellowGreen, 0.4f);
color = Editor.ContainsFocus ? style.SelectionBorder : Color.Lerp(style.ForegroundDisabled, style.SelectionBorder, 0.4f);
if (IsMouseOver)
color *= 1.1f;
Render2D.FillRectangle(rect, color);
@@ -244,14 +245,19 @@ namespace FlaxEditor.GUI
set => Editor.SetKeyframeTangentInternal(Index, IsIn, Component, value);
}
internal float TangentOffset => 50.0f / Editor.ViewScale.X;
/// <inheritdoc />
public override void Draw()
{
var style = Style.Current;
var thickness = 6.0f / Mathf.Max(Editor.ViewScale.X, 1.0f);
var size = Size;
var pointPos = PointFromParent(Point.Center);
Render2D.DrawLine(Size * 0.5f, pointPos, Color.Gray);
Render2D.DrawLine(size * 0.5f, pointPos, style.ForegroundDisabled, thickness);
var rect = new Rectangle(Float2.Zero, Size);
var color = Color.MediumVioletRed;
var rect = new Rectangle(Float2.Zero, size);
var color = style.BorderSelected;
if (IsMouseOver)
color *= 1.1f;
Render2D.FillRectangle(rect, color);
@@ -289,7 +295,7 @@ namespace FlaxEditor.GUI
/// <summary>
/// The curve time/value axes tick steps.
/// </summary>
protected float[] TickSteps = Utilities.Utils.CurveTickSteps;
protected double[] TickSteps = Utilities.Utils.CurveTickSteps;
/// <summary>
/// The curve contents area.
@@ -442,7 +448,7 @@ namespace FlaxEditor.GUI
_mainPanel = new Panel(ScrollBars.Both)
{
ScrollMargin = new Margin(150.0f),
AlwaysShowScrollbars = true,
AlwaysShowScrollbars = false,
AnchorPreset = AnchorPresets.StretchAll,
Offsets = Margin.Zero,
Parent = this
@@ -668,26 +674,82 @@ namespace FlaxEditor.GUI
OnEditingEnd();
}
private void ShowCurve(bool selectedOnly)
{
if (_points.Count == 0)
return;
int pass = 1;
REDO:
// Get curve bounds in Keyframes (time and value)
Float2 posMin = Float2.Maximum, posMax = Float2.Minimum;
// TODO: include bezier curve bounds calculation to handle curve outside the bounds made out of points
foreach (var point in _points)
{
if (selectedOnly && !point.IsSelected)
continue;
var pos = point.Point;
Float2.Min(ref posMin, ref pos, out posMin);
Float2.Max(ref posMax, ref pos, out posMax);
}
// Apply margin around the area
var posMargin = (posMax - posMin) * 0.05f;
posMin -= posMargin;
posMax += posMargin;
// Convert from Keyframes to Contents
_mainPanel.GetDesireClientArea(out var viewRect);
PointFromKeyframesToContents(ref posMin, ref viewRect);
PointFromKeyframesToContents(ref posMax, ref viewRect);
var tmp = posMin;
Float2.Min(ref posMin, ref posMax, out posMin);
Float2.Max(ref posMax, ref tmp, out posMax);
var contentsSize = posMax - posMin;
// Convert from Contents to Main Panel
posMin = _contents.PointToParent(posMin);
posMax = _contents.PointToParent(posMax);
tmp = posMin;
Float2.Min(ref posMin, ref posMax, out posMin);
Float2.Max(ref posMax, ref tmp, out posMax);
// Update zoom (leave unchanged when focusing a single point)
var zoomMask = EnableZoom;
if (Mathf.IsZero(posMargin.X))
zoomMask &= ~UseMode.Horizontal;
if (Mathf.IsZero(posMargin.Y))
zoomMask &= ~UseMode.Vertical;
ViewScale = ApplyUseModeMask(zoomMask, viewRect.Size / contentsSize, ViewScale);
// Update scroll (attempt to center the area when it's smaller than the view)
Float2 viewOffset = -posMin;
Float2 viewSize = _mainPanel.Size;
Float2 viewSizeLeft = viewSize - Float2.Clamp(posMax - posMin, Float2.Zero, viewSize);
viewOffset += viewSizeLeft * 0.5f;
viewOffset = ApplyUseModeMask(EnablePanning, viewOffset, _mainPanel.ViewOffset);
_mainPanel.ViewOffset = viewOffset;
// Do it multiple times so the view offset can be properly calculate once the view scale gets changes
if (pass++ <= 2)
goto REDO;
UpdateKeyframes();
}
/// <summary>
/// Focuses the view on the selected keyframes.
/// </summary>
public void FocusSelection()
{
// Fallback to showing whole curve if nothing is selected
ShowCurve(SelectionCount != 0);
}
/// <inheritdoc />
public override void ShowWholeCurve()
{
_mainPanel.GetDesireClientArea(out var mainPanelArea);
ViewScale = ApplyUseModeMask(EnableZoom, mainPanelArea.Size / _contents.Size, ViewScale);
Float2 minPos = Float2.Maximum;
foreach (var point in _points)
{
var pos = point.PointToParent(point.Location);
Float2.Min(ref minPos, ref pos, out minPos);
}
var minPosPoint = _contents.PointToParent(ref minPos);
var scroll = new Float2(_mainPanel.HScrollBar?.TargetValue ?? 0, _mainPanel.VScrollBar?.TargetValue ?? 0);
scroll = ApplyUseModeMask(EnablePanning, minPosPoint, scroll);
if (_mainPanel.HScrollBar != null)
_mainPanel.HScrollBar.TargetValue = scroll.X;
if (_mainPanel.VScrollBar != null)
_mainPanel.VScrollBar.TargetValue = scroll.Y;
UpdateKeyframes();
ShowCurve(false);
}
/// <inheritdoc />
@@ -766,10 +828,7 @@ namespace FlaxEditor.GUI
point = _contents.PointFromParent(point);
// Contents -> Keyframes
return new Float2(
(point.X + _contents.Location.X) / UnitsPerSecond,
(point.Y + _contents.Location.Y - curveContentAreaBounds.Height) / -UnitsPerSecond
);
return PointFromContentsToKeyframes(ref point, ref curveContentAreaBounds);
}
/// <summary>
@@ -781,10 +840,7 @@ namespace FlaxEditor.GUI
protected Float2 PointFromKeyframes(Float2 point, ref Rectangle curveContentAreaBounds)
{
// Keyframes -> Contents
point = new Float2(
point.X * UnitsPerSecond - _contents.Location.X,
point.Y * -UnitsPerSecond + curveContentAreaBounds.Height - _contents.Location.Y
);
PointFromKeyframesToContents(ref point, ref curveContentAreaBounds);
// Contents -> Main Panel
point = _contents.PointToParent(point);
@@ -793,11 +849,27 @@ namespace FlaxEditor.GUI
return _mainPanel.PointToParent(point);
}
internal Float2 PointFromContentsToKeyframes(ref Float2 point, ref Rectangle curveContentAreaBounds)
{
return new Float2(
(point.X + _contents.Location.X) / UnitsPerSecond,
(point.Y + _contents.Location.Y - curveContentAreaBounds.Height) / -UnitsPerSecond
);
}
internal void PointFromKeyframesToContents(ref Float2 point, ref Rectangle curveContentAreaBounds)
{
point = new Float2(
point.X * UnitsPerSecond - _contents.Location.X,
point.Y * -UnitsPerSecond + curveContentAreaBounds.Height - _contents.Location.Y
);
}
private void DrawAxis(Float2 axis, Rectangle viewRect, float min, float max, float pixelRange)
{
Utilities.Utils.DrawCurveTicks((float tick, float strength) =>
Utilities.Utils.DrawCurveTicks((decimal tick, double step, float strength) =>
{
var p = PointFromKeyframes(axis * tick, ref viewRect);
var p = PointFromKeyframes(axis * (float)tick, ref viewRect);
// Draw line
var lineRect = new Rectangle
@@ -820,6 +892,24 @@ namespace FlaxEditor.GUI
}, TickSteps, ref _tickStrengths, min, max, pixelRange);
}
private void SetupGrid(out Float2 min, out Float2 max, out Float2 pixelRange)
{
var viewRect = _mainPanel.GetClientArea();
var upperLeft = PointToKeyframes(viewRect.Location, ref viewRect);
var bottomRight = PointToKeyframes(viewRect.Size, ref viewRect);
min = Float2.Min(upperLeft, bottomRight);
max = Float2.Max(upperLeft, bottomRight);
pixelRange = (max - min) * ViewScale * UnitsPerSecond;
}
private Float2 GetGridSnap()
{
SetupGrid(out var min, out var max, out var pixelRange);
return new Float2(Utilities.Utils.GetCurveGridSnap(TickSteps, ref _tickStrengths, min.X, max.X, pixelRange.X),
Utilities.Utils.GetCurveGridSnap(TickSteps, ref _tickStrengths, min.Y, max.Y, pixelRange.Y));
}
/// <summary>
/// Draws the curve.
/// </summary>
@@ -849,12 +939,7 @@ namespace FlaxEditor.GUI
// Draw time and values axes
if (ShowAxes != UseMode.Off)
{
var upperLeft = PointToKeyframes(viewRect.Location, ref viewRect);
var bottomRight = PointToKeyframes(viewRect.Size, ref viewRect);
var min = Float2.Min(upperLeft, bottomRight);
var max = Float2.Max(upperLeft, bottomRight);
var pixelRange = (max - min) * ViewScale * UnitsPerSecond;
SetupGrid(out var min, out var max, out var pixelRange);
Render2D.PushClip(ref viewRect);
@@ -939,7 +1024,7 @@ namespace FlaxEditor.GUI
}
else if (options.FocusSelection.Process(this))
{
ShowWholeCurve();
FocusSelection();
return true;
}
@@ -2200,7 +2285,7 @@ namespace FlaxEditor.GUI
var tangent = t.TangentValue;
var direction = t.IsIn ? -1.0f : 1.0f;
var offset = 30.0f;
var offset = t.TangentOffset;
var location = GetKeyframePoint(ref k, selectedComponent);
t.Size = KeyframesSize / ViewScale;
t.Location = new Float2
@@ -2227,6 +2312,18 @@ namespace FlaxEditor.GUI
}
}
/// <inheritdoc />
protected override void SetScaleInternal(ref Float2 scale)
{
base.SetScaleInternal(ref scale);
if (!_showCollapsed)
{
// Refresh keyframes when zooming (their size depends on the scale)
UpdateKeyframes();
}
}
/// <inheritdoc />
protected override void OnShowContextMenu(ContextMenu.ContextMenu cm, int selectionCount)
{

View File

@@ -1,6 +1,8 @@
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
using System;
using FlaxEditor.Windows;
using FlaxEditor.Windows.Assets;
using FlaxEngine;
using FlaxEngine.GUI;
@@ -55,18 +57,26 @@ namespace FlaxEditor.GUI
private IsValidDelegate _isValid;
private Action<Actor> _selected;
private ActorSearchPopup(IsValidDelegate isValid, Action<Actor> selected)
private ActorSearchPopup(IsValidDelegate isValid, Action<Actor> selected, CustomEditors.IPresenterOwner context)
{
_isValid = isValid;
_selected = selected;
ItemClicked += OnItemClicked;
// TODO: use async thread to search scenes
for (int i = 0; i < Level.ScenesCount; i++)
if (context is PropertiesWindow propertiesWindow || context == null)
{
Find(Level.GetScene(i));
// TODO: use async thread to search scenes
for (int i = 0; i < Level.ScenesCount; i++)
{
Find(Level.GetScene(i));
}
}
else if (context is PrefabWindow prefabWindow)
{
Find(prefabWindow.Graph.MainActor);
}
SortItems();
}
@@ -98,10 +108,11 @@ namespace FlaxEditor.GUI
/// <param name="showTargetLocation">The show target location.</param>
/// <param name="isValid">Event called to check if a given actor item is valid to be used.</param>
/// <param name="selected">Event called on actor item pick.</param>
/// <param name="context">The presenter owner context (i.e. PrefabWindow, PropertiesWindow).</param>
/// <returns>The dialog.</returns>
public static ActorSearchPopup Show(Control showTarget, Float2 showTargetLocation, IsValidDelegate isValid, Action<Actor> selected)
public static ActorSearchPopup Show(Control showTarget, Float2 showTargetLocation, IsValidDelegate isValid, Action<Actor> selected, CustomEditors.IPresenterOwner context)
{
var popup = new ActorSearchPopup(isValid, selected);
var popup = new ActorSearchPopup(isValid, selected, context);
popup.Show(showTarget, showTargetLocation);
return popup;
}

View File

@@ -1,6 +1,8 @@
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
using System;
using FlaxEditor.Windows;
using FlaxEditor.Windows.Assets;
using FlaxEngine;
using FlaxEngine.GUI;
using FlaxEngine.Utilities;
@@ -66,18 +68,26 @@ namespace FlaxEditor.GUI
private IsValidDelegate _isValid;
private Action<Script> _selected;
private ScriptSearchPopup(IsValidDelegate isValid, Action<Script> selected)
private ScriptSearchPopup(IsValidDelegate isValid, Action<Script> selected, CustomEditors.IPresenterOwner context)
{
_isValid = isValid;
_selected = selected;
ItemClicked += OnItemClicked;
// TODO: use async thread to search scenes
for (int i = 0; i < Level.ScenesCount; i++)
if (context is PropertiesWindow propertiesWindow || context == null)
{
Find(Level.GetScene(i));
// TODO: use async thread to search scenes
for (int i = 0; i < Level.ScenesCount; i++)
{
Find(Level.GetScene(i));
}
}
else if (context is PrefabWindow prefabWindow)
{
Find(prefabWindow.Graph.MainActor);
}
SortItems();
}
@@ -113,10 +123,11 @@ namespace FlaxEditor.GUI
/// <param name="showTargetLocation">The show target location.</param>
/// <param name="isValid">Event called to check if a given script item is valid to be used.</param>
/// <param name="selected">Event called on script item pick.</param>
/// <param name="context">The presenter owner context (i.e. PrefabWindow, PropertiesWindow).</param>
/// <returns>The dialog.</returns>
public static ScriptSearchPopup Show(Control showTarget, Float2 showTargetLocation, IsValidDelegate isValid, Action<Script> selected)
public static ScriptSearchPopup Show(Control showTarget, Float2 showTargetLocation, IsValidDelegate isValid, Action<Script> selected, CustomEditors.IPresenterOwner context)
{
var popup = new ScriptSearchPopup(isValid, selected);
var popup = new ScriptSearchPopup(isValid, selected, context);
popup.Show(showTarget, showTargetLocation);
return popup;
}

View File

@@ -1,10 +1,13 @@
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
using System;
using System.ComponentModel;
using System.Linq;
using FlaxEditor.History;
using FlaxEditor.Scripting;
using FlaxEngine;
using FlaxEngine.GUI;
using CategoryAttribute = FlaxEngine.CategoryAttribute;
namespace FlaxEditor.GUI
{
@@ -101,11 +104,26 @@ namespace FlaxEditor.GUI
if (_isValid(type))
{
var attributes = type.GetAttributes(true);
if (attributes.FirstOrDefault(x => x is HideInEditorAttribute || x is System.Runtime.CompilerServices.CompilerGeneratedAttribute) == null)
if (IsHideAttributes(attributes))
{
var mType = type.Type;
if (mType != null && mType.IsValueType && mType.ReflectedType != null && string.Equals(mType.ReflectedType.Name, "<PrivateImplementationDetails>", StringComparison.Ordinal))
continue;
if (mType != null)
{
// Skip if type is compiler-generated
if (mType.IsValueType && mType.ReflectedType != null && string.Equals(mType.ReflectedType.Name, "<PrivateImplementationDetails>", StringComparison.Ordinal))
continue;
// Skip if outer type is hidden
if (mType.DeclaringType != null && IsHideAttributes(mType.DeclaringType.GetCustomAttributes(true)))
continue;
// Blacklist some types
if (typeof(TypeConverter).IsAssignableFrom(mType) ||
typeof(IHistoryAction).IsAssignableFrom(mType) ||
(mType.Namespace != null && mType.Namespace.StartsWith("Newtonsoft.Json")))
continue;
}
AddItem(new TypeItemView(type, attributes));
}
}
@@ -113,6 +131,17 @@ namespace FlaxEditor.GUI
SortItems();
}
private bool IsHideAttributes(object[] attributes)
{
return attributes.FirstOrDefault(IsHideAttribute) == null;
}
private bool IsHideAttribute(object attr)
{
return attr is HideInEditorAttribute ||
attr is System.Runtime.CompilerServices.CompilerGeneratedAttribute;
}
private void OnItemClicked(Item item)
{
_selected(((TypeItemView)item).Type);

View File

@@ -14,7 +14,7 @@ namespace FlaxEditor.GUI.Timeline.GUI
class Background : ContainerControl
{
private readonly Timeline _timeline;
private float[] _tickSteps;
private double[] _tickSteps;
private float[] _tickStrengths;
private bool _isSelecting;
private Float2 _selectingStartPos = Float2.Minimum;
@@ -176,9 +176,9 @@ namespace FlaxEditor.GUI.Timeline.GUI
// Draw vertical lines for time axis
var pixelsInRange = _timeline.Zoom;
var pixelRange = pixelsInRange * (max - min);
var tickRange = Utilities.Utils.DrawCurveTicks((float tick, float strength) =>
var tickRange = Utilities.Utils.DrawCurveTicks((decimal tick, double step, float strength) =>
{
var time = tick / _timeline.FramesPerSecond;
var time = (float)tick / _timeline.FramesPerSecond;
var x = time * zoom + Timeline.StartOffset;
var lineColor = style.ForegroundDisabled.RGBMultiplied(0.7f).AlphaMultiplied(strength);
Render2D.FillRectangle(new Rectangle(x - 0.5f, 0, 1.0f, height), lineColor);
@@ -233,20 +233,20 @@ namespace FlaxEditor.GUI.Timeline.GUI
int l = Mathf.Clamp(smallestTick + level, 0, _tickSteps.Length - 2);
var lStep = _tickSteps[l];
var lNextStep = _tickSteps[l + 1];
int startTick = Mathf.FloorToInt(min / lStep);
int endTick = Mathf.CeilToInt(max / lStep);
var startTick = Mathd.FloorToInt(min / lStep);
var endTick = Mathd.CeilToInt(max / lStep);
Color lineColor = style.Foreground.RGBMultiplied(0.8f).AlphaMultiplied(strength);
Color labelColor = style.ForegroundDisabled.AlphaMultiplied(strength);
for (int i = startTick; i <= endTick; i++)
for (var i = startTick; i <= endTick; i++)
{
if (l < biggestTick && (i % Mathf.RoundToInt(lNextStep / lStep) == 0))
if (l < biggestTick && (i % Mathd.RoundToInt(lNextStep / lStep) == 0))
continue;
var tick = i * lStep;
var time = tick / _timeline.FramesPerSecond;
var x = time * zoom + Timeline.StartOffset;
var tick = (decimal)lStep * i;
var time = (double)tick / _timeline.FramesPerSecond;
var x = (float)time * zoom + Timeline.StartOffset;
// Header line
var lineRect = new Rectangle(x - 0.5f, -verticalLinesHeaderExtend * 0.6f + timeAxisHeaderOffset, 1.0f, verticalLinesHeaderExtend * 0.6f);
var lineRect = new Rectangle((float)x - 0.5f, -verticalLinesHeaderExtend * 0.6f + timeAxisHeaderOffset, 1.0f, verticalLinesHeaderExtend * 0.6f);
Render2D.FillRectangle(lineRect, lineColor);
// Time label

View File

@@ -8,7 +8,6 @@ using System.Text;
using FlaxEditor.CustomEditors;
using FlaxEditor.GUI.ContextMenu;
using FlaxEditor.Options;
using FlaxEditor.Scripting;
using FlaxEngine;
using FlaxEngine.GUI;
using FlaxEngine.Json;

View File

@@ -264,7 +264,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
private void OnClickedSelect()
{
ActorSearchPopup.Show(this, PointFromScreen(FlaxEngine.Input.MouseScreenPosition), IsActorValid, SetActor);
ActorSearchPopup.Show(this, PointFromScreen(FlaxEngine.Input.MouseScreenPosition), IsActorValid, SetActor, null);
}
private void OnClickedSelectActor(Image image, MouseButton button)