Hi all,
I’m struggling with Eto layouts. I made a little tool that lets you search for blocks based on the block name (seems like this will be a Rhino 8 feature…). Like the below:
I want to make the form resizable with the listbox changing size and all the other elements remaining a fixed size. Currently, when the form is resized, the ok button streches and the listbox remains the same size.
If I remove the OK button and have the listbox as the last piece of content in the layout, then the listbox resizes correctly.
How can I keep the OK button but have the listbox resize instead?
Thanks in advance
#&description& Zoom and select to a choosen block
# Imports
from Rhino.UI import *
import Eto.Drawing as drawing
import Eto.Forms as forms
# https://developer.rhino3d.com/guides/rhinopython/eto-controls-python/
import Rhino
import rhinoscriptsyntax as rs
class BlockDefDialog(forms.Dialog[bool]):
# Dialog box Class initializer
def __init__(self, blockNames):
# Initialize dialog box
self.Title = 'Block Searcher'
self.Padding = drawing.Padding(10)
self.Resizable = True
self.u_blockNames = blockNames
self.m_checkbox = forms.CheckBox(Text = "Zoom Select ALL Block Instances")
self.m_checkbox.CheckedChanged += self.OnValueChange
self.m_infolabel_1 = forms.Label(Text="Click on a block name to zoom select it. Does not include locked or hidden blocks.")
self.m_infolabel_2 = forms.Label(Text="Filter the block names by typing below.")
self.m_textbox = forms.TextBox()
self.m_searchResultLabel = forms.Label(Text="")
self.m_listbox = forms.ListBox()
self.m_listbox.DataStore = self.u_blockNames
self.m_listbox.Height = 300
self.m_listbox.Width = 600
self.m_listbox.SelectedValueChanged += self.OnValueChange
# Create the search button
self.SearchButton = forms.Button(Text = 'Filter')
self.SearchButton.Click += self.OnSearchButtonClick
# Create the default button
self.DefaultButton = forms.Button(Text = 'OK')
self.DefaultButton.Click += self.OnOKButtonClick
self.DefaultButton.Height = 20
self.DefaultButton.Width = 100
# Create the abort button
self.AbortButton = forms.Button(Text = 'Cancel')
self.AbortButton.Click += self.OnCloseButtonClick
# Create a table layout and add all the controls
layout = forms.DynamicLayout()
layout.Spacing = drawing.Size(5, 5)
layout.BeginVertical()
layout.AddRow(self.m_infolabel_1)
layout.AddRow(None, "")
layout.AddRow(self.m_checkbox)
layout.AddRow(None, "")
layout.AddRow(self.m_infolabel_2)
layout.AddRow(self.m_textbox, self.SearchButton)
layout.AddRow(self.m_searchResultLabel)
layout.EndVertical()
layout.BeginVertical()
layout.AddRow(self.m_listbox)
layout.EndVertical()
layout.BeginVertical()
layout.AddRow(None)
layout.AddRow(None, self.DefaultButton)
layout.EndVertical()
# Set the dialog content
self.Content = layout
# Start of the class functions
def OnValueChange(self, sender, e):
bn = self.m_listbox.SelectedValue
if bn:
#print self.m_checkbox.Checked
zoomSelBlockName(bn, self.m_checkbox.Checked)
def OnSearchButtonClick(self, sender, e):
searchText = self.m_textbox.Text.lower()
passed_search = []
for n in self.u_blockNames:
if searchText in n.lower():
passed_search.append(n)
self.m_searchResultLabel.Text = str(len(passed_search)) + " block defintions match your filter."
self.m_listbox.DataStore = passed_search
return passed_search
# Close button click handler
def OnCloseButtonClick(self, sender, e):
self.Close(False)
# OK button click handler
def OnOKButtonClick(self, sender, e):
self.Close(True)
def GetBlockName(self):
return self.m_listbox.SelectedValue
def searchBlockDefs(blocknames):
dialog = BlockDefDialog(blocknames);
rc = dialog.ShowModal(Rhino.UI.RhinoEtoApp.MainWindow)
if (rc):
#print rc
res = dialog.GetBlockName()
return res
def zoomSelBlockName(bn, boolSelAll):
rs.EnableRedraw(False)
rs.UnselectAllObjects()
if bn:
rs.Command('-SelBlockInstanceNamed "' + bn+'"', echo=False)
# for single selection
if not boolSelAll:
sel = rs.SelectedObjects()[0]
rs.UnselectAllObjects()
rs.SelectObject(sel)
rs.Command("ZoomSelected", echo=False)
rs.EnableRedraw(True)
if __name__ == "__main__":
# dont get any nested blocks, only top level blocks
rs.EnableRedraw(False)
rs.Command("SelAll", echo=False)
sel_objs = rs.SelectedObjects()
rs.UnselectObjects(sel_objs)
rs.EnableRedraw(True)
block_names = []
# Sort blocks and other objects
for obj in sel_objs:
#print obj
if rs.IsBlockInstance(obj):
bName = rs.BlockInstanceName(obj)
if bName not in block_names:
block_names.append(bName)
block_names.sort()
blockName = searchBlockDefs(block_names)