diff --git a/Source/Editor/GUI/CurveEditor.cs b/Source/Editor/GUI/CurveEditor.cs
index 57f40d583..157e36434 100644
--- a/Source/Editor/GUI/CurveEditor.cs
+++ b/Source/Editor/GUI/CurveEditor.cs
@@ -611,12 +611,14 @@ namespace FlaxEditor.GUI
private bool _rightMouseDown;
internal Vector2 _leftMouseDownPos = Vector2.Minimum;
private Vector2 _rightMouseDownPos = Vector2.Minimum;
+ private Vector2 _movingViewLastPos;
internal Vector2 _mousePos = Vector2.Minimum;
- private float _mouseMoveAmount;
internal bool _isMovingSelection;
internal bool _isMovingTangent;
+ internal bool _movedKeyframes;
private TangentPoint _movingTangent;
- private Vector2 _movingSelectionViewPos;
+ private Vector2 _movingSelectionStart;
+ private Vector2[] _movingSelectionOffsets;
private Vector2 _cmShowPos;
///
@@ -669,14 +671,13 @@ namespace FlaxEditor.GUI
if (_rightMouseDown)
{
// Calculate delta
- Vector2 delta = location - _rightMouseDownPos;
+ Vector2 delta = location - _movingViewLastPos;
delta *= GetUseModeMask(_editor.EnablePanning);
if (delta.LengthSquared > 0.01f)
{
// Move view
- _mouseMoveAmount += delta.Length;
_editor.ViewOffset += delta * _editor.ViewScale;
- _rightMouseDownPos = location;
+ _movingViewLastPos = location;
Cursor = CursorType.SizeAll;
}
@@ -685,99 +686,82 @@ namespace FlaxEditor.GUI
// Moving selection
else if (_isMovingSelection)
{
- // Calculate delta (apply view offset)
- Vector2 viewDelta = _editor.ViewOffset - _movingSelectionViewPos;
- _movingSelectionViewPos = _editor.ViewOffset;
var viewRect = _editor._mainPanel.GetClientArea();
- var delta = location - _leftMouseDownPos - viewDelta;
- _mouseMoveAmount += delta.Length;
- if (delta.LengthSquared > 0.01f)
+ var locationKeyframes = PointToKeyframes(location, ref viewRect);
+ var accessor = _editor.Accessor;
+ var components = accessor.GetCurveComponents();
+ for (var i = 0; i < _editor._points.Count; i++)
{
- // Move selected keyframes
- var keyframeDelta = PointToKeyframes(location, ref viewRect) - PointToKeyframes(_leftMouseDownPos - viewDelta, ref viewRect);
- var accessor = _editor.Accessor;
- var components = accessor.GetCurveComponents();
- for (var i = 0; i < _editor._points.Count; i++)
+ var p = _editor._points[i];
+ if (p.IsSelected)
{
- var p = _editor._points[i];
- if (p.IsSelected)
+ var k = _editor.GetKeyframe(p.Index);
+ float time = _editor.GetKeyframeTime(k);
+ float value = _editor.GetKeyframeValue(k, p.Component);
+
+ float minTime = p.Index != 0 ? _editor.GetKeyframeTime(_editor.GetKeyframe(p.Index - 1)) + Mathf.Epsilon : float.MinValue;
+ float maxTime = p.Index != _editor.KeyframesCount - 1 ? _editor.GetKeyframeTime(_editor.GetKeyframe(p.Index + 1)) - Mathf.Epsilon : float.MaxValue;
+
+ var offset = _movingSelectionOffsets[i];
+
+ if (!_editor.ShowCollapsed)
{
- var k = _editor.GetKeyframe(p.Index);
- float time = _editor.GetKeyframeTime(k);
- float value = _editor.GetKeyframeValue(k, p.Component);
-
- float minTime = p.Index != 0 ? _editor.GetKeyframeTime(_editor.GetKeyframe(p.Index - 1)) + Mathf.Epsilon : float.MinValue;
- float maxTime = p.Index != _editor.KeyframesCount - 1 ? _editor.GetKeyframeTime(_editor.GetKeyframe(p.Index + 1)) - Mathf.Epsilon : float.MaxValue;
-
- if (!_editor.ShowCollapsed)
- {
- // Move on value axis
- value += keyframeDelta.Y;
- }
-
- // Let the first selected point of this keyframe to edit time
- bool isFirstSelected = false;
- for (var j = 0; j < components; j++)
- {
- var idx = p.Index * components + j;
- if (idx == i)
- {
- isFirstSelected = true;
- break;
- }
- if (_editor._points[idx].IsSelected)
- break;
- }
- if (isFirstSelected)
- {
- time += keyframeDelta.X;
-
- if (_editor.FPS.HasValue)
- {
- float fps = _editor.FPS.Value;
- time = Mathf.Floor(time * fps) / fps;
- }
-
- time = Mathf.Clamp(time, minTime, maxTime);
- }
-
- // TODO: snapping keyframes to grid when moving
-
- _editor.SetKeyframeInternal(p.Index, time, value, p.Component);
+ // Move on value axis
+ value = locationKeyframes.Y + offset.Y;
}
+
+ // Let the first selected point of this keyframe to edit time
+ bool isFirstSelected = false;
+ for (var j = 0; j < components; j++)
+ {
+ var idx = p.Index * components + j;
+ if (idx == i)
+ {
+ isFirstSelected = true;
+ break;
+ }
+ if (_editor._points[idx].IsSelected)
+ break;
+ }
+ if (isFirstSelected)
+ {
+ time = locationKeyframes.X + offset.X;
+
+ if (_editor.FPS.HasValue)
+ {
+ float fps = _editor.FPS.Value;
+ time = Mathf.Floor(time * fps) / fps;
+ }
+ time = Mathf.Clamp(time, minTime, maxTime);
+ }
+
+ // TODO: snapping keyframes to grid when moving
+
+ _editor.SetKeyframeInternal(p.Index, time, value, p.Component);
}
_editor.UpdateKeyframes();
_editor.UpdateTooltips();
if (_editor.EnablePanning == UseMode.On)
{
- _editor._mainPanel.ScrollViewTo(PointToParent(location));
+ //_editor._mainPanel.ScrollViewTo(PointToParent(_editor._mainPanel, location));
}
- _leftMouseDownPos = location;
Cursor = CursorType.SizeAll;
+ _movedKeyframes = true;
}
-
return;
}
// Moving tangent
else if (_isMovingTangent)
{
- // Calculate delta (apply view offset)
- Vector2 viewDelta = _editor.ViewOffset - _movingSelectionViewPos;
- _movingSelectionViewPos = _editor.ViewOffset;
var viewRect = _editor._mainPanel.GetClientArea();
- var delta = location - _leftMouseDownPos - viewDelta;
- _mouseMoveAmount += delta.Length;
- if (delta.LengthSquared > 0.01f)
- {
- // Move selected tangent
- var keyframeDelta = PointToKeyframes(location, ref viewRect) - PointToKeyframes(_leftMouseDownPos - viewDelta, ref viewRect);
- var direction = _movingTangent.IsIn ? -1.0f : 1.0f;
- _movingTangent.TangentValue += direction * keyframeDelta.Y;
- _editor.UpdateTangents();
- _leftMouseDownPos = location;
- Cursor = CursorType.SizeNS;
- }
-
+ var direction = _movingTangent.IsIn ? -1.0f : 1.0f;
+ var k = _editor.GetKeyframe(_movingTangent.Index);
+ var kv = _editor.GetKeyframeValue(k);
+ var value = _editor.Accessor.GetCurveValue(ref kv, _movingTangent.Component);
+ _movingTangent.TangentValue = direction * (PointToKeyframes(location, ref viewRect).Y - value);
+ _editor.UpdateTangents();
+ Cursor = CursorType.SizeNS;
+ _movedKeyframes = true;
return;
}
// Selecting
@@ -835,6 +819,7 @@ namespace FlaxEditor.GUI
{
_rightMouseDown = true;
_rightMouseDownPos = location;
+ _movingViewLastPos = location;
}
// Check if any node is under the mouse
@@ -861,11 +846,17 @@ namespace FlaxEditor.GUI
// Start moving selected nodes
StartMouseCapture();
- _mouseMoveAmount = 0;
_isMovingSelection = true;
- _movingSelectionViewPos = _editor.ViewOffset;
+ _movedKeyframes = false;
+ var viewRect = _editor._mainPanel.GetClientArea();
+ _movingSelectionStart = PointToKeyframes(location, ref viewRect);
+ if (_movingSelectionOffsets == null || _movingSelectionOffsets.Length != _editor._points.Count)
+ _movingSelectionOffsets = new Vector2[_editor._points.Count];
+ for (int i = 0; i < _movingSelectionOffsets.Length; i++)
+ _movingSelectionOffsets[i] = _editor._points[i].TimeValue - _movingSelectionStart;
_editor.OnEditingStart();
Focus();
+ Tooltip?.Hide();
return true;
}
}
@@ -875,12 +866,12 @@ namespace FlaxEditor.GUI
{
// Start moving tangent
StartMouseCapture();
- _mouseMoveAmount = 0;
_isMovingTangent = true;
+ _movedKeyframes = false;
_movingTangent = tangent;
- _movingSelectionViewPos = _editor.ViewOffset;
_editor.OnEditingStart();
Focus();
+ Tooltip?.Hide();
return true;
}
}
@@ -922,16 +913,17 @@ namespace FlaxEditor.GUI
// Editing tangent
if (_isMovingTangent)
{
- if (_mouseMoveAmount > 3.0f)
+ if (_movedKeyframes)
{
_editor.OnEdited();
_editor.OnEditingEnd();
+ _editor.UpdateKeyframes();
}
}
// Moving keyframes
else if (_isMovingSelection)
{
- if (_mouseMoveAmount > 3.0f)
+ if (_movedKeyframes)
{
_editor.OnEdited();
_editor.OnEditingEnd();
@@ -945,6 +937,7 @@ namespace FlaxEditor.GUI
_isMovingSelection = false;
_isMovingTangent = false;
+ _movedKeyframes = false;
}
if (_rightMouseDown && button == MouseButton.Right)
{
@@ -953,7 +946,7 @@ namespace FlaxEditor.GUI
Cursor = CursorType.Default;
// Check if no move has been made at all
- if (_mouseMoveAmount < 3.0f)
+ if (Vector2.Distance(ref location, ref _rightMouseDownPos) < 3.0f)
{
var selectionCount = _editor.SelectionCount;
var underMouse = GetChildAt(location);
@@ -993,7 +986,6 @@ namespace FlaxEditor.GUI
_editor.OnShowContextMenu(cm, selectionCount);
cm.Show(this, location);
}
- _mouseMoveAmount = 0;
}
if (base.OnMouseUp(location, button))
@@ -1073,6 +1065,20 @@ namespace FlaxEditor.GUI
///
public bool IsSelected;
+ ///
+ /// Gets the point time and value on a curve.
+ ///
+ public Vector2 TimeValue
+ {
+ get
+ {
+ var k = Editor.GetKeyframe(Index);
+ var time = Editor.GetKeyframeTime(k);
+ var value = Editor.GetKeyframeValue(k);
+ return new Vector2(time, Editor.Accessor.GetCurveValue(ref value, Component));
+ }
+ }
+
///
public override void Draw()
{
@@ -2878,7 +2884,8 @@ namespace FlaxEditor.GUI
bounds.Height = Mathf.Max(bounds.Height, 1.0f);
bounds.Location = ApplyUseModeMask(EnablePanning, bounds.Location, _contents.Location);
bounds.Size = ApplyUseModeMask(EnablePanning, bounds.Size, _contents.Size);
- _contents.Bounds = bounds;
+ if (!_contents._isMovingSelection)
+ _contents.Bounds = bounds;
}
else if (_contents.Bounds == Rectangle.Empty)
{
diff --git a/Source/Editor/GUI/Timeline/GUI/KeyframesEditor.cs b/Source/Editor/GUI/Timeline/GUI/KeyframesEditor.cs
index 783480c09..919d76f6b 100644
--- a/Source/Editor/GUI/Timeline/GUI/KeyframesEditor.cs
+++ b/Source/Editor/GUI/Timeline/GUI/KeyframesEditor.cs
@@ -72,9 +72,11 @@ namespace FlaxEditor.GUI
internal Vector2 _leftMouseDownPos = Vector2.Minimum;
private Vector2 _rightMouseDownPos = Vector2.Minimum;
internal Vector2 _mousePos = Vector2.Minimum;
- private float _mouseMoveAmount;
+ private Vector2 _movingViewLastPos;
internal bool _isMovingSelection;
- private Vector2 _movingSelectionViewPos;
+ internal bool _movedKeyframes;
+ private float _movingSelectionStart;
+ private float[] _movingSelectionOffsets;
private Vector2 _cmShowPos;
///
@@ -125,13 +127,12 @@ namespace FlaxEditor.GUI
if (_rightMouseDown)
{
// Calculate delta
- Vector2 delta = location - _rightMouseDownPos;
+ Vector2 delta = location - _movingViewLastPos;
if (delta.LengthSquared > 0.01f && _editor.EnablePanning)
{
// Move view
- _mouseMoveAmount += delta.Length;
_editor.ViewOffset += delta * _editor.ViewScale;
- _rightMouseDownPos = location;
+ _movingViewLastPos = location;
Cursor = CursorType.SizeAll;
}
@@ -140,44 +141,38 @@ namespace FlaxEditor.GUI
// Moving selection
else if (_isMovingSelection)
{
- // Calculate delta (apply view offset)
- Vector2 viewDelta = _editor.ViewOffset - _movingSelectionViewPos;
- _movingSelectionViewPos = _editor.ViewOffset;
var viewRect = _editor._mainPanel.GetClientArea();
- var delta = location - _leftMouseDownPos - viewDelta;
- _mouseMoveAmount += delta.Length;
- if (delta.LengthSquared > 0.01f)
+ var locationKeyframes = PointToKeyframes(location, ref viewRect);
+ for (var i = 0; i < _editor._points.Count; i++)
{
- // Move selected keyframes
- var keyframeDelta = PointToKeyframes(location, ref viewRect) - PointToKeyframes(_leftMouseDownPos - viewDelta, ref viewRect);
- for (var i = 0; i < _editor._points.Count; i++)
+ var p = _editor._points[i];
+ if (p.IsSelected)
{
- var p = _editor._points[i];
- if (p.IsSelected)
+ var k = _editor._keyframes[p.Index];
+
+ float minTime = p.Index != 0 ? _editor._keyframes[p.Index - 1].Time : float.MinValue;
+ float maxTime = p.Index != _editor._keyframes.Count - 1 ? _editor._keyframes[p.Index + 1].Time : float.MaxValue;
+
+ var offset = _movingSelectionOffsets[p.Index];
+ k.Time = locationKeyframes.X + offset;
+ if (_editor.FPS.HasValue)
{
- var k = _editor._keyframes[p.Index];
-
- float minTime = p.Index != 0 ? _editor._keyframes[p.Index - 1].Time : float.MinValue;
- float maxTime = p.Index != _editor._keyframes.Count - 1 ? _editor._keyframes[p.Index + 1].Time : float.MaxValue;
-
- k.Time += keyframeDelta.X;
- if (_editor.FPS.HasValue)
- {
- float fps = _editor.FPS.Value;
- k.Time = Mathf.Floor(k.Time * fps) / fps;
- }
- k.Time = Mathf.Clamp(k.Time, minTime, maxTime);
-
- // TODO: snapping keyframes to grid when moving
-
- _editor._keyframes[p.Index] = k;
+ float fps = _editor.FPS.Value;
+ k.Time = Mathf.Floor(k.Time * fps) / fps;
}
+ k.Time = Mathf.Clamp(k.Time, minTime, maxTime);
+
+ // TODO: snapping keyframes to grid when moving
+
+ _editor._keyframes[p.Index] = k;
}
_editor.UpdateKeyframes();
if (_editor.EnablePanning)
- _editor._mainPanel.ScrollViewTo(PointToParent(location));
- _leftMouseDownPos = location;
+ {
+ //_editor._mainPanel.ScrollViewTo(PointToParent(_editor._mainPanel, location));
+ }
Cursor = CursorType.SizeAll;
+ _movedKeyframes = true;
}
return;
@@ -234,6 +229,7 @@ namespace FlaxEditor.GUI
{
_rightMouseDown = true;
_rightMouseDownPos = location;
+ _movingViewLastPos = location;
}
// Check if any node is under the mouse
@@ -258,11 +254,17 @@ namespace FlaxEditor.GUI
// Start moving selected nodes
StartMouseCapture();
- _mouseMoveAmount = 0;
_isMovingSelection = true;
- _movingSelectionViewPos = _editor.ViewOffset;
+ _movedKeyframes = false;
+ var viewRect = _editor._mainPanel.GetClientArea();
+ _movingSelectionStart = PointToKeyframes(location, ref viewRect).X;
+ if (_movingSelectionOffsets == null || _movingSelectionOffsets.Length != _editor._keyframes.Count)
+ _movingSelectionOffsets = new float[_editor._keyframes.Count];
+ for (int i = 0; i < _movingSelectionOffsets.Length; i++)
+ _movingSelectionOffsets[i] = _editor._keyframes[i].Time - _movingSelectionStart;
_editor.OnEditingStart();
Focus();
+ Tooltip?.Hide();
return true;
}
}
@@ -303,10 +305,11 @@ namespace FlaxEditor.GUI
// Moving keyframes
if (_isMovingSelection)
{
- if (_mouseMoveAmount > 3.0f)
+ if (_movedKeyframes)
{
_editor.OnEdited();
_editor.OnEditingEnd();
+ _editor.UpdateKeyframes();
}
}
// Selecting
@@ -316,6 +319,7 @@ namespace FlaxEditor.GUI
}
_isMovingSelection = false;
+ _movedKeyframes = false;
}
if (_rightMouseDown && button == MouseButton.Right)
{
@@ -324,7 +328,7 @@ namespace FlaxEditor.GUI
Cursor = CursorType.Default;
// Check if no move has been made at all
- if (_mouseMoveAmount < 3.0f)
+ if (Vector2.Distance(ref location, ref _rightMouseDownPos) < 3.0f)
{
var selectionCount = _editor.SelectionCount;
var underMouse = GetChildAt(location);
@@ -362,7 +366,6 @@ namespace FlaxEditor.GUI
}
cm.Show(this, location);
}
- _mouseMoveAmount = 0;
}
if (base.OnMouseUp(location, button))
@@ -1045,8 +1048,10 @@ namespace FlaxEditor.GUI
}
// Adjust contents bounds to fill the keyframes area
- if (EnablePanning)
+ if (EnablePanning && !_contents._isMovingSelection)
+ {
_contents.Bounds = bounds;
+ }
// Offset the keyframes (parent container changed its location)
var posOffset = _contents.Location;