widgets: create autogrid: a custom grid that arranges itself (#1307)

This commit is contained in:
Alfredo Monclus 2024-03-20 23:14:43 -03:00 committed by GitHub
parent 4d168c2319
commit 14a02e5bcf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 77 additions and 58 deletions

View File

@ -0,0 +1,52 @@
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
class AutoGrid(Gtk.Grid):
"""
A subclass of Gtk.Grid that auto-arranges its children on init
Args:
items (list): All the widgets to be arranged.
max_columns (int: 4): The maximum number of columns, up to 4.
expand_last (bool: False): expand the last widget to double width.
vertical (bool: False): optimize for vertical orientation.
Example:
grid = Autogrid([Gtk.Button(), Gtk.Button()])
"""
def __init__(self, items=None, max_columns=None, expand_last=False, vertical=False):
super().__init__(row_homogeneous=True, column_homogeneous=True)
if not max_columns:
max_columns = 3 if vertical else 4
self.expand_last = expand_last
if not items:
return
length = len(items)
if vertical and length < 4:
# Arrange 1 x 4
columns = 1
elif length in {4, 2}:
# Arrange 2 x 2
columns = min(2, max_columns)
elif length in {3, 5, 6}:
# Arrange 3 x 2
columns = min(3, max_columns)
else:
# Arrange 4 x n
columns = min(4, max_columns)
for i, widget in enumerate(items):
col = i % columns
row = int(i / columns)
if self.expand_last and (i + 1) == length and length % 2 == 1:
self.attach(widget, col, row, 2, 1)
else:
self.attach(widget, col, row, 1, 1)
def clear(self):
for i in self.get_children():
self.remove(i)

View File

@ -6,6 +6,7 @@ gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Pango
from ks_includes.KlippyGcodes import KlippyGcodes
from ks_includes.screen_panel import ScreenPanel
from ks_includes.widgets.autogrid import AutoGrid
class Panel(ScreenPanel):
@ -54,14 +55,10 @@ class Panel(ScreenPanel):
"panel": "spoolman"
})
self.labels['extruders_menu'] = self._gtk.ScrolledWindow()
self.labels['extruders'] = Gtk.FlowBox(hexpand=True, vexpand=True, homogeneous=True,
selection_mode=Gtk.SelectionMode.NONE, max_children_per_line=4)
self.labels['extruders_menu'].add(self.labels['extruders'])
xbox = Gtk.Box(homogeneous=True)
limit = 4
i = 0
extruder_buttons = []
for extruder in self._printer.get_tools():
if self._printer.extrudercount == 1:
self.labels[extruder] = self._gtk.Button("extruder", "")
@ -75,7 +72,11 @@ class Panel(ScreenPanel):
xbox.add(self.labels[extruder])
i += 1
else:
self.labels['extruders'].add(self.labels[extruder])
extruder_buttons.append(self.labels[extruder])
if extruder_buttons:
self.labels['extruders'] = AutoGrid(extruder_buttons, vertical=self._screen.vertical_mode)
self.labels['extruders_menu'] = self._gtk.ScrolledWindow()
self.labels['extruders_menu'].add(self.labels['extruders'])
if self._printer.extrudercount > limit:
changer = self._gtk.Button("toolchanger")
changer.connect("clicked", self.load_menu, 'extruders', _('Extruders'))

View File

@ -6,6 +6,7 @@ gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
from jinja2 import Template
from ks_includes.screen_panel import ScreenPanel
from ks_includes.widgets.autogrid import AutoGrid
class Panel(ScreenPanel):
@ -15,9 +16,9 @@ class Panel(ScreenPanel):
self.items = items
self.j2_data = self._printer.get_printer_status_data()
self.create_menu_items()
self.grid = Gtk.Grid(row_homogeneous=True, column_homogeneous=True)
self.scroll = self._gtk.ScrolledWindow()
self.scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
self.autogrid = AutoGrid()
def activate(self):
self.j2_data = self._printer.get_printer_status_data()
@ -26,42 +27,21 @@ class Panel(ScreenPanel):
def add_content(self):
for child in self.scroll.get_children():
self.scroll.remove(child)
if self._screen.vertical_mode:
self.scroll.add(self.arrangeMenuItems(self.items, 3))
else:
self.scroll.add(self.arrangeMenuItems(self.items, 4))
self.scroll.add(self.arrangeMenuItems(self.items))
if not self.content.get_children():
self.content.add(self.scroll)
def arrangeMenuItems(self, items, columns, expand_last=False):
for child in self.grid.get_children():
self.grid.remove(child)
length = len(items)
i = 0
def arrangeMenuItems(self, items, columns=None, expand_last=False):
self.autogrid.clear()
enabled = []
for item in items:
key = list(item)[0]
if not self.evaluate_enable(item[key]['enable']):
logging.debug(f"X > {key}")
continue
if columns == 4:
if length <= 4:
# Arrange 2 x 2
columns = 2
elif 4 < length <= 6:
# Arrange 3 x 2
columns = 3
col = i % columns
row = int(i / columns)
width = height = 1
if expand_last is True and i + 1 == length and length % 2 == 1:
width = 2
self.grid.attach(self.labels[key], col, row, width, height)
i += 1
return self.grid
enabled.append(self.labels[key])
self.autogrid.__init__(enabled, columns, expand_last, self._screen.vertical_mode)
return self.autogrid
def create_menu_items(self):
count = sum(bool(self.evaluate_enable(i[next(iter(i))]['enable'])) for i in self.items)

View File

@ -3,6 +3,7 @@ import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib
from ks_includes.screen_panel import ScreenPanel
from ks_includes.widgets.autogrid import AutoGrid
class Panel(ScreenPanel):
@ -10,33 +11,18 @@ class Panel(ScreenPanel):
super().__init__(screen, title)
printers = self._config.get_printers()
grid = Gtk.Grid(row_homogeneous=True, column_homogeneous=True)
scroll = self._gtk.ScrolledWindow()
scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
scroll.add(grid)
self.content.add(scroll)
length = len(printers)
if length == 4:
# Arrange 2 x 2
columns = 2
elif 4 < length <= 6:
# Arrange 3 x 2
columns = 3
else:
columns = 4
printer_buttons = []
for i, printer in enumerate(printers):
name = list(printer)[0]
self.labels[name] = self._gtk.Button("extruder", name, f"color{1 + i % 4}")
self.labels[name].connect("clicked", self.connect_printer, name)
if self._screen.vertical_mode:
row = i % columns
col = int(i / columns)
else:
col = i % columns
row = int(i / columns)
grid.attach(self.labels[name], col, row, 1, 1)
printer_buttons.append(self.labels[name])
grid = AutoGrid(printer_buttons, vertical=self._screen.vertical_mode)
scroll = self._gtk.ScrolledWindow()
scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
scroll.add(grid)
self.content.add(scroll)
def connect_printer(self, widget, name):
self._screen.connect_printer(name)