diff --git a/ks_includes/config.py b/ks_includes/config.py
index 71d17cc4..b3006911 100644
--- a/ks_includes/config.py
+++ b/ks_includes/config.py
@@ -161,7 +161,7 @@ class KlipperScreenConfig:
bools = (
'invert_x', 'invert_y', 'invert_z', '24htime', 'only_heaters', 'show_cursor', 'confirm_estop',
'autoclose_popups', 'use_dpms', 'use_default_menu', 'side_macro_shortcut', 'use-matchbox-keyboard',
- 'show_heater_power', "show_scroll_steppers", "auto_open_extrude"
+ 'show_heater_power', "show_scroll_steppers", "auto_open_extrude" , 'onboarding'
)
strs = (
'default_printer', 'language', 'print_sort_dir', 'theme', 'screen_blanking_printing', 'font_size',
@@ -319,6 +319,7 @@ class KlipperScreenConfig:
{"print_sort_dir": {"section": "main", "type": None, "value": "name_asc"}},
{"print_view": {"section": "main", "type": None, "value": "thumbs"}},
{"language": {"section": "main", "name": _("Language"), "type": None, "value": "system_lang"}},
+ {"onboarding": {"section": "main", "type": None, "value": "False"}},
]
self.configurable_options.extend(panel_options)
diff --git a/panels/base_panel.py b/panels/base_panel.py
index 38fc0906..00bf3f55 100644
--- a/panels/base_panel.py
+++ b/panels/base_panel.py
@@ -30,11 +30,12 @@ class BasePanel(ScreenPanel):
self.control['back'].set_no_show_all(True)
self.control['home'] = self._gtk.Button('main', scale=abscale)
self.control['home'].connect("clicked", self._screen._menu_go_back, True)
+ self.control['home'].set_no_show_all(True)
self.move = {
"panel": "move",
}
self.control['move'] = self._gtk.Button('move', scale=abscale)
- self.control['move'].connect("clicked", self.menu_item_clicked, self.move)
+ self.control['move'].connect("clicked", self.menu_item_clicked, self.move)
self.control['move'].set_no_show_all(True)
self.extrude = {
"panel": "extrude",
@@ -82,7 +83,6 @@ class BasePanel(ScreenPanel):
self.action_bar.set_hexpand(False)
self.action_bar.set_vexpand(True)
self.action_bar.get_style_context().add_class('action_bar')
- self.action_bar.set_size_request(self._gtk.action_bar_width, self._gtk.action_bar_height)
self.action_bar.add(self.control['back'])
self.action_bar.add(self.control['home'])
self.action_bar.add(self.control['move'])
@@ -229,10 +229,15 @@ class BasePanel(ScreenPanel):
panels_has_back = ['gcodes', 'temperature']
cur_panel_count = len(self._screen._cur_panels)
is_last_panel_in_back_list = self._screen._cur_panels[-1] in panels_has_back
- if cur_panel_count > 2 or is_last_panel_in_back_list:
- self.control['back'].set_visible(True)
+
+ should_show_back = (cur_panel_count > 2 or is_last_panel_in_back_list or
+ (self._screen._cur_panels[0] != 'main_menu' and cur_panel_count >= 2))
+ self.control['back'].set_visible(should_show_back)
+ if any(child.get_visible() for child in self.action_bar.get_children()):
+ self.show_action_bar()
else:
- self.control['back'].set_visible(False)
+ self.hide_action_bar()
+
self.current_panel = panel
self.set_title(panel.title)
self.content.add(panel.content)
@@ -321,7 +326,7 @@ class BasePanel(ScreenPanel):
def set_control_sensitive(self, value=True, control='home'):
self.control[control].set_sensitive(value)
-
+
def show_shortcut(self, show=True):
show = (
show
@@ -335,6 +340,14 @@ class BasePanel(ScreenPanel):
self.set_control_sensitive(self._screen._cur_panels[-1] != self.files['panel'], control='files')
self.set_control_sensitive(self._screen._cur_panels[-1] != self.more['panel'], control='more')
+ def show_action_bar(self):
+ self.action_bar.set_size_request(self._gtk.action_bar_width, self._gtk.action_bar_height)
+ self.control['home'].set_visible(True)
+
+ def hide_action_bar(self):
+ self.action_bar.set_size_request(-1, -1)
+ self.control['home'].set_visible(False)
+
def show_printer_select(self, show=True):
self.control['printer_select'].set_visible(
show and 'printer_select' not in self._screen._cur_panels
diff --git a/panels/gcodes.py b/panels/gcodes.py
index 771251bd..987e75de 100644
--- a/panels/gcodes.py
+++ b/panels/gcodes.py
@@ -67,6 +67,7 @@ class Panel(ScreenPanel):
self.loading_msg = _('Loading...')
self.labels['path'] = Gtk.Label(label=self.loading_msg, vexpand=True, no_show_all=True)
+ self.labels['path'].set_ellipsize(Pango.EllipsizeMode.END)
self.labels['path'].show()
self.thumbsize = self._gtk.img_scale * self._gtk.button_image_scale * 2.5
logging.info(f"Thumbsize: {self.thumbsize}")
diff --git a/panels/job_status.py b/panels/job_status.py
index 2b8cf420..515afa6a 100644
--- a/panels/job_status.py
+++ b/panels/job_status.py
@@ -166,7 +166,7 @@ class Panel(ScreenPanel):
'extra': extruder})
self.buttons['extruder'][extruder].set_halign(Gtk.Align.START)
- self.labels['temp_grid'] = Gtk.Grid()
+ self.labels['temp_grid'] = Gtk.Grid(column_homogeneous=True)
nlimit = 3 if self._screen.width <= 500 else 4
n = 0
if nlimit > 2 and len(self._printer.get_tools()) == 2:
@@ -179,6 +179,7 @@ class Panel(ScreenPanel):
self.labels['temp_grid'].attach(self.buttons['extruder'][self.current_extruder], n, 0, 1, 1)
n += 1
self.buttons['heater'] = {}
+ n = 0
for dev in self._printer.get_heaters():
if n >= nlimit:
break
@@ -194,7 +195,7 @@ class Panel(ScreenPanel):
self.buttons['heater'][dev].connect("clicked", self.menu_item_clicked,
{"panel": "numpad", "extra": dev})
self.buttons['heater'][dev].set_halign(Gtk.Align.START)
- self.labels['temp_grid'].attach(self.buttons['heater'][dev], n, 0, 1, 1)
+ self.labels['temp_grid'].attach(self.buttons['heater'][dev], n, 1, 1, 1)
n += 1
extra_item = not self._show_heater_power
if self.ks_printer_cfg is not None:
@@ -218,7 +219,7 @@ class Panel(ScreenPanel):
self.buttons['heater'][device].connect("clicked", self.menu_item_clicked,
{"panel": "numpad"})
self.buttons['heater'][device].set_halign(Gtk.Align.START)
- self.labels['temp_grid'].attach(self.buttons['heater'][device], n, 0, 1, 1)
+ self.labels['temp_grid'].attach(self.buttons['heater'][device], n, 1, 1, 1)
n += 1
break
@@ -232,10 +233,10 @@ class Panel(ScreenPanel):
info = Gtk.Grid(row_homogeneous=True)
info.get_style_context().add_class("printing-info")
- info.attach(self.labels['temp_grid'], 0, 0, 1, 1)
- info.attach(szfe, 0, 1, 1, 2)
- info.attach(self.buttons['elapsed'], 0, 3, 1, 1)
- info.attach(self.buttons['left'], 0, 4, 1, 1)
+ info.attach(self.labels['temp_grid'], 0, 0, 1, 2)
+ info.attach(szfe, 0, 2, 1, 2)
+ info.attach(self.buttons['elapsed'], 0, 4, 1, 1)
+ info.attach(self.buttons['left'], 0, 5, 1, 1)
self.status_grid = info
def create_extrusion_grid(self, widget=None):
diff --git a/panels/language_select.py b/panels/language_select.py
new file mode 100644
index 00000000..296ae123
--- /dev/null
+++ b/panels/language_select.py
@@ -0,0 +1,61 @@
+import logging
+import gi
+
+gi.require_version("Gtk", "3.0")
+from gi.repository import Gtk, GLib
+from ks_includes.screen_panel import ScreenPanel
+
+class Panel(ScreenPanel):
+ def __init__(self, screen, title):
+ title = title or "Select Language"
+ super().__init__(screen, title)
+ self.language_map = {
+ 'cs': 'Čeština',
+ 'da': 'Dansk',
+ 'de': 'Deutsch',
+ 'de_formal': 'Höfliches Deutsch',
+ 'en': 'English',
+ 'es': 'Español',
+ 'et': 'Eesti',
+ 'fr': 'Français',
+ 'he': 'עברית',
+ 'hu': 'Magyar',
+ 'it': 'Italiano',
+ 'jp': '日本語',
+ 'ko': '한국어',
+ 'lt': 'Lietuvių',
+ 'nl': 'Nederlands',
+ 'pl': 'Polski',
+ 'pt': 'Português',
+ 'pt_BR': 'Português (Brasil)',
+ 'ru': 'Русский',
+ 'sl': 'Slovenščina',
+ 'sv': 'Svenska',
+ 'tr': 'Türkçe',
+ 'uk': 'Українська',
+ 'vi': 'Tiếng Việt',
+ 'zh_CN': '简体中文',
+ 'zh_TW': '繁體中文',
+ }
+ self.langs = {}
+ self.labels['lang_menu'] = self._gtk.ScrolledWindow()
+ self.labels['lang'] = Gtk.Grid()
+ self.labels['lang_menu'].add(self.labels['lang'])
+ self.labels['lang'].set_margin_start(50)
+ for lang in self._config.lang_list:
+ name = self.language_map.get(lang)
+ if name:
+ self.langs[lang] = {
+ "name": name,
+ "type": "button",
+ "callback": self.change_language,
+ }
+ self.add_option("lang", self.langs, lang, self.langs[lang])
+ self.content.add(self.labels["lang_menu"])
+ self.content.show_all()
+
+ def change_language(self, widget, lang):
+ reverse_language_map = {v: k for k, v in self.language_map.items()}
+ language_code = reverse_language_map.get(lang, 'en')
+ self._screen.change_language(widget, language_code)
+ self._screen.initial_connection()
diff --git a/panels/onboarding.py b/panels/onboarding.py
new file mode 100644
index 00000000..3c1daf54
--- /dev/null
+++ b/panels/onboarding.py
@@ -0,0 +1,69 @@
+import logging
+import os
+import gi
+
+gi.require_version("Gtk", "3.0")
+from gi.repository import Gtk, Pango
+from ks_includes.screen_panel import ScreenPanel
+
+
+class Panel(ScreenPanel):
+
+ def __init__(self, screen, title):
+ title = title or _('Welcome')
+ super().__init__(screen, title)
+
+ buttons = [
+ {"name": _("Next"), "response": Gtk.ResponseType.YES, "style": 'dialog-secondary'}
+ ]
+
+ image = self._gtk.Image(
+ "retainer", self._gtk.content_width * 0.3, self._gtk.content_height * 0.5
+ )
+ start_text = _("1. For first use, refer to the accompanying diagram to disassemble the fixed components of the X, Y, and Z axes.")
+ space = "\n\n"
+ end_text = _("2. Once the disassembly is complete, click the 'Next' button to proceed.")
+ label = Gtk.Label(hexpand=True, vexpand=True, wrap=True, wrap_mode=Pango.WrapMode.WORD_CHAR)
+ label.set_markup(f"{start_text + space + end_text}\n")
+ box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, vexpand=True)
+ image.set_margin_start(60)
+ image.set_margin_top(80)
+ box.pack_start(image, False, True, 0)
+ box.pack_start(label, False, False, 20)
+
+ self._gtk.Dialog(f'Welcome', buttons, box, self.confirm_print_response)
+
+ def create_raise_platform(self):
+ buttons = [
+ {"name": _("Raise Platform"), "response": Gtk.ResponseType.OK},
+ {"name": _("Finish"), "response": Gtk.ResponseType.APPLY, "style": 'dialog-secondary'}
+ ]
+
+ image = self._gtk.Image(
+ "take_out", self._gtk.content_width * 0.3, self._gtk.content_height * 0.5
+ )
+
+ start_text = _("1. Ensure that all fixed components have been properly removed before proceeding.")
+ center_text = _("2. Press the 'Raise Platform' button to lift the platform and remove the items underneath.")
+ end_text = _("3. Once the operation is complete, click the \'Finish\' button to conclude the process.")
+ space = "\n\n"
+ label = Gtk.Label(hexpand=True, vexpand=True, wrap=True, wrap_mode=Pango.WrapMode.WORD_CHAR)
+ label.set_markup(f"{start_text + space + center_text + space + end_text}\n")
+ box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, vexpand=True)
+ image.set_margin_start(60)
+ image.set_margin_top(80)
+ box.pack_start(image, False, True, 0)
+ box.pack_start(label, False, False, 20)
+
+ self._gtk.Dialog(f'Test', buttons, box, self.confirm_print_response)
+
+ def confirm_print_response(self, dialog, response_id):
+ if response_id == Gtk.ResponseType.YES:
+ self._gtk.remove_dialog(dialog)
+ self.create_raise_platform()
+ elif response_id == Gtk.ResponseType.OK:
+ self._screen._ws.klippy.gcode_script("SET_KINEMATIC_POSITION Z=5\nG28")
+ elif response_id == Gtk.ResponseType.APPLY:
+ self._screen.show_panel("main_menu", remove_all=True, items=self._config.get_menu_items("__main"))
+ self._config.set("main", "onboarding", "False")
+ self._config.save_user_config_options()
diff --git a/panels/settings.py b/panels/settings.py
index 09bc678b..5b0f6d05 100644
--- a/panels/settings.py
+++ b/panels/settings.py
@@ -24,15 +24,50 @@ class Panel(ScreenPanel):
name = list(option)[0]
self.add_option('settings', self.settings, name, option[name])
+ self.language_map = {
+ 'cs': 'Čeština',
+ 'da': 'Dansk',
+ 'de': 'Deutsch',
+ 'de_formal': 'Höfliches Deutsch',
+ 'en': 'English',
+ 'es': 'Español',
+ 'et': 'Eesti',
+ 'fr': 'Français',
+ 'he': 'עברית',
+ 'hu': 'Magyar',
+ 'it': 'Italiano',
+ 'jp': '日本語',
+ 'ko': '한국어',
+ 'lt': 'Lietuvių',
+ 'nl': 'Nederlands',
+ 'pl': 'Polski',
+ 'pt': 'Português',
+ 'pt_BR': 'Português (Brasil)',
+ 'ru': 'Русский',
+ 'sl': 'Slovenščina',
+ 'sv': 'Svenska',
+ 'tr': 'Türkçe',
+ 'uk': 'Українська',
+ 'vi': 'Tiếng Việt',
+ 'zh_CN': '简体中文',
+ 'zh_TW': '繁體中文',
+ }
+
self.labels['lang_menu'] = self._gtk.ScrolledWindow()
self.labels['lang'] = Gtk.Grid()
self.labels['lang_menu'].add(self.labels['lang'])
- for lang in ["system_lang", *self._config.lang_list]:
+ for lang in self._config.lang_list:
+ name = self.language_map.get(lang)
self.langs[lang] = {
- "name": lang,
+ "name": name,
"type": "button",
- "callback": self._screen.change_language,
+ "callback": self.change_language,
}
self.add_option("lang", self.langs, lang, self.langs[lang])
self.content.add(self.labels['settings_menu'])
+
+ def change_language(self, widget, lang):
+ reverse_language_map = {v: k for k, v in self.language_map.items()}
+ language_code = reverse_language_map.get(lang, 'en')
+ self._screen.change_language(widget, language_code)
\ No newline at end of file
diff --git a/panels/splash_screen.py b/panels/splash_screen.py
index da0352b8..4c8f4a36 100644
--- a/panels/splash_screen.py
+++ b/panels/splash_screen.py
@@ -50,7 +50,7 @@ class Panel(ScreenPanel):
scroll.add(self.labels["text"])
info = Gtk.Box()
- info.pack_start(image, False, True, 8)
+ info.pack_start(image, False, True, 50)
info.pack_end(scroll, True, True, 8)
main = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
diff --git a/panels/system.py b/panels/system.py
index 9b57bbf7..e0f53e9e 100644
--- a/panels/system.py
+++ b/panels/system.py
@@ -17,6 +17,8 @@ class Panel(ScreenPanel):
self.current_row = 0
self.mem_multiplier = None
self.model_config = None
+ self.info_panel = None
+ self.select_model = False
self.scales = {}
self.labels = {}
self.models = {}
@@ -34,15 +36,20 @@ class Panel(ScreenPanel):
screen.printer.system_info = self.sysinfo['system_info']
self.sysinfo = self.sysinfo['system_info']
logging.debug(self.sysinfo)
+
if self.sysinfo:
- self.content.add(self.create_layout())
+ self.info_panel = self.create_layout()
else:
self.content.add(Gtk.Label(label=_("No info available"), vexpand=True))
def back(self):
+ if self.select_model:
+ self.hide_select_model()
+ return True
if not self.sysinfo:
self._screen.panels_reinit.append("system")
return False
+
def create_layout(self):
self.labels["cpu_usage"] = Gtk.Label(label="", xalign=0)
self.grid.attach(self.labels["cpu_usage"], 0, self.current_row, 1, 1)
@@ -70,6 +77,11 @@ class Panel(ScreenPanel):
scroll = self._gtk.ScrolledWindow()
scroll.add(self.grid)
self.content.add(scroll)
+ return scroll
+
+ def create_select_model(self):
+ if "model_menu" in self.labels:
+ return
if self.model_config is None:
self.model_config = ModelConfig()
self.labels["model_menu"] = self._gtk.ScrolledWindow()
@@ -91,9 +103,10 @@ class Panel(ScreenPanel):
self.add_option(
"model", self.models, model_name, self.models[model_name]
)
- return scroll
+
def change_model(self, widget, event):
self.model_config.generate_config(event)
+
def on_model_click(self, widget, event):
current_time = time.time()
if (current_time - self.last_click_time) <= self.click_threshold:
@@ -101,9 +114,22 @@ class Panel(ScreenPanel):
else:
self.click_count = 0
self.last_click_time = current_time
- if self.click_count == self.target_clicks:
+ if self.click_count >= self.target_clicks:
+ for child in self.content.get_children():
+ self.content.remove(child)
self.click_count = 0
- self.load_menu(self, "model", _("model select"))
+ self.create_select_model()
+ self.content.add(self.labels["model_menu"])
+ self.content.show_all()
+ self.select_model = True
+
+ def hide_select_model(self):
+ for child in self.content.get_children():
+ self.content.remove(child)
+ if self.info_panel:
+ self.content.add(self.info_panel)
+ self.content.show_all()
+ self.select_model = False
def set_mem_multiplier(self, data):
memory_units = data.get("memory_units", "kB").lower()
@@ -122,12 +148,13 @@ class Panel(ScreenPanel):
label = Gtk.Label(label=text, use_markup=True, xalign=0, wrap=True)
self.grid.attach(label, column, self.current_row, 1, 1)
self.current_row += 1
+
def machine_info(self):
self.add_label_to_grid(self.prettify("device"), 0, bold=True)
self.current_row -= 1
self.add_label_to_grid("Maker: CreatBot", 1)
event_box = Gtk.EventBox()
- event_box.connect("button-press-event", self.on_model_click)
+ event_box.connect("button-release-event", self.on_model_click)
mode = self._screen.connecting_to_printer.split("-")[0]
label = Gtk.Label(label=f"Model: {mode}", use_markup=True, xalign=0, wrap=True)
self.grid.attach(event_box, 1, self.current_row, 1, 1)
diff --git a/screen.py b/screen.py
index 9c152c17..99562310 100755
--- a/screen.py
+++ b/screen.py
@@ -167,7 +167,10 @@ class KlipperScreen(Gtk.Window):
self.base_panel.activate()
self.set_screenblanking_timeout(self._config.get_main_config().get('screen_blanking'))
self.log_notification("KlipperScreen Started", 1)
- self.initial_connection()
+
+ lang = self._config.get_main_config().get("language", 'system_lang')
+ (self.show_language_select() if lang == 'system_lang' else self.initial_connection())
+
def state_execute(self, state, callback):
self.close_screensaver()
@@ -716,9 +719,16 @@ class KlipperScreen(Gtk.Window):
self.reset_screensaver_timeout()
return
+ def show_language_select(self, widget=None):
+ self.show_panel("language_select", remove_all=True)
+
+ def show_onboarding(self, widget=None):
+ self.show_panel("onboarding", remove_all=True)
+
def show_printer_select(self, widget=None):
- self.base_panel.show_heaters(False)
- self.show_panel("printer_select", remove_all=True)
+ if 'printer_select' not in self._cur_panels:
+ self.base_panel.show_heaters(False)
+ self.show_panel("printer_select", remove_all=True)
def websocket_connection_cancel(self):
self.printer_initializing(
@@ -781,8 +791,12 @@ class KlipperScreen(Gtk.Window):
self.printer.state = "not ready"
return
self.files.refresh_files()
- self.show_panel("main_menu", remove_all=True, items=self._config.get_menu_items("__main"))
- self._ws.klippy.gcode_script("UPDATE_DELAYED_GCODE ID=_CHECK_POWER_LOSS_RECOVERY DURATION=0.1")
+ guided = self._config.get_main_config().get("onboarding", False)
+ if guided == 'True':
+ self.show_onboarding()
+ else:
+ self.show_panel("main_menu", remove_all=True, items=self._config.get_menu_items("__main"))
+ self._ws.klippy.gcode_script("UPDATE_DELAYED_GCODE ID=_CHECK_POWER_LOSS_RECOVERY DURATION=0.1")
def state_startup(self):
self.printer_initializing(_("Klipper is attempting to start"))
@@ -938,7 +952,8 @@ class KlipperScreen(Gtk.Window):
def printer_initializing(self, msg, go_to_splash=False):
if 'splash_screen' not in self.panels or go_to_splash:
- self.show_panel("splash_screen", remove_all=True)
+ if self._cur_panels != ['splash_screen']:
+ self.show_panel("splash_screen", remove_all=True)
self.panels['splash_screen'].update_text(msg)
self.log_notification(msg, 0)
diff --git a/styles/dark/images/retainer.svg b/styles/dark/images/retainer.svg
new file mode 100644
index 00000000..b31fc957
--- /dev/null
+++ b/styles/dark/images/retainer.svg
@@ -0,0 +1,19 @@
+
diff --git a/styles/dark/images/take_out.svg b/styles/dark/images/take_out.svg
new file mode 100644
index 00000000..2c91f69b
--- /dev/null
+++ b/styles/dark/images/take_out.svg
@@ -0,0 +1,21 @@
+