Keyboard event handle in RhinoCommon

Currently dealing with an interactive tool , but quite stuck with windows.form.keys. Which should be a small part but I am not known to the associated class, methods and delegates. in RhinoCommon for keyboard event… no example so far online and it is hard to locate the right classes and methods. Only one Python code found and I am not able to convert it, because it does not show classes and methods of RhinoCommon…

I mean keyboard events from Rhino side. I need to implement “enter” press after some draw operation interactively, but I should not get out of the command, by that enter pressing. So I know, I will need System.Windows.Forms.Keys.Enter, from Windows side. But I am not aware of associated Rhino class just for this event handle.

But unfortunately I could not find related event args for keyboard in c# dot net RhinoCommon.
. I do not want to use windows form buttons in the process… I want to do it un-interrupted without any windows form buttons hence, want to know how you would write those few lines to call KeyboardCallBackEvent Args? I know these name KeyboardCallBackEvent Args does not exist in Rhino common, I wrote it comparing mouseCallBackEventArgs
in short my question is, how you would relate System.Windows.Forms.Keys.Enter to event args for keyboard inside RhinoCommon.
Only sample found by Steve as below written in Python, again he used form button, I do not want to use for keyboard event handle. A small sample or few lines of code to deal with keyboard event will be a big help. Many thanks !
:

import Rhino
import System.Drawing
import System.Windows.Forms
import scriptcontext

class Form1(System.Windows.Forms.Form):
    def __init__(self):
        self.InitializeComponent()
    def InitializeComponent(self):
        self.SuspendLayout()
        self.ClientSize = System.Drawing.Size(250, 102)
        self.Controls.Add(self._button)
        self.KeyPreview = True
        seljf.Text = "Press J or K"
        self.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow
        self.KeyDown += self.OnKeyDownEvent
        self.Closing += self.OnClosingEvent
        self.ResumeLayout(False)



    def OnKeyDownEvent(self, sender, e):
        left = e.KeyCode == System.Windows.Forms.Keys.J
        right = e.KeyCode == System.Windows.Forms.Keys.K
        if left or right:
            amount = 0.1
            if right: amount = -0.1
            viewport = scriptcontext.doc.Views.ActiveView.MainViewport
            z = viewport.ConstructionPlane().ZAxis
            viewport.Rotate(amount, z, Rhino.Geometry.Point3d.Origin)
            scriptcontext.doc.Views.Redraw()
        finish = e.KeyCode == System.Windows.Forms.Keys.Escape
        finish = finish or e.KeyCode == System.Windows.Forms.Keys.Enter
        if finish:
            self.Close()
        e.Handled = True
    def OnClosingEvent(self, sender, e):
        Rhino.Input.Custom.GetBaseClass.PostCustomMessage("exit")

f = Form1()
f.Show(Rhino.RhinoApp.MainWindow())
gs = Rhino.Input.Custom.GetString()
gs.SetCommandPrompt("press escape to exit")
gs.AcceptCustomMessage(True)
gs.Get()
if not f.IsDisposed:
    f.Close()

If you need to prompt the user for string input on the Rhino command line, you can use the Rhino.Input.RhinoGet.GetString static function. If you need to get fancier, you can use the Rhino.Input.Custom.GetString class.

Here is a simple example using the static function approach.

protected override Result RunCommand(RhinoDoc doc, RunMode mode)
{
  Random random = new Random();

  Result res = Result.Success;
  while (res == Result.Success)
  {
    Rhino.Geometry.Point3d center = new Point3d(
      RandomDouble(random, -20.0, 20.0),
      RandomDouble(random, -20.0, 20.0),
      0.0
      );

    double radius = RandomDouble(random, 1.0, 10.0);

    Rhino.Geometry.Circle circle = new Circle(center, radius);

    doc.Objects.AddCircle(circle);
    doc.Views.Redraw();

    string str = null;
    res = Rhino.Input.RhinoGet.GetString("Press <Enter> to continue, <Esc> to cancel", true, ref str);
    if (res == Result.Nothing)
      res = Result.Success;
  }
     
  return Result.Success;
}

public double RandomDouble(Random random, double minimum, double maximum)
{
  return random.NextDouble() * (maximum - minimum) + minimum;
}

Is this what you want?

Hi Dale,
Thanks for the response.
No , I want event handling of keyboard in proper way, the way we handle mouse button click.
I saw this example. I gave a sample python example, where keyboard event handling is managed. But I could not find the associated c# dot net class and methods for it.
Please have a look at the python code above.
Best regards
Tahmina

1 Like

We cannot use user prompt at all. We must have to do it as interactive manner, and uninterrupted, as we do handle mouse button events.
how to write this python lines in C# dot net…Python does not explain what is the class/member name…This is why I could not locate it in RhinoCommon Library. I could not find associated class in C#
So I need a method for keyboard event handle something like below…
def OnKeyDownEvent(self, sender, e):
e.KeyCode == System.Windows.Forms.Keys.J
e.KeyCode == System.Windows.Forms.Keys.K

e.KeyCode == System.Windows.Forms.Keys.Enter

for mouse we have…Rhino.UI.MouseCallbackEventArgs

but for Keyboard I was looking for something inside rhino. But looks like , it does not exist. Please correct me if I am wrong.
I have Windows.Forms.KeyEventArgs e, but it is from windows.form.

My finding…
… So far nothing in Rhino for keyboard event handle, like Rhino.UI.MouseCallbackEventArgs e… I will need to use System.Windows.Forms.KeyEventArgs. to event handling for keyboard within rhino.
So it need to be handled via Windows.form
If I am wrong , then just correct me please. if there is something within Rhino for keyboard event handle then please let me know. I did posted some reply to you in the forum.
I am only confused, if I am missing out Rhino bit of event handling for keyboard, as long , we already have mouse event handling within Rhino.UI.

I still have not heard why (you think you) need some kind of keyboard API. Is there something you are trying to do that is no like Rhino does? Perhaps you can describe for me what kind of keyboard input you are looking of and why?

Rhino does not provide any special keyboard API. If you are looking for keyboard input while in a plug-in command, use one of the Rhino input static functions or class (like I mentioned earlier). If you are looking to handle keyboard input while in a Windows Form, then .NET handles all this for you.

Like I mentioned, Rhino does not provide any special keyboard API. All native Rhino commands just use the Rhino “Get” functions and classes. So if there is something you are looking to do differently than other Rhino command, please explain.

"If you are looking to handle keyboard input while in a Windows Form, then .NET handles all this for you."
as you said above, all I needed to ensure from you is this line. I was confused, if there is anything inside Rhino for keyboard event handling. My confusion is gone now , completely So I have to handle keyboard event from windows and .Net Handles. Many thanks !
Tah

Hi Dale ,OK, Lets forget about keyboard event now.I wanted to implement mouse event as below. But the code is showing unexpected behavior. It is sometimes drawing the poly line in Rhino interface and sometimes it is not drawing any poly line.
What I exactly need to do…as marked below.Draw polyline until press right mouse button press and then wait for a left mouse button to be pressed , to start drawing poly line again.After pressing right mouse button, the command should not end , it should wait for a left mouse button click, to start the while loop again, I mean getpoint() and draw polyline again…

Date: Thu, 17 Apr 2014 15:41:59 +0000
From: steve@mcneel.com
To: code_lab@live.com
Subject: [McNeel Forum] Keyboard event handle in RhinoCommon

    dale

April 17

I still have not heard why (you think you) need some kind of keyboard API. Is there something you are trying to do that is no like Rhino does? Perhaps you can describe for me what kind of keyboard input you are looking of and why?

Rhino does not provide any special keyboard API. If you are looking for keyboard input while in a plug-in command, use one of the Rhino input static functions or class (like I mentioned earlier). If you are looking to handle keyboard input while in a Windows Form, then .NET handles all this for you.

Like I mentioned, Rhino does not provide any special keyboard API. All native Rhino commands just use the Rhino “Get” functions and classes. So if there is something you are looking to do differently than other Rhino command, please explain.

To respond, reply to this email or visit http://discourse.mcneel.com/t/keyboard-event-handle-in-rhinocommon/7578/7 in your browser.

To draw polyline, we use getpoint() and draw the polyline until press “Enter” button in key board… which I am trying to do now with right mouse button click, but that will not work as digitizer accept enter button press, to end the polyline. and then by left mouse button click, start again getpoint() for another polyline and end it again by Enter button press in key board. the whole process should be interactive and as a loop, until pressing a double enter press in keyboard. All points should be stored in an array from beginning of first polyline to last polyline.Hope I could explain now , why I need to press keyboard event.
I tried with only mouse event as in the last code I have send you, but it is showing unexpected behavior.Best regardsTahmina

To draw polyline, we use getpoint() and draw the polyline until press “Enter” button in key board… which I am trying to do now with right mouse button click, but that will not work as digitizer accept enter button press, to end the polyline. and then by left mouse button click, start again getpoint() for another polyline and end it again by Enter button press in key board. the whole process should be interactive and as a loop, until pressing a double enter press in keyboard. All points should be stored in an array from beginning of first polyline to last polyline.
Hope I could explain now , why I need to press keyboard event.

I tried with only mouse event as in the last code I have send you, but it is showing unexpected behavior.

OK… I could do keyboard event handling from Windows form. It is completely working fine with Rhino Common. Just could not implement multiple event inside one button scenario, but looks like I have found other solution.
it is something like this below: for keyboard event handling it is all about Windows form and nothing to do with Rhino common, as you mentioned

public void OnKeyDownEvent(object sender,
System.Windows.Forms.KeyEventArgs e)
{

        if (e.KeyCode == System.Windows.Forms.Keys.Enter)
        {
             RhinoApp.WriteLine("Tah is entered");
            
            done = true;
        }
        e.Handled = true;

    }

this need to be in windows Form class.
and it is important to put in …

public Form1()
{
InitializeComponent();
this.KeyPreview = true;
this.KeyDown +=
new KeyEventHandler(OnKeyDownEvent);
}

In Form1.Designer.cs…
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnKeyDownEvent);

1 Like

I believe it is now possible within RhinoCommon. See this:

Create an event handler like this,

public void OnKeyboardEvent(int key)
{
RhinoApp.WriteLine("Char: " + key);
}

and then register the handler like this,

RhinoApp.KeyboardEvent += OnKeyboardEvent;

It worked for me.

1 Like