How-to: Create a custom mouse operator requiring two buttons

Typically, standard mouse operators use a single mouse button. This article show how to setup an operator that uses two mouse buttons. Additionally, it describes creating a custom mouse operator which is triggered by two mouse buttons, if you needed other customizations.

Instructions

Let’s assume we want to use the middle mouse for selection, right mouse to orbit, the middle mouse (wheel) to zoom and both the left and right mouse buttons together to pan.

Simple Approach

Set up your operators as follows;

// Remove standard operators if they've already been set up.
view.GetOperatorControl().Pop()  // Orbit
view.GetOperatorControl().Pop()  // Pan
view.GetOperatorControl().Pop(); // Zoom
// Add the operators as described
GetCanvas().GetFrontView().GetOperatorControl()
   .Push(new HPS.ZoomOperator(HPS.MouseButtons.ButtonMiddle()))
   .Push(new HPS.PanOperator(HPS.MouseButtons.ButtonRight() + HPS.MouseButtons.ButtonLeft()), Operator.Priority.High)
   .Push(new HPS.OrbitOperator(HPS.MouseButtons.ButtonRight()))
   .Push(new HPS.HighlightOperator(HPS.MouseButtons.ButtonLeft()), HPS.Operator.Priority.Low);

Custom Mouse Operator

Here are the steps to achieve and use a custom mouse operator;

  1. In this example, we’ll customize the standard HPS::PanOperator so that both the Left and the Right mouse buttons are required to use the pan operator. Here’s the custom class;
public class MyPanOperator : HPS.PanOperator
{
    public MyPanOperator() 
        : base(HPS.MouseButtons.ButtonLeft(), new HPS.ModifierKeys())
    {}
    ~MyPanOperator(){}
    public override bool OnMouseDown(HPS.MouseState iMouseState)
    {
       return iMouseState.GetButtons().Right() && base.OnMouseDown(iMouseState);
    }
    public override bool OnMouseMove(HPS.MouseState iMouseState)
    {
        return iMouseState.GetButtons().Right() && base.OnMouseMove(iMouseState);
    }
    public override bool OnMouseUp(HPS.MouseState iMouseState)
    {
        return iMouseState.GetButtons().Right() && base.OnMouseUp(iMouseState);
    }
}
  1. Notice that the OnMouse* methods first check the state of the Right button and then use the base class to finish (and check the state of the Left button).
  2. Next we’ll set up a set of operators as follows;
view.GetOperatorControl()
    .Push(new HPS.ZoomOperator(HPS.MouseButtons.ButtonMiddle()))
    .Push(new MyPanOperator(), Operator.Priority.High)
    .Push(new HPS.OrbitOperator(HPS.MouseButtons.ButtonRight()))
    .Push(new HPS.HighlightOperator(HPS.MouseButtons.ButtonLeft()),HPS.Operator.Priority.Low);
  • Notice that since the custom pan operator requires two buttons, it needs the High priority so the other operators don’t steal the event with less restrictive requirements (i.e. only one button).