diff --git a/Source/Editor/GUI/CurveEditor.Base.cs b/Source/Editor/GUI/CurveEditor.Base.cs
index 0dc6f3b4f..7891eacb1 100644
--- a/Source/Editor/GUI/CurveEditor.Base.cs
+++ b/Source/Editor/GUI/CurveEditor.Base.cs
@@ -54,6 +54,11 @@ namespace FlaxEditor.GUI
///
public event Action EditingEnd;
+ ///
+ /// The function for custom view panning. Gets input movement delta (in curve control space) and returns the renaming input delta to process by curve editor itself.
+ ///
+ public Func CustomViewPanning;
+
///
/// The maximum amount of keyframes to use in a single curve.
///
diff --git a/Source/Editor/GUI/CurveEditor.Contents.cs b/Source/Editor/GUI/CurveEditor.Contents.cs
index 9964c0485..96b796f9f 100644
--- a/Source/Editor/GUI/CurveEditor.Contents.cs
+++ b/Source/Editor/GUI/CurveEditor.Contents.cs
@@ -78,22 +78,31 @@ namespace FlaxEditor.GUI
if (_rightMouseDown)
{
Vector2 delta = location - _movingViewLastPos;
+ if (_editor.CustomViewPanning != null)
+ delta = _editor.CustomViewPanning(delta);
delta *= GetUseModeMask(_editor.EnablePanning) * _editor.ViewScale;
if (delta.LengthSquared > 0.01f)
{
_editor._mainPanel.ViewOffset += delta;
_movingViewLastPos = location;
- switch (_editor.EnablePanning)
+ if (_editor.CustomViewPanning != null)
{
- case UseMode.Vertical:
- Cursor = CursorType.SizeNS;
- break;
- case UseMode.Horizontal:
- Cursor = CursorType.SizeWE;
- break;
- case UseMode.On:
Cursor = CursorType.SizeAll;
- break;
+ }
+ else
+ {
+ switch (_editor.EnablePanning)
+ {
+ case UseMode.Vertical:
+ Cursor = CursorType.SizeNS;
+ break;
+ case UseMode.Horizontal:
+ Cursor = CursorType.SizeWE;
+ break;
+ case UseMode.On:
+ Cursor = CursorType.SizeAll;
+ break;
+ }
}
}
diff --git a/Source/Editor/GUI/Timeline/GUI/KeyframesEditor.cs b/Source/Editor/GUI/Timeline/GUI/KeyframesEditor.cs
index 919d76f6b..6942b0fc0 100644
--- a/Source/Editor/GUI/Timeline/GUI/KeyframesEditor.cs
+++ b/Source/Editor/GUI/Timeline/GUI/KeyframesEditor.cs
@@ -128,12 +128,19 @@ namespace FlaxEditor.GUI
{
// Calculate delta
Vector2 delta = location - _movingViewLastPos;
- if (delta.LengthSquared > 0.01f && _editor.EnablePanning)
+ if (delta.LengthSquared > 0.01f)
{
- // Move view
- _editor.ViewOffset += delta * _editor.ViewScale;
- _movingViewLastPos = location;
- Cursor = CursorType.SizeAll;
+ if (_editor.CustomViewPanning != null)
+ delta = _editor.CustomViewPanning(delta);
+ if (_editor.EnablePanning)
+ {
+ // Move view
+ _editor.ViewOffset += delta * _editor.ViewScale;
+ _movingViewLastPos = location;
+ Cursor = CursorType.SizeAll;
+ }
+ else if (_editor.CustomViewPanning != null)
+ Cursor = CursorType.SizeAll;
}
return;
@@ -560,6 +567,11 @@ namespace FlaxEditor.GUI
///
public event Action EditingEnd;
+ ///
+ /// The function for custom view panning. Gets input movement delta (in keyframes editor control space) and returns the renaming input delta to process by keyframes editor itself.
+ ///
+ public Func CustomViewPanning;
+
///
/// The maximum amount of keyframes to use.
///
diff --git a/Source/Editor/GUI/Timeline/Timeline.cs b/Source/Editor/GUI/Timeline/Timeline.cs
index 258dbbe81..7ded468e7 100644
--- a/Source/Editor/GUI/Timeline/Timeline.cs
+++ b/Source/Editor/GUI/Timeline/Timeline.cs
@@ -1809,6 +1809,30 @@ namespace FlaxEditor.GUI.Timeline
{
}
+ ///
+ /// Custom event for keyframes or curve editor view panning to handle timeline background panning horizontally too.
+ ///
+ ///
+ ///
+ /// The input delta.
+ /// The result input delta.
+ public Vector2 OnKeyframesViewPanning(Vector2 delta)
+ {
+ var area = _backgroundArea;
+ var hScroll = area.HScrollBar.Visible && area.HScrollBar.Enabled;
+ if (hScroll)
+ {
+ bool wasLocked = area.IsLayoutLocked;
+ area.IsLayoutLocked = true;
+ area.HScrollBar.TargetValue -= delta.X;
+ delta.X = 0.0f;
+ area.IsLayoutLocked = wasLocked;
+ area.PerformLayout();
+ area.Cursor = CursorType.SizeWE;
+ }
+ return delta;
+ }
+
///
/// Mark timeline as edited.
///
diff --git a/Source/Editor/GUI/Timeline/Tracks/AudioTrack.cs b/Source/Editor/GUI/Timeline/Tracks/AudioTrack.cs
index 513ae30ad..74e9483e8 100644
--- a/Source/Editor/GUI/Timeline/Tracks/AudioTrack.cs
+++ b/Source/Editor/GUI/Timeline/Tracks/AudioTrack.cs
@@ -476,7 +476,10 @@ namespace FlaxEditor.GUI.Timeline.Tracks
{
if (_audioMedia == null || Curve == null || Timeline == null)
return;
-
+ Curve.Visible = Visible;
+ if (!Visible)
+ return;
+ Curve.CustomViewPanning = Timeline.OnKeyframesViewPanning;
Curve.Bounds = new Rectangle(_audioMedia.X, Y + 1.0f, _audioMedia.Width, Height - 2.0f);
var expanded = IsExpanded;
diff --git a/Source/Editor/GUI/Timeline/Tracks/CurvePropertyTrack.cs b/Source/Editor/GUI/Timeline/Tracks/CurvePropertyTrack.cs
index 6b46978e7..251a3a76e 100644
--- a/Source/Editor/GUI/Timeline/Tracks/CurvePropertyTrack.cs
+++ b/Source/Editor/GUI/Timeline/Tracks/CurvePropertyTrack.cs
@@ -69,7 +69,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
return base.OnMouseDown(location, button);
}
-
+
public override void OnMouseMove(Vector2 location)
{
base.OnMouseMove(location);
@@ -84,7 +84,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
}
}
}
-
+
public override bool OnMouseUp(Vector2 location, MouseButton button)
{
if (button == MouseButton.Left && _clicked)
@@ -228,6 +228,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
if (!Visible)
return;
var expanded = IsExpanded;
+ Curve.CustomViewPanning = Timeline.OnKeyframesViewPanning;
Curve.Bounds = new Rectangle(Timeline.StartOffset, Y + 1.0f, Timeline.Duration * Timeline.UnitsPerSecond * Timeline.Zoom, Height - 2.0f);
Curve.ViewScale = new Vector2(Timeline.Zoom, Curve.ViewScale.Y);
Curve.ShowCollapsed = !expanded;
@@ -238,7 +239,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
Curve.UpdateKeyframes();
if (expanded)
{
- if(_splitter == null)
+ if (_splitter == null)
_splitter = new Splitter
{
_track = this,
diff --git a/Source/Editor/GUI/Timeline/Tracks/EventTrack.cs b/Source/Editor/GUI/Timeline/Tracks/EventTrack.cs
index 32e81e466..255f23bb3 100644
--- a/Source/Editor/GUI/Timeline/Tracks/EventTrack.cs
+++ b/Source/Editor/GUI/Timeline/Tracks/EventTrack.cs
@@ -281,9 +281,12 @@ namespace FlaxEditor.GUI.Timeline.Tracks
private void UpdateEvents()
{
- if (Events == null)
+ if (Events == null || Timeline == null)
return;
-
+ Events.Visible = Visible;
+ if (!Visible)
+ return;
+ Events.CustomViewPanning = Timeline.OnKeyframesViewPanning;
Events.Bounds = new Rectangle(Timeline.StartOffset, Y + 1.0f, Timeline.Duration * Timeline.UnitsPerSecond * Timeline.Zoom, Height - 2.0f);
Events.ViewScale = new Vector2(Timeline.Zoom, 1.0f);
Events.Visible = Visible;
diff --git a/Source/Editor/GUI/Timeline/Tracks/KeyframesPropertyTrack.cs b/Source/Editor/GUI/Timeline/Tracks/KeyframesPropertyTrack.cs
index 03291b3d2..2c5490f62 100644
--- a/Source/Editor/GUI/Timeline/Tracks/KeyframesPropertyTrack.cs
+++ b/Source/Editor/GUI/Timeline/Tracks/KeyframesPropertyTrack.cs
@@ -248,11 +248,12 @@ namespace FlaxEditor.GUI.Timeline.Tracks
private void UpdateKeyframes()
{
- if (Keyframes == null)
+ if (Keyframes == null || Timeline == null)
return;
Keyframes.Visible = Visible;
if (!Visible)
return;
+ Keyframes.CustomViewPanning = Timeline.OnKeyframesViewPanning;
Keyframes.Bounds = new Rectangle(Timeline.StartOffset, Y + 1.0f, Timeline.Duration * Timeline.UnitsPerSecond * Timeline.Zoom, Height - 2.0f);
Keyframes.ViewScale = new Vector2(Timeline.Zoom, 1.0f);
Keyframes.UpdateKeyframes();