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);