widgets: create autogrid: a custom grid that arranges itself (#1307)
This commit is contained in:
parent
4d168c2319
commit
14a02e5bcf
52
ks_includes/widgets/autogrid.py
Normal file
52
ks_includes/widgets/autogrid.py
Normal 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)
|
@ -6,6 +6,7 @@ gi.require_version("Gtk", "3.0")
|
|||||||
from gi.repository import Gtk, Pango
|
from gi.repository import Gtk, Pango
|
||||||
from ks_includes.KlippyGcodes import KlippyGcodes
|
from ks_includes.KlippyGcodes import KlippyGcodes
|
||||||
from ks_includes.screen_panel import ScreenPanel
|
from ks_includes.screen_panel import ScreenPanel
|
||||||
|
from ks_includes.widgets.autogrid import AutoGrid
|
||||||
|
|
||||||
|
|
||||||
class Panel(ScreenPanel):
|
class Panel(ScreenPanel):
|
||||||
@ -54,14 +55,10 @@ class Panel(ScreenPanel):
|
|||||||
"panel": "spoolman"
|
"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)
|
xbox = Gtk.Box(homogeneous=True)
|
||||||
limit = 4
|
limit = 4
|
||||||
i = 0
|
i = 0
|
||||||
|
extruder_buttons = []
|
||||||
for extruder in self._printer.get_tools():
|
for extruder in self._printer.get_tools():
|
||||||
if self._printer.extrudercount == 1:
|
if self._printer.extrudercount == 1:
|
||||||
self.labels[extruder] = self._gtk.Button("extruder", "")
|
self.labels[extruder] = self._gtk.Button("extruder", "")
|
||||||
@ -75,7 +72,11 @@ class Panel(ScreenPanel):
|
|||||||
xbox.add(self.labels[extruder])
|
xbox.add(self.labels[extruder])
|
||||||
i += 1
|
i += 1
|
||||||
else:
|
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:
|
if self._printer.extrudercount > limit:
|
||||||
changer = self._gtk.Button("toolchanger")
|
changer = self._gtk.Button("toolchanger")
|
||||||
changer.connect("clicked", self.load_menu, 'extruders', _('Extruders'))
|
changer.connect("clicked", self.load_menu, 'extruders', _('Extruders'))
|
||||||
|
@ -6,6 +6,7 @@ gi.require_version("Gtk", "3.0")
|
|||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
from jinja2 import Template
|
from jinja2 import Template
|
||||||
from ks_includes.screen_panel import ScreenPanel
|
from ks_includes.screen_panel import ScreenPanel
|
||||||
|
from ks_includes.widgets.autogrid import AutoGrid
|
||||||
|
|
||||||
|
|
||||||
class Panel(ScreenPanel):
|
class Panel(ScreenPanel):
|
||||||
@ -15,9 +16,9 @@ class Panel(ScreenPanel):
|
|||||||
self.items = items
|
self.items = items
|
||||||
self.j2_data = self._printer.get_printer_status_data()
|
self.j2_data = self._printer.get_printer_status_data()
|
||||||
self.create_menu_items()
|
self.create_menu_items()
|
||||||
self.grid = Gtk.Grid(row_homogeneous=True, column_homogeneous=True)
|
|
||||||
self.scroll = self._gtk.ScrolledWindow()
|
self.scroll = self._gtk.ScrolledWindow()
|
||||||
self.scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
|
self.scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
|
||||||
|
self.autogrid = AutoGrid()
|
||||||
|
|
||||||
def activate(self):
|
def activate(self):
|
||||||
self.j2_data = self._printer.get_printer_status_data()
|
self.j2_data = self._printer.get_printer_status_data()
|
||||||
@ -26,42 +27,21 @@ class Panel(ScreenPanel):
|
|||||||
def add_content(self):
|
def add_content(self):
|
||||||
for child in self.scroll.get_children():
|
for child in self.scroll.get_children():
|
||||||
self.scroll.remove(child)
|
self.scroll.remove(child)
|
||||||
if self._screen.vertical_mode:
|
self.scroll.add(self.arrangeMenuItems(self.items))
|
||||||
self.scroll.add(self.arrangeMenuItems(self.items, 3))
|
|
||||||
else:
|
|
||||||
self.scroll.add(self.arrangeMenuItems(self.items, 4))
|
|
||||||
if not self.content.get_children():
|
if not self.content.get_children():
|
||||||
self.content.add(self.scroll)
|
self.content.add(self.scroll)
|
||||||
|
|
||||||
def arrangeMenuItems(self, items, columns, expand_last=False):
|
def arrangeMenuItems(self, items, columns=None, expand_last=False):
|
||||||
for child in self.grid.get_children():
|
self.autogrid.clear()
|
||||||
self.grid.remove(child)
|
enabled = []
|
||||||
length = len(items)
|
|
||||||
i = 0
|
|
||||||
for item in items:
|
for item in items:
|
||||||
key = list(item)[0]
|
key = list(item)[0]
|
||||||
if not self.evaluate_enable(item[key]['enable']):
|
if not self.evaluate_enable(item[key]['enable']):
|
||||||
logging.debug(f"X > {key}")
|
logging.debug(f"X > {key}")
|
||||||
continue
|
continue
|
||||||
|
enabled.append(self.labels[key])
|
||||||
if columns == 4:
|
self.autogrid.__init__(enabled, columns, expand_last, self._screen.vertical_mode)
|
||||||
if length <= 4:
|
return self.autogrid
|
||||||
# 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
|
|
||||||
|
|
||||||
def create_menu_items(self):
|
def create_menu_items(self):
|
||||||
count = sum(bool(self.evaluate_enable(i[next(iter(i))]['enable'])) for i in self.items)
|
count = sum(bool(self.evaluate_enable(i[next(iter(i))]['enable'])) for i in self.items)
|
||||||
|
@ -3,6 +3,7 @@ import gi
|
|||||||
gi.require_version("Gtk", "3.0")
|
gi.require_version("Gtk", "3.0")
|
||||||
from gi.repository import Gtk, GLib
|
from gi.repository import Gtk, GLib
|
||||||
from ks_includes.screen_panel import ScreenPanel
|
from ks_includes.screen_panel import ScreenPanel
|
||||||
|
from ks_includes.widgets.autogrid import AutoGrid
|
||||||
|
|
||||||
|
|
||||||
class Panel(ScreenPanel):
|
class Panel(ScreenPanel):
|
||||||
@ -10,33 +11,18 @@ class Panel(ScreenPanel):
|
|||||||
super().__init__(screen, title)
|
super().__init__(screen, title)
|
||||||
printers = self._config.get_printers()
|
printers = self._config.get_printers()
|
||||||
|
|
||||||
grid = Gtk.Grid(row_homogeneous=True, column_homogeneous=True)
|
printer_buttons = []
|
||||||
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
|
|
||||||
|
|
||||||
for i, printer in enumerate(printers):
|
for i, printer in enumerate(printers):
|
||||||
name = list(printer)[0]
|
name = list(printer)[0]
|
||||||
self.labels[name] = self._gtk.Button("extruder", name, f"color{1 + i % 4}")
|
self.labels[name] = self._gtk.Button("extruder", name, f"color{1 + i % 4}")
|
||||||
self.labels[name].connect("clicked", self.connect_printer, name)
|
self.labels[name].connect("clicked", self.connect_printer, name)
|
||||||
if self._screen.vertical_mode:
|
printer_buttons.append(self.labels[name])
|
||||||
row = i % columns
|
grid = AutoGrid(printer_buttons, vertical=self._screen.vertical_mode)
|
||||||
col = int(i / columns)
|
|
||||||
else:
|
scroll = self._gtk.ScrolledWindow()
|
||||||
col = i % columns
|
scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
|
||||||
row = int(i / columns)
|
scroll.add(grid)
|
||||||
grid.attach(self.labels[name], col, row, 1, 1)
|
self.content.add(scroll)
|
||||||
|
|
||||||
def connect_printer(self, widget, name):
|
def connect_printer(self, widget, name):
|
||||||
self._screen.connect_printer(name)
|
self._screen.connect_printer(name)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user