喷头偏移值校准功能的实现
This commit is contained in:
parent
40ecbb3ea4
commit
3d6eed9d95
@ -34,6 +34,11 @@ name: {{ gettext('Z Calibrate') }}
|
||||
icon: z-farther
|
||||
panel: zcalibrate
|
||||
|
||||
[menu __main more nozzle_offset]
|
||||
name: {{ gettext('Nozzle Offset') }}
|
||||
icon: nozzle_offset
|
||||
panel: nozzle_offset
|
||||
|
||||
[menu __main more limits]
|
||||
name: {{ gettext('Limits') }}
|
||||
icon: fine-tune
|
||||
|
322
panels/nozzle_offset.py
Normal file
322
panels/nozzle_offset.py
Normal file
@ -0,0 +1,322 @@
|
||||
import logging
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Pango
|
||||
|
||||
from ks_includes.KlippyGcodes import KlippyGcodes
|
||||
from ks_includes.screen_panel import ScreenPanel
|
||||
|
||||
|
||||
class Panel(ScreenPanel):
|
||||
widgets = {}
|
||||
distances = [".01", ".05", ".1", ".5", "1", "5"]
|
||||
distance = distances[-2]
|
||||
|
||||
def __init__(self, screen, title):
|
||||
title = title or _("Nozzle Offset")
|
||||
super().__init__(screen, title)
|
||||
|
||||
self.start_z_calibrate = False
|
||||
self.z_hop_speed = 15.0
|
||||
self.z_hop = 5.0
|
||||
self.showing_input_box = False
|
||||
|
||||
self.offset_data = [
|
||||
(_("Z Offset"), "z_offset_val", "0"),
|
||||
(_("X Offset"), "x_offset_val", "0"),
|
||||
(_("Y Offset"), "y_offset_val", "0"),
|
||||
]
|
||||
|
||||
for label_text, offset_key, value_text in self.offset_data:
|
||||
self.widgets[offset_key[:8]] = Gtk.Label(label=label_text)
|
||||
self.widgets[offset_key] = Gtk.Label(label=value_text)
|
||||
event_box = Gtk.EventBox()
|
||||
event_box.add(self.widgets[offset_key])
|
||||
event_box.connect("button-release-event", self.change_offset, label_text, self.widgets[offset_key])
|
||||
setattr(self, f"{offset_key[0]}_event_box", event_box)
|
||||
|
||||
pos = Gtk.Grid(row_homogeneous=True, column_homogeneous=True)
|
||||
pos.attach(self.widgets["z_offset"], 0, 1, 2, 1)
|
||||
pos.attach(self.z_event_box, 0, 2, 2, 1)
|
||||
pos.attach(self.widgets["x_offset"], 0, 3, 1, 1)
|
||||
pos.attach(self.x_event_box, 0, 4, 1, 1)
|
||||
pos.attach(self.widgets["y_offset"], 1, 3, 1, 1)
|
||||
pos.attach(self.y_event_box, 1, 4, 1, 1)
|
||||
for label in pos.get_children():
|
||||
if isinstance(label, Gtk.Label):
|
||||
label.set_ellipsize(Pango.EllipsizeMode.END)
|
||||
self.buttons = {
|
||||
"z+": self._gtk.Button("z-farther", _("Lower Bed"), "color4"),
|
||||
"z-": self._gtk.Button("z-closer", _("Raise Bed"), "color1"),
|
||||
"start_z_offset": self._gtk.Button("offset_z", _("Z offset Calibrate"), "color3"),
|
||||
"start_xy_offset": self._gtk.Button("resume", _("XY offset Calibrate"), "color3"),
|
||||
"complete": self._gtk.Button("complete", _("Save"), "color3"),
|
||||
"cancel": self._gtk.Button("cancel", _("Cancel"), "color2"),
|
||||
}
|
||||
self.buttons["z+"].connect("clicked", self.move, "z", "+")
|
||||
self.buttons["z-"].connect("clicked", self.move, "z", "-")
|
||||
self.buttons["complete"].connect("clicked", self.accept)
|
||||
script = {"script": "ABORT"}
|
||||
self.buttons["cancel"].connect("clicked", self.cancel)
|
||||
|
||||
self.popover = Gtk.Popover(position=Gtk.PositionType.BOTTOM)
|
||||
script = {"script": "_NOZZLE_Z_OFFSET_CALIBRATE"}
|
||||
self.buttons["start_z_offset"].connect("clicked", self.nozzle_z_offset)
|
||||
script = {"script": "_NOZZLE_XY_OFFSET_CALIBRATE"}
|
||||
self.buttons["start_xy_offset"].connect("clicked", self.nozzle_xy_offset)
|
||||
|
||||
distgrid = Gtk.Grid()
|
||||
for j, i in enumerate(self.distances):
|
||||
self.widgets[i] = self._gtk.Button(label=i)
|
||||
self.widgets[i].set_direction(Gtk.TextDirection.LTR)
|
||||
self.widgets[i].connect("clicked", self.change_distance, i)
|
||||
ctx = self.widgets[i].get_style_context()
|
||||
ctx.add_class("horizontal_togglebuttons")
|
||||
if i == self.distance:
|
||||
ctx.add_class("horizontal_togglebuttons_active")
|
||||
distgrid.attach(self.widgets[i], j, 0, 1, 1)
|
||||
|
||||
self.widgets["move_dist"] = Gtk.Label(_("Move Distance (mm)"))
|
||||
distances = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
distances.pack_start(self.widgets["move_dist"], True, True, 0)
|
||||
distances.pack_start(distgrid, True, True, 0)
|
||||
|
||||
self.grid = Gtk.Grid(column_homogeneous=True)
|
||||
if self._screen.vertical_mode:
|
||||
if self._config.get_config()["main"].getboolean("invert_z", False):
|
||||
self.grid.attach(self.buttons["z+"], 0, 1, 1, 1)
|
||||
self.grid.attach(self.buttons["z-"], 0, 0, 1, 1)
|
||||
else:
|
||||
self.grid.attach(self.buttons["z+"], 0, 0, 1, 1)
|
||||
self.grid.attach(self.buttons["z-"], 0, 1, 1, 1)
|
||||
self.grid.attach(self.buttons["start_z_offset"], 1, 0, 1, 1)
|
||||
self.grid.attach(pos, 1, 1, 2, 1)
|
||||
self.grid.attach(self.buttons["start_xy_offset"], 2, 0, 1, 1)
|
||||
self.grid.attach(self.buttons["complete"], 3, 0, 1, 1)
|
||||
self.grid.attach(self.buttons["cancel"], 3, 1, 1, 1)
|
||||
self.grid.attach(distances, 0, 2, 4, 1)
|
||||
else:
|
||||
if self._config.get_config()["main"].getboolean("invert_z", False):
|
||||
self.grid.attach(self.buttons["z+"], 0, 2, 1, 1)
|
||||
self.grid.attach(self.buttons["z-"], 0, 1, 1, 1)
|
||||
else:
|
||||
self.grid.attach(self.buttons["z+"], 0, 1, 1, 1)
|
||||
self.grid.attach(self.buttons["z-"], 0, 2, 1, 1)
|
||||
self.grid.attach(self.buttons["start_z_offset"], 0, 0, 2, 1)
|
||||
self.grid.attach(self.buttons["start_xy_offset"], 2, 0, 2, 1)
|
||||
self.grid.attach(pos, 1, 1, 2, 2)
|
||||
self.grid.attach(self.buttons["complete"], 3, 1, 1, 1)
|
||||
self.grid.attach(self.buttons["cancel"], 3, 2, 1, 1)
|
||||
self.grid.attach(distances, 0, 3, 4, 1)
|
||||
self.content.add(self.grid)
|
||||
|
||||
def nozzle_z_offset(self, widget):
|
||||
text = (
|
||||
_("Start testing the Z offset value of the second nozzle?\n")
|
||||
+ "\n\n"
|
||||
+ _("Please ensure that the Z Calibrate has been performed")
|
||||
)
|
||||
label = Gtk.Label(wrap=True, vexpand=True)
|
||||
label.set_markup(text)
|
||||
buttons = [
|
||||
{"name": _("Accept"), "response": Gtk.ResponseType.OK, "style": "dialog-info"},
|
||||
{"name": _("Cancel"), "response": Gtk.ResponseType.CANCEL, "style": "dialog-error"},
|
||||
]
|
||||
self._gtk.Dialog(_("Calibrate Nozzle Z Offset"), buttons, label, self.confirm_nozzle_z_offset)
|
||||
|
||||
def confirm_nozzle_z_offset(self, dialog, response_id):
|
||||
self._gtk.remove_dialog(dialog)
|
||||
if response_id == Gtk.ResponseType.OK:
|
||||
self.start_z_calibrate = True
|
||||
self.buttons_calibration_start()
|
||||
self._screen._send_action(
|
||||
self.buttons["start_z_offset"], "printer.gcode.script", {"script": "_NOZZLE_Z_OFFSET_CALIBRATE"}
|
||||
)
|
||||
|
||||
def nozzle_xy_offset(self, widget):
|
||||
text = (
|
||||
_("This operation is about to print the model")
|
||||
+ "\n\n"
|
||||
+ _("Please load two different colored PLA filaments!")
|
||||
)
|
||||
|
||||
label = Gtk.Label(wrap=True, vexpand=True)
|
||||
label.set_markup(text)
|
||||
buttons = [
|
||||
{"name": _("Accept"), "response": Gtk.ResponseType.OK, "style": "dialog-info"},
|
||||
{"name": _("Cancel"), "response": Gtk.ResponseType.CANCEL, "style": "dialog-error"},
|
||||
]
|
||||
self._gtk.Dialog(_("Calibrate Nozzle XY Offset"), buttons, label, self.confirm_nozzle_xy_offset)
|
||||
|
||||
def confirm_nozzle_xy_offset(self, dialog, response_id):
|
||||
self._gtk.remove_dialog(dialog)
|
||||
if response_id == Gtk.ResponseType.OK:
|
||||
self._screen.offset_fine_tune_mode = True
|
||||
self.buttons_calibration_start()
|
||||
self._screen._send_action(
|
||||
self.buttons["start_z_offset"], "printer.gcode.script", {"script": "_NOZZLE_XY_OFFSET_CALIBRATE"}
|
||||
)
|
||||
|
||||
def change_offset(self, widget, event, title_label, offset_label):
|
||||
self._create_input_box(title_label, offset_label)
|
||||
|
||||
def _create_input_box(self, title_label, offset_label):
|
||||
current_val = offset_label.get_text()
|
||||
title_label += " " + _("Current value:") + f"{current_val}"
|
||||
for child in self.content.get_children():
|
||||
self.content.remove(child)
|
||||
lbl = Gtk.Label(label=title_label, halign=Gtk.Align.START, hexpand=False)
|
||||
self.labels["entry"] = Gtk.Entry(hexpand=True)
|
||||
self.labels["entry"].connect("focus-in-event", self._screen.show_keyboard)
|
||||
save = self._gtk.Button("complete", _("Save"), "color3")
|
||||
save.set_hexpand(False)
|
||||
save.connect("clicked", self.store_value, offset_label)
|
||||
box = Gtk.Box()
|
||||
box.pack_start(self.labels["entry"], True, True, 5)
|
||||
box.pack_start(save, False, False, 5)
|
||||
self.labels["input_box"] = Gtk.Box(
|
||||
orientation=Gtk.Orientation.VERTICAL, spacing=5, hexpand=True, vexpand=True, valign=Gtk.Align.CENTER
|
||||
)
|
||||
self.labels["input_box"].pack_start(lbl, True, True, 5)
|
||||
self.labels["input_box"].pack_start(box, True, True, 5)
|
||||
self.content.add(self.labels["input_box"])
|
||||
self.labels["entry"].grab_focus_without_selecting()
|
||||
self.showing_input_box = True
|
||||
|
||||
def hide_input_box(self):
|
||||
self._screen.remove_keyboard()
|
||||
for child in self.content.get_children():
|
||||
self.content.remove(child)
|
||||
self.content.add(self.grid)
|
||||
self.content.show()
|
||||
self.showing_input_box = False
|
||||
|
||||
def store_value(self, widget, offset_label):
|
||||
val_text = self.labels["entry"].get_text()
|
||||
try:
|
||||
val = round(float(val_text), 3)
|
||||
name = None
|
||||
for label_text, offset_key, _ in self.offset_data:
|
||||
if offset_label == self.widgets[offset_key]:
|
||||
name = offset_key
|
||||
break
|
||||
if name is not None:
|
||||
name = "nozzle_" + name
|
||||
self.set_nozzle_offset(name, val)
|
||||
if self.showing_input_box:
|
||||
self.hide_input_box()
|
||||
except ValueError:
|
||||
self._screen.show_popup_message(_("Please enter a valid number"))
|
||||
|
||||
def set_nozzle_offset(self, option, value):
|
||||
script = KlippyGcodes.set_save_variables(option, value)
|
||||
self._screen._send_action(None, "printer.gcode.script", {"script": script})
|
||||
logging.info(f"Set {option}:{value}")
|
||||
|
||||
def back(self):
|
||||
if self.showing_input_box:
|
||||
self.hide_input_box()
|
||||
return True
|
||||
return False
|
||||
|
||||
def _add_button(self, label, method, pobox):
|
||||
popover_button = self._gtk.Button(label=label)
|
||||
pobox.pack_start(popover_button, True, True, 5)
|
||||
|
||||
def on_popover_clicked(self, widget):
|
||||
self.popover.set_relative_to(widget)
|
||||
self.popover.show_all()
|
||||
|
||||
def activate(self):
|
||||
is_sensitive = self.buttons["start_z_offset"].get_sensitive()
|
||||
if is_sensitive:
|
||||
self.buttons_not_z_calibration()
|
||||
else:
|
||||
self.buttons_calibration_start()
|
||||
|
||||
def deactivate(self):
|
||||
if self.start_z_calibrate:
|
||||
self.start_z_calibrate = False
|
||||
|
||||
def process_update(self, action, data):
|
||||
|
||||
if action == "notify_gcode_response":
|
||||
if self.start_z_calibrate and "extruder1" in data:
|
||||
self.buttons_z_calibration()
|
||||
elif "action:resumed" in data:
|
||||
return
|
||||
if action != "notify_status_update":
|
||||
return
|
||||
if "save_variables" in data and "variables" in data["save_variables"]:
|
||||
variables = data["save_variables"]["variables"]
|
||||
nozzle_offsets = ["nozzle_z_offset_val", "nozzle_x_offset_val", "nozzle_y_offset_val"]
|
||||
|
||||
for offset in nozzle_offsets:
|
||||
if offset in variables:
|
||||
self.widgets[f'{offset.split("_")[1]}_offset_val'].set_text(f"{variables[offset]}")
|
||||
|
||||
if "gcode_move" in data or "toolhead" in data and "homed_axes" in data["toolhead"]:
|
||||
homed_axes = self._printer.get_stat("toolhead", "homed_axes")
|
||||
|
||||
if "z" in homed_axes:
|
||||
self.pos_z = round(data["gcode_move"]["gcode_position"][2], 3)
|
||||
if self.start_z_calibrate:
|
||||
self.widgets["z_offset_val"].set_text(f"{self.pos_z}")
|
||||
|
||||
def change_distance(self, widget, distance):
|
||||
logging.info(f"### Distance {distance}")
|
||||
self.widgets[f"{self.distance}"].get_style_context().remove_class("horizontal_togglebuttons_active")
|
||||
self.widgets[f"{distance}"].get_style_context().add_class("horizontal_togglebuttons_active")
|
||||
self.distance = distance
|
||||
|
||||
def move(self, widget, axis, direction):
|
||||
dist = f"{direction}{self.distance}"
|
||||
script = f"{KlippyGcodes.MOVE_RELATIVE}\nG0 {axis}{dist} F300"
|
||||
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")
|
||||
|
||||
def accept(self, widget):
|
||||
logging.info("Accepting nozzle Z offset")
|
||||
script = f"SET_GCODE_OFFSET Z={self.pos_z}"
|
||||
self._screen._send_action(None, "printer.gcode.script", {"script": script})
|
||||
script = f"G91\n G0 Z5 F6000"
|
||||
self._screen._send_action(None, "printer.gcode.script", {"script": script})
|
||||
|
||||
self.set_nozzle_offset("nozzle_z_offset_val", self.pos_z)
|
||||
self.buttons_not_z_calibration()
|
||||
self.start_z_calibrate = False
|
||||
|
||||
def cancel(self, widget):
|
||||
self.start_z_calibrate = False
|
||||
self.buttons_not_z_calibration()
|
||||
variables = self._printer.get_stat("save_variables", "variables")
|
||||
if "nozzle_z_offset_val" in variables:
|
||||
self.widgets["z_offset_val"].set_text(f"{variables['nozzle_z_offset_val']}")
|
||||
|
||||
def buttons_calibration_start(self):
|
||||
self.buttons["start_z_offset"].set_sensitive(False)
|
||||
self.buttons["start_xy_offset"].set_sensitive(False)
|
||||
|
||||
self.buttons["z+"].set_sensitive(False)
|
||||
self.buttons["z-"].set_sensitive(False)
|
||||
self.buttons["complete"].set_sensitive(False)
|
||||
self.buttons["cancel"].set_sensitive(False)
|
||||
|
||||
def buttons_z_calibration(self):
|
||||
self.buttons["start_z_offset"].set_sensitive(False)
|
||||
self.buttons["start_xy_offset"].set_sensitive(False)
|
||||
self.buttons["z+"].set_sensitive(True)
|
||||
self.buttons["z-"].set_sensitive(True)
|
||||
self.buttons["complete"].set_sensitive(True)
|
||||
self.buttons["cancel"].set_sensitive(True)
|
||||
|
||||
def buttons_not_z_calibration(self):
|
||||
self.buttons["start_z_offset"].set_sensitive(True)
|
||||
self.buttons["start_xy_offset"].set_sensitive(True)
|
||||
self.buttons["z+"].set_sensitive(False)
|
||||
self.buttons["z-"].set_sensitive(False)
|
||||
self.buttons["complete"].set_sensitive(False)
|
||||
self.buttons["cancel"].set_sensitive(False)
|
214
panels/offset_fine_tune.py
Normal file
214
panels/offset_fine_tune.py
Normal file
@ -0,0 +1,214 @@
|
||||
import re
|
||||
import logging
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk
|
||||
from ks_includes.KlippyGcodes import KlippyGcodes
|
||||
from ks_includes.screen_panel import ScreenPanel
|
||||
|
||||
|
||||
class Panel(ScreenPanel):
|
||||
distances = [".01", ".05", "0.1"]
|
||||
distance = distances[-2]
|
||||
|
||||
def __init__(self, screen, title):
|
||||
title = title or _("offset fine tune")
|
||||
super().__init__(screen, title)
|
||||
|
||||
self.state = "standby"
|
||||
|
||||
if self.ks_printer_cfg is not None:
|
||||
dis = self.ks_printer_cfg.get("move_distances", "")
|
||||
if re.match(r"^[0-9,\.\s]+$", dis):
|
||||
dis = [str(i.strip()) for i in dis.split(",")]
|
||||
if 1 < len(dis) <= 7:
|
||||
self.distances = dis
|
||||
self.distance = self.distances[-2]
|
||||
|
||||
self.labels["qr_code_box"] = Gtk.Grid(row_homogeneous=True, column_homogeneous=True)
|
||||
qr_code = self._gtk.Image("wiki_qr_code", self._gtk.content_width * 0.46, self._gtk.content_height * 0.46)
|
||||
qr_code_url = Gtk.Label(label="https://www.creatbot.com/en/faqs.html")
|
||||
self.labels["qr_code_box"].attach(qr_code, 0, 0, 1, 3)
|
||||
self.labels["qr_code_box"].attach(qr_code_url, 0, 2, 1, 1)
|
||||
|
||||
self.action_btn = {}
|
||||
self.action_btn["fine_tune"] = self._gtk.Button("fine-tune", scale=0.7)
|
||||
self.action_btn["pause"] = self._gtk.Button("pause", scale=0.8)
|
||||
self.action_btn["resume"] = self._gtk.Button("resume", scale=0.8)
|
||||
self.action_btn["stop"] = self._gtk.Button("stop", scale=0.8)
|
||||
|
||||
self.action_btn["fine_tune"].connect("clicked", self.menu_item_clicked, {"panel": "fine_tune"})
|
||||
self.action_btn["pause"].connect("clicked", self.pause)
|
||||
self.action_btn["resume"].connect("clicked", self.resume)
|
||||
self.action_btn["stop"].connect("clicked", self.cancel)
|
||||
|
||||
self.labels["action_menu"] = Gtk.Grid(row_homogeneous=True, column_homogeneous=True)
|
||||
self.labels["action_menu"].attach(self.action_btn["pause"], 0, 0, 1, 1)
|
||||
self.labels["action_menu"].attach(self.action_btn["stop"], 1, 0, 1, 1)
|
||||
self.labels["action_menu"].attach(self.action_btn["fine_tune"], 2, 0, 1, 1)
|
||||
|
||||
self.buttons = {
|
||||
"x+": self._gtk.Button("arrow-right", "X+", "color1"),
|
||||
"x-": self._gtk.Button("arrow-left", "X-", "color1"),
|
||||
"y+": self._gtk.Button("arrow-up", "Y+", "color2"),
|
||||
"y-": self._gtk.Button("arrow-down", "Y-", "color2"),
|
||||
"z+": self._gtk.Button("z-farther", "Z+", "color3"),
|
||||
"z-": self._gtk.Button("z-closer", "Z-", "color3"),
|
||||
}
|
||||
self.buttons["x+"].connect("clicked", self.move, "X", "+")
|
||||
self.buttons["x-"].connect("clicked", self.move, "X", "-")
|
||||
self.buttons["y+"].connect("clicked", self.move, "Y", "+")
|
||||
self.buttons["y-"].connect("clicked", self.move, "Y", "-")
|
||||
self.buttons["z+"].connect("clicked", self.move, "Z", "+")
|
||||
self.buttons["z-"].connect("clicked", self.move, "Z", "-")
|
||||
|
||||
grid = Gtk.Grid(row_homogeneous=True, column_homogeneous=True)
|
||||
if self._screen.vertical_mode:
|
||||
if self._screen.lang_ltr:
|
||||
grid.attach(self.buttons["x+"], 2, 1, 1, 1)
|
||||
grid.attach(self.buttons["x-"], 0, 1, 1, 1)
|
||||
grid.attach(self.buttons["z+"], 2, 2, 1, 1)
|
||||
grid.attach(self.buttons["z-"], 0, 2, 1, 1)
|
||||
else:
|
||||
grid.attach(self.buttons["x+"], 0, 1, 1, 1)
|
||||
grid.attach(self.buttons["x-"], 2, 1, 1, 1)
|
||||
grid.attach(self.buttons["z+"], 0, 2, 1, 1)
|
||||
grid.attach(self.buttons["z-"], 2, 2, 1, 1)
|
||||
|
||||
grid.attach(self.buttons["y+"], 1, 0, 1, 1)
|
||||
grid.attach(self.buttons["y-"], 1, 2, 1, 1)
|
||||
|
||||
else:
|
||||
if self._screen.lang_ltr:
|
||||
grid.attach(self.buttons["x+"], 2, 1, 1, 1)
|
||||
grid.attach(self.buttons["x-"], 0, 1, 1, 1)
|
||||
else:
|
||||
grid.attach(self.buttons["x+"], 0, 1, 1, 1)
|
||||
grid.attach(self.buttons["x-"], 2, 1, 1, 1)
|
||||
grid.attach(self.buttons["y+"], 1, 0, 1, 1)
|
||||
grid.attach(self.buttons["y-"], 1, 2, 1, 1)
|
||||
grid.attach(self.buttons["z-"], 3, 0, 1, 1)
|
||||
grid.attach(self.buttons["z+"], 3, 2, 1, 1)
|
||||
|
||||
distgrid = Gtk.Grid()
|
||||
for j, i in enumerate(self.distances):
|
||||
self.labels[i] = self._gtk.Button(label=i)
|
||||
self.labels[i].set_direction(Gtk.TextDirection.LTR)
|
||||
self.labels[i].connect("clicked", self.change_distance, i)
|
||||
ctx = self.labels[i].get_style_context()
|
||||
ctx.add_class("horizontal_togglebuttons")
|
||||
if i == self.distance:
|
||||
ctx.add_class("horizontal_togglebuttons_active")
|
||||
distgrid.attach(self.labels[i], j, 0, 1, 1)
|
||||
|
||||
for p in ("x_offset_val", "y_offset_val", "z_offset_val"):
|
||||
self.labels[p] = Gtk.Label(f"{p[0].upper()} " + _("Offset") + ": 0")
|
||||
self.labels["move_dist"] = Gtk.Label(label=_("Move Distance (mm)"))
|
||||
|
||||
bottomgrid = Gtk.Grid(row_homogeneous=True, column_homogeneous=True)
|
||||
bottomgrid.set_direction(Gtk.TextDirection.LTR)
|
||||
bottomgrid.attach(self.labels["x_offset_val"], 0, 0, 1, 1)
|
||||
bottomgrid.attach(self.labels["y_offset_val"], 1, 0, 1, 1)
|
||||
bottomgrid.attach(self.labels["z_offset_val"], 2, 0, 1, 1)
|
||||
bottomgrid.attach(self.labels["move_dist"], 0, 1, 3, 1)
|
||||
|
||||
self.labels["move_menu"] = Gtk.Grid(row_homogeneous=True, column_homogeneous=True)
|
||||
self.labels["move_menu"].attach(self.labels["qr_code_box"], 0, 0, 2, 4)
|
||||
self.labels["move_menu"].attach(grid, 2, 0, 2, 3)
|
||||
self.labels["move_menu"].attach(bottomgrid, 2, 3, 2, 1)
|
||||
self.labels["move_menu"].attach(distgrid, 2, 4, 2, 1)
|
||||
self.labels["move_menu"].attach(self.labels["action_menu"], 0, 4, 2, 1)
|
||||
|
||||
self.content.add(self.labels["move_menu"])
|
||||
|
||||
def process_update(self, action, data):
|
||||
if action != "notify_status_update":
|
||||
return
|
||||
if "save_variables" in data and "variables" in data["save_variables"]:
|
||||
variables = data["save_variables"]["variables"]
|
||||
nozzle_offsets = ["nozzle_z_offset_val", "nozzle_x_offset_val", "nozzle_y_offset_val"]
|
||||
|
||||
for offset in nozzle_offsets:
|
||||
if offset in variables:
|
||||
axis = offset.split("_")[1]
|
||||
self.labels[f"{axis}_offset_val"].set_text(
|
||||
f"{axis.upper()} " + _("Offset") + f": {variables[offset]}"
|
||||
)
|
||||
if "print_stats" in data:
|
||||
if "state" in data["print_stats"]:
|
||||
self.state = data["print_stats"]["state"]
|
||||
self.show_buttons_for_state()
|
||||
|
||||
def pause(self, widget):
|
||||
self.disable_button("pause")
|
||||
self._screen._ws.klippy.print_pause()
|
||||
self._screen.show_all()
|
||||
|
||||
def resume(self, widget):
|
||||
self.disable_button("resume")
|
||||
self._screen._ws.klippy.print_resume()
|
||||
self._screen.show_all()
|
||||
|
||||
def cancel(self, widget):
|
||||
buttons = [
|
||||
{"name": _("Cancel Print"), "response": Gtk.ResponseType.OK, "style": "dialog-error"},
|
||||
{"name": _("Go Back"), "response": Gtk.ResponseType.CANCEL, "style": "dialog-info"},
|
||||
]
|
||||
label = Gtk.Label(hexpand=True, vexpand=True, wrap=True)
|
||||
label.set_markup(_("Are you sure you wish to cancel this test?"))
|
||||
self._gtk.Dialog(_("Cancel"), buttons, label, self.cancel_confirm)
|
||||
|
||||
def cancel_confirm(self, dialog, response_id):
|
||||
self._gtk.remove_dialog(dialog)
|
||||
if response_id == Gtk.ResponseType.OK:
|
||||
self.disable_button("pause", "resume", "stop", "fine_tune")
|
||||
self._screen._ws.klippy.print_cancel()
|
||||
logging.debug("Canceling print test")
|
||||
return
|
||||
if response_id == Gtk.ResponseType.CANCEL:
|
||||
self.enable_button("pause", "stop", "fine_tune")
|
||||
return
|
||||
|
||||
def disable_button(self, *args):
|
||||
for arg in args:
|
||||
self.action_btn[arg].set_sensitive(False)
|
||||
|
||||
def show_buttons_for_state(self):
|
||||
self.labels["action_menu"].remove_row(0)
|
||||
self.labels["action_menu"].insert_row(0)
|
||||
if self.state == "paused":
|
||||
self.labels["action_menu"].attach(self.action_btn["resume"], 0, 0, 1, 1)
|
||||
self.labels["action_menu"].attach(self.action_btn["stop"], 1, 0, 1, 1)
|
||||
self.labels["action_menu"].attach(self.action_btn["fine_tune"], 2, 0, 1, 1)
|
||||
else:
|
||||
self.labels["action_menu"].attach(self.action_btn["pause"], 0, 0, 1, 1)
|
||||
self.labels["action_menu"].attach(self.action_btn["stop"], 1, 0, 1, 1)
|
||||
self.labels["action_menu"].attach(self.action_btn["fine_tune"], 2, 0, 1, 1)
|
||||
self.content.show_all()
|
||||
|
||||
def change_distance(self, widget, distance):
|
||||
logging.info(f"### Distance {distance}")
|
||||
self.labels[f"{self.distance}"].get_style_context().remove_class("horizontal_togglebuttons_active")
|
||||
self.labels[f"{distance}"].get_style_context().add_class("horizontal_togglebuttons_active")
|
||||
self.distance = distance
|
||||
|
||||
def move(self, widget, axis, direction):
|
||||
axis = axis.lower()
|
||||
offset_name = f"nozzle_{axis}_offset_val"
|
||||
data = self._printer.data
|
||||
last_val = 0
|
||||
if "save_variables" in data and "variables" in data["save_variables"]:
|
||||
variables = data["save_variables"]["variables"]
|
||||
last_val = variables.get(offset_name, 0)
|
||||
try:
|
||||
expression = f"{last_val} {direction} {self.distance}"
|
||||
result = eval(expression)
|
||||
self.set_nozzle_offset(offset_name, round(float(result), 2))
|
||||
except Exception as e:
|
||||
logging.error(f"Error setting {offset_name}: eval failed with expression '{expression}'. Exception: {e}")
|
||||
|
||||
def set_nozzle_offset(self, option, value):
|
||||
script = KlippyGcodes.set_save_variables(option, value)
|
||||
self._screen._send_action(None, "printer.gcode.script", {"script": script})
|
||||
logging.info(f"Set {option}:{value}")
|
@ -83,6 +83,7 @@ class KlipperScreen(Gtk.Window):
|
||||
GLib.set_prgname('KlipperScreen')
|
||||
self.blanking_time = 600
|
||||
self.use_dpms = True
|
||||
self.offset_fine_tune_mode = False
|
||||
self.apiclient = None
|
||||
self.dialogs = []
|
||||
self.confirm = None
|
||||
@ -780,7 +781,10 @@ class KlipperScreen(Gtk.Window):
|
||||
self.show_panel("extrude")
|
||||
|
||||
def state_printing(self):
|
||||
self.show_panel("job_status", remove_all=True)
|
||||
if not self.offset_fine_tune_mode:
|
||||
self.show_panel("job_status", remove_all=True)
|
||||
else:
|
||||
self.show_panel("offset_fine_tune", remove_all=True)
|
||||
|
||||
def state_ready(self, wait=True):
|
||||
# Do not return to main menu if completing a job, timeouts/user input will return
|
||||
@ -797,6 +801,8 @@ class KlipperScreen(Gtk.Window):
|
||||
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")
|
||||
if self.offset_fine_tune_mode:
|
||||
self.offset_fine_tune_mode = False
|
||||
|
||||
def state_startup(self):
|
||||
self.printer_initializing(_("Klipper is attempting to start"))
|
||||
|
26
styles/dark/images/nozzle_offset.svg
Normal file
26
styles/dark/images/nozzle_offset.svg
Normal file
@ -0,0 +1,26 @@
|
||||
<svg width="44" height="47" viewBox="0 0 44 47" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M28.0475 20.6077L25.2011 25.8358H19.2178L16.7781 21.1886C17.1847 21.0724 17.5332 20.7239 17.8237 20.2592C17.998 20.143 18.4627 20.0268 18.9855 20.3172C19.0297 20.3393 19.0783 20.3641 19.1311 20.3911C19.7721 20.7183 21.0351 21.3629 22.6451 21.3629C23.7488 21.3629 25.0268 21.0143 26.3629 20.0849C26.5371 19.9687 26.8857 19.9106 27.3504 20.2011C27.4483 20.2663 27.5644 20.3316 27.6989 20.4071C27.8039 20.466 27.9201 20.5313 28.0475 20.6077ZM30.5453 8.87359C30.3711 8.69932 30.1968 8.64123 30.0225 8.64123H27.6408V8.69932H26.5371L26.5952 19.7364C26.8276 19.7364 27.118 19.7944 27.4085 19.9687C28.1056 20.4334 29.4416 21.0143 30.4872 19.9106L30.5453 19.7944C30.559 19.767 30.576 19.7364 30.5939 19.704L30.5939 19.704C30.6518 19.5992 30.7196 19.4766 30.7196 19.3878V9.33831C30.7196 9.16404 30.6615 9.04786 30.5453 8.87359ZM16.4295 21.2467C15.8486 21.3048 15.2677 21.0724 14.803 20.782C15.37 21.5694 16.2444 22.6984 16.9817 23.6505L16.9818 23.6506L16.9818 23.6507C17.6042 24.4543 18.1289 25.1317 18.2884 25.371C18.4627 25.6034 18.7531 25.7777 19.0436 25.8939L16.6038 21.1886C16.5748 21.1886 16.5457 21.2031 16.5167 21.2176C16.4876 21.2322 16.4586 21.2467 16.4295 21.2467ZM28.2217 20.6077L25.3753 25.8358H25.5496C26.479 25.6615 26.7695 25.2549 26.7695 25.2549L29.6159 21.1305C29.6159 21.1305 29.6159 21.0724 29.674 21.0724L30.0225 20.6077C29.3835 20.8981 28.7445 20.8401 28.2217 20.6077ZM17.5913 20.0849C17.6021 20.0741 17.613 20.0613 17.6245 20.0475C17.6751 19.9876 17.74 19.9106 17.8818 19.9106L17.8237 8.75741H17.3009L14.8611 8.69932C14.6869 8.69932 14.4545 8.75741 14.3383 8.93168L14.2802 8.98977C14.2665 9.01719 14.2496 9.04786 14.2317 9.08023C14.1738 9.18499 14.106 9.30764 14.106 9.3964V19.5621C14.106 19.7364 14.164 19.8525 14.2221 19.9687C14.2802 20.0849 14.2802 20.0849 14.3383 20.143C14.803 20.5496 15.6163 21.0724 16.4295 21.0143C16.9523 20.9562 17.1847 20.6658 17.5913 20.0849ZM27.3504 2.33441C27.3504 1.22984 26.455 0.334412 25.3504 0.334412H19.3009C18.1963 0.334412 17.3009 1.22984 17.3009 2.33441V6.11842C17.3009 7.22299 18.1963 8.11842 19.3009 8.11842H25.3504C26.455 8.11842 27.3504 7.22299 27.3504 6.11842V2.33441ZM20.1588 8.68513L26.3048 8.64123L26.305 8.68513H26.32V11.5435L26.3629 19.7364C26.3374 19.7618 26.3008 19.7761 26.2676 19.7891C26.2252 19.8056 26.1886 19.8199 26.1886 19.8525C23.0518 22.2342 20.2054 20.782 19.0436 20.0849C18.7531 19.9106 18.4627 19.8525 18.2303 19.8525L18.2285 19.4979H18.2007V14.1703L18.1722 8.69932L18.2007 8.69912V8.68513H20.1588ZM19.3339 26.0098C19.5082 26.0679 19.6244 26.184 19.7405 26.3002L20.8442 28.101C20.9604 28.2753 21.1347 28.3914 21.4251 28.3914H23.1097C23.3421 28.3914 23.5745 28.2753 23.6906 28.101C23.8359 27.8686 23.9811 27.5782 24.1263 27.2878L24.1263 27.2877C24.2715 26.9973 24.4168 26.7069 24.562 26.4745C24.6201 26.3002 24.9025 26.0679 25.0768 26.0098L19.3339 26.0098Z" fill="url(#paint0_linear_35_476)"/>
|
||||
<path d="M36.0437 13.7123C38.2623 16.3874 39.6721 19.6397 40.1079 23.0877C40.5436 26.5357 39.9871 30.0364 38.5037 33.1793C37.0203 36.3222 34.6714 38.977 31.7326 40.8323C28.7938 42.6875 25.387 43.6664 21.9116 43.654C18.4362 43.6415 15.0364 42.6384 12.111 40.7622C9.18549 38.886 6.85567 36.2145 5.39474 33.0611C3.93381 29.9076 3.40235 26.403 3.86268 22.9582C4.32302 19.5134 5.75606 16.2713 7.99375 13.6122" stroke="#D0CECF" stroke-width="2"/>
|
||||
<path d="M32.9441 20.8903C33.6989 22.7347 33.9764 24.7397 33.7508 26.7197C33.5253 28.6998 32.8041 30.591 31.6538 32.2183C30.5036 33.8457 28.9615 35.1568 27.1702 36.0301C25.3789 36.9035 23.3963 37.311 21.4058 37.215C19.4152 37.1189 17.481 36.5224 15.7822 35.4807C14.0833 34.4389 12.6746 32.9855 11.6863 31.2549C10.6981 29.5244 10.1623 27.5725 10.1284 25.58C10.0946 23.5874 10.5638 21.6185 11.4926 19.8553" stroke="#D0CECF" stroke-width="2"/>
|
||||
<path d="M22.4127 45.9058L22.4127 37.9058" stroke="url(#paint1_linear_35_476)" stroke-width="1.9" stroke-linecap="round"/>
|
||||
<path d="M42.8739 25.3902L34.6739 25.3676" stroke="url(#paint2_linear_35_476)" stroke-width="1.9" stroke-linecap="round"/>
|
||||
<path d="M1.02307 25.356L9.22304 25.3786" stroke="url(#paint3_linear_35_476)" stroke-width="1.9" stroke-linecap="round"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_35_476" x1="22.2604" y1="8.68515" x2="22.2604" y2="19.498" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D0CECF"/>
|
||||
<stop offset="1" stop-color="#A5A2A3"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_35_476" x1="21.9127" y1="45.9058" x2="21.9127" y2="37.9058" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#E8E8E8"/>
|
||||
<stop offset="1" stop-color="#D8D3D3"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_35_476" x1="42.8753" y1="24.8902" x2="34.6753" y2="24.8676" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#E8E8E8"/>
|
||||
<stop offset="1" stop-color="#D8D3D3"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_35_476" x1="1.02445" y1="24.856" x2="9.22442" y2="24.8786" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#E8E8E8"/>
|
||||
<stop offset="1" stop-color="#D8D3D3"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 5.0 KiB |
1
styles/dark/images/offset_z.svg
Normal file
1
styles/dark/images/offset_z.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1731045447381" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13273" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24"><path d="M251.392 713.728l331.776-396.8H277.504V202.752h486.912v107.52l-331.776 396.8H773.12v114.176H251.392v-107.52zM173.056 902.144v-100.864H128V947.2h146.432v-45.056H173.056zM850.944 121.856v100.864h45.056V76.8h-146.432v45.056h101.376z" p-id="13274" fill="#6C71C4"></path></svg>
|
After Width: | Height: | Size: 604 B |
31
styles/light/images/nozzle_offset.svg
Normal file
31
styles/light/images/nozzle_offset.svg
Normal file
@ -0,0 +1,31 @@
|
||||
<svg width="46" height="47" viewBox="0 0 46 47" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect y="0.582275" width="46" height="46" rx="10" fill="url(#paint0_linear_2203_545)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M28.0781 21.6847L25.8958 25.6929H21.3087L19.4382 22.13C19.75 22.041 20.0172 21.7738 20.2399 21.4175C20.3735 21.3284 20.7297 21.2393 21.1306 21.462C21.1644 21.479 21.2017 21.498 21.2421 21.5186L21.2422 21.5186C21.7336 21.7695 22.7019 22.2637 23.9363 22.2637C24.7825 22.2637 25.7622 21.9964 26.7866 21.2839C26.9202 21.1948 27.1874 21.1503 27.5437 21.3729C27.6187 21.423 27.7078 21.473 27.8109 21.5309C27.8914 21.5761 27.9804 21.6261 28.0781 21.6847ZM29.9931 12.6885C29.8595 12.5549 29.7259 12.5104 29.5923 12.5104H27.7663V12.5549H26.9202L26.9647 21.0167C27.1428 21.0167 27.3655 21.0612 27.5882 21.1948C28.1226 21.5511 29.1469 21.9964 29.9486 21.1503L29.9931 21.0612C30.0036 21.0402 30.0166 21.0167 30.0303 20.9919C30.0747 20.9115 30.1267 20.8175 30.1267 20.7495V13.0448C30.1267 12.9112 30.0822 12.8222 29.9931 12.6885ZM19.171 22.1746C18.7256 22.2191 18.2803 22.041 17.924 21.8183C18.3587 22.422 19.0291 23.2877 19.5944 24.0176L19.5944 24.0176L19.5944 24.0177C20.0716 24.6338 20.4738 25.1531 20.5961 25.3366C20.7297 25.5147 20.9524 25.6483 21.1751 25.7374L19.3046 22.13C19.2823 22.13 19.2601 22.1412 19.2378 22.1523C19.2155 22.1635 19.1933 22.1746 19.171 22.1746ZM28.2117 21.6847L26.0295 25.6929H26.1631C26.8756 25.5593 27.0983 25.2475 27.0983 25.2475L29.2805 22.0855C29.2805 22.0855 29.2805 22.041 29.3251 22.041L29.5923 21.6847C29.1024 21.9074 28.6125 21.8628 28.2117 21.6847ZM20.0871 21.2552L20.0872 21.2552C20.1259 21.2093 20.1757 21.1503 20.2844 21.1503L20.2399 12.5995H19.839L17.9685 12.5549C17.8349 12.5549 17.6568 12.5995 17.5677 12.7331L17.5232 12.7776C17.5127 12.7986 17.4997 12.8221 17.486 12.847L17.486 12.847C17.4416 12.9273 17.3896 13.0213 17.3896 13.0894V20.8831C17.3896 21.0167 17.4341 21.1057 17.4787 21.1948C17.5232 21.2839 17.5232 21.2839 17.5677 21.3284C17.924 21.6402 18.5475 22.041 19.171 21.9964C19.5718 21.9519 19.75 21.7292 20.0617 21.2839C20.07 21.2756 20.0783 21.2658 20.0871 21.2552ZM27.5437 8.14185C27.5437 7.03728 26.6482 6.14185 25.5437 6.14185H21.839C20.7345 6.14185 19.839 7.03728 19.839 8.14185V10.1096C19.839 11.2142 20.7345 12.1096 21.839 12.1096H25.5437C26.6482 12.1096 27.5437 11.2142 27.5437 10.1096V8.14185ZM22.031 12.5441L26.742 12.5104L26.7422 12.5441H26.7536V14.7274L26.7866 21.0167C26.767 21.0362 26.7389 21.0472 26.7136 21.0571C26.681 21.0698 26.6529 21.0807 26.6529 21.1057C24.248 22.9317 22.0658 21.8183 21.1751 21.2839C20.9524 21.1503 20.7297 21.1057 20.5516 21.1057L20.5502 20.8338H20.5289V16.7413L20.5071 12.5549L20.5289 12.5548V12.5441H22.031ZM21.3977 25.8261C21.5313 25.8706 21.6203 25.9597 21.7094 26.0488L22.5556 27.4294C22.6447 27.563 22.7783 27.652 23.0009 27.652H24.2925C24.4706 27.652 24.6487 27.563 24.7378 27.4294C24.8492 27.2512 24.9605 27.0285 25.0718 26.8059C25.1832 26.5832 25.2945 26.3605 25.4058 26.1824C25.4504 26.0488 25.6669 25.8706 25.8005 25.8261L21.3977 25.8261Z" fill="url(#paint1_linear_2203_545)"/>
|
||||
<path d="M34.0289 16.5472C35.7015 18.564 36.7644 21.0158 37.0929 23.6153C37.4214 26.2147 37.0019 28.8539 35.8835 31.2234C34.7652 33.5928 32.9944 35.5942 30.7788 36.9929C28.5633 38.3916 25.9948 39.1295 23.3747 39.1202C20.7547 39.1108 18.1916 38.3545 15.9861 36.9401C13.7806 35.5256 12.0241 33.5116 10.9227 31.1342C9.82132 28.7568 9.42065 26.1147 9.7677 23.5177C10.1147 20.9207 11.1951 18.4764 12.8821 16.4717" stroke="white" stroke-width="2"/>
|
||||
<path d="M31.6163 21.9899C32.1801 23.3676 32.3873 24.8652 32.2189 26.3443C32.0504 27.8233 31.5116 29.236 30.6524 30.4516C29.7932 31.6672 28.6413 32.6465 27.3033 33.2989C25.9652 33.9513 24.4843 34.2557 22.9974 34.184C21.5105 34.1122 20.0657 33.6667 18.7967 32.8885C17.5277 32.1103 16.4754 31.0247 15.7372 29.732C14.999 28.4393 14.5988 26.9813 14.5735 25.4929C14.5482 24.0045 14.8987 22.5338 15.5925 21.2167" stroke="white" stroke-width="2"/>
|
||||
<path d="M23.7582 41.0798L23.7582 34.9465" stroke="url(#paint2_linear_2203_545)" stroke-width="1.9" stroke-linecap="round"/>
|
||||
<path d="M39.4451 25.3511L33.1584 25.3337" stroke="url(#paint3_linear_2203_545)" stroke-width="1.9" stroke-linecap="round"/>
|
||||
<path d="M7.35944 25.3252L13.6461 25.3425" stroke="url(#paint4_linear_2203_545)" stroke-width="1.9" stroke-linecap="round"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_2203_545" x1="23" y1="0.582275" x2="23" y2="46.5823" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#7EB6FF"/>
|
||||
<stop offset="1" stop-color="#2570EC"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_2203_545" x1="23.6413" y1="12.544" x2="23.6413" y2="20.8338" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#F4F4F4"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_2203_545" x1="23.2582" y1="41.0798" x2="23.2582" y2="34.9465" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="white"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_2203_545" x1="39.4464" y1="24.8511" x2="33.1598" y2="24.8337" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="white"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear_2203_545" x1="7.36081" y1="24.8252" x2="13.6475" y2="24.8425" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="white"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 5.3 KiB |
1
styles/light/images/offset_z.svg
Normal file
1
styles/light/images/offset_z.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1731045447381" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13273" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24"><path d="M251.392 713.728l331.776-396.8H277.504V202.752h486.912v107.52l-331.776 396.8H773.12v114.176H251.392v-107.52zM173.056 902.144v-100.864H128V947.2h146.432v-45.056H173.056zM850.944 121.856v100.864h45.056V76.8h-146.432v45.056h101.376z" p-id="13274" fill="#6C71C4"></path></svg>
|
After Width: | Height: | Size: 604 B |
Loading…
x
Reference in New Issue
Block a user