Can Eto dialog scroll?

I’ve set my dialog Resizable to True but not sure how to implement this Scrollable class.
Anyone has an example? I’d like to have the ability for user to resize the dialog but the user should be able to scroll when dialog window is too small.

See if this helps. I added a basic scrollable panel to the Room Number dialog example.

All you really need to do is create your scrollable and apply any padding to it that you want. Next set it to your dialog’s content, then place your existing content into the scrollables content.

# Imports
import Rhino
import scriptcontext
import System
import Rhino.UI
import Eto.Drawing as drawing
import Eto.Forms as forms

# SampleEtoRoomNumber dialog class
class SampleEtoRoomNumberDialog(forms.Dialog[bool]):

    # Dialog box Class initializer
    def __init__(self):
        # Initialize dialog box
        self.Title = 'Sample Eto: Room Number'
        self.Padding = drawing.Padding(10)
        self.Resizable = True

        # Create controls for the dialog
        self.m_label = forms.Label(Text = 'Enter the Room Number:')
        self.m_textbox = forms.TextBox(Text = None)

        # Create the default button
        self.DefaultButton = forms.Button(Text = 'OK')
        self.DefaultButton.Click += self.OnOKButtonClick

        # Create the abort button
        self.AbortButton = forms.Button(Text = 'Cancel')
        self.AbortButton.Click += self.OnCloseButtonClick

        # Create the scollable container
        scrollable = forms.Scrollable()
        scrollable.Padding = drawing.Padding(10)
        # Create a table layout and add all the controls
        layout = forms.DynamicLayout()
        layout.Spacing = drawing.Size(5, 5)
        layout.AddRow(self.m_label, self.m_textbox)
        layout.AddRow(None) # spacer
        layout.AddRow(self.DefaultButton, self.AbortButton)
        # Add content to the scrollable container
        scrollable.Content = layout

        # Set the scrollable to the dialog content
        self.Content = scrollable

    # Start of the class functions

    # Get the value of the textbox
    def GetText(self):
        return self.m_textbox.Text

    # Close button click handler
    def OnCloseButtonClick(self, sender, e):
        self.m_textbox.Text = ""
        self.Close(False)

    # OK button click handler
    def OnOKButtonClick(self, sender, e):
        if self.m_textbox.Text == "":
            self.Close(False)
        else:
            self.Close(True)

    ## End of Dialog Class ##

# The script that will be using the dialog.
def RequestRoomNumber():
    dialog = SampleEtoRoomNumberDialog();
    rc = dialog.ShowModal(Rhino.UI.RhinoEtoApp.MainWindow)
    if (rc):
        print dialog.GetText() #Print the Room Number from the dialog control

##########################################################################
# Check to see if this file is being executed as the "main" python
# script instead of being used as a module by some other python script
# This allows us to use the module which ever way we want.
if __name__ == "__main__":
    RequestRoomNumber()
1 Like

This is great! I think I’m starting to understand the Panel class and its children classes a little better. This is essentially adding contents to the Scrollable which gets added to the Dialog

On the topic of Eto, do you happen to know how to communicate with Rhino doc while the dialog is open? I noticed that if I launch a Dialog from GhPython, things like scriptcontext.doc.Objects.AddBrep() won’t actually add the object until the dialog is closed. Does this have to do with the ShowModal()?

This page should give better clarity as to what is happening. See question 3

There’s a slight difference in ghPython to improve the performance by avoiding things like undo recording, redraws, meshing and so on.

If you want to force your modal dialog to update the Rhino document from your script component you could use RhinoCommon to update it instead.

Using
Rhino.RhinoDoc.ActiveDoc.Objects.AddBrep()
Rhino.RhinoDoc.ActiveDoc.Views.Redraw()
in place of ghPythons
scriptconext.doc.Objects.AddBrep()

this should work for your purposes.

I see. I realize what I need isn’t really a Dialog, which is the only example I can find on the McNeel documentation pages. Would you recommend an alternative to Dialog? One where the user can interact with Rhino views? Must I move to Windows.Forms?

Rhino.UI.Forms.CommandDialog supports a ShowSemiModal which allows for interactions with Rhino while the dialog is visible.

Thanks for the help. Really clarifies some things for me.
However…
image
image

Also I couldn’t find documentation on CommandDialog() or even Rhino.UI.Forms

This is where it gets a little tricky as there is a Rhino.UI.dll that adds OS platform specific extensions to RhinoCommons Rhino.UI namespace. These should get loaded by the Python engine for you. Something like this should do the trick for you.

import Rhino
import Eto

def ShowCommandDialog():
    cmd = Rhino.UI.Forms.CommandDialog()
    cmd.Content = Eto.Forms.Label(Text = "Hello World")
    res = Rhino.UI.EtoExtensions.ShowSemiModal(cmd,Rhino.RhinoDoc.ActiveDoc,Rhino.UI.RhinoEtoApp.MainWindow)
    print(res)

if __name__ == "__main__":
    ShowCommandDialog()
2 Likes