Eto - Side by side gridviews

Hey there,

Has anyone ever tried side-by-side grid views in the dynamic layout - nested within a collapsible view?

Gridview 1 contains:

  • Row 1: list box (100x400px)
  • Row 2: text

Gridview 2 contains:

  • Row 1: small image,
  • Rows 2,4,6,8: spacers
  • Rows 3,5,7,9: text with a textbox (Updates from event handler from option selected in list box)

A normal grid view doesn’t work - due to the length of the listbox. So I’ve built it with the list box then text & textboxes below this (within a collapsible view) - but ideally it would be perfect side by side - whether that is possible? Has somebody tried this before?

I’ve seen TableLayout and PixelLayout - but the later creates issues on Mac (from digging this forum) - whether they are better alternatives?

If I can’t it’ll be switching the listbox to a dropdown - but would prefer not too!

Thanks!

Hi @Dan_Cornick,

This shouldn’t be a problem.

Make the contents of expander 2 a TableLayout. Then add a row that contains a GridView and another TableLayout. The second table layout will contain 5 rows with you image view, etc.

– Dale

Thanks @dale

Do you have a python example of the TableLayout - specifically the add rows part? I’ve dug around but only seem to find the C# code via the google/Rhino guides: TableLayout · picoe/Eto Wiki · GitHub

I’ve got the GridView working, just I can’t get it into the TableLayout!

Thanks
Dan

Just to add - @dale

Extract of the code. I’m sure I’ve got the layout.Add part right? It’s asking me to define tablelayout size?

    layout = forms.TableLayout()
    layout.AutoSized()
    
    GridviewA = forms.DynamicLayout()
    GridviewA.Spacing = drawing.Size(5, 5)
    GridviewA.AddRow(self.m_label, self.m_textbox)
    GridviewA.AddRow(None) # spacer
    GridviewA.AddRow(None) # spacer
    layout.Add(GridviewA,0,0)
    
    GridviewB = forms.DynamicLayout()
    GridviewB.Spacing = drawing.Size(5, 5)
    GridviewB.AddRow(self.m_label2, self.m_textbox2)
    GridviewB.AddRow(self.m_label3, self.m_textbox3)
    GridviewB.AddRow(self.m_label4, self.m_textbox4)
    GridviewB.AddRow(None) # spacer
    GridviewB.AddRow(self.DefaultButton, self.AbortButton)
    layout.Add(GridviewB,1,1)
    
    self.Content = layout

Thanks
Dan

Hi @Dan_Cornick,

This isn’t exacly what you asked for. But it might help.

TestDan.py (1.9 KB)

– Dale

Hey @dale

So I’ve taken your code and messed around with it - to get into the format I’m after. And switched the treeview for a listbox, and the database for a collection.

But the event handler on the ok button click, doesn’t seem to work now? Since switching from a gridview to tablelayout…I’ve played around with the ‘return’ but still doesn’t seem to like it! Just trying to return the selected index, (which eventually recalls from a csv file).

Any ideas?

#Imports
import System
from System.Collections.ObjectModel import ObservableCollection
import Rhino
import Rhino.UI
import Eto.Drawing as drawing
from Eto.Drawing import Size, Font, FontStyle
import Eto.Forms as forms
import scriptcontext as sc

####### Element Class #######

class Element(object):

# Initializer
def __init__(self, name):
    self.m_name = name

@property
def Name(self):
    return self.m_name

####### TableViewListBox Class #######

class ElementSelector(forms.Dialog[bool]):

#Initializer
def __init__(self, collection):
    self.m_collection = collection
    
    #Initialize Dialog Box Properties
    self.Title = 'Element Selector'
    self.Padding = drawing.Padding(10) #10px padding to all sides
    self.Resizable = False
    self.Size = drawing.Size(550,525) #Width x Length px
    
    table1 = self.CreateTable1()    #FirstRowLeftHandTable
    table10 = self.CreateTable10()  #Ok/Close Buttons
    
    layout = Rhino.UI.Controls.RhinoDialogTableLayout(False)
    layout.Rows.Add(forms.TableRow(table1))
    layout.Rows.Add(forms.TableRow(table10))
    
    self.Content = layout
    
# Delegate function to retrieve the name of a Beam object
def ElementDelegate(self, element):
    return element.Name
    
def CreateGrid(self):
    #grid
    grid = self.CreateListBox()
    return grid
    
   # Creates a ListBox control
def CreateListBox(self):
    # Create labels
    listbox = forms.ListBox()
    listbox.Size = drawing.Size(150, 300)
    listbox.ItemTextBinding = forms.Binding.Delegate[Element, System.String](self.ElementDelegate)
    listbox.DataStore = self.m_collection
    listbox.SelectedIndex = 0
    self.m_listbox = listbox
    return self.m_listbox
    
def CreateTable1(self): #Textbox
    grid = self.CreateGrid()
    grid_cell = forms.TableCell(grid,True)
    grid_row = forms.TableRow(grid_cell)
    grid_row.ScaleHeight = True
    
    table1 = forms.TableLayout()
    table1.Spacing = drawing.Size(0,5)
    table1.Rows.Add(grid_row)
    return table1
    
def OnOkButtonClick(self, sender, e):
    self.m_selected_index = self.m_listbox.SelectedIndex
    self.Close(True)

# Cancel button click handler
def OnCancelButtonClick(self, sender, e):
    self.Close(False)
    
####### Table 10 #######
def CreateTable10(self): #Ok/Cancel
    
    # Create the default button
    self.DefaultButton = forms.Button(Text = 'OK')
    self.m_selected_index = self.m_listbox.SelectedIndex
    self.DefaultButton.Click += self.OnOkButtonClick
    
    # Create the abort button
    self.AbortButton = forms.Button(Text = 'Cancel')
    self.AbortButton.Click += self.OnCancelButtonClick
    
    # Create button layout
    grid = self.CreateGrid()
    grid_cell = forms.TableCell(grid,True)
    grid_row = forms.TableRow(grid_cell)
    grid_row.ScaleHeight = True
    
    table10 = forms.TableLayout()
    table10.Spacing = drawing.Size(0,10)
    table10.Rows.Add(None) #Spacer
    table10.Rows.Add(self.DefaultButton)
    table10.Rows.Add(self.AbortButton)
    return table10
    
# Returns the selected index
@property
def SelectedIndex(self):
    return self.m_selected_index

################################################################################
def SectionDialogTest():
# Create and initialize collection
collection = ObservableCollectionElement future ref: Revise collection for each new section shape
collection.Add(Element(‘Row1’))
collection.Add(Element(‘Row2’))
collection.Add(Element(‘Row3’))
collection.Add(Element(‘Row4’))
collection.Add(Element(‘Row5’))
collection.Add(Element(‘Row6’))

# Create and display dialog - then generate geometry, layers etc for element
dialog = ElementSelector(collection)
rc = dialog.ShowModal(Rhino.UI.RhinoEtoApp.MainWindow)
if (rc):
    # Print results
    Elementindex = (dialog.SelectedIndex) #Use +1 to get correct row in CSV file
    print Elementindex

if name == “main”:
SectionDialogTest()

Thanks
Dan

@dale

Actually I’ve just solved it! I moved the CreateListBox into Table 1, with a return for SelectedIndex - which now works nicely! :smiley:

Funny how the next thing I try then works… :man_facepalming:

1 Like