Hi @Ex_John,
You can’t stop the command line from seeing the keystroke — while a Get is running it owns keyboard input by design. RhinoApp.KeyboardEvent is a passive Windows hook, so the key still lands in the command line after your handler runs. There’s no mouse-wheel hook either.
The Rhino way to do what you want is to make X and Z hidden command line options. They don’t show up in the prompt, they’re activated by typing the name, and because the name is one character it’s a single key plus Enter.
GetSectionPoint gp = new GetSectionPoint(mesh);
double step = RhinoMath.ToRadians(15.0);
while (true)
{
gp.SetCommandPrompt("Section location. Type X or Z to tilt 15 degrees");
gp.ClearCommandOptions();
int x_option = gp.AddOption("X", null, true); // true == hidden
int z_option = gp.AddOption("Z", null, true);
gp.AcceptNumber(true, false); // type an angle if you like
GetResult res = gp.Get();
if (res == GetResult.Option)
{
int index = gp.OptionIndex();
if (index == x_option)
gp.TiltX += step;
else if (index == z_option)
gp.TiltZ += step;
continue; // back into the drag
}
if (res == GetResult.Number)
{
step = RhinoMath.ToRadians(gp.Number());
continue;
}
if (res != GetResult.Point)
return Result.Cancel;
break;
}
Plane section_plane = gp.SectionPlane;
Two things to know. Enter is still needed — command line options are matched by text, so there’s no way to fire one from a bare keypress. And each option ends the Get, so you re-enter it in the loop; keep the tilt on your GetPoint subclass as fields so it survives, and expect the preview to reappear on the next mouse move.
If you want truly modifier-style control with no Enter at all, use Shift and Ctrl instead — those never reach the command line. Cache them in OnMouseMove and use them in OnDynamicDraw, and turn off the built-ins that already claim them:
PermitOrthoSnap(false); // Shift
PermitElevatorMode(0); // Ctrl
PermitTabMode(false);
protected override void OnMouseMove(GetPointMouseEventArgs e)
{
bool tilt_x = e.ShiftKeyDown;
bool tilt_z = e.ControlKeyDown;
if (tilt_x || tilt_z)
{
if (!m_tilting) // modifier just went down - anchor here
{
m_tilting = true;
m_anchor = e.WindowPoint;
m_tilt_start = tilt_x ? m_tilt_x : m_tilt_z;
}
double delta = (e.WindowPoint.X - m_anchor.X) * 0.01; // radians per pixel
if (tilt_x)
m_tilt_x = m_tilt_start + delta;
else
m_tilt_z = m_tilt_start + delta;
}
else
{
m_tilting = false;
m_origin = e.Point;
}
// do the work here, not in OnDynamicDraw - this runs once per mouse
// move, OnDynamicDraw runs once per frame
m_sections = Intersection.MeshPlane(m_mesh, m_cache, SectionPlane, RhinoMath.ZeroTolerance);
base.OnMouseMove(e);
}
protected override void OnDynamicDraw(GetPointDrawEventArgs e)
{
if (null != m_sections)
{
foreach (Polyline section in m_sections)
e.Display.DrawPolyline(section, System.Drawing.Color.Yellow, 2);
}
base.OnDynamicDraw(e);
}
Note the MeshIntersectionCache overload of Intersection.MeshPlane — worth using when you re-intersect the same mesh every mouse move.
– Dale