alfrix d3281379ee gtk: change scaling of images
This reduces the amount of magic numbers used, some images will scale to bigger sizes, most of the icons and images in vertical mode will be bigger, thumbnails should be bigger in both modes.
2022-10-26 22:36:52 -03:00

312 lines
14 KiB
Python

# -*- coding: utf-8 -*-
import contextlib
import datetime
import gi
import logging
gi.require_version("Gtk", "3.0")
from gi.repository import GLib, Gtk, Pango
from jinja2 import Environment
from ks_includes.screen_panel import ScreenPanel
class BasePanel(ScreenPanel):
def __init__(self, screen, title, back=True):
super().__init__(screen, title, back)
self.current_panel = None
self.time_min = -1
self.time_format = self._config.get_main_config().getboolean("24htime", True)
self.time_update = None
self.titlebar_name_type = None
self.buttons_showing = {
'back': not back,
'macros_shortcut': False,
'printer_select': False
}
self.current_extruder = None
# Action bar buttons
self.control['back'] = self._gtk.ButtonImage('back', scale=1)
self.control['back'].connect("clicked", self.back)
self.control['home'] = self._gtk.ButtonImage('main', scale=1)
self.control['home'].connect("clicked", self.menu_return, True)
if len(self._config.get_printers()) > 1:
self.control['printer_select'] = self._gtk.ButtonImage('shuffle', scale=1)
self.control['printer_select'].connect("clicked", self._screen.show_printer_select)
self.control['macros_shortcut'] = self._gtk.ButtonImage('custom-script', scale=1)
self.control['macros_shortcut'].connect("clicked", self.menu_item_clicked, "gcode_macros", {
"name": "Macros",
"panel": "gcode_macros"
})
self.control['estop'] = self._gtk.ButtonImage('emergency', scale=1)
self.control['estop'].connect("clicked", self.emergency_stop)
# Any action bar button should close the keyboard
for item in self.control:
self.control[item].connect("clicked", self._screen.remove_keyboard)
# Action bar
self.action_bar = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5)
if self._screen.vertical_mode:
self.action_bar.set_hexpand(True)
self.action_bar.set_vexpand(False)
self.action_bar.set_size_request(0, self._gtk.get_action_bar_height())
else:
self.action_bar.set_hexpand(False)
self.action_bar.set_vexpand(True)
self.action_bar.set_size_request(self._gtk.get_action_bar_width(), 0)
self.action_bar.get_style_context().add_class('action_bar')
self.action_bar.add(self.control['back'])
self.action_bar.add(self.control['home'])
if len(self._config.get_printers()) > 1:
self.action_bar.add(self.control['printer_select'])
self.action_bar.add(self.control['macros_shortcut'])
self.action_bar.add(self.control['estop'])
# Titlebar
# This box will be populated by show_heaters
self.control['temp_box'] = Gtk.Box(spacing=10)
self.titlelbl = Gtk.Label()
self.titlelbl.set_hexpand(True)
self.titlelbl.set_halign(Gtk.Align.CENTER)
self.titlelbl.set_ellipsize(Pango.EllipsizeMode.END)
self.set_title(title)
self.control['time'] = Gtk.Label("00:00 AM")
self.control['time_box'] = Gtk.Box()
self.control['time_box'].set_halign(Gtk.Align.END)
self.control['time_box'].pack_end(self.control['time'], True, True, 5)
self.titlebar = Gtk.Box(spacing=5)
self.titlebar.set_size_request(0, self._gtk.get_titlebar_height())
self.titlebar.set_valign(Gtk.Align.CENTER)
self.titlebar.add(self.control['temp_box'])
self.titlebar.add(self.titlelbl)
self.titlebar.add(self.control['time_box'])
# Main layout
self.main_grid = Gtk.Grid()
# To achieve rezisability this needs to be removed
# The main issue is that currently the content doesn't expand correctly
self.main_grid.set_size_request(self._screen.width, self._screen.height)
if self._screen.vertical_mode:
self.main_grid.attach(self.titlebar, 0, 0, 1, 1)
self.main_grid.attach(self.content, 0, 1, 1, 1)
self.main_grid.attach(self.action_bar, 0, 2, 1, 1)
self.action_bar.set_orientation(orientation=Gtk.Orientation.HORIZONTAL)
else:
self.main_grid.attach(self.action_bar, 0, 0, 1, 2)
self.action_bar.set_orientation(orientation=Gtk.Orientation.VERTICAL)
self.main_grid.attach(self.titlebar, 1, 0, 1, 1)
self.main_grid.attach(self.content, 1, 1, 1, 1)
# Layout is and content are on screen_panel
self.layout.add(self.main_grid)
def initialize(self, panel_name):
self.update_time()
return
def show_heaters(self, show=True):
printer_cfg = self._config.get_printer_config(self._screen.connected_printer)
if printer_cfg is not None:
self.titlebar_name_type = printer_cfg.get("titlebar_name_type", None)
else:
self.titlebar_name_type = None
logging.info(f"Titlebar name type: {self.titlebar_name_type}")
for child in self.control['temp_box'].get_children():
self.control['temp_box'].remove(child)
if not show or self._screen.printer.get_temp_store_devices() is None:
return
img_size = self._gtk.img_scale * .5
for device in self._screen.printer.get_temp_store_devices():
if device.startswith("extruder"):
if self._screen.printer.extrudercount > 1:
if device == "extruder":
icon = self._gtk.Image("extruder-0", img_size, img_size)
else:
icon = self._gtk.Image(f"extruder-{device[8:]}", img_size, img_size)
else:
icon = self._gtk.Image("extruder", img_size, img_size)
elif device.startswith("heater_bed"):
icon = self._gtk.Image("bed", img_size, img_size)
# Extra items
elif self.titlebar_name_type is not None:
# The item has a name, do not use an icon
icon = None
elif device.startswith("temperature_fan"):
icon = self._gtk.Image("fan", img_size, img_size)
elif device.startswith("heater_generic"):
icon = self._gtk.Image("heater", img_size, img_size)
else:
icon = self._gtk.Image("heat-up", img_size, img_size)
self.labels[device] = Gtk.Label(label="100º")
self.labels[device].set_ellipsize(Pango.EllipsizeMode.START)
self.labels[f'{device}_box'] = Gtk.Box()
if icon is not None:
self.labels[f'{device}_box'].pack_start(icon, False, False, 3)
self.labels[f'{device}_box'].pack_start(self.labels[device], False, False, 0)
# Limit the number of items according to resolution
if self._screen.width <= 480:
nlimit = 3
elif self._screen.width <= 800:
nlimit = 4
else:
nlimit = 5
n = 0
if self._screen.printer.get_tools():
self.current_extruder = self._screen.printer.get_stat("toolhead", "extruder")
if self.current_extruder:
self.control['temp_box'].add(self.labels[f"{self.current_extruder}_box"])
n += 1
if self._screen.printer.has_heated_bed():
self.control['temp_box'].add(self.labels['heater_bed_box'])
n += 1
# Options in the config have priority
if printer_cfg is not None:
titlebar_items = printer_cfg.get("titlebar_items", None)
if titlebar_items is not None:
titlebar_items = [str(i.strip()) for i in titlebar_items.split(',')]
logging.info(f"Titlebar items: {titlebar_items}")
for device in self._screen.printer.get_temp_store_devices():
# Users can fill the bar if they want
if n >= nlimit + 1:
break
name = device.split()[1] if len(device.split()) > 1 else device
for item in titlebar_items:
if name == item:
self.control['temp_box'].add(self.labels[f"{device}_box"])
n += 1
break
# If there is enough space fill with heater_generic
for device in self._screen.printer.get_temp_store_devices():
if n >= nlimit:
break
if device.startswith("heater_generic"):
self.control['temp_box'].add(self.labels[f"{device}_box"])
n += 1
self.control['temp_box'].show_all()
def activate(self):
if self.time_update is None:
self.time_update = GLib.timeout_add_seconds(1, self.update_time)
def add_content(self, panel):
self.current_panel = panel
self.set_title(panel.get_title())
self.content.add(panel.get_content())
def back(self, widget):
if self.current_panel is None:
return
self._screen.remove_keyboard()
if hasattr(self.current_panel, "back") \
and not self.current_panel.back() \
or not hasattr(self.current_panel, "back"):
self._screen._menu_go_back()
def process_update(self, action, data):
if action != "notify_status_update" or self._screen.printer is None:
return
devices = self._screen.printer.get_temp_store_devices()
if devices is not None:
for device in devices:
temp = self._screen.printer.get_dev_stat(device, "temperature")
if temp is not None and device in self.labels:
name = ""
if not (device.startswith("extruder") or device.startswith("heater_bed")):
if self.titlebar_name_type == "full":
name = device.split()[1] if len(device.split()) > 1 else device
name = f'{name.capitalize().replace("_", " ")}: '
elif self.titlebar_name_type == "short":
name = device.split()[1] if len(device.split()) > 1 else device
name = f"{name[:1].upper()}: "
self.labels[device].set_label(f"{name}{int(temp)}°")
with contextlib.suppress(KeyError):
if data["toolhead"]["extruder"] != self.current_extruder:
self.control['temp_box'].remove(self.labels[f"{self.current_extruder}_box"])
self.current_extruder = data["toolhead"]["extruder"]
self.control['temp_box'].pack_start(self.labels[f"{self.current_extruder}_box"], True, True, 3)
self.control['temp_box'].reorder_child(self.labels[f"{self.current_extruder}_box"], 0)
self.control['temp_box'].show_all()
def remove(self, widget):
self.content.remove(widget)
def show_back(self, show=True):
if show is True and self.buttons_showing['back'] is False:
self.control['back'].set_sensitive(True)
self.control['home'].set_sensitive(True)
self.buttons_showing['back'] = True
elif show is False and self.buttons_showing['back'] is True:
self.control['back'].set_sensitive(False)
self.control['home'].set_sensitive(False)
self.buttons_showing['back'] = False
def show_macro_shortcut(self, show=True):
if show is True and self.buttons_showing['macros_shortcut'] is False:
self.action_bar.add(self.control['macros_shortcut'])
if self.buttons_showing['printer_select'] is False:
self.action_bar.reorder_child(self.control['macros_shortcut'], 2)
else:
self.action_bar.reorder_child(self.control['macros_shortcut'], 3)
self.buttons_showing['macros_shortcut'] = True
elif show is False and self.buttons_showing['macros_shortcut'] is True:
self.action_bar.remove(self.control['macros_shortcut'])
self.buttons_showing['macros_shortcut'] = False
self._screen.show_all()
def show_printer_select(self, show=True):
if len(self._config.get_printers()) <= 1:
return
if show and self.buttons_showing['printer_select'] is False:
self.action_bar.add(self.control['printer_select'])
self.action_bar.reorder_child(self.control['printer_select'], 2)
self.buttons_showing['printer_select'] = True
elif show is False and self.buttons_showing['printer_select']:
self.action_bar.remove(self.control['printer_select'])
self.buttons_showing['printer_select'] = False
self._screen.show_all()
def set_title(self, title):
try:
env = Environment(extensions=["jinja2.ext.i18n"], autoescape=True)
env.install_gettext_translations(self.lang)
j2_temp = env.from_string(title)
title = j2_temp.render()
except Exception as e:
logging.debug(f"Error parsing jinja for title: {title}\n{e}")
self.titlelbl.set_label(f"{self._screen.connecting_to_printer} | {title}")
def update_time(self):
now = datetime.datetime.now()
confopt = self._config.get_main_config().getboolean("24htime", True)
if now.minute != self.time_min or self.time_format != confopt:
if confopt:
self.control['time'].set_text(f'{now:%H:%M}')
else:
self.control['time'].set_text(f'{now:%I:%M %p}')
return True