Add timeline view panning with right mouse button

This commit is contained in:
Wojtek Figat
2021-08-10 13:29:12 +02:00
parent e4bd5c7251
commit 94b4c20b35
2 changed files with 132 additions and 34 deletions

View File

@@ -0,0 +1,95 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
using FlaxEngine;
using FlaxEngine.GUI;
namespace FlaxEditor.GUI.Timeline.GUI
{
/// <summary>
/// The timeline background area control.
/// </summary>
class BackgroundArea : Panel
{
private Timeline _timeline;
internal bool _rightMouseButtonDown;
private Vector2 _rightMouseButtonLastPos;
private float _rightMouseButtonMovement;
public BackgroundArea(Timeline timeline)
: base(ScrollBars.Both)
{
_timeline = timeline;
}
/// <inheritdoc />
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;
}
/// <inheritdoc />
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);
}
/// <inheritdoc />
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);
}
}
}

View File

@@ -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);
}
/// <inheritdoc />
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);