Related to Clickable.ProcessMoveEvent and MouseMoveEvent
I think code explains it easier
protected override void ProcessMoveEvent(EventBase evt, Vector2 localPosition)
{
base.ProcessMoveEvent(evt, localPosition);
if (evt is MouseMoveEvent moveEvent)
{
// BUG: this currently always returns 0 so can't differentiate between left/right buttons
// BUG: middle mouse button never triggers ProcessMoveEvent either
var button = moveEvent.button;
That’s interesting, because Clickable.clickedWithEventInfo definitely fires on right click as I’ve been using it to pop up options menus on a editor window
this.clickedWithEventInfo += evt =>
{
if (evt is MouseUpEvent mouseEvent)
{
switch (mouseEvent.button)
{
case 0:
this.ClickedLeft?.Invoke();
break;
case 1:
this.ClickedRight?.Invoke();
break;
}
}
};
As for using MouseManipulator, I think I tried that originally but ran into an issue with something being internal, however this was a while ago and I have a better understanding of how things work now. If this is not the intended behavior of clickable I’ll definitely go have a look and try to re-implement it from that.
Background: I implemented this because I wanted to add some drag support while stopping clicks from triggering. Full code here:
/// <summary> Extended Clickable manipulator that provides dragging support. </summary>
public class Draggable : Clickable
{
private readonly long clickGrace;
private IVisualElementScheduledItem gracePeriodRepeater;
private bool hasDragged;
private bool allowClick;
private int mouseButtonDown;
/// <summary> Initializes a new instance of the <see cref="Draggable"/> class. </summary>
/// <param name="clickGrace"> The grace period for clicking to avoid tiny movements stopping clicks. </param>
/// <param name="delay"> <see cref="Clickable.m_Delay"/>. </param>
/// <param name="interval"> <see cref="Clickable.m_Interval"/>.</param>
public Draggable(long clickGrace = 200L, long delay = 250L, long interval = 30L)
: base(null, delay, interval)
{
this.clickGrace = clickGrace;
this.activators.Add(new ManipulatorActivationFilter { button = MouseButton.RightMouse });
this.clickedWithEventInfo += evt =>
{
if (evt is MouseUpEvent mouseEvent)
{
switch (mouseEvent.button)
{
case 0:
this.ClickedLeft?.Invoke();
break;
case 1:
this.ClickedRight?.Invoke();
break;
}
}
};
}
/// <summary> Any mouse button is dragging. </summary>
public event Action Dragging;
/// <summary> Left mouse button dragging. </summary>
public event Action DraggingLeft;
/// <summary> Right mouse button dragging. </summary>
public event Action DraggingRight;
/// <summary> Left button clicked. </summary>
public event Action ClickedLeft;
/// <summary> Right button clicked. </summary>
public event Action ClickedRight;
/// <summary> Gets the start position of the drag. </summary>
[SuppressMessage("ReSharper", "SA1300", Justification = "Matching unity style of lastMousePosition")]
[SuppressMessage("ReSharper", "InconsistentNaming", Justification = "Matching unity style of lastMousePosition")]
public Vector2 startMousePosition { get; private set; }
/// <summary> Gets the frames delta. </summary>
public Vector2 Delta => this.lastMousePosition - this.startMousePosition;
/// <inheritdoc/>
protected override void ProcessDownEvent(EventBase evt, Vector2 localPosition, int pointerId)
{
this.hasDragged = false;
this.startMousePosition = localPosition;
base.ProcessDownEvent(evt, localPosition, pointerId);
this.mouseButtonDown = evt is MouseDownEvent moveEvent ? moveEvent.button : -1;
if (this.gracePeriodRepeater == null)
{
// Target is null in constructor so need to delay it
this.gracePeriodRepeater = this.target.schedule.Execute(() => this.allowClick = false);
}
else
{
this.gracePeriodRepeater.ExecuteLater(this.clickGrace);
}
this.allowClick = true;
}
/// <inheritdoc/>
protected override void ProcessMoveEvent(EventBase evt, Vector2 localPosition)
{
base.ProcessMoveEvent(evt, localPosition);
if (evt is MouseMoveEvent)
{
this.Dragging?.Invoke();
// moveEvent.button currently always returns 0 so can't differentiate between left/right instead stored on down
switch (this.mouseButtonDown)
{
case 0: this.DraggingLeft?.Invoke();
break;
case 1: this.DraggingRight?.Invoke();
break;
}
}
this.hasDragged = true;
}
/// <inheritdoc/>
protected override void ProcessUpEvent(EventBase evt, Vector2 localPosition, int pointerId)
{
base.ProcessUpEvent(evt, localPosition, pointerId);
this.gracePeriodRepeater.Pause();
// Because we are a repeating does not trigger
if (this.target.ContainsPoint(localPosition) && (!this.hasDragged || this.allowClick))
{
this.Invoke(evt);
}
}
}
Used in a node editor
Where you can drag around the nodes, but right click to popup menus etc.
Anyway, thanks for the advice will have a look at the example.