Files
linuxcncAllWasm/share/gscreen/skins/silverdragon/silverdragon_handler.py
2026-08-20 06:17:39 +08:00

1482 lines
65 KiB
Python

# This is a handler file for using Gscreen's infrastructure
# to load a completely custom glade screen.
# The only thing that really matters is that it's saved as a GTK builder project,
# the toplevel window is called window1 (The default name) and you connect a destroy
# window signal otherwise you can't close down linuxcnc
import gi
from gi.repository import Gtk as gtk
from gi.repository import Gdk as gdk
from gi.repository import GObject as gobject
from gi.repository import Pango as pango
import hal
import hal_glib
import linuxcnc
from time import strftime
# constants
_RELEASE = " 1.1"
_INCH = 0
_MM = 1
# Mode Notebook Tabs
_MODE_MANUAL = 1
_MODE_MDI = 0
_MODE_AUTO = 1
# Main Notebook Tabs
_NB_PREVIEW = 0
_NB_OFFSET = 1
_NB_TOOL = 2
_NB_ALARMS = 3
_NB_SETUP = 4
NOTIFY_AVAILABLE = False
ALERT_ICON = "/home/jim/linuxcnc/configs/silverdragon/images/applet-critical.png"
INFO_ICON = "/home/jim/linuxcnc/configs/silverdragon/images/std_info.gif"
# standard handler call
def get_handlers(halcomp,builder,useropts,gscreen):
return [HandlerClass(halcomp,builder,useropts,gscreen)]
class HandlerClass:
# This will be pretty standard to gain access to everything
# command is for control and status of linuxcnc
# data is important data from gscreen and linuxcnc
# widgets is all the widgets from the glade files
# gscreen is for access to gscreens methods
def __init__(self, halcomp,builder,useropts,gscreen):
self.command = linuxcnc.command()
self.data = gscreen.data
self.widgets = gscreen.widgets
self.gscreen = gscreen
self.stat = linuxcnc.stat()
self.halcomp = self.gscreen.halcomp
self.error_channel = linuxcnc.error_channel()
# global variables
self.initialized = False
self.factor = 1.0
self.slow_jog = 0
self.fast_jog = 0
self.slow_jog_factor = 10
self.metric_units = True
self.start_system = "G54"
self.system_list = ("0", "G54", "G55", "G56", "G57", "G58", "G59", "G59.1", "G59.2", "G59.3")
self.units = ["", "IN", "MM", "CM"]
self.must_be_auto = "Must be in AUTO mode"
self.program_length = 0
self.program_progress = 0.0
self.current_line = 1
self.distance = 0
self.jog_increments = []
self.tool_diameter = 0.0
self.load_tool = False
self.tool_change = False
self.use_auto_zref = False
self.tool_sensor = False
self.tool_sensor_x = 0.0
self.tool_sensor_y = 0.0
self.tool_sensor_z = 0.0
self.laser_x = 0.0
self.laser_y = 0.0
self.home_x = 0.0
self.home_y = 0.0
self.home_z = 0.0
self.axis_to_ref = []
self.xpos = 0
self.ypos = 0
self.width = 0
self.height = 0
self.file_to_load = ""
gobject.timeout_add(1000, self.clock)
self.default_theme = gtk.Settings.get_default().get_property("gtk-theme-name")
self.label_home_x = self.widgets.btn_home_x.get_children()[0]
self.label_home_y = self.widgets.btn_home_y.get_children()[0]
self.label_home_z = self.widgets.btn_home_z.get_children()[0]
self.init_file_to_load()
def __getitem__(self, item):
return getattr(self, item)
# This connects signals without using glade's autoconnect method
# in this case to destroy the window
# it calls the method in gscreen: gscreen.on_window_destroy()
# Signals in this list are connected to gscreen methods
def connect_signals(self,handlers):
signal_list = [ ["window1","destroy", "on_window1_destroy"],
["btn_show_hal", "clicked", "on_halshow"],
["btn_hal_meter", "clicked", "on_halmeter"],
["btn_hal_scope", "clicked", "on_halscope"],
["btn_classicladder", "clicked", "on_ladder"],
["btn_status", "clicked", "on_status"],
["btn_calibration", "clicked", "on_calibration"],
["desktop_notify", "toggled", "on_desktop_notify_toggled"],
["theme_choice", "changed", "on_theme_choice_changed"],
["btn_pop_statusbar", "clicked", "on_pop_statusbar_clicked"]]
for i in signal_list:
if len(i) == 3:
self.gscreen.widgets[i[0]].connect(i[1], self.gscreen[i[2]])
elif len(i) == 4:
self.gscreen.widgets[i[0]].connect(i[1], self.gscreen[i[2]],i[3])
for i in('x','y','z'):
self.widgets[i+'neg'].connect("pressed", self['jog_'+i],0,True)
self.widgets[i+'neg'].connect("released", self['jog_'+i],0,False)
self.widgets[i+'pos'].connect("pressed", self['jog_'+i],1,True)
self.widgets[i+'pos'].connect("released", self['jog_'+i],1,False)
self.widgets.jog_speed.connect("value_changed",self.jog_speed_changed)
self.widgets.full_window.connect("pressed", self.on_fullscreen_pressed)
self.widgets.max_window.connect("pressed", self.on_max_window_pressed)
self.widgets.default_window.connect("pressed", self.on_default_window_pressed)
# We don't want Gscreen to initialize it's regular widgets because this custom
# screen doesn't have most of them. So we add this function call.
# Since this custom screen uses gladeVCP magic for its interaction with linuxcnc
# We don't add much to this function, but we do want the window to display.
# init_show_window will do this
def initialize_widgets(self):
self.gscreen.init_show_windows()
self.gscreen.init_gremlin()
self.gscreen.init_audio()
self.gscreen.init_desktop_notify()
self.gscreen.init_statusbar()
self.gscreen.init_tooleditor()
self.gscreen.init_themes()
self.init_home()
self.init_jog_increments()
self.init_tool_measurement()
self.init_button_colors()
self.init_offsetpage()
self.init_sensitive_on_off()
self.init_sensitive_run_idle()
self.init_sensitive_all_homed()
self.init_unit_labels()
self.widgets.chk_reload_tool.set_active(self.gscreen.prefs.getpref("reload_tool", True, bool))
self.widgets.rbt_abs.emit("toggled")
self.widgets.rbt_rel.set_label(self.start_system)
opt_blocks = self.gscreen.prefs.getpref("blockdel", False, bool)
self.widgets.tbtn_optional_blocks.set_active(opt_blocks)
self.command.set_block_delete(opt_blocks)
optional_stops = self.gscreen.prefs.getpref( "opstop", False, bool )
self.widgets.tbtn_optional_stops.set_active( optional_stops )
self.command.set_optional_stop( optional_stops )
self.widgets.chk_show_dro.set_active(self.gscreen.prefs.getpref("enable_dro", False, bool))
self.widgets.show_offsets.set_active(self.gscreen.prefs.getpref("show_offsets", False, bool))
self.widgets.chk_show_dtg.set_active(self.gscreen.prefs.getpref("show_dtg", False, bool))
self.widgets.show_offsets.set_sensitive(self.widgets.chk_show_dro.get_active())
self.widgets.chk_show_dtg.set_sensitive(self.widgets.chk_show_dro.get_active())
self.widgets.cmb_mouse_button_mode.set_active(self.gscreen.prefs.getpref("mouse_btn_mode", 4, int))
self.widgets.tbtn_view_tool_path.set_active(self.gscreen.prefs.getpref("view_tool_path", True, bool))
self.widgets.tbtn_view_dimension.set_active(self.gscreen.prefs.getpref("view_dimension", True, bool))
self.widgets.rbt_view_p.emit("toggled")
self.widgets.tbtn_units.set_label("MM")
if self.gscreen.prefs.getpref("run_from_line", "no_run", str) == "no_run":
self.widgets.chk_run_from_line.set_active(False)
self.widgets.btn_from_line.set_sensitive(False)
else:
self.widgets.chk_run_from_line.set_active(True)
self.widgets.btn_from_line.set_sensitive(True)
if self.gscreen.prefs.getpref("show_preview_on_offset", False, bool):
self.widgets.rbtn_show_preview.set_active(True)
else:
self.widgets.rbtn_show_offsets.set_active(True)
self.widgets.chk_use_kb_shortcuts.set_active(self.gscreen.prefs.getpref("use_keyboard_shortcuts", False, bool))
self.widgets.adj_start_spindle_RPM.set_value(self.spindle_start_rpm)
self.widgets.gcode_view.set_sensitive(False)
self.widgets.ntb_main.set_current_page(_NB_PREVIEW)
self.gscreen.sensitize_widgets(self.data.sensitive_on_off, False)
self.command.mode(linuxcnc.MODE_MANUAL)
self.command.wait_complete()
def initialize_preferences(self):
self.gscreen.init_general_pref()
self.gscreen.init_theme_pref()
self.gscreen.init_window_geometry_pref()
self.no_force_homing = self.gscreen.inifile.getbool("TRAJ", "NO_FORCE_HOMING", fallback=False)
if self.no_force_homing:
self.widgets.chk_reload_tool.set_sensitive(False)
self.widgets.chk_reload_tool.set_active(False)
self.widgets.lbl_reload_tool.set_visible(True)
default_spindle_speed = self.gscreen.inifile.getreal("DISPLAY", "DEFAULT_SPINDLE_SPEED")
self.spindle_start_rpm = self.gscreen.prefs.getpref( 'spindle_start_rpm', default_spindle_speed, float )
# get the values for the sliders
default_jog_vel = self.gscreen.inifile.getreal("TRAJ", "DEFAULT_LINEAR_VELOCITY")
self.fast_jog = default_jog_vel
self.slow_jog = default_jog_vel / self.slow_jog_factor
self.jog_rate_max = self.gscreen.inifile.getreal("TRAJ", "MAX_LINEAR_VELOCITY")
self.data.spindle_override_max = self.gscreen.inifile.getreal("DISPLAY", "MAX_SPINDLE_OVERRIDE")
self.data.spindle_override_min = self.gscreen.inifile.getreal("DISPLAY", "MIN_SPINDLE_OVERRIDE")
self.data.feed_override_max = self.gscreen.inifile.getreal("DISPLAY", "MAX_FEED_OVERRIDE")
self.data.dro_actual = self.gscreen.inifile.find("DISPLAY", "POSITION_FEEDBACK")
# set the slider limits
self.widgets.jog_speed.set_range(100, float(self.jog_rate_max) * 60)
self.widgets.jog_speed.set_value(default_jog_vel * 60)
self.widgets.jog_speed.set_digits(0)
self.widgets.spc_spindle.set_range(float(self.data.spindle_override_min) * 100, float(self.data.spindle_override_max) * 100)
self.widgets.spc_spindle.set_value(100)
self.widgets.spc_rapid.set_range(1, 100)
self.widgets.spc_rapid.set_value(100)
self.widgets.spc_feed.set_range(1, float(self.data.feed_override_max) * 100)
self.widgets.spc_feed.set_value(100)
self.max_velocity = self.stat.max_velocity
def initialize_keybindings(self):
self.widgets.window1.connect("key_press_event", self.gscreen.on_key_event, 1)
self.widgets.window1.connect("key_release_event", self.gscreen.on_key_event, 0)
def init_home(self):
self.home_x = self.gscreen.inifile.getreal("JOINT_0", "HOME")
self.home_y = self.gscreen.inifile.getreal("JOINT_1", "HOME")
self.home_z = self.gscreen.inifile.getreal("JOINT_2", "HOME")
def init_tool_measurement(self):
# set up auto zref
xpos = self.gscreen.inifile.getreal("TOOLSENSOR", "X")
ypos = self.gscreen.inifile.getreal("TOOLSENSOR", "Y")
zpos = self.gscreen.inifile.getreal("TOOLSENSOR", "Z")
sensor_height = self.gscreen.inifile.getreal("TOOLSENSOR", "SENSOR_HEIGHT")
maxprobe = self.gscreen.inifile.getreal("TOOLSENSOR", "MAXPROBE")
search_vel = self.gscreen.inifile.getreal("TOOLSENSOR", "SEARCH_VEL")
probe_vel = self.gscreen.inifile.getreal("TOOLSENSOR", "PROBE_VEL")
self.halcomp["probe_vel"] = probe_vel
self.halcomp["search_vel"] = search_vel
self.halcomp["sensor_height"] = sensor_height
self.halcomp["maxprobe"] = maxprobe
if not xpos or not ypos or not zpos or not maxprobe:
self.widgets.chk_use_auto_zref.set_active(False)
self.widgets.chk_use_auto_zref.set_sensitive(False)
self.widgets.btn_g30.set_sensitive(False)
self.widgets.btn_blockheight.set_sensitive(False)
self.widgets.lbl_blockheight.hide()
self.widgets.chk_use_auto_zref.set_sensitive(False)
print(_("No valid tool sensor location"))
print(_("Block Height - Disabled"))
else:
self.widgets.lbl_tool_measurement.hide()
self.widgets.lbl_xpos.set_label(str(xpos))
self.widgets.lbl_ypos.set_label(str(ypos))
self.widgets.lbl_zpos.set_label(str(zpos))
self.widgets.lbl_max_probe.set_label(str(maxprobe))
self.widgets.lbl_sensor_height.set_label(str(sensor_height))
self.widgets.lbl_search_vel.set_label(str(search_vel))
self.widgets.lbl_probe_vel.set_label(str(probe_vel))
self.use_auto_zref = self.gscreen.prefs.getpref("use_autozref", False, bool)
self.tool_sensor = True
self.tool_sensor_x = xpos
self.tool_sensor_y = ypos
self.tool_sensor_z = zpos
print(_("Block Height - Enabled"))
self.widgets.chk_use_auto_zref.emit("toggled")
# set up laser crosshair offsets
xpos = self.gscreen.inifile.getreal("LASER", "X")
ypos = self.gscreen.inifile.getreal("LASER", "Y")
if not xpos or not ypos:
self.widgets.btn_laser_zero.set_sensitive(False)
self.widgets.tbtn_laser.set_sensitive(False)
else:
self.laser_x = xpos
self.laser_y = ypos
def init_button_colors(self):
# set the button background colors and digits of the DRO
self.homed_textcolor = self.gscreen.prefs.getpref("homed_textcolor", "#00FF00", str) # default green
self.unhomed_textcolor = self.gscreen.prefs.getpref("unhomed_textcolor", "#FF0000", str) # default red
self.homed_color = gdk.RGBA()
self.homed_color.parse(self.homed_textcolor)
self.widgets.homed_colorbtn.set_rgba(self.homed_color)
self.unhomed_color = gdk.RGBA()
self.unhomed_color.parse(self.unhomed_textcolor)
self.widgets.unhomed_colorbtn.set_rgba(self.unhomed_color)
self.widgets.tbtn_estop.modify_bg(gtk.StateFlags.NORMAL, gdk.color_parse("#00FF00"))
self.widgets.tbtn_estop.modify_bg(gtk.StateFlags.ACTIVE, gdk.color_parse("#FF0000"))
self.widgets.tbtn_on.modify_bg(gtk.StateFlags.NORMAL, gdk.color_parse("#FF0000"))
self.widgets.tbtn_on.modify_bg(gtk.StateFlags.ACTIVE, gdk.color_parse("#00FF00"))
self.label_home_x.modify_fg(gtk.StateFlags.NORMAL, gdk.color_parse("#FF0000"))
self.label_home_y.modify_fg(gtk.StateFlags.NORMAL, gdk.color_parse("#FF0000"))
self.label_home_z.modify_fg(gtk.StateFlags.NORMAL, gdk.color_parse("#FF0000"))
# set the active colours of togglebuttons and radiobuttons
blue_list = ["tbtn_mist", "tbtn_flood", "tbtn_laser", "tbtn_spare",
"tbtn_units", "tbtn_pause",
"tbtn_optional_stops", "tbtn_optional_blocks",
"rbt_abs", "rbt_rel", "rbt_dtg",
"rbt_reverse", "rbt_stop", "rbt_forward"]
green_list = ["rbt_manual", "rbt_mdi", "rbt_auto"]
other_list = ["rbt_view_p", "rbt_view_x", "rbt_view_y", "rbt_view_z",
"tbtn_view_dimension", "tbtn_view_tool_path"]
for btn in blue_list:
self.widgets["{0}".format(btn)].modify_bg(gtk.StateFlags.ACTIVE, gdk.color_parse("#44A2CF"))
for btn in green_list:
self.widgets["{0}".format(btn)].modify_bg(gtk.StateFlags.ACTIVE, gdk.color_parse("#A2E592"))
for btn in other_list:
self.widgets["{0}".format(btn)].modify_bg(gtk.StateFlags.ACTIVE, gdk.color_parse("#BB81B5"))
def init_sensitive_on_off(self):
self.data.sensitive_on_off = ["table_run", "tbl_dro", "vbox_overrides",
"vbox_tool", "hbox_spindle_ctl"]
def init_sensitive_run_idle(self):
self.data.sensitive_run_idle = ["rbt_manual", "rbt_mdi", "rbt_auto",
"tbtn_optional_blocks", "tbtn_optional_stops",
"btn_run", "rbt_reverse", "rbt_stop", "rbt_forward"]
def init_sensitive_all_homed(self):
self.data.sensitive_all_homed = ["btn_zero_x", "btn_zero_y", "btn_zero_z",
"btn_ref_x", "btn_ref_y", "btn_ref_z"]
def initialize_pins(self):
# pins for block height
self.halcomp.newpin("sensor_height", hal.HAL_FLOAT, hal.HAL_OUT)
pin = self.halcomp.newpin("block_height", hal.HAL_FLOAT, hal.HAL_OUT)
hal_glib.GPin(pin).connect("value_changed", self.on_blockheight_changed)
self.halcomp["block_height"] = self.gscreen.prefs.getpref("blockheight", 0.0, float)
# pins for probing
self.halcomp.newpin("search_vel", hal.HAL_FLOAT, hal.HAL_OUT)
self.halcomp.newpin("probe_vel", hal.HAL_FLOAT, hal.HAL_OUT)
self.halcomp.newpin("maxprobe", hal.HAL_FLOAT, hal.HAL_OUT)
# pins for clear_mdi button
self.halcomp.newpin("clear_mdi", hal.HAL_BIT, hal.HAL_OUT)
pin = self.halcomp.newpin("clear_mdi-waiting", hal.HAL_BIT, hal.HAL_OUT)
pin = self.halcomp.newpin("clear_mdi-response", hal.HAL_BIT, hal.HAL_OUT)
hal_glib.GPin(pin).connect("value_changed", self.on_clear_mdi_changed)
# every 100 milli seconds this gets called
# add pass so gscreen doesn't try to update it's regular widgets or
# add the individual function names that you would like to call.
def periodic(self):
# put the poll command in a try, so if the linuxcnc pid is killed
# from an external command, also quit the GUI
try:
self.stat.poll()
except:
raise SystemExit("SilverDragon cannot poll linuxcnc status any more")
error = self.error_channel.poll()
if error:
self.gscreen.notify(_("ERROR"), _(error), ALERT_ICON)
if self.data.active_gcodes != self.stat.gcodes:
self.gscreen.update_active_gcodes()
if self.data.active_mcodes != self.stat.mcodes:
self.gscreen.update_active_mcodes()
if self.stat.task_mode == linuxcnc.MODE_MANUAL \
and self.stat.interp_state == linuxcnc.INTERP_IDLE \
and self.widgets.ntb_main.get_current_page() == _NB_PREVIEW:
self.widgets.hal_led_jog.set_active(True)
else:
self.widgets.hal_led_jog.set_active(False)
self._update_vel()
self._update_coolant()
self._update_spindle()
self._update_vc()
return True
def clock(self):
self.update_progress()
self.update_dro()
self.widgets.rbt_rel.set_label(self.system_list[self.stat.g5x_index])
self.widgets.entry_clock.set_text(strftime("%H:%M:%S"))
return True
# ========================
# Start of widget handlers
# ========================
def on_window1_show(self, widget, data=None):
self.stat.poll()
if self.stat.task_state == linuxcnc.STATE_ESTOP:
self.widgets.tbtn_estop.set_active(True)
self.widgets.tbtn_on.set_sensitive(False)
else:
self.widgets.tbtn_estop.set_active(False)
self.widgets.tbtn_on.set_sensitive(True)
if self.file_to_load != "":
self.widgets.hal_action_open.load_file(self.file_to_load)
start_as = self.gscreen.prefs.getpref("window_geometry", "default", str)
if start_as == "fullscreen":
self.widgets.window1.fullscreen()
elif start_as == "max":
self.widgets.window1.maximize()
else:
self.xpos = int(self.gscreen.prefs.getpref("x_pos", 10, float))
self.ypos = int(self.gscreen.prefs.getpref("y_pos", 10, float))
self.width = int(self.gscreen.prefs.getpref("width", 1440, float))
self.height = int(self.gscreen.prefs.getpref("height", 900, float))
# set the adjustments according to Window position and size
self.widgets.adj_x_pos.set_value(self.xpos)
self.widgets.adj_y_pos.set_value(self.ypos)
self.widgets.adj_width.set_value(self.width)
self.widgets.adj_height.set_value(self.height)
# move and resize the window
self.widgets.window1.move(self.xpos, self.ypos)
self.widgets.window1.resize(self.width, self.height)
self.initialized = True
# estop machine before closing
def on_window1_destroy(self, widget, data=None):
print("estopping / killing silverdragon")
self.command.state(linuxcnc.STATE_OFF)
self.command.state(linuxcnc.STATE_ESTOP)
gtk.main_quit()
def on_btn_exit_clicked(self, widget, data=None):
self.widgets.tbtn_estop.emit("toggled")
self.widgets.window1.destroy()
return
def on_rbt_manual_clicked(self, widget):
if self.widgets.ntb_main.get_current_page() == _NB_SETUP:
return
self.command.mode(linuxcnc.MODE_MANUAL)
self.command.wait_complete()
def on_rbt_mdi_clicked(self, widget):
if self.widgets.ntb_main.get_current_page() == _NB_SETUP:
self.widgets.rbt_manual.set_active(True)
self.widgets.rbt_mdi.set_active(False)
else:
self.command.mode(linuxcnc.MODE_MDI)
self.command.wait_complete()
def on_rbt_auto_clicked(self, widget):
if self.widgets.ntb_main.get_current_page() == _NB_SETUP:
self.widgets.rbt_manual.set_active(True)
self.widgets.rbt_auto.set_active(False)
else:
self.command.mode(linuxcnc.MODE_AUTO)
self.command.wait_complete()
def on_ntb_main_switch_page(self, widget, tab, index):
if self.stat.task_mode == linuxcnc.MODE_AUTO:
return
if index == _NB_OFFSET:
names = self.widgets.offsetpage1.get_names()
for system, name in names:
system_name = "system_name_{0}".format(system)
self.gscreen.prefs.putpref(system_name, name, str)
self.widgets.offsetpage1.mark_active((self.system_list[self.stat.g5x_index]).lower())
elif index == _NB_TOOL:
self.widgets.tooledit1.set_selected_tool(self.stat.tool_in_spindle)
elif index == _NB_ALARMS:
return
elif index == _NB_SETUP:
self.widgets.rbt_manual.emit("clicked")
else:
return
def on_rbt_forward_clicked(self, widget, data=None):
self._set_spindle("forward")
def on_rbt_reverse_clicked(self, widget, data=None):
self._set_spindle("reverse")
def on_rbt_stop_clicked(self, widget, data=None):
self._set_spindle("stop")
def on_tbtn_units_toggled(self, widget, data=None):
if widget.get_active():
self.metric_units = False
widget.set_label("IN")
else:
self.metric_units = True
widget.set_label("MM")
for axis in self.data.axis_list:
self.widgets["hal_dro_{0}".format(axis)].set_property("display_units_mm", self.metric_units)
self.gscreen.set_dro_units(not widget.get_active(), 1)
def on_rbt_abs_toggled(self, widget, data=None):
for axis in self.data.axis_list:
self.widgets["hal_dro_{0}".format(axis)].set_property("reference_type", 0)
def on_rbt_rel_toggled(self, widget, data=None):
for axis in self.data.axis_list:
self.widgets["hal_dro_{0}".format(axis)].set_property("reference_type", 1)
def on_rbt_dtg_toggled(self, widget, data=None):
for axis in self.data.axis_list:
self.widgets["hal_dro_{0}".format(axis)].set_property("reference_type", 2)
def on_zero_axis_clicked(self, widget):
if not self.data.all_homed:
self.gscreen.notify(_("INFO"), _("Must be all homed to perform this operation"), INFO_ICON)
return
if self.stat.interp_state != linuxcnc.INTERP_IDLE:
self.gscreen.notify(_("INFO"), _("Interpreter is not IDLE"), INFO_ICON)
return
if widget == self.widgets.btn_zero_x:
self.axis_to_ref = "x"
elif widget == self.widgets.btn_zero_y:
self.axis_to_ref = "y"
elif widget == self.widgets.btn_zero_z:
self.axis_to_ref = "z"
else:
self.gscreen.notify(_("ERROR"), _("Unknown axis selected"), ALERT_ICON)
return
self.command.mode(linuxcnc.MODE_MDI)
self.command.wait_complete()
command = "G10 L20 P0 {0}0".format(self.axis_to_ref)
self.command.mdi(command)
self.command.wait_complete()
self.gscreen.reload_plot()
self.command.mode(linuxcnc.MODE_MDI)
self.command.wait_complete()
self.gscreen.prefs.putpref("offset_axis_{0}".format(self.axis_to_ref), 0, float)
def on_ref_axis_clicked(self, widget):
if not self.data.all_homed:
self.gscreen.notify(_("INFO"), _("Must be all homed to perform this operation"), INFO_ICON)
return
if self.stat.interp_state != linuxcnc.INTERP_IDLE:
self.gscreen.notify(_("INFO"), _("Interpreter is not IDLE"), INFO_ICON)
return
if widget == self.widgets.btn_ref_x:
self.axis_to_ref = "x"
elif widget == self.widgets.btn_ref_y:
self.axis_to_ref = "y"
elif widget == self.widgets.btn_ref_z:
self.axis_to_ref = "z"
else:
self.gscreen.notify(_("ERROR"), _("Unknown axis selected"), ALERT_ICON)
return
callback = "on_offset_axis_return"
title = "Enter Offset for Axis %s"%self.axis_to_ref
self.gscreen.launch_numerical_input(callback, 0, 0, title)
self.command.mode(linuxcnc.MODE_MDI)
self.command.wait_complete()
def on_tbtn_flood_toggled(self, widget, data=None):
if self.stat.flood == widget.get_active():
return
if widget.get_active():
self.command.flood(linuxcnc.FLOOD_ON)
else:
self.command.flood(linuxcnc.FLOOD_OFF)
def on_tbtn_mist_toggled(self, widget, data=None):
if self.stat.mist == widget.get_active():
return
if widget.get_active():
self.command.mist(linuxcnc.MIST_ON)
else:
self.command.mist(linuxcnc.MIST_OFF)
def on_tbtn_optional_blocks_toggled(self, widget, data=None):
opt_blocks = widget.get_active()
self.command.set_block_delete(opt_blocks)
self.gscreen.prefs.putpref("blockdel", opt_blocks)
def on_tbtn_optional_stops_toggled(self, widget, data=None):
opt_stops = widget.get_active()
self.command.set_optional_stop(opt_stops)
self.gscreen.prefs.putpref("opstop", opt_stops)
def on_tbtn_pause_toggled(self, widget, data=None):
widgetlist = ["rbt_forward", "rbt_reverse", "rbt_stop"]
paused = widget.get_active()
self.gscreen.sensitize_widgets(widgetlist, paused)
def on_btn_stop_clicked(self, widget, data=None):
self.command.abort()
self.set_restart_line(1)
self.widgets.gcode_view.set_line_number(1)
def on_btn_run_clicked(self, widget, data=None):
if self.stat.task_mode != linuxcnc.MODE_AUTO:
self.gscreen.notify(_("INFO"), self.must_be_auto, INFO_ICON)
return
self.widgets.ntb_main.set_current_page(_NB_PREVIEW)
self.program_progress = 0.0
self.gscreen.notify(_("INFO"), _("Cycle start pressed in AUTO mode"), INFO_ICON)
self.widgets.hal_toggleaction_run.emit('activate')
def on_btn_from_line_clicked(self, widget, data=None):
if self.stat.task_mode != linuxcnc.MODE_AUTO:
self.gscreen.notify(_("INFO"), self.must_be_auto, INFO_ICON)
return
self.gscreen.launch_restart_dialog(self)
def on_spc_spindle_value_changed(self, widget, data=None):
if not self.initialized:
return
# this is in a try except, because on initializing the window,
# the values are still zero, so we would get a divide by zero error
value = widget.get_value()
try:
if not abs(self.stat.settings[2]):
if self.widgets.rbt_forward.get_active() or self.widgets.rbt_reverse.get_active():
speed = self.stat.spindle[0]['speed']
else:
speed = 0
else:
speed = abs(self.stat.spindle[0]['speed'])
spindle_override = value / 100
self.command.spindleoverride(spindle_override)
except:
pass
def on_spc_feed_value_changed(self, widget, data=None):
if not self.initialized:
return
value = widget.get_value() / 100
self.data.feed_override = value
self.command.feedrate(value)
def on_spc_rapid_value_changed(self, widget, data=None):
if not self.initialized:
return
value = widget.get_value() / 100
self.data.rapid_override = value
self.command.rapidrate(value)
def on_btn_home_clicked(self, widget, data=None):
command = "G90 G53 G0 Z{}".format(self.home_z)
self.command.mdi(command)
self.command.wait_complete()
command = "G53 G0 X{} Y{}".format(self.home_x, self.home_y)
self.command.mdi(command)
self.command.wait_complete()
def on_btn_laser_zero_clicked(self, widget, data=None):
if self.stat.task_mode != linuxcnc.MODE_MDI:
self.gscreen.notify(_("INFO"), _("Must be in MDI mode"), INFO_ICON)
return
command = "G10 L20 P0 X{} Y{}".format(self.laser_x, self.laser_y)
self.command.mdi(command)
self.command.wait_complete()
self.gscreen.reload_plot()
def on_btn_M6_clicked(self, widget, data=None):
tool = str(self.widgets.enter_tool.get_text())
if not tool.isdigit():
self.gscreen.notify(_("ERROR"), _("Invalid tool specified"), ALERT_ICON)
self.widgets.enter_tool.set_text(str(self.stat.tool_in_spindle))
else:
command = "T{} M6".format(tool)
self.command.mdi(command)
self.command.wait_complete()
def on_btn_g30_clicked(self, widget, data=None):
if not self.data.all_homed:
self.gscreen.notify(_("ERROR"), _("Machine is not homed"), ALERT_ICON)
return
self.command.mdi("G53 G0 Z0")
self.command.wait_complete()
command = "G53 G0 X{} Y{}".format(self.tool_sensor_x, self.tool_sensor_y)
self.command.mdi(command)
self.command.wait_complete()
def on_btn_blockheight_clicked(self, widget, data=None):
title = "Enter Block Height"
callback = "on_blockheight_return"
self.gscreen.launch_numerical_input(callback, 0, 0, title)
def on_btn_touchoff_clicked(self, widget, data=None):
if self.stat.tool_in_spindle == 0:
self.gscreen.notify(_("INFO"), _("Cannot probe with no tool loaded"), INFO_ICON)
return
self.widgets.gremlin.clear_live_plotter()
if self.use_auto_zref is True:
command = "o< tool_sensor > call"
else:
command = "o< touch_plate > call"
self.command.mdi(command)
def on_btn_rapid_100_clicked(self, widget, data=None):
self.widgets.spc_rapid.set_value(100)
def on_btn_feed_100_clicked(self, widget, data=None):
self.widgets.spc_feed.set_value(100)
def on_btn_spindle_100_clicked(self, widget, data=None):
self.widgets.spc_spindle.set_value(100)
def jog_x(self,widget,direction,state):
self.gscreen.do_key_jog(0,direction,state)
def jog_y(self,widget,direction,state):
self.gscreen.do_key_jog(1,direction,state)
def jog_z(self,widget,direction,state):
self.gscreen.do_key_jog(2,direction,state)
def jog_speed_changed(self,widget):
value = widget.get_value()
self.gscreen.set_jog_rate(absolute = value)
def on_cmb_increments_changed(self, widget, data=None):
index = widget.get_active()
if index == 0:
self.data.current_jogincr_index = len(self.data.jog_increments) - 1
else:
self.data.current_jogincr_index = index - 1
def on_rbt_view_p_toggled(self, widget, data=None):
if self.widgets.rbt_view_p.get_active():
self.widgets.gremlin.set_property("view", "p")
def on_rbt_view_x_toggled(self, widget, data=None):
if self.widgets.rbt_view_x.get_active():
self.widgets.gremlin.set_property("view", "x")
def on_rbt_view_y_toggled(self, widget, data=None):
if self.widgets.rbt_view_y.get_active():
self.widgets.gremlin.set_property("view", "y")
def on_rbt_view_z_toggled(self, widget, data=None):
if self.widgets.rbt_view_z.get_active():
self.widgets.gremlin.set_property("view", "z")
def on_btn_zoom_in_clicked(self, widget, data=None):
self.widgets.gremlin.zoom_in()
def on_btn_zoom_out_clicked(self, widget, data=None):
self.widgets.gremlin.zoom_out()
def on_btn_delete_view_clicked(self, widget, data=None):
self.widgets.gremlin.clear_live_plotter()
def on_tbtn_view_dimension_toggled(self, widget, data=None):
self.widgets.gremlin.set_property("show_extents_option", widget.get_active())
self.gscreen.prefs.putpref("view_dimension", self.widgets.tbtn_view_dimension.get_active())
def on_tbtn_view_tool_path_toggled(self, widget, data=None):
self.widgets.gremlin.set_property("show_live_plot", widget.get_active())
self.gscreen.prefs.putpref("view_tool_path", self.widgets.tbtn_view_tool_path.get_active())
def on_tbtn_jog_speed_toggled(self, widget, data=None):
# due to imperial and metric options we have to get first the values of the widget
max = self.widgets.adj_scale_jog_vel.get_upper()
min = self.widgets.adj_scale_jog_vel.get_lower()
value = self.widgets.jog_speed.get_value()
if widget.get_active():
self.fast_jog = value
widget.set_label("SLOW")
self.widgets.jog_speed.set_range(min / self.slow_jog_factor, max / self.slow_jog_factor)
self.widgets.jog_speed.set_value(self.fast_jog / self.slow_jog_factor)
else:
self.slow_jog = value
widget.set_label("FAST")
self.widgets.jog_speed.set_range(min * self.slow_jog_factor, max * self.slow_jog_factor)
self.widgets.jog_speed.set_value(self.fast_jog)
def on_rbtn_show_preview_toggled(self, widget, data=None):
self.gscreen.prefs.putpref("show_preview_on_offset", widget.get_active())
def on_fullscreen_pressed(self, widget):
self.gscreen.prefs.putpref("window_geometry", "fullscreen", str)
self.widgets.window1.fullscreen()
def on_max_window_pressed(self, widget):
self.gscreen.prefs.putpref("window_geometry", "max", str)
self.widgets.window1.unfullscreen()
self.widgets.window1.maximize()
def on_default_window_pressed(self, widget):
self.gscreen.prefs.putpref("window_geometry", "default", str)
self.widgets.window1.unfullscreen()
self.widgets.window1.unmaximize()
self.widgets.spbtn_x_pos.set_sensitive(True)
self.widgets.spbtn_y_pos.set_sensitive(True)
self.widgets.spbtn_width.set_sensitive(True)
self.widgets.spbtn_height.set_sensitive(True)
self.widgets.window1.move(self.xpos, self.ypos)
self.widgets.window1.resize(self.width, self.height)
def on_btn_zero_g92_clicked(self, widget, data=None):
self.command.mode(linuxcnc.MODE_MDI)
self.command.wait_complete()
self.command.mdi("G92.1")
self.command.mode(linuxcnc.MODE_MANUAL)
self.command.wait_complete()
self.widgets.rbt_offset.emit("toggled")
def on_tbtn_edit_offsets_toggled(self, widget, data=None):
state = widget.get_active()
self.widgets.offsetpage.edit_button.set_active(state)
widgetlist = ["btn_set_selected", "btn_zero_g92"]
self.gscreen.sensitize_widgets(widgetlist, not state)
if not state: # must switch back to manual mode, otherwise jogging is not possible
self.command.mode(linuxcnc.MODE_MANUAL)
self.command.wait_complete()
def on_chk_ignore_limits_toggled(self, widget, data=None):
if self.widgets.chk_ignore_limits.get_active():
if not self._check_limits():
self.gscreen.notify(_("ERROR"), _("No limit switch is active, ignore limits will not be set."), ALERT_ICON)
return
self.command.override_limits()
def on_chk_use_auto_zref_toggled(self, widget, data=None):
state = widget.get_active()
self.gscreen.prefs.putpref("use_autozref", state, bool)
self.widgets.btn_blockheight.set_sensitive(state)
self.widgets.frm_probe_pos.set_sensitive(state)
self.use_auto_zref = state
if state is True:
self.widgets.lbl_blockheight.show()
else:
self.widgets.lbl_blockheight.hide()
def on_chk_reload_tool_toggled(self, widget, data=None):
state = widget.get_active()
self.reload_tool_enabled = state
self.gscreen.prefs.putpref("reload_tool", state)
def on_chk_run_from_line_toggled(self, widget, data=None):
if widget.get_active():
self.gscreen.prefs.putpref("run_from_line", "run")
self.widgets.btn_from_line.set_sensitive(True)
else:
self.gscreen.prefs.putpref("run_from_line", "no_run")
self.widgets.btn_from_line.set_sensitive(False)
def on_chk_use_kb_shortcuts_toggled(self, widget, data=None):
self.gscreen.prefs.putpref("use_keyboard_shortcuts", widget.get_active())
def on_chk_show_dro_toggled(self, widget, data=None):
self.widgets.gremlin.set_property("enable_dro", widget.get_active())
self.gscreen.prefs.putpref("enable_dro", widget.get_active())
self.widgets.show_offsets.set_sensitive(widget.get_active())
self.widgets.chk_show_dtg.set_sensitive(widget.get_active())
def on_chk_show_dtg_toggled(self, widget, data=None):
self.widgets.gremlin.set_property("show_dtg", widget.get_active())
self.gscreen.prefs.putpref("show_dtg", widget.get_active())
def on_show_offsets_toggled(self, widget, data=None):
self.widgets.gremlin.show_offsets = widget.get_active()
self.gscreen.prefs.putpref("show_offsets", widget.get_active())
def on_btn_delete_clicked(self, widget, data=None):
message = _("Do you really want to delete the MDI history?\n")
message += _("This will not delete the MDI History file, but will\n")
message += _("delete the listbox entries for this session")
self.halcomp["clear_mdi-waiting"] = True
self.gscreen.warning_dialog(message, False, None, "clear_mdi")
def on_change_sound(self, widget, sound=None):
file = widget.get_filename()
if file:
if widget == self.widgets.audio_error_chooser:
self.error_sound = file
self.gscreen.prefs.putpref("audio_error", file)
else:
self.alert_sound = file
self.gscreen.prefs.putpref("audio_alert", file)
def on_homed_colorbtn_color_set(self, widget):
self.gscreen.prefs.putpref('homed_textcolor', gdk.RGBA.to_string(widget.get_rgba()), str)
def on_unhomed_colorbtn_color_set(self, widget):
self.gscreen.prefs.putpref('unhomed_textcolor', gdk.RGBA.to_string(widget.get_rgba()), str)
def _from_internal_linear_unit(self, v, unit=None):
if unit is None:
unit = self.stat.linear_units
lu = (unit or 1) * 25.4
return v * lu
def on_adj_x_pos_value_changed(self, widget, data=None):
if not self.initialized:
return
value = int(widget.get_value())
self.gscreen.prefs.putpref("x_pos", value, float)
self.xpos = value
self.widgets.window1.move(value, self.ypos)
def on_adj_y_pos_value_changed(self, widget, data=None):
if not self.initialized:
return
value = int(widget.get_value())
self.gscreen.prefs.putpref("y_pos", value, float)
self.ypos = value
self.widgets.window1.move(self.xpos, value)
def on_adj_width_value_changed(self, widget, data=None):
if not self.initialized:
return
value = int(widget.get_value())
self.gscreen.prefs.putpref("width", value, float)
self.width = value
self.widgets.window1.resize(value, self.height)
def on_adj_start_spindle_RPM_value_changed(self, widget, data=None):
self.spindle_start_rpm = widget.get_value()
self.gscreen.prefs.putpref("spindle_start_rpm", self.spindle_start_rpm, float)
def on_adj_scale_jog_vel_value_changed(self, widget, data=None):
self.gscreen.prefs.putpref("scale_jog_vel", widget.get_value(), float)
self.scale_jog_vel = widget.get_value()
def on_adj_scale_feed_override_value_changed(self, widget, data=None):
self.gscreen.prefs.putpref("scale_feed_override", widget.get_value(), float)
self.scale_feed_override = widget.get_value()
def on_adj_scale_rapid_override_value_changed(self, widget, data=None):
self.gscreen.prefs.putpref("scale_rapid_override", widget.get_value(), float)
self.scale_rapid_override = widget.get_value()
def on_adj_scale_spindle_override_value_changed(self, widget, data=None):
self.gscreen.prefs.putpref("scale_spindle_override", widget.get_value(), float)
self.scale_spindle_override = widget.get_value()
def on_adj_height_value_changed(self, widget, data=None):
if not self.initialized:
return
value = int(widget.get_value())
self.gscreen.prefs.putpref("height", value, float)
self.height = value
self.widgets.window1.resize(self.width, value)
# ==========
# HAL status
# ==========
def on_hal_status_all_homed(self, widget):
self.data.all_homed = True
self.widgets.ntb_main.set_current_page(_NB_PREVIEW)
self.command.mode(linuxcnc.MODE_MANUAL)
self.command.wait_complete()
self.gscreen.sensitize_widgets(self.data.sensitive_all_homed, True)
self.set_motion_mode(1)
self.widgets.statusbar1.remove(self.gscreen.statusbar_id, self.gscreen.homed_status_message)
self.gscreen.notify(_("INFO"), _("All axes have been homed"), INFO_ICON)
if self.widgets.chk_reload_tool.get_active():
if self.stat.tool_in_spindle == 0:
self.reload_tool()
self.command.mode(linuxcnc.MODE_MANUAL)
def on_hal_status_not_all_homed(self, widget, joints):
self.data.all_homed = False
if self.no_force_homing:
return
self.gscreen.sensitize_widgets(self.data.sensitive_all_homed, False)
self.set_motion_mode(0)
def on_hal_status_file_loaded(self, widget, filename):
if filename:
fileobject = file(filename, 'r')
lines = fileobject.readlines()
fileobject.close()
self.program_length = len(lines)
if len(filename) > 70:
filename = filename[0:10] + "..." + filename[len(filename) - 50:len(filename)]
self.widgets.gcode_tab.set_text(filename)
self.gscreen.notify(_("INFO"), _("Program loaded: %s"%filename), INFO_ICON)
else:
self.program_length = 0
self.widgets.gcode_tab.set_text("No program loaded")
def on_hal_status_line_changed(self, widget, line):
self.current_line = line
def on_hal_status_interp_idle(self, widget):
print("IDLE")
if self.load_tool:
return
if self.stat.task_state == linuxcnc.STATE_ESTOP or self.stat.task_state == linuxcnc.STATE_OFF:
self.gscreen.sensitize_widgets(self.data.sensitive_run_idle, False)
else:
self.gscreen.sensitize_widgets(self.data.sensitive_run_idle, True)
if self.tool_change:
self.command.mode(linuxcnc.MODE_MANUAL)
self.command.wait_complete()
self.tool_change = False
self.current_line = 0
def on_hal_status_interp_run(self, widget):
print("RUN")
self.gscreen.sensitize_widgets(self.data.sensitive_run_idle, False)
def on_hal_status_tool_in_spindle_changed(self, object, new_tool_no):
self.gscreen.prefs.putpref("tool_in_spindle", new_tool_no, int)
self.widgets.tooledit1.set_selected_tool(self.stat.tool_in_spindle)
self.update_toolinfo(new_tool_no)
def on_hal_status_state_estop(self, widget=None):
self.widgets.tbtn_estop.set_active(True)
self.widgets.tbtn_on.set_sensitive(False)
self.widgets.tbtn_on.set_active(False)
self.widgets.tbtn_estop.set_label("ESTOP")
self.widgets.chk_ignore_limits.set_sensitive(False)
self.command.mode(linuxcnc.MODE_MANUAL)
self.command.wait_complete()
def on_hal_status_state_estop_reset(self, widget=None):
self.widgets.tbtn_estop.set_active(False)
self.widgets.tbtn_on.set_sensitive(True)
self.widgets.tbtn_estop.set_label("RESET")
self.widgets.chk_ignore_limits.set_sensitive(True)
self._check_limits()
def on_hal_status_state_off(self, widget):
if self.widgets.tbtn_on.get_active():
self.widgets.tbtn_on.set_active(False)
self.widgets.chk_ignore_limits.set_sensitive(True)
self.widgets.tbtn_on.set_label("OFF")
self.gscreen.sensitize_widgets(self.data.sensitive_on_off, False)
def on_hal_status_state_on(self, widget):
if not self.widgets.tbtn_on.get_active():
self.widgets.tbtn_on.set_active(True)
self.widgets.chk_ignore_limits.set_sensitive(False)
self.widgets.tbtn_on.set_label("ON")
self.gscreen.sensitize_widgets(self.data.sensitive_on_off, True)
self.widgets.rbt_manual.set_active(True)
self.widgets.ntb_mode.set_current_page(_MODE_MANUAL)
self.command.mode(linuxcnc.MODE_MANUAL)
self.command.wait_complete()
def on_hal_status_mode_manual(self, widget):
print("MANUAL Mode")
if self.widgets.ntb_main.get_current_page() == _NB_SETUP:
return
self.widgets.rbt_manual.set_active(True)
self.widgets.ntb_main.set_current_page(_NB_PREVIEW)
self.widgets.ntb_mode.set_current_page(_MODE_MANUAL)
self._check_limits()
self.last_key_event = None, 0
def on_hal_status_mode_mdi(self, widget):
if self.tool_change:
self.widgets.ntb_mode.set_current_page(_MODE_MDI)
return
if not self.widgets.rbt_mdi.get_sensitive():
self.command.abort()
self.command.mode(linuxcnc.MODE_MANUAL)
self.command.wait_complete()
self.gscreen.notify(_("INFO"), _("It is not possible to change to MDI Mode at the moment"), INFO_ICON)
return
else:
print("MDI Mode")
self.widgets.hal_mdihistory.entry.grab_focus()
self.widgets.ntb_mode.set_current_page(_MODE_MDI)
self.widgets.rbt_mdi.set_active(True)
self.last_key_event = None, 0
def on_hal_status_mode_auto(self, widget):
if not self.widgets.rbt_auto.get_sensitive():
self.command.abort()
self.command.mode(linuxcnc.MODE_MANUAL)
self.command.wait_complete()
self.gscreen.notify(_("INFO"), _("It is not possible to change to AUTO Mode at the moment"), INFO_ICON)
else:
print("AUTO Mode")
self.widgets.ntb_mode.set_current_page(_MODE_AUTO)
self.widgets.rbt_auto.set_active(True)
self.last_key_event = None, 0
def on_hal_dro_system_changed(self, widget, system):
self.widgets.btn_rel.set_label(system)
self.widgets.gremlin.set_property("metric_units", metric_units)
widgetlist = ["jog_speed"]
# self.stat.linear_units will return 1.0 for metric and 1/25,4 for imperial
# display units not equal machine units
if metric_units != int(self.stat.linear_units):
if self.stat.linear_units == _MM:
self.factor = (1.0 / 25.4)
else:
self.factor = 25.4
self._update_slider(widgetlist)
else:
# display units equal machine units would be factor = 1,
# but if factor not equal 1.0 than we have to reconvert from previous first
if self.factor != 1.0:
self.factor = 1 / self.factor
self._update_slider(widgetlist)
self.factor = 1.0
self._update_slider(widgetlist)
def on_hal_status_motion_mode_changed(self, widget, new_mode):
if self.widgets.ntb_main.get_current_page() == _NB_SETUP:
return
if new_mode == 1 and self.stat.kinematics_type != linuxcnc.KINEMATICS_IDENTITY:
self.widgets.gremlin.set_property("enable_dro", True)
self.widgets.gremlin.use_joints_mode = True
else:
self.widgets.gremlin.use_joints_mode = False
# ================
# Helper functions
# ================
def init_unit_labels(self):
if self.stat.linear_units == 1:
self.widgets.lbl_feed_units.set_text("MM/MIN")
self.widgets.lbl_vc_units.set_text("M/MIN")
else:
self.widgets.lbl_feed_units.set_text("IN/MIN")
self.widgets.lbl_vc_units.set_text("FT/MIN")
def _check_limits(self):
for axis in self.data.axis_list:
axisnumber = "xyzabcuvw".index(axis)
if self.stat.limit[axisnumber] != 0:
return True
if self.widgets.chk_ignore_limits.get_active():
self.widgets.chk_ignore_limits.set_active(False)
return False
def on_blockheight_changed(self, pin):
self.widgets.lbl_blockheight.set_text("{0:.3f}".format(pin.get()))
def on_clear_mdi_changed(self, pin):
if self.halcomp["clear_mdi-waiting"] is False:
if self.halcomp["clear_mdi-response"] is True:
self.widgets.hal_mdihistory.model.clear()
def on_tool_change(self,widget):
change = self.halcomp['change-tool']
tool_no = self.halcomp['tool-number']
if change:
if tool_no == 0:
message = _("Please remove the mounted tool")
secondary = ""
else:
message = _("Please change to tool # %s"%tool_no)
secondary = self.widgets.tooledit1.get_toolinfo(tool_no)[16]
self.data.tool_message = self.gscreen.notify(_("INFO:"),message,None)
self.gscreen.warning_dialog(message, True, secondary, pinname="TOOLCHANGE")
else:
self.halcomp['tool-changed'] = False
def notify(self, alert, message):
msg_text = alert + " " + message
self.widgets.lbl_notify.set_text(msg_text)
def check_mode(self):
string=[]
if self.stat.task_mode == linuxcnc.MODE_MANUAL and self.widgets.ntb_main.get_current_page() == _NB_PREVIEW:
string.append( self.data._MAN)
if self.stat.interp_state == linuxcnc.INTERP_IDLE:
string.append(self.data._JOG)
return string
# ==========================
# override gscreen key calls
# ==========================
def on_keycall_ESTOP(self,state,SHIFT,CNTRL,ALT):
if state:
self.command.state(linuxcnc.STATE_ESTOP)
return True
def on_keycall_POWER(self,state,SHIFT,CNTRL,ALT):
if state:
if self.widgets.tbtn_estop.get_active():
return True
self.widgets.tbtn_on.emit("clicked")
return True
def on_keycall_ABORT(self,state,SHIFT,CNTRL,ALT):
if state:
self.command.abort()
return True
def on_keycall_XPOS(self,state,SHIFT,CNTRL,ALT):
if not self.check_kb_shortcuts(): return
self.gscreen.do_key_jog(0, 1, state)
def on_keycall_XNEG(self,state,SHIFT,CNTRL,ALT):
if not self.check_kb_shortcuts(): return
self.gscreen.do_key_jog(0, 0, state)
def on_keycall_YPOS(self,state,SHIFT,CNTRL,ALT):
if not self.check_kb_shortcuts(): return
self.gscreen.do_key_jog(1, 1, state)
def on_keycall_YNEG(self,state,SHIFT,CNTRL,ALT):
if not self.check_kb_shortcuts(): return
self.gscreen.do_key_jog(1, 0, state)
def on_keycall_ZPOS(self,state,SHIFT,CNTRL,ALT):
if not self.check_kb_shortcuts(): return
self.gscreen.do_key_jog(2, 1, state)
def on_keycall_ZNEG(self,state,SHIFT,CNTRL,ALT):
if not self.check_kb_shortcuts(): return
self.gscreen.do_key_jog(2, 0, state)
def on_keycall_INCREMENTS(self,state,SHIFT,CNTRL,ALT):
if not self.check_kb_shortcuts(): return
widget = self.widgets.cmb_increments
if state:
index = widget.get_active()
length = len(self.data.jog_increments)
if SHIFT: # increment index
if index < length - 1:
index = index + 1
else: # decrement index
if index > 0:
index = index - 1
widget.set_active(index)
self.on_cmb_increments_changed(widget)
return(True)
def check_kb_shortcuts(self):
use_shortcuts = self.widgets.chk_use_kb_shortcuts.get_active()
if not use_shortcuts:
self.gscreen.notify(_("INFO"), _("Keyboard shortcuts are disabled"), INFO_ICON)
return (use_shortcuts)
def _update_vel(self):
real_feed = float(self.stat.settings[1] * self.stat.feedrate)
if self.stat.linear_units == _MM: # metric
self.widgets.lbl_velocity.set_text("{0:d}".format(int(self.stat.current_vel * 60.0 * self.factor)))
if "G95" in self.data.active_gcodes:
feed_str = "{0:d}".format(int(self.stat.settings[1]))
real_feed_str = "{0:.2f}".format(real_feed)
else:
feed_str = "{0:d}".format(int(self.stat.settings[1]))
real_feed_str = "{0:d}".format(int(real_feed))
else: # imperial
self.widgets.lbl_velocity.set_text("{0:.2f}".format(self.stat.current_vel * 60.0 * self.factor))
if "G95" in self.data.active_gcodes:
feed_str = "{0:.4f}".format(self.stat.settings[1])
real_feed_str = "{0:.4f}".format(real_feed)
else:
feed_str = "{0:.3f}".format(self.stat.settings[1])
real_feed_str = "{0:.3f}".format(real_feed)
def set_motion_mode(self, state):
# 1:teleop, 0: joint
self.command.teleop_enable(state)
self.command.wait_complete()
def reload_tool(self):
tool_to_load = self.gscreen.prefs.getpref("tool_in_spindle", 0, int)
if tool_to_load == 0:
return
self.load_tool = True
self.tool_change = True
self.command.mode(linuxcnc.MODE_MDI)
self.command.wait_complete()
command = "M61 Q {0} G43".format(tool_to_load)
self.command.mdi(command)
self.command.wait_complete()
def _update_coolant(self):
if self.stat.flood != self.widgets.tbtn_flood.get_active():
self.widgets.tbtn_flood.set_active(self.stat.flood)
if self.stat.mist != self.widgets.tbtn_mist.get_active():
self.widgets.tbtn_mist.set_active(self.stat.mist)
def _update_spindle(self):
if self.stat.spindle[0]['direction'] > 0:
if not self.widgets.rbt_forward.get_active():
self.widgets.rbt_forward.set_active(True)
elif self.stat.spindle[0]['direction'] < 0:
if not self.widgets.rbt_reverse.get_active():
self.widgets.rbt_reverse.set_active(True)
elif not self.widgets.rbt_stop.get_active():
self.widgets.rbt_stop.set_active(True)
if not abs(self.stat.spindle[0]['speed']):
self.widgets.rbt_stop.set_active(True)
if self.stat.spindle[0]['speed'] == 0:
speed = 0
else:
speed = self.stat.spindle[0]['speed']
self.widgets.lbl_spindle_rpm.set_text("{0}".format(int(speed * self.data.spindle_override)))
def _update_vc(self):
if self.stat.spindle[0]['direction'] != 0:
if self.stat.spindle[0]['speed'] == 0:
speed = 0
else:
speed = self.stat.spindle[0]['speed']
vc = abs(int(speed * self.data.spindle_override) * self.tool_diameter * 3.1416 / 1000)
else:
vc = 0
if vc >= 100:
text = "{0:d}".format(int(vc))
elif vc >= 10:
text = "{0:2.1f}".format(vc)
else:
text = "{0:.2f}".format(vc)
self.widgets.lbl_vc.set_text(text)
def update_dro(self):
j = 0
for i in self.data.axis_list:
if self.stat.joint[j]['homed']:
self["label_home_%s"%i].modify_fg(gtk.StateFlags.NORMAL, gdk.color_parse("#0000FF"))
color = self.homed_color
else:
self["label_home_%s"%i].modify_fg(gtk.StateFlags.NORMAL, gdk.color_parse("#FF0000"))
color = self.unhomed_color
j += 1
self.widgets["hal_dro_%s"%i].override_color(gtk.StateFlags.NORMAL, color)
def _set_spindle(self, command):
if self.stat.task_state == linuxcnc.STATE_ESTOP:
return
if self.stat.task_mode != linuxcnc.MODE_MANUAL:
if self.stat.interp_state == linuxcnc.INTERP_READING or self.stat.interp_state == linuxcnc.INTERP_WAITING:
if self.stat.spindle[0]['direction'] > 0:
self.widgets.rbt_forward.set_sensitive(True)
self.widgets.rbt_reverse.set_sensitive(False)
self.widgets.rbt_stop.set_sensitive(False)
elif self.stat.spindle[0]['direction'] < 0:
self.widgets.rbt_forward.set_sensitive(False)
self.widgets.rbt_reverse.set_sensitive(True)
self.widgets.rbt_stop.set_sensitive(False)
else:
self.widgets.rbt_forward.set_sensitive(False)
self.widgets.rbt_reverse.set_sensitive(False)
self.widgets.rbt_stop.set_sensitive(True)
return
rpm = self.check_spindle_range()
try:
rpm_out = rpm / self.stat.spindle[0]['override']
except:
rpm_out = 0
if command == "stop":
self.command.spindle(0)
elif command == "forward":
self.command.spindle(1, rpm_out)
elif command == "reverse":
self.command.spindle(-1, rpm_out)
else:
print(_("Something went wrong, we have an unknown spindle widget {0}").format(command))
def update_progress(self):
if self.stat.task_mode != linuxcnc.MODE_AUTO:
return
if self.program_length > 0:
progress = float(self.current_line) / float(self.program_length)
else:
progress = 0.0
self.widgets.pgm_progress.set_fraction(progress)
self.widgets.pgm_progress.set_text("{0:2.1f} % Complete".format(progress * 100))
def init_jog_increments(self):
list = self.data.jog_increments[:]
del list[-1]
# populate the increments combobox with rearranged increment values
model = self.widgets.cmb_increments.get_model()
model.clear()
model.append(["continuous"])
for index, inc in enumerate(list):
model.append((inc,))
self.widgets.cmb_increments.set_active(0)
self.data.current_jogincr_index = index + 1
def check_spindle_range(self):
rpm = (self.stat.settings[2])
if rpm == 0:
rpm = abs(self.spindle_start_rpm)
spindle_override = self.widgets.spc_spindle.get_value() / 100
real_spindle_speed = rpm * spindle_override
return real_spindle_speed
def init_file_to_load(self):
default_path = self.gscreen.inifile.find("DISPLAY", "PROGRAM_PREFIX")
if not default_path:
print("Path %s from DISPLAY , PROGRAM_PREFIX does not exist" % default_path)
print("Trying default path...")
default_path = "~/linuxcnc/nc_files/"
open_file = self.gscreen.inifile.find("DISPLAY", "OPEN_FILE")
if not open_file:
print("No file to open")
else:
self.file_to_load = default_path + open_file
def update_toolinfo(self, tool):
toolinfo = self.widgets.tooledit1.get_toolinfo(tool)
if toolinfo:
# toolinfo[0] = cell toggle
# toolinfo[1] = tool number
# toolinfo[2] = pocket number
# toolinfo[3] = X offset
# toolinfo[4] = Y offset
# toolinfo[5] = Z offset
# toolinfo[6] = A offset
# toolinfo[7] = B offset
# toolinfo[8] = C offset
# toolinfo[9] = U offset
# toolinfo[10] = V offset
# toolinfo[11] = W offset
# toolinfo[12] = tool diameter
# toolinfo[13] = frontangle
# toolinfo[14] = backangle
# toolinfo[15] = tool orientation
# toolinfo[16] = tool info
self.widgets.enter_tool.set_text(str(toolinfo[1]))
# this assumes that all values in the tool table are metric
self.widgets.lbl_tool_diameter.set_text(toolinfo[12])
self.tool_diameter = float(toolinfo[12])
self.widgets.lbl_tool_comment.set_text(toolinfo[16])
if tool <= 0:
self.widgets.enter_tool.set_text("0")
self.widgets.lbl_tool_diameter.set_text("----")
self.widgets.lbl_tool_comment.set_text("NO TOOL LOADED")
if self.load_tool:
self.load_tool = False
self.on_hal_status_interp_idle(None)
return
if "G43" in self.data.active_gcodes and self.stat.task_mode != linuxcnc.MODE_AUTO:
self.command.mode(linuxcnc.MODE_MDI)
self.command.wait_complete()
self.command.mdi("G43")
self.command.wait_complete()
def _update_slider(self, widgetlist):
for widget in widgetlist:
value = self.widgets[widget].get_value()
min = self.widgets[widget].get_property("min")
max = self.widgets[widget].get_property("max")
self.widgets[widget].set_range(min * self.factor, max * self.factor)
self.widgets[widget].set_value(value * self.factor)
self.scale_jog_vel = self.scale_jog_vel * self.factor
self.fast_jog = self.fast_jog * self.factor
self.slow_jog = self.slow_jog * self.factor
def init_offsetpage(self):
self.gscreen.init_offsetpage()
self.widgets.offsetpage1.set_display_follows_program_units()
if self.stat.program_units != 1:
self.widgets.offsetpage1.set_to_mm()
self.widgets.offsetpage1.machine_units_mm = _MM
else:
self.widgets.offsetpage1.set_to_inch()
self.widgets.offsetpage1.machine_units_mm = _INCH
self.widgets.offsetpage1.set_row_visible("1", False)
self.widgets.offsetpage1.set_font("sans 12")
self.widgets.offsetpage1.set_foreground_color(gdk.RGBA(0.151, 0.813, 0.845, 1.0))
self.widgets.offsetpage1.selection_mask = ("Tool", "G5x", "Rot")
systemlist = ["Tool", "G5x", "Rot", "G92", "G54", "G55", "G56", "G57", "G58", "G59", "G59.1",
"G59.2", "G59.3"]
names = []
for system in systemlist:
system_name = "system_name_{0}".format(system)
name = self.gscreen.prefs.getpref(system_name, system, str)
names.append([system, name])
self.widgets.offsetpage1.set_names(names)
def on_offset_axis_return(self, widget, result, calc, userdata, userdata2):
value = calc.get_value()
if result == gtk.ResponseType.ACCEPT:
if value is not None:
r = self.axis_to_ref
self.gscreen.prefs.putpref("offset_axis_{}".format(r), value, str)
self.command.mode(linuxcnc.MODE_MDI)
self.command.wait_complete()
command = "G10 L20 P0 {}{}".format(r, value)
self.command.mdi(command)
self.gscreen.reload_plot()
self.command.mode(linuxcnc.MODE_MDI)
self.command.wait_complete()
widget.destroy()
self.data.entry_dialog = None
def on_blockheight_return(self, widget, result, calc, userdata, userdata2):
blockheight = calc.get_value()
if result == gtk.ResponseType.ACCEPT:
if blockheight == "CANCEL" or blockheight == "ERROR":
return
if blockheight is not None or blockheight is not False or blockheight == 0:
self.halcomp["block_height"] = blockheight
self.gscreen.prefs.putpref("blockheight", blockheight, float)
else:
self.halcomp["block_height"] = 0.0
self.gscreen.prefs.putpref("blockheight", 0.0, float)
widget.destroy()
self.data.entry_dialog = None