@@ -48,9 +48,23 @@ def run_gui(devices):
4848 root .title ("LED Matrix Control" )
4949 root .geometry ("400x900" )
5050
51+
52+ # Scrollbar
53+ main_container = ttk .Frame (root )
54+ main_container .pack (fill = "both" , expand = True )
55+ canvas = tk .Canvas (main_container , bg = "#2b2b2b" )
56+ scrollbar = ttk .Scrollbar (main_container , orient = "vertical" , command = canvas .yview )
57+ content_frame = ttk .Frame (canvas , style = "Content.TFrame" )
58+ canvas .configure (yscrollcommand = scrollbar .set )
59+ scrollbar .pack (side = "right" , fill = "y" )
60+ canvas .pack (side = "left" , fill = "both" , expand = True )
61+ canvas_frame = canvas .create_window ((0 , 0 ), window = content_frame , anchor = "nw" )
62+
63+
5164 # Configure dark theme
5265 style = ttk .Style ()
5366 root .configure (bg = "#2b2b2b" )
67+ style .configure ("Content.TFrame" , background = "#2b2b2b" )
5468 style .configure ("TLabelframe" , background = "#2b2b2b" , foreground = "white" )
5569 style .configure ("TLabelframe.Label" , background = "#2b2b2b" , foreground = "white" )
5670 style .configure ("TCheckbutton" , background = "#2b2b2b" , foreground = "white" )
@@ -65,7 +79,7 @@ def run_gui(devices):
6579 style .map ("TButton" , background = [("active" , "gray" ), ("!active" , "#2b2b2b" )])
6680
6781 # Device Checkboxes
68- detected_devices_frame = ttk .LabelFrame (root , text = "Detected Devices" , style = "TLabelframe" )
82+ detected_devices_frame = ttk .LabelFrame (content_frame , text = "Detected Devices" , style = "TLabelframe" )
6983 detected_devices_frame .pack (fill = "x" , padx = 10 , pady = 5 )
7084
7185 global device_checkboxes
@@ -81,7 +95,7 @@ def run_gui(devices):
8195 device_checkboxes [dev .name ] = checkbox_var
8296
8397 # Device Control Buttons
84- device_control_frame = ttk .LabelFrame (root , text = "Device Control" , style = "TLabelframe" )
98+ device_control_frame = ttk .LabelFrame (content_frame , text = "Device Control" , style = "TLabelframe" )
8599 device_control_frame .pack (fill = "x" , padx = 10 , pady = 5 )
86100 control_buttons = {
87101 "Bootloader" : "bootloader" ,
@@ -92,15 +106,15 @@ def run_gui(devices):
92106 ttk .Button (device_control_frame , text = text , command = lambda a = action : perform_action (devices , a ), style = "TButton" ).pack (side = "left" , padx = 5 , pady = 5 )
93107
94108 # Brightness Slider
95- brightness_frame = ttk .LabelFrame (root , text = "Brightness" , style = "TLabelframe" )
109+ brightness_frame = ttk .LabelFrame (content_frame , text = "Brightness" , style = "TLabelframe" )
96110 brightness_frame .pack (fill = "x" , padx = 10 , pady = 5 )
97111 global brightness_scale
98112 brightness_scale = tk .Scale (brightness_frame , from_ = 0 , to = 255 , orient = 'horizontal' , command = lambda value : set_brightness (devices , value ), bg = "#2b2b2b" , fg = "white" , troughcolor = "gray" , highlightbackground = "#2b2b2b" )
99113 brightness_scale .set (120 ) # Default value
100114 brightness_scale .pack (fill = "x" , padx = 5 , pady = 5 )
101115
102116 # Animation Control
103- animation_frame = ttk .LabelFrame (root , text = "Animation" , style = "TLabelframe" )
117+ animation_frame = ttk .LabelFrame (content_frame , text = "Animation" , style = "TLabelframe" )
104118 animation_frame .pack (fill = "x" , padx = 10 , pady = 5 )
105119 animation_buttons = {
106120 "Start Animation" : "start_animation" ,
@@ -110,20 +124,20 @@ def run_gui(devices):
110124 ttk .Button (animation_frame , text = text , command = lambda a = action : perform_action (devices , a ), style = "TButton" ).pack (side = "left" , padx = 5 , pady = 5 )
111125
112126 # Pattern Combo Box
113- pattern_frame = ttk .LabelFrame (root , text = "Pattern" , style = "TLabelframe" )
127+ pattern_frame = ttk .LabelFrame (content_frame , text = "Pattern" , style = "TLabelframe" )
114128 pattern_frame .pack (fill = "x" , padx = 10 , pady = 5 )
115129 pattern_combo = ttk .Combobox (pattern_frame , values = PATTERNS , style = "TCombobox" )
116130 pattern_combo .pack (fill = "x" , padx = 5 , pady = 5 )
117131 pattern_combo .bind ("<<ComboboxSelected>>" , lambda event : set_pattern (devices , pattern_combo .get ()))
118132
119133 # Percentage Slider
120- percentage_frame = ttk .LabelFrame (root , text = "Fill screen X% (could be volume indicator)" , style = "TLabelframe" )
134+ percentage_frame = ttk .LabelFrame (content_frame , text = "Fill screen X% (could be volume indicator)" , style = "TLabelframe" )
121135 percentage_frame .pack (fill = "x" , padx = 10 , pady = 5 )
122136 percentage_scale = tk .Scale (percentage_frame , from_ = 0 , to = 100 , orient = 'horizontal' , command = lambda value : set_percentage (devices , value ), bg = "#2b2b2b" , fg = "white" , troughcolor = "gray" , highlightbackground = "#2b2b2b" )
123137 percentage_scale .pack (fill = "x" , padx = 5 , pady = 5 )
124138
125139 # Countdown Timer
126- countdown_frame = ttk .LabelFrame (root , text = "Countdown Timer" , style = "TLabelframe" )
140+ countdown_frame = ttk .LabelFrame (content_frame , text = "Countdown Timer" , style = "TLabelframe" )
127141 countdown_frame .pack (fill = "x" , padx = 10 , pady = 5 )
128142 countdown_spinbox = tk .Spinbox (countdown_frame , from_ = 1 , to = 60 , width = 5 , bg = "#2b2b2b" , fg = "white" , textvariable = tk .StringVar (value = 10 ))
129143 countdown_spinbox .pack (side = "left" , padx = 5 , pady = 5 )
@@ -132,42 +146,60 @@ def run_gui(devices):
132146 ttk .Button (countdown_frame , text = "Stop" , command = stop_thread , style = "TButton" ).pack (side = "left" , padx = 5 , pady = 5 )
133147
134148 # Black & White and Greyscale Images in same row
135- image_frame = ttk .LabelFrame (root , text = "Black&White Images / Greyscale Images" , style = "TLabelframe" )
149+ image_frame = ttk .LabelFrame (content_frame , text = "Black&White Images / Greyscale Images" , style = "TLabelframe" )
136150 image_frame .pack (fill = "x" , padx = 10 , pady = 5 )
137151 ttk .Button (image_frame , text = "Send stripe.gif" , command = lambda : send_image (devices , "stripe.gif" , image_bl ), style = "TButton" ).pack (side = "left" , padx = 5 , pady = 5 )
138152 ttk .Button (image_frame , text = "Send greyscale.gif" , command = lambda : send_image (devices , "greyscale.gif" , image_greyscale ), style = "TButton" ).pack (side = "left" , padx = 5 , pady = 5 )
139153
140154 # Display Current Time
141- time_frame = ttk .LabelFrame (root , text = "Display Current Time" , style = "TLabelframe" )
155+ time_frame = ttk .LabelFrame (content_frame , text = "Display Current Time" , style = "TLabelframe" )
142156 time_frame .pack (fill = "x" , padx = 10 , pady = 5 )
143157 ttk .Button (time_frame , text = "Start" , command = lambda : perform_action (devices , "start_time" ), style = "TButton" ).pack (side = "left" , padx = 5 , pady = 5 )
144158 ttk .Button (time_frame , text = "Stop" , command = stop_thread , style = "TButton" ).pack (side = "left" , padx = 5 , pady = 5 )
145159
146160 # Custom Text
147- custom_text_frame = ttk .LabelFrame (root , text = "Custom Text" , style = "TLabelframe" )
161+ custom_text_frame = ttk .LabelFrame (content_frame , text = "Custom Text" , style = "TLabelframe" )
148162 custom_text_frame .pack (fill = "x" , padx = 10 , pady = 5 )
149163 custom_text_entry = ttk .Entry (custom_text_frame , width = 20 , style = "TEntry" )
150164 custom_text_entry .pack (side = "left" , padx = 5 , pady = 5 )
151165 ttk .Button (custom_text_frame , text = "Show" , command = lambda : show_custom_text (devices , custom_text_entry .get ()), style = "TButton" ).pack (side = "left" , padx = 5 , pady = 5 )
152166
153167 # Display Text with Symbols
154- symbols_frame = ttk .LabelFrame (root , text = "Display Text with Symbols" , style = "TLabelframe" )
168+ symbols_frame = ttk .LabelFrame (content_frame , text = "Display Text with Symbols" , style = "TLabelframe" )
155169 symbols_frame .pack (fill = "x" , padx = 10 , pady = 5 )
156170 ttk .Button (symbols_frame , text = "Send '2 5 degC thunder'" , command = lambda : send_symbols (devices ), style = "TButton" ).pack (side = "left" , padx = 5 , pady = 5 )
157171
158172 # PWM Frequency Combo Box
159- pwm_freq_frame = ttk .LabelFrame (root , text = "PWM Frequency" , style = "TLabelframe" )
173+ pwm_freq_frame = ttk .LabelFrame (content_frame , text = "PWM Frequency" , style = "TLabelframe" )
160174 pwm_freq_frame .pack (fill = "x" , padx = 10 , pady = 5 )
161175 pwm_freq_combo = ttk .Combobox (pwm_freq_frame , values = PWM_FREQUENCIES , style = "TCombobox" )
162176 pwm_freq_combo .pack (fill = "x" , padx = 5 , pady = 5 )
163177 pwm_freq_combo .bind ("<<ComboboxSelected>>" , lambda : set_pwm_freq (devices , pwm_freq_combo .get ()))
164178
165179 # Equalizer
166- equalizer_frame = ttk .LabelFrame (root , text = "Equalizer" , style = "TLabelframe" )
180+ equalizer_frame = ttk .LabelFrame (content_frame , text = "Equalizer" , style = "TLabelframe" )
167181 equalizer_frame .pack (fill = "x" , padx = 10 , pady = 5 )
168182 ttk .Button (equalizer_frame , text = "Start random equalizer" , command = lambda : perform_action (devices , "start_eq" ), style = "TButton" ).pack (side = "left" , padx = 5 , pady = 5 )
169183 ttk .Button (equalizer_frame , text = "Stop" , command = stop_thread , style = "TButton" ).pack (side = "left" , padx = 5 , pady = 5 )
170184
185+ # Update scroll region when frame size changes
186+ def configure_scroll_region (event ):
187+ canvas .configure (scrollregion = canvas .bbox ("all" ))
188+
189+ content_frame .bind ("<Configure>" , configure_scroll_region )
190+
191+ # Bind mouse wheel to scroll
192+ def on_mousewheel (event ):
193+ canvas .yview_scroll (int (- 1 * (event .delta / 120 )), "units" )
194+
195+ canvas .bind_all ("<MouseWheel>" , on_mousewheel )
196+
197+ # Make canvas expand with window
198+ def on_canvas_configure (event ):
199+ canvas .itemconfig (canvas_frame , width = event .width )
200+
201+ canvas .bind ("<Configure>" , on_canvas_configure )
202+
171203 root .mainloop ()
172204
173205def perform_action (devices , action ):
0 commit comments