Hello,
I have the following code in which I am attempting to change the height of a row when that rows custom button is hovered on.
I’m successfully changing the “visual state” of the button and returning it’s index.
However, I’m struggling to simply update only this Row’s padding dynamically.
I am trying to “shift” the other buttons down vertically and when a button is no longer hovered on, they should all “tighten up” again.
Here’s the current “hover state” on a button on the form:
Here’s a crude sketch of what I am trying to achieve:
No buttons hovered:
Hover on button 01:
Hover on button 02:
Here is my code attempt thus far:
#! python3
import Rhino
import Eto.Drawing as drawing
import Eto.Forms as forms
main_layout_instance = None
current_button_index = None
button_width = 120
button_full_height = 120
button_height = button_full_height / 4
# Code for Custom Toolbar Buttons
class CustomButton(forms.Drawable):
# Initialize CustomButton Class
def __init__(self, state: bool):
super(CustomButton, self).__init__()
global main_layout_instance
self._hover = False
self.Size = drawing.Size(button_width, button_full_height)
self.Radius = 15
self._b_rect = drawing.RectangleF(0, 0, self.Bounds.Width, self.Bounds.Height / 4)
self._h_rect = drawing.RectangleF(0, 0, self.Bounds.Width, self.Bounds.Height)
self._path = drawing.GraphicsPath.GetRoundRect(self._b_rect, self.Radius)
self._h_path = drawing.GraphicsPath.GetRoundRect(self._h_rect, self.Radius)
def OnPaint(self, e):
try:
# draws the shape outline on hover
e.Graphics.FillPath(drawing.Colors.BlueViolet if self._hover else drawing.Colors.DarkGray, self._h_path if self._hover else self._path)
except Exception as ex:
Rhino.RhinoApp.WriteLine(f"Error in OnPaint: {ex}")
def OnMouseEnter(self, e):
try:
global current_button_index
current_button_index = result_buttons.index(self)
# Rhino.RhinoApp.WriteLine(f"Button[{current_button_index}] Hovered")
self._hover = True
self.Invalidate()
main_layout_instance.update_row_height(self)
except Exception as ex:
Rhino.RhinoApp.WriteLine(f"Error in OnMouseEnter: {ex}")
def OnMouseLeave(self, e):
try:
global current_button_index
current_button_index = None
self._hover = False
self.Invalidate()
except Exception as ex:
Rhino.RhinoApp.WriteLine(f"Error in OnMouseLeave: {ex}")
def OnMouseDown(self, e):
try:
pass
except Exception as ex:
Rhino.RhinoApp.WriteLine(f"Error in OnMouseDown: {ex}")
def OnMouseUp(self, e):
try:
if e.Buttons == forms.MouseButtons.Primary and self._hover:
global current_button_index
except Exception as ex:
Rhino.RhinoApp.WriteLine(f"Error in OnMouseUp: {ex}")
def OnPreLoad(self, e):
pass
test_results = ["Test Button 01", "Test Button 02", "Test Button 03", "Test Button 04"]
result_buttons = []
for result in test_results:
result_buttons.append(CustomButton(False))
class DynamicLayoutRowTest(forms.Form):
def __init__(self):
super().__init__()
self.Title = "Dynamic Row Height Test"
self.ClientSize = drawing.Size(300, 600)
# self.Padding = drawing.Padding(10)
self.Resizable = True
global main_layout_instance
main_layout_instance = self # Storing reference to DynamicLayoutRowTest instance
# Create the dynamic layout
self.dynamic_layout = forms.DynamicLayout()
self.dynamic_layout.DefaultSpacing = drawing.Size(5, 5)
self.dynamic_layout.Padding = drawing.Padding(10)
# Create and add some buttons to the layout
self.buttons = []
for result in result_buttons:
result.main_layout = self # Set the layout reference for each button
self.dynamic_layout.AddRow(result)
self.buttons.append(result)
self.Content = self.dynamic_layout
def update_row_height(self, button):
global current_button_index
Rhino.RhinoApp.WriteLine(f"Button[{current_button_index}] Hovered")
# Clear the dynamic layout and rebuild it with updated heights
self.dynamic_layout.Invalidate()
# self.dynamic_layout.Clear()
for i, btn in enumerate(result_buttons):
padding = drawing.Padding(0, button_height) if i != current_button_index else drawing.Padding(0, button_full_height) # Dynamically Change Row Height If Row Index Matches Current Button Index
self.dynamic_layout.AddRow(btn)
btn.Padding = padding
def main():
form = DynamicLayoutRowTest()
form.Owner = Rhino.UI.RhinoEtoApp.MainWindow
form.Show()
if __name__ == "__main__":
main()
Thanks for any guidance and help!