Three Eto questions

Hi @curtisw,

three quick questions about Eto.

  1. Is there a way to fill a path with a circular gradient brush? If no, can you add that to the Graphics class?
  2. Is there a way to assign a Brush to a Pen? If no, can you add that? What I need basically is to have a pen with varying levels of transparency.
  3. How do I keep a modeless Eto.Forms.Form on top of the Rhino window?

Hey David,

  1. There’s no radial gradient in Eto yet, but I’ll add that to my todo list. This shouldn’t be too difficult to add.
  2. There’s no way to do that yet, and I’m unsure if this would be available on all platforms. I’ll check into the options here.
  3. Use Eto.Forms.Dialog - it has a Rhino-Specific ShowSemiModal() extension which will allow the user to interact with the main Rhino window while keeping it on top.

Hope this helps!

I can’t find ShowSemiModal anywhere, though if it’s an extension method I’m probably just not looking in the right places.

Instead of supporting brushes as pen fills, perhaps a way to convert a path+pen into an outline path? I think this is called ‘widening’ in GDI+.

ShowSemiModal is in Rhino.UI.EtoExtensions, so just add “using Rhino.UI;” at the top of your source file and you should see it.

Thanks for the idea of converting to an outline path! I’ll investigate that as well.

I didn’t realise I also had to reference Rhino.UI.dll in addition to RhinoCommon and Eto, my bad. The extension method shows up now, but I don’t understand it. It’s defined for Dialog of type T, but I don’t need to have a return value, my window is just supposed to sit there on top of Rhino potentially forever. The window is also not tied to any specific RhinoDoc instance.

I turned my class into a Dialog of type bool so I can use the extension method, but now while it’s up it’s blocking the command line and not allowing any viewport selections.

I think I misunderstood what you were looking to do. The ShowSemiModal extension written by John Morse mirrors previous functionality for dialogs that require the ability for the user to do only specific things with the main window.

Perhaps what you’re looking for is the Form’s TopMost property, which will keep the window above all others (though this also means it will be above non-rhino windows).

You could also potentially use the LostFocus event and BringToFront() to always keep it on top.

Just curious, what API in winforms did you use to do this previously?

In winforms when you use Form.Show, you can specify a parent form. The form then becomes a child of that parent, i.e. always being on top of it, minimizing along with it.

Wouldn’t this work as a panel (that you have to register with Rhino) that you can dock or have float? You won’t be a dialog, but you can have in your panel your canvas as you need…

This is commonly referred to as a modeless dialog.


I am currently messing with the extension method for making the window semiModal with the Eto, and I am running into an issue where Rhino instantly crashes.

I am wondering if there is something I am missing with making it transfer to the active rhino doc, or if there are any other methods of getting the Eto dialog to work with the ShowSemiModal()

It is currently invoking when the user presses a button that is inside of the dialog; once the button is pressed, that is when the program decides to crash. The extension is set to the selectButton_Click def in the screen capture below. Any help or advice would be greatly appreciated, thanks in advance.



Hi @Colby_Evans,

Looking at your code, it appears like you are attempting to use ShowSemiModal() after the dialog is shown. Instead, you need to replace the dialog.ShowModalAsync(..) line at the bottom with ShowSemiModal. Note that ShowSemiModal() is a blocking call (it will not return until the dialog is closed), vs ShowModalAsync which is not.

When semi-modal, a Dialog will allow interaction with the main rhino window.

Hope this helps!


Thank you for the response; it helps me to understand that I need to be making the call to the extension before the dialog is shown, but I don’t think I understand how to attached the extension method to the Eto Dialog.

This is what I get when I try to use the Rhino.UI.EtoExtensions.ShowSemiModal(): (even if I try to make it so doc is set to Rhino.RhinoDoc.ActiveDoc) It gives me the two arguments error.

This is what I get when I try to use the extension on the dialog, similar to the dialog.ShowModal()

Thank you again for the help.

Hi @Colby_Evans,

Sorry for the late response! I totally missed your reply.

The reason for this is the ShowSemiModal expects a generic version of Dialog for its first parameter, not just Dialog. Second, it actually expects three parameters even though the error specifies it requires two: Dialog[T], RhinoDoc, Window

I got it to work using the following script:

import Eto.Forms
import Rhino.UI

class MyCustomDialog(Eto.Forms.Dialog[bool]):
    def __init__(self):
        self.Content = Eto.Forms.Label(Text="Woodle")

dlg = MyCustomDialog()

Rhino.UI.EtoExtensions.ShowSemiModal(dlg, Rhino.RhinoDoc.ActiveDoc, Rhino.UI.RhinoEtoApp.MainWindow)

I hope this helps!

BTW, creating a new post on discourse for any further issues would be greatly appreciated as we have tools to make sure they are responded to and resolved.

1 Like


No worries, I actually figured out the method a few days after this post; from looking at what was missing from the arguments needed, seeing that it was looking for the active doc. In the future I will make sure to make another post. Thank you for the response, and the help.

Colby Evans