forked from CreatBot/CreatBotKlipperScreen
job_status: Refactored layout in panel
This commit is contained in:
@@ -16,6 +16,13 @@ config is included here: [ks_includes/KlipperScreen.conf](../ks_includes/Klipper
|
|||||||
invert_x: False
|
invert_x: False
|
||||||
invert_y: False
|
invert_y: False
|
||||||
invert_z: False
|
invert_z: False
|
||||||
|
|
||||||
|
# Time (seconds) before the Job Status page reverts to main menu after a successful job
|
||||||
|
job_complete_timeout: 30
|
||||||
|
|
||||||
|
# Time (seconds) before the Job Status page reverts to main menu after a successful job.
|
||||||
|
# If this option is 0, the user must click on a button to go back to the main menu.
|
||||||
|
job_error_timeout: 0
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,5 +1,12 @@
|
|||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
#### 2020 12 08
|
||||||
|
* Screen Width/Height are now definable in the configuration file
|
||||||
|
* Changed job page to allow for more information, display thumbnail of STL
|
||||||
|
* Job page will now say a job is complete and timeout to the main menu (time changeable from the config)
|
||||||
|
* Job page will now stay on the job page if there is an error.
|
||||||
|
* Restart option is available upon a completed/failed job
|
||||||
|
|
||||||
#### 2020 12 05
|
#### 2020 12 05
|
||||||
* Added ability to invert Z axis in move panel
|
* Added ability to invert Z axis in move panel
|
||||||
* Fixed problem with metadata being retreived constantly
|
* Fixed problem with metadata being retreived constantly
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 273 KiB |
@@ -14,15 +14,16 @@ class KlippyFiles:
|
|||||||
callbacks = []
|
callbacks = []
|
||||||
filelist = []
|
filelist = []
|
||||||
files = {}
|
files = {}
|
||||||
timeout = None
|
|
||||||
metadata_timeout = {}
|
metadata_timeout = {}
|
||||||
|
timeout = None
|
||||||
|
thumbnail_dir = "/tmp/.KS-thumbnails"
|
||||||
|
|
||||||
def __init__(self, screen):
|
def __init__(self, screen):
|
||||||
self._screen = screen
|
self._screen = screen
|
||||||
self.add_timeout()
|
self.add_timeout()
|
||||||
|
|
||||||
if not os.path.exists('/tmp/.KS-thumbnails'):
|
if not os.path.exists(self.thumbnail_dir):
|
||||||
os.makedirs('/tmp/.KS-thumbnails')
|
os.makedirs(self.thumbnail_dir)
|
||||||
GLib.idle_add(self.ret_files, False)
|
GLib.idle_add(self.ret_files, False)
|
||||||
|
|
||||||
|
|
||||||
@@ -71,7 +72,7 @@ class KlippyFiles:
|
|||||||
self.files[params['filename']]['thumbnails'].sort(key=lambda x: x['size'], reverse=True)
|
self.files[params['filename']]['thumbnails'].sort(key=lambda x: x['size'], reverse=True)
|
||||||
|
|
||||||
for thumbnail in self.files[params['filename']]['thumbnails']:
|
for thumbnail in self.files[params['filename']]['thumbnails']:
|
||||||
f = open("/tmp/.KS-thumbnails/%s-%s" % (params['filename'], thumbnail['size']), "wb")
|
f = open("%s/%s-%s" % (self.thumbnail_dir, params['filename'], thumbnail['size']), "wb")
|
||||||
f.write(base64.b64decode(thumbnail['data']))
|
f.write(base64.b64decode(thumbnail['data']))
|
||||||
f.close()
|
f.close()
|
||||||
for cb in self.callbacks:
|
for cb in self.callbacks:
|
||||||
@@ -84,11 +85,33 @@ class KlippyFiles:
|
|||||||
if self.timeout == None:
|
if self.timeout == None:
|
||||||
self.timeout = GLib.timeout_add(4000, self.ret_files)
|
self.timeout = GLib.timeout_add(4000, self.ret_files)
|
||||||
|
|
||||||
|
def file_exists(self, filename):
|
||||||
|
return True if filename in self.filelist else False
|
||||||
|
|
||||||
|
def file_metadata_exists(self, filename):
|
||||||
|
if not self.file_exists(filename):
|
||||||
|
return False
|
||||||
|
if "slicer" in self.files[filename]:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_thumbnail_location(self, filename):
|
||||||
|
if not self.has_thumbnail(filename):
|
||||||
|
return None
|
||||||
|
return "%s/%s-%s" % (self.thumbnail_dir, filename, self.files[filename]['thumbnails'][0]['size'])
|
||||||
|
|
||||||
|
def has_thumbnail(self, filename):
|
||||||
|
if filename not in self.files:
|
||||||
|
return False
|
||||||
|
return "thumbnails" in self.files[filename] and len(self.files[filename]) > 0
|
||||||
|
|
||||||
def remove_timeout(self):
|
def remove_timeout(self):
|
||||||
if self.timeout != None:
|
if self.timeout != None:
|
||||||
self.timeout = None
|
self.timeout = None
|
||||||
|
|
||||||
def request_metadata(self, filename):
|
def request_metadata(self, filename):
|
||||||
|
if filename not in self.filelist:
|
||||||
|
return False
|
||||||
if filename in self.metadata_timeout:
|
if filename in self.metadata_timeout:
|
||||||
GLib.source_remove(self.metadata_timeout[filename])
|
GLib.source_remove(self.metadata_timeout[filename])
|
||||||
self.metadata_timeout[filename] = GLib.timeout_add(
|
self.metadata_timeout[filename] = GLib.timeout_add(
|
||||||
|
@@ -15,6 +15,7 @@ class ScreenPanel:
|
|||||||
def __init__(self, screen, title, back=True):
|
def __init__(self, screen, title, back=True):
|
||||||
self._screen = screen
|
self._screen = screen
|
||||||
self._config = screen._config
|
self._config = screen._config
|
||||||
|
self._files = screen.files
|
||||||
self.lang = self._screen.lang
|
self.lang = self._screen.lang
|
||||||
self._printer = screen.printer
|
self._printer = screen.printer
|
||||||
self.labels = {}
|
self.labels = {}
|
||||||
@@ -62,6 +63,11 @@ class ScreenPanel:
|
|||||||
def get(self):
|
def get(self):
|
||||||
return self.layout
|
return self.layout
|
||||||
|
|
||||||
|
def get_file_image(self, filename, width=1.6, height=1.6):
|
||||||
|
if not self._files.has_thumbnail(filename):
|
||||||
|
return None
|
||||||
|
return self._gtk.PixbufFromFile(self._files.get_thumbnail_location(filename), None, width, height)
|
||||||
|
|
||||||
def home(self, widget):
|
def home(self, widget):
|
||||||
self._screen._ws.klippy.gcode_script(KlippyGcodes.HOME)
|
self._screen._ws.klippy.gcode_script(KlippyGcodes.HOME)
|
||||||
|
|
||||||
@@ -83,6 +89,9 @@ class ScreenPanel:
|
|||||||
def set_title(self, title):
|
def set_title(self, title):
|
||||||
self.title.set_label(title)
|
self.title.set_label(title)
|
||||||
|
|
||||||
|
def show_all(self):
|
||||||
|
self._screen.show_all()
|
||||||
|
|
||||||
def update_image_text(self, label, text):
|
def update_image_text(self, label, text):
|
||||||
if label in self.labels and 'l' in self.labels[label]:
|
if label in self.labels and 'l' in self.labels[label]:
|
||||||
self.labels[label]['l'].set_text(text)
|
self.labels[label]['l'].set_text(text)
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import gi
|
import gi
|
||||||
import logging
|
import logging
|
||||||
|
import math
|
||||||
|
|
||||||
gi.require_version("Gtk", "3.0")
|
gi.require_version("Gtk", "3.0")
|
||||||
from gi.repository import Gtk, Gdk, GLib, Pango
|
from gi.repository import Gtk, Gdk, GLib, Pango
|
||||||
@@ -14,32 +15,38 @@ def create_panel(*args):
|
|||||||
class JobStatusPanel(ScreenPanel):
|
class JobStatusPanel(ScreenPanel):
|
||||||
is_paused = False
|
is_paused = False
|
||||||
filename = None
|
filename = None
|
||||||
|
file_metadata = {}
|
||||||
|
progress = 0
|
||||||
|
state = "printing"
|
||||||
|
|
||||||
def initialize(self, panel_name):
|
def initialize(self, panel_name):
|
||||||
_ = self.lang.gettext
|
_ = self.lang.gettext
|
||||||
self.layout = Gtk.Layout()
|
self.layout = Gtk.Layout()
|
||||||
self.layout.set_size(self._screen.width, self._screen.height)
|
self.layout.set_size(self._screen.width, self._screen.height)
|
||||||
|
|
||||||
|
self.create_buttons()
|
||||||
|
|
||||||
grid = self._gtk.HomogeneousGrid()
|
grid = self._gtk.HomogeneousGrid()
|
||||||
grid.set_size_request(self._screen.width, self._screen.height)
|
grid.set_size_request(self._screen.width, self._screen.height)
|
||||||
|
|
||||||
self.labels['progress'] = self._gtk.ProgressBar("printing-progress-bar")
|
fi_box = Gtk.VBox(spacing=0)
|
||||||
self.labels['progress'].set_show_text(False)
|
fi_box.set_hexpand(True)
|
||||||
self.labels['progress_text'] = Gtk.Label()
|
fi_box.set_vexpand(False)
|
||||||
self.labels['progress_text'].get_style_context().add_class("printing-progress-text")
|
fi_box.set_halign(Gtk.Align.START)
|
||||||
overlay = Gtk.Overlay()
|
|
||||||
overlay.add(self.labels['progress'])
|
self.labels['file'] = Gtk.Label(label="file")
|
||||||
overlay.add_overlay(self.labels['progress_text'])
|
self.labels['file'].set_halign(Gtk.Align.START)
|
||||||
|
self.labels['file'].set_vexpand(False)
|
||||||
|
self.labels['file'].get_style_context().add_class("printing-filename")
|
||||||
|
self.labels['status'] = Gtk.Label()
|
||||||
|
self.labels['status'].set_halign(Gtk.Align.START)
|
||||||
|
self.labels['status'].set_vexpand(False)
|
||||||
|
self.labels['status'].get_style_context().add_class("printing-status")
|
||||||
|
|
||||||
|
fi_box.add(self.labels['file']) #, True, True, 0)
|
||||||
|
fi_box.add(self.labels['status']) #, True, True, 0)
|
||||||
|
fi_box.set_valign(Gtk.Align.CENTER)
|
||||||
|
|
||||||
self.labels['file'] = self._gtk.ImageLabel("file","",20,"printing-status-label")
|
|
||||||
self.labels['time_label'] = self._gtk.ImageLabel("speed-step",_("Time Elapsed"),20,"printing-status-label")
|
|
||||||
self.labels['time'] = self._gtk.Label(_("Time Elapsed"),"printing-status-label")
|
|
||||||
self.labels['time_left_label'] = self._gtk.ImageLabel("speed-step",_("Time Left"),20,"printing-status-label")
|
|
||||||
self.labels['time_left'] = self._gtk.Label(_("Time Left"),"printing-status-label")
|
|
||||||
timegrid = Gtk.Grid()
|
|
||||||
timegrid.attach(self.labels['time_label']['b'], 0, 0, 1, 1)
|
|
||||||
timegrid.attach(self.labels['time'], 0, 1, 1, 1)
|
|
||||||
timegrid.attach(self.labels['time_left_label']['b'], 1, 0, 1, 1)
|
|
||||||
timegrid.attach(self.labels['time_left'], 1, 1, 1, 1)
|
|
||||||
info = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
info = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||||
info.props.valign = Gtk.Align.CENTER
|
info.props.valign = Gtk.Align.CENTER
|
||||||
info.set_hexpand(True)
|
info.set_hexpand(True)
|
||||||
@@ -50,51 +57,222 @@ class JobStatusPanel(ScreenPanel):
|
|||||||
|
|
||||||
#grid.attach(info,2,0,2,1)
|
#grid.attach(info,2,0,2,1)
|
||||||
|
|
||||||
pbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
#pbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||||
pbox.pack_start(self.labels['file']['b'], False, True, 0)
|
#pbox.pack_start(self.labels['file']['b'], False, True, 0)
|
||||||
pbox.pack_end(timegrid, False, False, 0)
|
#pbox.pack_end(timegrid, False, False, 0)
|
||||||
#pbox.pack_end(self.labels['progress'], False, False, 0)
|
#pbox.pack_end(self.labels['progress'], False, False, 0)
|
||||||
pbox.pack_end(overlay, False, False, 0)
|
#pbox.pack_end(overlay, False, False, 0)
|
||||||
|
|
||||||
grid.attach(pbox, 1, 0, 3, 2)
|
#grid.attach(pbox, 0, 0, 4, 3)
|
||||||
|
self.labels['darea'] = Gtk.DrawingArea()
|
||||||
|
self.labels['darea'].connect("draw", self.on_draw)
|
||||||
|
|
||||||
self.labels['extruder'] = self._gtk.ButtonImage("extruder-1", self._gtk.formatTemperatureString(0, 0))
|
box = Gtk.Box()
|
||||||
self.labels['extruder'].set_sensitive(False)
|
box.set_hexpand(True)
|
||||||
grid.attach(self.labels['extruder'], 0, 0, 1, 1)
|
box.set_vexpand(True)
|
||||||
|
box.set_halign(Gtk.Align.CENTER)
|
||||||
|
self.labels['progress_text'] = Gtk.Label()
|
||||||
|
self.labels['progress_text'].get_style_context().add_class("printing-progress-text")
|
||||||
|
box.add(self.labels['progress_text'])
|
||||||
|
|
||||||
self.labels['heater_bed'] = self._gtk.ButtonImage("bed", self._gtk.formatTemperatureString(0, 0))
|
overlay = Gtk.Overlay()
|
||||||
self.labels['heater_bed'].set_sensitive(False)
|
overlay.set_hexpand(True)
|
||||||
grid.attach(self.labels['heater_bed'], 0, 1, 1, 1)
|
overlay.set_vexpand(True)
|
||||||
|
overlay.add(self.labels['darea'])
|
||||||
|
overlay.add_overlay(box)
|
||||||
|
|
||||||
self.labels['resume'] = self._gtk.ButtonImage("resume",_("Resume"),"color1")
|
#self.labels['extruder'] = self._gtk.ButtonImage("extruder-1", self._gtk.formatTemperatureString(0, 0))
|
||||||
self.labels['resume'].connect("clicked",self.resume)
|
#self.labels['extruder'].set_sensitive(False)
|
||||||
self.labels['pause'] = self._gtk.ButtonImage("pause",_("Pause"),"color1" )
|
#grid.attach(self.labels['extruder'], 0, 0, 1, 1)
|
||||||
self.labels['pause'].connect("clicked",self.pause)
|
|
||||||
|
|
||||||
if self._printer.get_stat('pause_resume','is_paused') == True:
|
#self.labels['heater_bed'] = self._gtk.ButtonImage("bed", self._gtk.formatTemperatureString(0, 0))
|
||||||
self.is_paused = True
|
#self.labels['heater_bed'].set_sensitive(False)
|
||||||
grid.attach(self.labels['resume'], 0, 2, 1, 1)
|
#grid.attach(self.labels['heater_bed'], 0, 1, 1, 1)
|
||||||
else:
|
|
||||||
grid.attach(self.labels['pause'], 0, 2, 1, 1)
|
|
||||||
|
|
||||||
self.labels['cancel'] = self._gtk.ButtonImage("stop",_("Cancel"),"color2")
|
self.labels['thumbnail'] = self._gtk.Image("file.svg", False, 1.6, 1.6)
|
||||||
self.labels['cancel'].connect("clicked", self.cancel)
|
|
||||||
grid.attach(self.labels['cancel'], 1, 2, 1, 1)
|
extruder = self._gtk.Image("extruder-1.svg", None, .6, .6)
|
||||||
self.labels['estop'] = self._gtk.ButtonImage("emergency",_("Emergency Stop"),"color4")
|
self.labels['extruder'] = Gtk.Label(label="")
|
||||||
self.labels['estop'].connect("clicked", self.emergency_stop)
|
self.labels['extruder'].get_style_context().add_class("printing-info")
|
||||||
grid.attach(self.labels['estop'], 2, 2, 1, 1)
|
extruder_box = Gtk.Box(spacing=0)
|
||||||
self.labels['control'] = self._gtk.ButtonImage("control",_("Control"),"color3")
|
extruder_box.add(extruder)
|
||||||
self.labels['control'].connect("clicked", self._screen._go_to_submenu, "")
|
extruder_box.add(self.labels['extruder'])
|
||||||
grid.attach(self.labels['control'], 3, 2, 1, 1)
|
heater_bed = self._gtk.Image("bed.svg", None, .6, .6)
|
||||||
|
self.labels['heater_bed'] = Gtk.Label(label="")
|
||||||
|
self.labels['heater_bed'].get_style_context().add_class("printing-info")
|
||||||
|
heater_bed_box = Gtk.Box(spacing=0)
|
||||||
|
heater_bed_box.add(heater_bed)
|
||||||
|
heater_bed_box.add(self.labels['heater_bed'])
|
||||||
|
temp_grid = self._gtk.HomogeneousGrid()
|
||||||
|
temp_grid.attach(extruder_box, 0, 0, 1, 1)
|
||||||
|
temp_grid.attach(heater_bed_box, 1, 0, 1, 1)
|
||||||
|
self.labels['temp_grid'] = temp_grid
|
||||||
|
|
||||||
|
# Create time remaining items
|
||||||
|
hourglass = self._gtk.Image("hourglass.svg", None, .6, .6)
|
||||||
|
self.labels['left'] = Gtk.Label(label=_("Left:"))
|
||||||
|
self.labels['left'].get_style_context().add_class("printing-info")
|
||||||
|
self.labels['time_left'] = Gtk.Label(label="0s")
|
||||||
|
self.labels['time_left'].get_style_context().add_class("printing-info")
|
||||||
|
itl_box = Gtk.Box(spacing=0)
|
||||||
|
itl_box.add(hourglass)
|
||||||
|
itl_box.add(self.labels['left'])
|
||||||
|
itl_box.add(self.labels['time_left'])
|
||||||
|
self.labels['itl_box'] = itl_box
|
||||||
|
|
||||||
|
# Create overall items
|
||||||
|
clock = self._gtk.Image("clock.svg", None, .6, .6)
|
||||||
|
self.labels['elapsed'] = Gtk.Label(label=_("Elapsed:"))
|
||||||
|
self.labels['elapsed'].get_style_context().add_class("printing-info")
|
||||||
|
self.labels['duration'] = Gtk.Label(label="0s")
|
||||||
|
self.labels['duration'].get_style_context().add_class("printing-info")
|
||||||
|
self.labels['est_time'] = Gtk.Label(label="/ 0s")
|
||||||
|
self.labels['est_time'].get_style_context().add_class("printing-info")
|
||||||
|
it_box = Gtk.Box(spacing=0)
|
||||||
|
it_box.add(clock)
|
||||||
|
it_box.add(self.labels['elapsed'])
|
||||||
|
it_box.add(self.labels['duration'])
|
||||||
|
it_box.add(self.labels['est_time'])
|
||||||
|
self.labels['it_box'] = it_box
|
||||||
|
|
||||||
|
position = self._gtk.Image("move.svg", None, .6, .6)
|
||||||
|
self.labels['pos_x'] = Gtk.Label(label="X: 0")
|
||||||
|
self.labels['pos_x'].get_style_context().add_class("printing-info")
|
||||||
|
self.labels['pos_y'] = Gtk.Label(label="Y: 0")
|
||||||
|
self.labels['pos_y'].get_style_context().add_class("printing-info")
|
||||||
|
self.labels['pos_z'] = Gtk.Label(label="Z: 0")
|
||||||
|
self.labels['pos_z'].get_style_context().add_class("printing-info")
|
||||||
|
pos_box = Gtk.Box(spacing=0)
|
||||||
|
posgrid = self._gtk.HomogeneousGrid()
|
||||||
|
posgrid.set_hexpand(True)
|
||||||
|
posgrid.attach(self.labels['pos_x'], 0, 0, 1, 1)
|
||||||
|
posgrid.attach(self.labels['pos_y'], 1, 0, 1, 1)
|
||||||
|
posgrid.attach(self.labels['pos_z'], 2, 0, 1, 1)
|
||||||
|
pos_box.add(position)
|
||||||
|
pos_box.add(posgrid)
|
||||||
|
self.labels['pos_box'] = pos_box
|
||||||
|
|
||||||
|
speed = self._gtk.Image("speed-step.svg", None, .6, .6)
|
||||||
|
self.labels['speed'] = Gtk.Label(label="")
|
||||||
|
self.labels['speed'].get_style_context().add_class("printing-info")
|
||||||
|
speed_box = Gtk.Box(spacing=0)
|
||||||
|
speed_box.add(speed)
|
||||||
|
speed_box.add(self.labels['speed'])
|
||||||
|
extrusion = self._gtk.Image("extrude.svg", None, .6, .6)
|
||||||
|
self.labels['extrusion'] = Gtk.Label(label="")
|
||||||
|
self.labels['extrusion'].get_style_context().add_class("printing-info")
|
||||||
|
extrusion_box = Gtk.Box(spacing=0)
|
||||||
|
extrusion_box.add(extrusion)
|
||||||
|
extrusion_box.add(self.labels['extrusion'])
|
||||||
|
fan = self._gtk.Image("fan.svg", None, .6, .6)
|
||||||
|
self.labels['fan'] = Gtk.Label(label="")
|
||||||
|
self.labels['fan'].get_style_context().add_class("printing-info")
|
||||||
|
fan_box = Gtk.Box(spacing=0)
|
||||||
|
fan_box.add(fan)
|
||||||
|
fan_box.add(self.labels['fan'])
|
||||||
|
sfe_grid = self._gtk.HomogeneousGrid()
|
||||||
|
sfe_grid.set_hexpand(True)
|
||||||
|
sfe_grid.attach(speed_box, 0, 0, 1, 1)
|
||||||
|
sfe_grid.attach(extrusion_box, 1, 0, 1, 1)
|
||||||
|
sfe_grid.attach(fan_box, 2, 0, 1, 1)
|
||||||
|
self.labels['sfe_grid'] = sfe_grid
|
||||||
|
|
||||||
|
self.labels['i1_box'] = Gtk.VBox(spacing=0)
|
||||||
|
self.labels['i1_box'].get_style_context().add_class("printing-info-box")
|
||||||
|
self.labels['i1_box'].set_valign(Gtk.Align.CENTER)
|
||||||
|
self.labels['i2_box'] = Gtk.VBox(spacing=0)
|
||||||
|
self.labels['i2_box'].get_style_context().add_class("printing-info-box")
|
||||||
|
|
||||||
|
grid.attach(overlay, 0, 0, 1, 1)
|
||||||
|
grid.attach(fi_box, 1, 0, 3, 1)
|
||||||
|
grid.attach(self.labels['i1_box'], 0, 1, 2, 2)
|
||||||
|
grid.attach(self.labels['i2_box'], 2, 1, 2, 2)
|
||||||
|
|
||||||
|
self.add_labels()
|
||||||
|
|
||||||
self.grid = grid
|
self.grid = grid
|
||||||
self.layout.put(grid, 0, 0)
|
self.layout.put(grid, 0, 0)
|
||||||
|
|
||||||
self._screen.add_subscription(panel_name)
|
self._screen.add_subscription(panel_name)
|
||||||
|
|
||||||
|
def on_draw(self, da, ctx):
|
||||||
|
w = da.get_allocated_width()
|
||||||
|
h = da.get_allocated_height()
|
||||||
|
r = min(w,h)*.4
|
||||||
|
|
||||||
|
ctx.set_source_rgb(0.6, 0.6, 0.6)
|
||||||
|
ctx.set_line_width(self._gtk.get_font_size() * .75)
|
||||||
|
ctx.translate(w / 2, h / 2)
|
||||||
|
ctx.arc(0, 0, r, 0, 2*math.pi)
|
||||||
|
ctx.stroke()
|
||||||
|
|
||||||
|
ctx.set_source_rgb(1, 0, 0)
|
||||||
|
ctx.arc(0, 0, r, 3/2*math.pi, 3/2*math.pi+(self.progress*2*math.pi))
|
||||||
|
ctx.stroke()
|
||||||
|
|
||||||
|
|
||||||
def activate(self):
|
def activate(self):
|
||||||
|
_ = self.lang.gettext
|
||||||
|
self.progress = self._printer.get_stat('virtual_sdcard','progress')
|
||||||
|
self.update_progress()
|
||||||
self.enable_button("pause","cancel","resume")
|
self.enable_button("pause","cancel","resume")
|
||||||
|
|
||||||
|
state = "printing"
|
||||||
|
self.update_text("status",_("Printing"))
|
||||||
|
|
||||||
|
self.filename = self._printer.get_stat('print_stats','filename')
|
||||||
|
self.update_file_metadata()
|
||||||
|
|
||||||
|
self.grid.remove_row(3)
|
||||||
|
self.grid.insert_row(3)
|
||||||
|
|
||||||
|
ps = self._printer.get_stat("print_stats")
|
||||||
|
logger.debug("Act State: %s" % ps['state'])
|
||||||
|
self.set_state(ps['state'])
|
||||||
|
self.show_buttons_for_state()
|
||||||
|
|
||||||
|
def add_labels(self):
|
||||||
|
for child in self.labels['i1_box'].get_children():
|
||||||
|
self.labels['i1_box'].remove(child)
|
||||||
|
for child in self.labels['i2_box'].get_children():
|
||||||
|
self.labels['i2_box'].remove(child)
|
||||||
|
|
||||||
|
#if self.file_metadata == None:
|
||||||
|
# self.labels['i1_box'].add(self.labels['temp_grid'])
|
||||||
|
# self.labels['i1_box'].add(self.labels['pos_box'])
|
||||||
|
# self.labels['i1_box'].add(self.labels['sfe_grid'])
|
||||||
|
# self.labels['i2_box'].add(self.labels['it_box'])
|
||||||
|
# self.labels['i2_box'].add(self.labels['itl_box'])
|
||||||
|
#else:
|
||||||
|
self.labels['i1_box'].add(self.labels['thumbnail'])
|
||||||
|
self.labels['i2_box'].add(self.labels['temp_grid'])
|
||||||
|
self.labels['i2_box'].add(self.labels['pos_box'])
|
||||||
|
self.labels['i2_box'].add(self.labels['sfe_grid'])
|
||||||
|
self.labels['i2_box'].add(self.labels['it_box'])
|
||||||
|
self.labels['i2_box'].add(self.labels['itl_box'])
|
||||||
|
|
||||||
|
|
||||||
|
def create_buttons(self):
|
||||||
|
_ = self.lang.gettext
|
||||||
|
self.labels['cancel'] = self._gtk.ButtonImage("stop",_("Cancel"),"color2")
|
||||||
|
self.labels['cancel'].connect("clicked", self.cancel)
|
||||||
|
self.labels['control'] = self._gtk.ButtonImage("control",_("Control"),"color3")
|
||||||
|
self.labels['control'].connect("clicked", self._screen._go_to_submenu, "")
|
||||||
|
self.labels['estop'] = self._gtk.ButtonImage("emergency",_("Emergency Stop"),"color4")
|
||||||
|
self.labels['estop'].connect("clicked", self.emergency_stop)
|
||||||
|
self.labels['menu'] = self._gtk.ButtonImage("complete",_("Main Menu"),"color4")
|
||||||
|
self.labels['menu'].connect("clicked", self.close_panel)
|
||||||
|
self.labels['pause'] = self._gtk.ButtonImage("pause",_("Pause"),"color1" )
|
||||||
|
self.labels['pause'].connect("clicked",self.pause)
|
||||||
|
self.labels['restart'] = self._gtk.ButtonImage("restart",_("Restart"),"color3")
|
||||||
|
self.labels['restart'].connect("clicked", self.restart)
|
||||||
|
self.labels['resume'] = self._gtk.ButtonImage("resume",_("Resume"),"color1")
|
||||||
|
self.labels['resume'].connect("clicked",self.resume)
|
||||||
|
|
||||||
|
def restart(self, widget):
|
||||||
|
if self.filename != "none":
|
||||||
|
self._screen._ws.klippy.print_start(self.filename)
|
||||||
|
|
||||||
def resume(self, widget):
|
def resume(self, widget):
|
||||||
#self.disable_button("resume","cancel")
|
#self.disable_button("resume","cancel")
|
||||||
self._screen._ws.klippy.print_resume(self._response_callback, "enable_button", "pause", "cancel")
|
self._screen._ws.klippy.print_resume(self._response_callback, "enable_button", "pause", "cancel")
|
||||||
@@ -138,6 +316,11 @@ class JobStatusPanel(ScreenPanel):
|
|||||||
if func == "enable_button":
|
if func == "enable_button":
|
||||||
self.enable_button(*args)
|
self.enable_button(*args)
|
||||||
|
|
||||||
|
def close_panel(self, widget=None):
|
||||||
|
if self._screen.is_printing():
|
||||||
|
self._screen.printer_ready()
|
||||||
|
return False
|
||||||
|
|
||||||
def enable_button(self, *args):
|
def enable_button(self, *args):
|
||||||
for arg in args:
|
for arg in args:
|
||||||
self.labels[arg].set_sensitive(True)
|
self.labels[arg].set_sensitive(True)
|
||||||
@@ -146,10 +329,10 @@ class JobStatusPanel(ScreenPanel):
|
|||||||
for arg in args:
|
for arg in args:
|
||||||
self.labels[arg].set_sensitive(False)
|
self.labels[arg].set_sensitive(False)
|
||||||
|
|
||||||
|
|
||||||
def process_update(self, action, data):
|
def process_update(self, action, data):
|
||||||
if action != "notify_status_update":
|
if action != "notify_status_update":
|
||||||
return
|
return
|
||||||
|
_ = self.lang.gettext
|
||||||
|
|
||||||
self.update_temp("heater_bed",
|
self.update_temp("heater_bed",
|
||||||
self._printer.get_dev_stat("heater_bed","temperature"),
|
self._printer.get_dev_stat("heater_bed","temperature"),
|
||||||
@@ -161,38 +344,134 @@ class JobStatusPanel(ScreenPanel):
|
|||||||
self._printer.get_dev_stat(x,"target")
|
self._printer.get_dev_stat(x,"target")
|
||||||
)
|
)
|
||||||
|
|
||||||
vsd = self._printer.get_stat("print_stats")
|
|
||||||
if "filename" in vsd and self.filename != vsd['filename']:
|
if "toolhead" in data and "position" in data["toolhead"]:
|
||||||
if vsd['filename'] != "":
|
self.labels['pos_x'].set_text("X: %.2f" % (data["toolhead"]["position"][0]))
|
||||||
self.filename = self._gtk.formatFileName(vsd['filename'])
|
self.labels['pos_y'].set_text("Y: %.2f" % (data["toolhead"]["position"][1]))
|
||||||
self.update_image_text("file", self.filename)
|
self.labels['pos_z'].set_text("Z: %.2f" % (data["toolhead"]["position"][2]))
|
||||||
|
if "gcode_move" in data:
|
||||||
|
#if "homing_origin" in data["gcode_move"]:
|
||||||
|
# self.labels['zoffset'].set_text("%.2fmm" % data["gcode_move"]["homing_origin"][2])
|
||||||
|
if "extrude_factor" in data["gcode_move"]:
|
||||||
|
self.extrusion = int(data["gcode_move"]["extrude_factor"]*100)
|
||||||
|
self.labels['extrusion'].set_text("%3d%%" % self.extrusion)
|
||||||
|
if "speed_factor" in data["gcode_move"]:
|
||||||
|
self.speed = int(data["gcode_move"]["speed_factor"]*100)
|
||||||
|
self.labels['speed'].set_text("%3d%%" % self.speed)
|
||||||
|
if "fan" in data and "speed" in data['fan']:
|
||||||
|
self.fan = int(round(data['fan']['speed'],2)*100)
|
||||||
|
self.labels['fan'].set_text("%3d%%" % self.fan)
|
||||||
|
|
||||||
|
if "print_stats" in data or "virtual_sdcard" in data:
|
||||||
|
ps = self._printer.get_stat("print_stats")
|
||||||
|
vsd = self._printer.get_stat("virtual_sdcard")
|
||||||
|
if ps['state'] == "printing" and self.state != "printing":
|
||||||
|
self.set_state("printing")
|
||||||
|
self.show_buttons_for_state()
|
||||||
|
if ps['state'] == "complete" and self.state != "complete":
|
||||||
|
self.progress = 1
|
||||||
|
self.update_progress()
|
||||||
|
self.set_state("complete")
|
||||||
|
self.show_buttons_for_state()
|
||||||
|
timeout = self._config.get_main_config().getint("job_complete_timeout", 30)
|
||||||
|
GLib.timeout_add(timeout * 1000, self.close_panel)
|
||||||
|
elif ps['state'] == "error" and self.state != "error":
|
||||||
|
logger.debug("Error!")
|
||||||
|
self.set_state("error")
|
||||||
|
self.labels['status'].set_text("Error - %s" % ps['message'])
|
||||||
|
self.show_buttons_for_state()
|
||||||
|
timeout = self._config.get_main_config().getint("job_error_timeout", 0)
|
||||||
|
if timeout != 0:
|
||||||
|
GLib.timeout_add(timeout * 1000, self.close_panel)
|
||||||
|
|
||||||
|
if "filename" in ps and self.filename != ps['filename']:
|
||||||
|
if ps['filename'] != "":
|
||||||
|
self.filename = ps['filename']
|
||||||
|
self.file_metadata = None
|
||||||
|
self.update_text("file", self.filename)
|
||||||
|
else:
|
||||||
|
file = "Unknown"
|
||||||
|
self.update_text("file", "Unknown file")
|
||||||
|
|
||||||
|
if self.file_metadata == None:
|
||||||
|
if self._files.file_metadata_exists(self.filename):
|
||||||
|
self.update_file_metadata()
|
||||||
|
self.add_labels()
|
||||||
else:
|
else:
|
||||||
file = "Unknown"
|
if "gcode_start_byte" in self.file_metadata:
|
||||||
self.update_image_text("file", "Unknown")
|
progress = (max(vsd['file_position'] - self.file_metadata['gcode_start_byte'],0) /
|
||||||
|
(self.file_metadata['gcode_end_byte'] - self.file_metadata['gcode_start_byte']))
|
||||||
|
else:
|
||||||
|
progress = 0 if self._printer.get_stat('virtual_sdcard','progress') == 0 else (ps['print_duration']/
|
||||||
|
self._printer.get_stat('virtual_sdcard','progress') - ps['print_duration'])
|
||||||
|
progress = round(progress,2)
|
||||||
|
|
||||||
|
if progress != self.progress:
|
||||||
|
self.progress = progress
|
||||||
|
self.labels['darea'].queue_draw()
|
||||||
|
|
||||||
progress = 0 if self._printer.get_stat('virtual_sdcard','progress') == 0 else (vsd['print_duration'] /
|
if ps['print_duration'] == 0:
|
||||||
self._printer.get_stat('virtual_sdcard','progress') - vsd['print_duration'])
|
time_left = self.file_metadata['estimated_time'] if "estimated_time" in self.file_metadata else 0
|
||||||
|
else:
|
||||||
|
est_time = self.file_metadata['estimated_time'] if "estimated_time" in self.file_metadata else 0
|
||||||
|
time_left = max(
|
||||||
|
est_time - ps['print_duration'] ,
|
||||||
|
0 #ps['print_duration'] / (vsd['progress'] if vsd['progress'] != 0 else 1)
|
||||||
|
)
|
||||||
|
|
||||||
self.update_text("time", str(self._gtk.formatTimeString(vsd['print_duration'])))
|
self.update_text("duration", str(self._gtk.formatTimeString(ps['print_duration'])))
|
||||||
self.update_text("time_left", str(self._gtk.formatTimeString(
|
self.update_text("time_left", str(self._gtk.formatTimeString(time_left)))
|
||||||
progress
|
self.update_progress()
|
||||||
)))
|
|
||||||
|
|
||||||
self.update_progress(self._printer.get_stat('virtual_sdcard','progress'))
|
if "pause_resume" in data and self.state != "complete":
|
||||||
|
if self.state == "paused" and data['pause_resume']['is_paused'] == False:
|
||||||
if "pause_resume" in data:
|
self.set_state("printing")
|
||||||
if self.is_paused == True and data['pause_resume']['is_paused'] == False:
|
self.update_text("status",_("Paused"))
|
||||||
self.is_paused = False
|
self.grid.attach(self.labels['pause'], 0, 3, 1, 1)
|
||||||
self.grid.attach(self.labels['pause'], 0, 2, 1, 1)
|
|
||||||
self.grid.remove(self.labels['resume'])
|
self.grid.remove(self.labels['resume'])
|
||||||
self.grid.show_all()
|
self.grid.show_all()
|
||||||
if self.is_paused == False and data['pause_resume']['is_paused'] == True:
|
if self.state != "paused" and data['pause_resume']['is_paused'] == True:
|
||||||
self.is_paused = True
|
self.set_state("paused")
|
||||||
self.grid.attach(self.labels['resume'], 0, 2, 1, 1)
|
self.grid.attach(self.labels['resume'], 0, 3, 1, 1)
|
||||||
self.grid.remove(self.labels['pause'])
|
self.grid.remove(self.labels['pause'])
|
||||||
self.grid.show_all()
|
self.grid.show_all()
|
||||||
|
|
||||||
|
def set_state(self, state):
|
||||||
|
self.state = state
|
||||||
|
self.update_text("status",state.capitalize())
|
||||||
|
|
||||||
|
def show_buttons_for_state(self):
|
||||||
|
self.grid.remove_row(3)
|
||||||
|
self.grid.insert_row(3)
|
||||||
|
if self.state == "printing":
|
||||||
|
self.grid.attach(self.labels['pause'], 0, 3, 1, 1)
|
||||||
|
self.grid.attach(self.labels['cancel'], 1, 3, 1, 1)
|
||||||
|
self.grid.attach(self.labels['estop'], 2, 3, 1, 1)
|
||||||
|
self.grid.attach(self.labels['control'], 3, 3, 1, 1)
|
||||||
|
elif self.state == "paused":
|
||||||
|
self.grid.attach(self.labels['resume'], 0, 3, 1, 1)
|
||||||
|
self.grid.attach(self.labels['cancel'], 1, 3, 1, 1)
|
||||||
|
self.grid.attach(self.labels['estop'], 2, 3, 1, 1)
|
||||||
|
self.grid.attach(self.labels['control'], 3, 3, 1, 1)
|
||||||
|
elif self.state == "error" or self.state == "complete":
|
||||||
|
self.grid.attach(self.labels['restart'], 2, 3, 1, 1)
|
||||||
|
self.grid.attach(self.labels['menu'], 3, 3, 1, 1)
|
||||||
|
self.show_all()
|
||||||
|
|
||||||
|
def show_file_thumbnail(self):
|
||||||
|
if self._files.has_thumbnail(self.filename):
|
||||||
|
pixbuf = self.get_file_image(self.filename, 7, 3.25)
|
||||||
|
if pixbuf != None:
|
||||||
|
self.labels['thumbnail'].set_from_pixbuf(pixbuf)
|
||||||
|
|
||||||
|
def update_file_metadata(self):
|
||||||
|
if self._files.file_metadata_exists(self.filename):
|
||||||
|
self.file_metadata = self._files.get_file_info(self.filename)
|
||||||
|
self.update_text("est_time","/ %s" % str(self._gtk.formatTimeString(self.file_metadata['estimated_time'])))
|
||||||
|
self.show_file_thumbnail()
|
||||||
|
else:
|
||||||
|
self.file_metadata = None
|
||||||
|
|
||||||
def update_image_text(self, label, text):
|
def update_image_text(self, label, text):
|
||||||
if label in self.labels and 'l' in self.labels[label]:
|
if label in self.labels and 'l' in self.labels[label]:
|
||||||
self.labels[label]['l'].set_text(text)
|
self.labels[label]['l'].set_text(text)
|
||||||
@@ -201,10 +480,14 @@ class JobStatusPanel(ScreenPanel):
|
|||||||
if label in self.labels:
|
if label in self.labels:
|
||||||
self.labels[label].set_text(text)
|
self.labels[label].set_text(text)
|
||||||
|
|
||||||
def update_progress (self, progress):
|
def update_progress (self):
|
||||||
self.labels['progress'].set_fraction(progress)
|
self.labels['progress_text'].set_text("%s%%" % (str(int(self.progress*100))))
|
||||||
self.labels['progress_text'].set_text("%s%%" % (str(int(progress*100))))
|
|
||||||
|
|
||||||
def update_temp(self, dev, temp, target):
|
#def update_temp(self, dev, temp, target):
|
||||||
if dev in self.labels:
|
# if dev in self.labels:
|
||||||
self.labels[dev].set_label(self._gtk.formatTemperatureString(temp, target))
|
# self.labels[dev].set_label(self._gtk.formatTemperatureString(temp, target))
|
||||||
|
|
||||||
|
def update_temp(self, x, temp, target):
|
||||||
|
self.labels[x].set_markup(
|
||||||
|
"%.1f<big>/</big>%.0f °C" % (temp, target)
|
||||||
|
)
|
||||||
|
11
screen.py
11
screen.py
@@ -271,6 +271,9 @@ class KlipperScreen(Gtk.Window):
|
|||||||
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
|
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def is_printing(self):
|
||||||
|
return "job_status" in self._cur_panels
|
||||||
|
|
||||||
def _go_to_submenu(self, widget, name):
|
def _go_to_submenu(self, widget, name):
|
||||||
logger.info("#### Go to submenu " + str(name))
|
logger.info("#### Go to submenu " + str(name))
|
||||||
#self._remove_current_panel(False)
|
#self._remove_current_panel(False)
|
||||||
@@ -355,10 +358,7 @@ class KlipperScreen(Gtk.Window):
|
|||||||
else:
|
else:
|
||||||
active = self.printer.get_stat('virtual_sdcard','is_active')
|
active = self.printer.get_stat('virtual_sdcard','is_active')
|
||||||
paused = self.printer.get_stat('pause_resume','is_paused')
|
paused = self.printer.get_stat('pause_resume','is_paused')
|
||||||
if "job_status" in self._cur_panels:
|
if "job_status" not in self._cur_panels:
|
||||||
if active == False and paused == False:
|
|
||||||
self.printer_ready()
|
|
||||||
else:
|
|
||||||
if active == True or paused == True:
|
if active == True or paused == True:
|
||||||
self.printer_printing()
|
self.printer_printing()
|
||||||
elif action == "notify_filelist_changed":
|
elif action == "notify_filelist_changed":
|
||||||
@@ -463,6 +463,9 @@ class KlipperScreen(Gtk.Window):
|
|||||||
self.printer_initializing(_("Klipper has shutdown"))
|
self.printer_initializing(_("Klipper has shutdown"))
|
||||||
return
|
return
|
||||||
if (data['print_stats']['state'] == "printing" or data['print_stats']['state'] == "paused"):
|
if (data['print_stats']['state'] == "printing" or data['print_stats']['state'] == "paused"):
|
||||||
|
filename = self.printer.get_stat("print_stats","filename")
|
||||||
|
if not self.files.file_metadata_exists(filename):
|
||||||
|
self.files.request_metadata(filename)
|
||||||
self.printer_printing()
|
self.printer_printing()
|
||||||
return
|
return
|
||||||
self.printer_ready()
|
self.printer_ready()
|
||||||
|
@@ -220,12 +220,38 @@ trough {
|
|||||||
margin: 0 .15em .15em 0;
|
margin: 0 .15em .15em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.printing-filename {
|
||||||
|
font-size: 1.75em;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: .25em 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.printing-info {
|
||||||
|
font-size: 1.2em;
|
||||||
|
margin-left: .25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.printing-info-box {
|
||||||
|
padding-left: .25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.printing-info-box box {
|
||||||
|
margin-bottom: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.printing-status {
|
||||||
|
color: #f0f0f0;
|
||||||
|
font-style: italic;
|
||||||
|
margin: 0 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
.printing-progress-bar {
|
.printing-progress-bar {
|
||||||
color: #00C9B4;
|
color: #00C9B4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.printing-progress-text {
|
.printing-progress-text {
|
||||||
font-size: 1.25em;
|
font-size: 1.5em;
|
||||||
|
font-weight: bold;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
styles/z-bolt/images/clock.svg
Normal file
1
styles/z-bolt/images/clock.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" ?><svg data-name="Layer 1" id="Layer_1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title/><path style="fill:#FFFFFF" d="M12,2A10,10,0,1,0,22,12,10,10,0,0,0,12,2Zm0,18a8,8,0,1,1,8-8A8,8,0,0,1,12,20ZM13,6H11v7h6V11H13Z"/></svg>
|
After Width: | Height: | Size: 259 B |
1
styles/z-bolt/images/hourglass.svg
Normal file
1
styles/z-bolt/images/hourglass.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" ?><svg data-name="Layer 1" id="Layer_1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title/><path style="fill:#FFFFFF" d="M19,6.76V2H6V6.76A4,4,0,0,0,7.17,9.59L9.59,12,7.17,14.41A4.06,4.06,0,0,0,6,17.24V22H19V17.24a4.06,4.06,0,0,0-1.17-2.83L15.41,12l2.42-2.41A4,4,0,0,0,19,6.76ZM8,4h9V6H8Zm8.41,11.83A2,2,0,0,1,17,17.24V20H8V17.24a2,2,0,0,1,.59-1.41l2.76-2.77L11.4,13h2.2l.05.06Zm-2.76-4.89L13.6,11H11.4l-.05-.06L8.59,8.17A1.22,1.22,0,0,1,8.44,8h8.12a1.22,1.22,0,0,1-.15.17Z"/></svg>
|
After Width: | Height: | Size: 515 B |
Reference in New Issue
Block a user