Use callbacks to disable and enable buttons to improve user feedback

buttons now show a spinner if watiting for callback
This commit is contained in:
alfrix 2023-08-08 02:07:06 -03:00 committed by Alfredo Monclus
parent e7b58edfbf
commit 90fc3288d7
12 changed files with 77 additions and 73 deletions

View File

@ -165,8 +165,13 @@ class KlippyGtk:
scale = scale * 1.4
width = height = self.img_scale * scale
b.set_image(self.Image(image_name, width, height))
b.set_image_position(position)
b.set_always_show_image(True)
b.set_image_position(position)
b.set_always_show_image(True)
spinner = Gtk.Spinner.new()
spinner.set_no_show_all(True)
spinner.set_size_request(width, height)
spinner.hide()
b.get_child().get_child().add(spinner)
if label is not None:
format_label(b, lines)
@ -175,6 +180,24 @@ class KlippyGtk:
b.connect("clicked", self.screen.reset_screensaver_timeout)
return b
@staticmethod
def Button_busy(widget, busy):
box = widget.get_child().get_child()
if busy:
widget.set_sensitive(False)
widget.set_always_show_image(False)
box.get_children()[0].hide()
if type(box.get_children()[1]) == Gtk.Spinner:
box.get_children()[1].start()
box.get_children()[1].show()
else:
box.get_children()[0].show()
if type(box.get_children()[1]) == Gtk.Spinner:
box.get_children()[1].stop()
box.get_children()[1].hide()
widget.set_always_show_image(True)
widget.set_sensitive(True)
def Dialog(self, screen, buttons, content, callback=None, *args):
dialog = Gtk.Dialog()
dialog.set_default_size(screen.width, screen.height)

View File

@ -306,6 +306,7 @@ class Panel(ScreenPanel):
self._screen._ws.klippy.gcode_script("Z_TILT_ADJUST")
def go_to_position(self, widget, position):
widget.set_sensitive(False)
self.home()
logging.debug(f"Going to position: {position}")
script = [
@ -314,15 +315,10 @@ class Panel(ScreenPanel):
f"G1 X{position[0]} Y{position[1]} F{self.horizontal_speed * 60}\n",
f"G1 Z{self.probe_z_height} F{self.lift_speed * 60}\n"
]
self._screen._ws.klippy.gcode_script(
"\n".join(script)
)
self._screen._send_action(widget, "printer.gcode.script", {"script": "\n".join(script)})
def disable_motors(self, widget):
self._screen._ws.klippy.gcode_script(
"M18" # Disable motors
)
self._screen._send_action(widget, "printer.gcode.script", {"script": "M18"})
def process_busy(self, busy):
for button in self.buttons:
@ -401,7 +397,8 @@ class Panel(ScreenPanel):
return sorted(screws, key=lambda s: (float(s[1]), float(s[0])))
def screws_tilt_calculate(self, widget):
widget.set_sensitive(False)
self.home()
self.response_count = 0
self.buttons['screws'].set_sensitive(False)
self._screen._ws.klippy.gcode_script("SCREWS_TILT_CALCULATE")
self._screen._send_action(widget, "printer.gcode.script", {"script": "SCREWS_TILT_CALCULATE"})

View File

@ -172,20 +172,7 @@ class Panel(ScreenPanel):
if prof not in bm_profiles:
self.remove_profile(prof)
def process_busy(self, busy):
for button in self.buttons:
if button == 'clear':
self.buttons[button].set_sensitive(self.active_mesh is not None)
continue
self.buttons[button].set_sensitive((not busy))
for profile in self.profiles:
self.profiles[profile]["save"].set_sensitive((not busy))
self.profiles[profile]["delete"].set_sensitive((not busy))
def process_update(self, action, data):
if action == "notify_busy":
self.process_busy(data)
return
if action != "notify_status_update":
return
if 'bed_mesh' in data and 'profile_name' in data['bed_mesh']:
@ -257,29 +244,30 @@ class Panel(ScreenPanel):
if self.active_mesh is None:
self.calibrate_mesh(None)
self._screen._ws.klippy.gcode_script(f"BED_MESH_PROFILE SAVE={name}")
self._screen._send_action(widget, "printer.gcode.script", {"script": f"BED_MESH_PROFILE SAVE={name}"})
self.remove_create()
def calibrate_mesh(self, widget):
widget.set_sensitive(False)
self._screen.show_popup_message(_("Calibrating"), level=1)
if self._printer.get_stat("toolhead", "homed_axes") != "xyz":
self._screen._ws.klippy.gcode_script("G28")
self._screen._ws.klippy.gcode_script("BED_MESH_CALIBRATE")
self._screen._send_action(widget, "printer.gcode.script", {"script": "BED_MESH_CALIBRATE"})
# Load zcalibrate to do a manual mesh
if not self._printer.get_probe():
self.menu_item_clicked(widget, {"name": _("Mesh calibrate"), "panel": "zcalibrate"})
def send_clear_mesh(self, widget):
self._screen._ws.klippy.gcode_script("BED_MESH_CLEAR")
self._screen._send_action(widget, "printer.gcode.script", {"script": "BED_MESH_CLEAR"})
def send_load_mesh(self, widget, profile):
self._screen._ws.klippy.gcode_script(KlippyGcodes.bed_mesh_load(profile))
self._screen._send_action(widget, "printer.gcode.script", {"script": KlippyGcodes.bed_mesh_load(profile)})
def send_save_mesh(self, widget, profile):
self._screen._ws.klippy.gcode_script(KlippyGcodes.bed_mesh_save(profile))
self._screen._send_action(widget, "printer.gcode.script", {"script": KlippyGcodes.bed_mesh_save(profile)})
def send_remove_mesh(self, widget, profile):
self._screen._ws.klippy.gcode_script(KlippyGcodes.bed_mesh_remove(profile))
self._screen._send_action(widget, "printer.gcode.script", {"script": KlippyGcodes.bed_mesh_remove(profile)})
self.remove_profile(profile)

View File

@ -216,8 +216,8 @@ class Panel(ScreenPanel):
for tool in self._printer.get_tools():
self.labels[tool].get_style_context().remove_class("button_active")
self.labels[extruder].get_style_context().add_class("button_active")
self._screen._ws.klippy.gcode_script(f"T{self._printer.get_tool_number(extruder)}")
self._screen._send_action(widget, "printer.gcode.script",
{"script": f"T{self._printer.get_tool_number(extruder)}"})
def change_speed(self, widget, speed):
logging.info(f"### Speed {speed}")
@ -227,19 +227,22 @@ class Panel(ScreenPanel):
def extrude(self, widget, direction):
self._screen._ws.klippy.gcode_script(KlippyGcodes.EXTRUDE_REL)
self._screen._ws.klippy.gcode_script(f"G1 E{direction}{self.distance} F{self.speed * 60}")
self._screen._send_action(widget, "printer.gcode.script",
{"script": f"G1 E{direction}{self.distance} F{self.speed * 60}"})
def load_unload(self, widget, direction):
if direction == "-":
if not self.unload_filament:
self._screen.show_popup_message("Macro UNLOAD_FILAMENT not found")
else:
self._screen._ws.klippy.gcode_script(f"UNLOAD_FILAMENT SPEED={self.speed * 60}")
self._screen._send_action(widget, "printer.gcode.script",
{"script": f"UNLOAD_FILAMENT SPEED={self.speed * 60}"})
if direction == "+":
if not self.load_filament:
self._screen.show_popup_message("Macro LOAD_FILAMENT not found")
else:
self._screen._ws.klippy.gcode_script(f"LOAD_FILAMENT SPEED={self.speed * 60}")
self._screen._send_action(widget, "printer.gcode.script",
{"script": f"LOAD_FILAMENT SPEED={self.speed * 60}"})
def enable_disable_fs(self, switch, gparams, name, x):
if switch.get_active():

View File

@ -144,14 +144,15 @@ class Panel(ScreenPanel):
def change_babystepping(self, widget, direction):
if direction == "reset":
self.labels['zoffset'].set_label(' 0.00mm')
self._screen._ws.klippy.gcode_script("SET_GCODE_OFFSET Z=0 MOVE=1")
self._screen._send_action(widget, "printer.gcode.script", {"script": "SET_GCODE_OFFSET Z=0 MOVE=1"})
return
elif direction == "+":
self.z_offset += float(self.z_delta)
elif direction == "-":
self.z_offset -= float(self.z_delta)
self.labels['zoffset'].set_label(f' {self.z_offset:.3f}mm')
self._screen._ws.klippy.gcode_script(f"SET_GCODE_OFFSET Z_ADJUST={direction}{self.z_delta} MOVE=1")
self._screen._send_action(widget, "printer.gcode.script",
{"script": f"SET_GCODE_OFFSET Z_ADJUST={direction}{self.z_delta} MOVE=1"})
def change_extrusion(self, widget, direction):
if direction == "+":
@ -162,7 +163,8 @@ class Panel(ScreenPanel):
self.extrusion = 100
self.extrusion = max(self.extrusion, 1)
self.labels['extrudefactor'].set_label(f" {self.extrusion:3}%")
self._screen._ws.klippy.gcode_script(KlippyGcodes.set_extrusion_rate(self.extrusion))
self._screen._send_action(widget, "printer.gcode.script",
{"script": KlippyGcodes.set_extrusion_rate(self.extrusion)})
def change_speed(self, widget, direction):
if direction == "+":
@ -174,7 +176,7 @@ class Panel(ScreenPanel):
self.speed = max(self.speed, 1)
self.labels['speedfactor'].set_label(f" {self.speed:3}%")
self._screen._ws.klippy.gcode_script(KlippyGcodes.set_speed_rate(self.speed))
self._screen._send_action(widget, "printer.gcode.script", {"script": KlippyGcodes.set_speed_rate(self.speed)})
def change_percent_delta(self, widget, array, delta):
logging.info(f"### Delta {delta}")

View File

@ -111,9 +111,9 @@ class Panel(ScreenPanel):
for param in self.macros[macro]["params"]:
value = self.macros[macro]["params"][param].get_text()
if value:
params += f'{param}={value} '
params += f' {param}={value}'
self._screen.show_popup_message(f"{macro} {params}", 1)
self._screen._ws.klippy.gcode_script(f"{macro} {params}")
self._screen._send_action(widget, "printer.gcode.script", {"script": f"{macro}{params}"})
def change_sort(self, widget):
self.sort_reverse ^= True

View File

@ -110,14 +110,12 @@ class Panel(ScreenPanel):
self._screen._ws.klippy.gcode_script("G28")
self.calibrating_axis = method
if method == "x":
self._screen._ws.klippy.gcode_script('SHAPER_CALIBRATE AXIS=X')
self._screen._send_action(self.calibrate_btn, "printer.gcode.script", {"script": 'SHAPER_CALIBRATE AXIS=X'})
if method == "y":
self._screen._ws.klippy.gcode_script('SHAPER_CALIBRATE AXIS=Y')
self._screen._send_action(self.calibrate_btn, "printer.gcode.script", {"script": 'SHAPER_CALIBRATE AXIS=Y'})
if method == "both":
self._screen._ws.klippy.gcode_script('SHAPER_CALIBRATE')
self._screen._send_action(self.calibrate_btn, "printer.gcode.script", {"script": 'SHAPER_CALIBRATE'})
self.calibrate_btn.set_label(_('Calibrating') + '...')
self.calibrate_btn.set_sensitive(False)
def set_opt_value(self, widget, opt, *args):
shaper_freq_x = self.freq_xy_adj['shaper_freq_x'].get_value()

View File

@ -420,8 +420,7 @@ class Panel(ScreenPanel):
if self.filename:
self.disable_button("restart")
if self.state == "error":
script = {"script": "SDCARD_RESET_FILE"}
self._screen._send_action(None, "printer.gcode.script", script)
self._screen._ws.klippy.gcode_script("SDCARD_RESET_FILE")
self._screen._ws.klippy.print_start(self.filename)
logging.info(f"Starting print: {self.filename}")
self.new_print()

View File

@ -36,7 +36,6 @@ class Panel(ScreenPanel):
self.buttons['motors_off'].connect("clicked", self._screen._confirm_send_action,
_("Are you sure you wish to disable motors?"),
"printer.gcode.script", script)
grid = self._gtk.HomogeneousGrid()
if self._screen.vertical_mode:
if self._screen.lang_ltr:
@ -135,16 +134,7 @@ class Panel(ScreenPanel):
name = list(option)[0]
self.add_option('options', self.settings, name, option[name])
def process_busy(self, busy):
buttons = ("home", "motors_off")
for button in buttons:
if button in self.buttons:
self.buttons[button].set_sensitive(not busy)
def process_update(self, action, data):
if action == "notify_busy":
self.process_busy(data)
return
if action != "notify_status_update":
return
homed_axes = self._printer.get_stat("toolhead", "homed_axes")
@ -186,8 +176,8 @@ class Panel(ScreenPanel):
if speed is None:
speed = self._config.get_config()['main'].getint(config_key, 20)
speed = 60 * max(1, speed)
self._screen._ws.klippy.gcode_script(f"{KlippyGcodes.MOVE_RELATIVE}\nG0 {axis}{dist} F{speed}")
script = f"{KlippyGcodes.MOVE_RELATIVE}\nG0 {axis}{dist} F{speed}"
self._screen._send_action(widget, "printer.gcode.script", {"script": script})
if self._printer.get_stat("gcode_move", "absolute_coordinates"):
self._screen._ws.klippy.gcode_script("G90")
@ -250,7 +240,7 @@ class Panel(ScreenPanel):
def home(self, widget):
if "delta" in self._printer.get_config_section("printer")['kinematics']:
self._screen._ws.klippy.gcode_script("G28")
self._screen._send_action(widget, "printer.gcode.script", {"script": 'G28'})
return
name = "homing"
disname = self._screen._config.get_menu_name("move", name)

View File

@ -257,7 +257,7 @@ class Panel(ScreenPanel):
self._screen._ws.klippy.set_temp_fan_temp(name, target)
# This small delay is needed to properly update the target if the user configured something above
# and then changed the target again using preheat gcode
GLib.timeout_add(250, self.preheat_gcode, setting)
GLib.timeout_add(250, self.preheat_gcode, widget, setting)
def validate(self, heater, target=None, max_temp=None):
if target is not None and max_temp is not None:
@ -270,9 +270,10 @@ class Panel(ScreenPanel):
logging.debug(f"Invalid {heater} Target:{target}/{max_temp}")
return False
def preheat_gcode(self, setting):
def preheat_gcode(self, widget, setting):
with suppress(KeyError):
self._screen._ws.klippy.gcode_script(self.preheat_options[setting]['gcode'])
script = {"script": self.preheat_options[setting]['gcode']}
self._screen._send_action(widget, "printer.gcode.script", script)
return False
def add_device(self, device):

View File

@ -125,9 +125,9 @@ class Panel(ScreenPanel):
def start_calibration(self, widget, method):
self.labels['popover'].popdown()
self.buttons['start'].set_sensitive(False)
if self._printer.get_stat("toolhead", "homed_axes") != "xyz":
self._screen._ws.klippy.gcode_script("G28")
if method == "probe":
self._move_to_position()
self._screen._ws.klippy.gcode_script("PROBE_CALIBRATE")
@ -217,19 +217,13 @@ class Panel(ScreenPanel):
logging.info(f"Moving to X:{x_position} Y:{y_position}")
self._screen._ws.klippy.gcode_script(f'G0 X{x_position} Y{y_position} F3000')
def process_busy(self, busy):
if busy:
for button in self.buttons:
self.buttons[button].set_sensitive(False)
elif self._printer.get_stat("manual_probe", "is_active"):
def activate(self):
if self._printer.get_stat("manual_probe", "is_active"):
self.buttons_calibrating()
else:
self.buttons_not_calibrating()
def process_update(self, action, data):
if action == "notify_busy":
self.process_busy(data)
return
if action == "notify_status_update":
if self._printer.get_stat("toolhead", "homed_axes") != "xyz":
self.widgets['zposition'].set_text("Z: ?")

View File

@ -792,7 +792,16 @@ class KlipperScreen(Gtk.Window):
def _send_action(self, widget, method, params):
logging.info(f"{method}: {params}")
self._ws.send_method(method, params)
if type(widget) == Gtk.Button:
self.gtk.Button_busy(widget, True)
self._ws.send_method(method, params, self.enable_widget, widget)
else:
self._ws.send_method(method, params)
def enable_widget(self, *args):
for x in args:
if type(x) == Gtk.Button:
GLib.timeout_add(150, self.gtk.Button_busy, x, False)
def printer_initializing(self, msg, remove=False):
if 'splash_screen' not in self.panels or remove: