diff --git a/Source/Editor/GUI/Timeline/GUI/BackgroundArea.cs b/Source/Editor/GUI/Timeline/GUI/BackgroundArea.cs
new file mode 100644
index 000000000..a62fb5023
--- /dev/null
+++ b/Source/Editor/GUI/Timeline/GUI/BackgroundArea.cs
@@ -0,0 +1,95 @@
+// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
+
+using FlaxEngine;
+using FlaxEngine.GUI;
+
+namespace FlaxEditor.GUI.Timeline.GUI
+{
+ ///
+ /// The timeline background area control.
+ ///
+ class BackgroundArea : Panel
+ {
+ private Timeline _timeline;
+ internal bool _rightMouseButtonDown;
+ private Vector2 _rightMouseButtonLastPos;
+ private float _rightMouseButtonMovement;
+
+ public BackgroundArea(Timeline timeline)
+ : base(ScrollBars.Both)
+ {
+ _timeline = timeline;
+ }
+
+ ///
+ public override bool OnMouseDown(Vector2 location, MouseButton button)
+ {
+ if (base.OnMouseDown(location, button))
+ return true;
+
+ if (button == MouseButton.Right)
+ {
+ _rightMouseButtonDown = true;
+ _rightMouseButtonLastPos = location;
+ _rightMouseButtonMovement = 0;
+ Focus();
+ StartMouseCapture();
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ public override void OnMouseMove(Vector2 location)
+ {
+ // Panning timeline view with a right-mouse button
+ if (_rightMouseButtonDown)
+ {
+ var movePos = location + ViewOffset;
+ var delta = _rightMouseButtonLastPos - movePos;
+ _rightMouseButtonLastPos = movePos;
+ _rightMouseButtonMovement += delta.Length;
+
+ var hScroll = HScrollBar.Visible && HScrollBar.Enabled;
+ var vScroll = VScrollBar.Visible && VScrollBar.Enabled;
+ if (vScroll && hScroll)
+ Cursor = CursorType.SizeAll;
+ else if (vScroll)
+ Cursor = CursorType.SizeNS;
+ else if (hScroll)
+ Cursor = CursorType.SizeWE;
+
+ bool wasLocked = IsLayoutLocked;
+ IsLayoutLocked = true;
+ if (hScroll)
+ HScrollBar.TargetValue += delta.X;
+ if (vScroll)
+ VScrollBar.TargetValue += delta.Y;
+ IsLayoutLocked = wasLocked;
+ PerformLayout();
+ return;
+ }
+
+ base.OnMouseMove(location);
+ }
+
+ ///
+ public override bool OnMouseUp(Vector2 location, MouseButton button)
+ {
+ if (button == MouseButton.Right && _rightMouseButtonDown)
+ {
+ EndMouseCapture();
+ _rightMouseButtonDown = false;
+ Cursor = CursorType.Default;
+ if (_rightMouseButtonMovement < 1.0f)
+ {
+ _timeline.ShowContextMenu(PointToParent(_timeline, location));
+ }
+ return true;
+ }
+
+ return base.OnMouseUp(location, button);
+ }
+ }
+}
diff --git a/Source/Editor/GUI/Timeline/Timeline.cs b/Source/Editor/GUI/Timeline/Timeline.cs
index 3e3b303f4..5f7dbb912 100644
--- a/Source/Editor/GUI/Timeline/Timeline.cs
+++ b/Source/Editor/GUI/Timeline/Timeline.cs
@@ -288,7 +288,7 @@ namespace FlaxEditor.GUI.Timeline
private TimeIntervalsHeader _timeIntervalsHeader;
private ContainerControl _backgroundScroll;
private Background _background;
- private Panel _backgroundArea;
+ private BackgroundArea _backgroundArea;
private TimelineEdge _leftEdge;
private TimelineEdge _rightEdge;
private Button _addTrackButton;
@@ -305,6 +305,7 @@ namespace FlaxEditor.GUI.Timeline
private PositionHandle _positionHandle;
private bool _isRightMouseButtonDown;
private Vector2 _rightMouseButtonDownPos;
+ private Vector2 _rightMouseButtonMovePos;
private float _zoom = 1.0f;
private bool _isMovingPositionHandle;
private bool _canPlayPauseStop = true;
@@ -912,7 +913,7 @@ namespace FlaxEditor.GUI.Timeline
Offsets = new Margin(0, 0, 0, HeaderTopAreaHeight),
Parent = _splitter.Panel2
};
- _backgroundArea = new Panel(ScrollBars.Both)
+ _backgroundArea = new BackgroundArea(this)
{
AutoFocus = false,
ClipChildren = false,
@@ -1954,6 +1955,38 @@ namespace FlaxEditor.GUI.Timeline
}
}
+ internal void ShowContextMenu(Vector2 location)
+ {
+ if (!ContainsFocus)
+ Focus();
+
+ var controlUnderMouse = GetChildAtRecursive(location);
+ var mediaUnderMouse = controlUnderMouse;
+ while (mediaUnderMouse != null && !(mediaUnderMouse is Media))
+ {
+ mediaUnderMouse = mediaUnderMouse.Parent;
+ }
+
+ var menu = new ContextMenu.ContextMenu();
+ if (mediaUnderMouse is Media media)
+ {
+ media.OnTimelineShowContextMenu(menu, controlUnderMouse);
+ if (media.PropertiesEditObject != null)
+ {
+ menu.AddButton("Edit media", () => ShowEditPopup(media.PropertiesEditObject, ref location, media.Track));
+ }
+ }
+ if (PropertiesEditObject != null)
+ {
+ menu.AddButton("Edit timeline", () => ShowEditPopup(PropertiesEditObject, ref location, this));
+ }
+ menu.AddSeparator();
+ menu.AddButton("Reset zoom", () => Zoom = 1.0f);
+ menu.AddButton("Show whole timeline", ShowWholeTimeline);
+ OnShowContextMenu(menu);
+ menu.Show(this, location);
+ }
+
///
protected override void PerformLayoutBeforeChildren()
{
@@ -1986,8 +2019,8 @@ namespace FlaxEditor.GUI.Timeline
{
_isRightMouseButtonDown = true;
_rightMouseButtonDownPos = location;
+ _rightMouseButtonMovePos = location;
Focus();
-
return true;
}
@@ -2006,38 +2039,8 @@ namespace FlaxEditor.GUI.Timeline
if (button == MouseButton.Right && _isRightMouseButtonDown)
{
_isRightMouseButtonDown = false;
-
if (Vector2.Distance(ref location, ref _rightMouseButtonDownPos) < 4.0f)
- {
- if (!ContainsFocus)
- Focus();
-
- var controlUnderMouse = GetChildAtRecursive(location);
- var mediaUnderMouse = controlUnderMouse;
- while (mediaUnderMouse != null && !(mediaUnderMouse is Media))
- {
- mediaUnderMouse = mediaUnderMouse.Parent;
- }
-
- var menu = new ContextMenu.ContextMenu();
- if (mediaUnderMouse is Media media)
- {
- media.OnTimelineShowContextMenu(menu, controlUnderMouse);
- if (media.PropertiesEditObject != null)
- {
- menu.AddButton("Edit media", () => ShowEditPopup(media.PropertiesEditObject, ref location, media.Track));
- }
- }
- if (PropertiesEditObject != null)
- {
- menu.AddButton("Edit timeline", () => ShowEditPopup(PropertiesEditObject, ref location, this));
- }
- menu.AddSeparator();
- menu.AddButton("Reset zoom", () => Zoom = 1.0f);
- menu.AddButton("Show whole timeline", ShowWholeTimeline);
- OnShowContextMenu(menu);
- menu.Show(this, location);
- }
+ ShowContextMenu(location);
}
return base.OnMouseUp(location, button);