From 207c026cb5ff0045bbf71d26954cdaeb8866df11 Mon Sep 17 00:00:00 2001 From: Jordan Date: Sat, 12 Jun 2021 11:21:15 -0400 Subject: [PATCH] Add console panel --- ks_includes/KlipperScreen.conf | 5 ++ ks_includes/screen_panel.py | 2 - panels/base_panel.py | 5 +- panels/console.py | 109 +++++++++++++++++++++++++++++++ screen.py | 25 +++---- styles/colorized/style.css | 8 +++ styles/z-bolt/images/console.svg | 20 ++++++ styles/z-bolt/style.css | 9 +++ 8 files changed, 169 insertions(+), 14 deletions(-) create mode 100644 panels/console.py create mode 100644 styles/z-bolt/images/console.svg diff --git a/ks_includes/KlipperScreen.conf b/ks_includes/KlipperScreen.conf index 9af3eaff..9564affd 100644 --- a/ks_includes/KlipperScreen.conf +++ b/ks_includes/KlipperScreen.conf @@ -118,6 +118,11 @@ icon: motor-off method: printer.gcode.script params: {"script":"M18"} +[menu __main actions console] +name: {{ gettext('Console') }} +icon: console +panel: console + [menu __main config bedlevel] name: {{ gettext('Bed Level') }} icon: bed-level diff --git a/ks_includes/screen_panel.py b/ks_includes/screen_panel.py index 7200c55d..6456f934 100644 --- a/ks_includes/screen_panel.py +++ b/ks_includes/screen_panel.py @@ -27,8 +27,6 @@ class ScreenPanel: action_bar_width = self._gtk.get_action_bar_width() if action_bar == True else 0 self.content = Gtk.Box(spacing=0) - self.content.set_size_request(self._screen.width - action_bar_width, self._screen.height - self.title_spacing) - def initialize(self, panel_name): # Create gtk items here diff --git a/panels/base_panel.py b/panels/base_panel.py index 10a83a0a..bfe3210a 100644 --- a/panels/base_panel.py +++ b/panels/base_panel.py @@ -73,7 +73,7 @@ class BasePanel(ScreenPanel): self.titlelbl.set_valign(Gtk.Align.CENTER) self.set_title(title) - self.content = Gtk.Box(spacing=0) + self.content = Gtk.VBox(spacing=0) self.content.set_size_request(self._screen.width - action_bar_width, self._screen.height - self.title_spacing) if action_bar == True: @@ -146,6 +146,9 @@ class BasePanel(ScreenPanel): if self.current_panel == None: return + if self._screen.is_keyboard_showing(): + self._screen.remove_keyboard() + if hasattr(self.current_panel, "back"): if not self.current_panel.back(): self._screen._menu_go_back() diff --git a/panels/console.py b/panels/console.py new file mode 100644 index 00000000..41b730c9 --- /dev/null +++ b/panels/console.py @@ -0,0 +1,109 @@ +import gi +import logging +import time + +gi.require_version("Gtk", "3.0") +from gi.repository import Gtk, Gdk, GLib + +from datetime import datetime +from ks_includes.KlippyGcodes import KlippyGcodes +from ks_includes.screen_panel import ScreenPanel + +def create_panel(*args): + return ConsolePanel(*args) + +COLORS = { + "command": "#bad8ff", + "response": "#cccccc", + "time": "grey" +} + +class ConsolePanel(ScreenPanel): + def initialize(self, panel_name): + _ = self.lang.gettext + + + gcodes = self._screen._ws.send_method("server.gcode_store",{"count": 100}, self.gcode_response) + + + vbox = Gtk.VBox() + vbox.set_hexpand(True) + vbox.set_vexpand(True) + + sw = Gtk.ScrolledWindow() + sw.set_hexpand(True) + sw.set_vexpand(True) + + tb = Gtk.TextBuffer() + tv = Gtk.TextView() + tv.set_buffer(tb) + tv.set_sensitive(False) + tv.connect("size-allocate", self._autoscroll) + + sw.add(tv) + + ebox = Gtk.Box() + ebox.set_hexpand(True) + ebox.set_vexpand(False) + + entry = Gtk.Entry() + entry.set_hexpand(True) + entry.set_vexpand(False) + entry.connect("focus-in-event", self._show_keyboard) + + enter = self._gtk.Button("Send") + enter.set_hexpand(False) + enter.connect("clicked",self._send_command) + + ebox.add(entry) #, True, 0, 0) + ebox.add(enter) #, True, 0, 0) + + self.labels.update({ + "entry": entry, + "sw": sw, + "tb": tb, + "tv": tv + }) + + vbox.add(sw) + vbox.pack_end(ebox, False, 0, 0) + self.content.add(vbox) + self._screen.add_subscription(panel_name) + + def add_gcode(self, type, time, message): + if type == "command": + message = '$ %s' % (COLORS['command'], message) + else: + message = '%s' % (COLORS['response'], message) + + message = message.replace('\n','\n ') + + self.labels['tb'].insert_markup(self.labels['tb'].get_end_iter(), + '\n%s %s' % (COLORS['time'], datetime.fromtimestamp(time).strftime("%H:%M:%S"), + message), -1) + + def gcode_response(self, result, method, params): + if method != "server.gcode_store": + return + + logging.info("Gcodes: %s " % result) + for resp in result['result']['gcode_store']: + self.add_gcode(resp['type'], resp['time'], resp['message']) + + def process_update(self, action, data): + if action == "notify_gcode_response": + self.add_gcode("response", time.time(), data) + + def _autoscroll(self, *args): + adj = self.labels['sw'].get_vadjustment() + adj.set_value(adj.get_upper() - adj.get_page_size()) + + def _show_keyboard(self, *args): + self._screen.show_keyboard() + + def _send_command(self, *args): + cmd = self.labels['entry'].get_text() + self.labels['entry'].set_text('') + + self.add_gcode("command", time.time(), cmd) + self._screen._ws.klippy.gcode_script(cmd) diff --git a/screen.py b/screen.py index 75de61de..dfede8bf 100644 --- a/screen.py +++ b/screen.py @@ -286,15 +286,16 @@ class KlipperScreen(Gtk.Window): def show_panel(self, panel_name, type, title, remove=None, pop=True, **kwargs): if panel_name not in self.panels: - self.panels[panel_name] = self._load_panel(type, self, title) - try: + self.panels[panel_name] = self._load_panel(type, self, title) + if kwargs != {}: self.panels[panel_name].initialize(panel_name, **kwargs) else: self.panels[panel_name].initialize(panel_name) except: - del self.panels[panel_name] + if panel_name in self.panels: + del self.panels[panel_name] logging.exception("Unable to load panel %s" % type) self.show_error_modal("Unable to load panel %s" % type) return @@ -438,6 +439,11 @@ class KlipperScreen(Gtk.Window): Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION ) + def is_keyboard_showing(self): + if self.keyboard == None: + return False + return True + def is_printing(self): return self.printer.get_state() == "printing" @@ -781,24 +787,21 @@ class KlipperScreen(Gtk.Window): env["MB_KBD_CONFIG"] = "ks_includes/locales/keyboard.xml" p = subprocess.Popen(["matchbox-keyboard", "--xid"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) - #p = subprocess.Popen(["onboard", "--xid"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + xid = int(p.stdout.readline()) logging.debug("XID %s" % xid) logging.debug("PID %s" % p.pid) keyboard = Gtk.Socket() - #keyboard.connect("plug-added", self.plug_added) action_bar_width = self.gtk.get_action_bar_width() box = Gtk.VBox() + box.set_vexpand(False) box.set_size_request(self.width - action_bar_width, self.keyboard_height) box.add(keyboard) - cur_panel = self.panels[self._cur_panels[-1]] - #for i in ['back','estop','home']: - # if i in cur_panel.control: - # cur_panel.control[i].set_sensitive(False) - self.base_panel.get().put(box, action_bar_width, self.height - 200) + self.base_panel.get_content().pack_end(box, False, 0, 0) + self.show_all() keyboard.add_id(xid) keyboard.show() @@ -814,7 +817,7 @@ class KlipperScreen(Gtk.Window): if self.keyboard is None: return - self.base_panel.get().remove(self.keyboard['box']) + self.base_panel.get_content().remove(self.keyboard['box']) os.kill(self.keyboard['process'].pid, signal.SIGTERM) self.keyboard = None diff --git a/styles/colorized/style.css b/styles/colorized/style.css index b09c25e5..7302592d 100644 --- a/styles/colorized/style.css +++ b/styles/colorized/style.css @@ -110,6 +110,14 @@ scrollbar slider { background-color: #586e75; /*base01*/ } +textview, textview text { + background: transparent; +} + +textview .time { + color: grey; +} + trough { margin: .5em 1em; } diff --git a/styles/z-bolt/images/console.svg b/styles/z-bolt/images/console.svg new file mode 100644 index 00000000..3d5d51b7 --- /dev/null +++ b/styles/z-bolt/images/console.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + diff --git a/styles/z-bolt/style.css b/styles/z-bolt/style.css index bc4f3067..dfa8de94 100644 --- a/styles/z-bolt/style.css +++ b/styles/z-bolt/style.css @@ -111,6 +111,15 @@ scrollbar slider { background-color: #404E57; } +textview, textview text { + background: transparent; + font-family: Free Mono; +} + +textview .time { + color: grey; +} + trough { margin: .5em 1em; }