Import LinuxCNC source tree
BIN
share/gscreen/images/applet-critical.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
share/gscreen/images/coolant_flood.xcf
Normal file
BIN
share/gscreen/images/coolant_flood_plain.gif
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
share/gscreen/images/coolant_flood_plain.xcf
Normal file
BIN
share/gscreen/images/coolant_mist.xcf
Normal file
BIN
share/gscreen/images/coolant_mist_plain.gif
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
share/gscreen/images/coolant_mist_plain.xcf
Normal file
BIN
share/gscreen/images/linuxcnc-wizard.gif
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
share/gscreen/images/spindle_ccw.gif
Normal file
|
After Width: | Height: | Size: 209 B |
BIN
share/gscreen/images/spindle_cw.gif
Normal file
|
After Width: | Height: | Size: 209 B |
BIN
share/gscreen/images/std_info.gif
Normal file
|
After Width: | Height: | Size: 659 B |
BIN
share/gscreen/images/tool_clear.gif
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
share/gscreen/images/tool_reload.gif
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
3595
share/gscreen/skins/9_axis/9_axis.glade
Normal file
129
share/gscreen/skins/9_axis/9_axis_handler.py
Normal file
@@ -0,0 +1,129 @@
|
||||
# This is a component of LinuxCNC
|
||||
# Copyright 2013, 2014 Chris Morley <chrisinnanaimo@hotmail.com>,
|
||||
# Chris Radek <chris@timeguy.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# This is a handler file for using Gscreen's infrastructure
|
||||
# to load a completely custom glade screen
|
||||
# The only things that really matters is that it's saved as a GTK builder project,
|
||||
# the toplevel window is caller window1 (The default name) and you connect a destroy
|
||||
# window signal else you can't close down linuxcnc
|
||||
class HandlerClass:
|
||||
|
||||
# this will be pretty standard to gain access to everything
|
||||
# emc 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
|
||||
#
|
||||
# we added setting the gremlin DRO on from the startup,
|
||||
# a global variable for the number of key presses,
|
||||
# and make only the active axis buttons visible
|
||||
def __init__(self, halcomp,builder,useropts,gscreen):
|
||||
self.emc = gscreen.emc
|
||||
self.data = gscreen.data
|
||||
self.widgets = gscreen.widgets
|
||||
self.gscreen = gscreen
|
||||
|
||||
self.nhits = 0
|
||||
self.widgets.gremlin.set_property('enable_dro',True)
|
||||
for i in ("x","y","z","a","b","c","u","v","w","s"):
|
||||
if i in self.data.axis_list:
|
||||
self.widgets["axis_%s"%i].set_visible(True)
|
||||
self.widgets.offsetpage1.set_row_visible("1",False)
|
||||
|
||||
# This is a new method for a couple of widgets we added callbacks to.
|
||||
# The argument 'widget' is a reference to the actual widget that called.
|
||||
# In this way we can use this method on a bunch of widgets without knowing
|
||||
# their name ahead of time.
|
||||
def on_button_press(self,widget,data=None):
|
||||
global nhits
|
||||
self.nhits += 1
|
||||
widget.set_label("hits: %d" % self.nhits)
|
||||
|
||||
# This is a new method that calls a gscreen method to toggle the DRO units
|
||||
# Gscreen's regular unit button saves the state
|
||||
# for startup, This one just changes it for the session
|
||||
def on_metric_select_clicked(self,widget):
|
||||
data = (self.data.dro_units -1) * -1
|
||||
self.gscreen.set_dro_units(data,False)
|
||||
for i in ("1","2","3"):
|
||||
for letter in self.data.axis_list:
|
||||
axis = "dro_%s%s"% (letter,i)
|
||||
try:
|
||||
self.widgets[axis].set_property("display_units_mm",data)
|
||||
except:
|
||||
pass
|
||||
|
||||
# This method is overridden from gscreen
|
||||
# We selected this method name in the glade file as a callback.
|
||||
# Since this method name is the same as one in gscreen,
|
||||
# gscreen won't connect a callback to it's method.
|
||||
# Meaning this is the only one called.
|
||||
def on_estop_clicked(self,*args):
|
||||
print("estop")
|
||||
if self.data.estopped:
|
||||
self.emc.estop_reset(1)
|
||||
else:
|
||||
self.emc.machine_off(1)
|
||||
self.emc.estop(1)
|
||||
self.widgets.on_label.set_text("Machine Off")
|
||||
return True
|
||||
|
||||
# This is a new method for our new button
|
||||
# we selected this method name in the glade file as a callback
|
||||
def on_machine_state_clicked(self,*args):
|
||||
if self.data.estopped:
|
||||
return
|
||||
elif not self.data.machine_on:
|
||||
self.emc.machine_on(1)
|
||||
self.widgets.on_label.set_text("Machine On")
|
||||
else:
|
||||
self.emc.machine_off(1)
|
||||
self.widgets.on_label.set_text("Machine Off")
|
||||
|
||||
# here we override gscreen's method of hiding the cursor
|
||||
# by writing a method with the same name that gscreen connects a signal to.
|
||||
# and our new method in fact calls a sound method and then the hide cursor method
|
||||
# that are both in gscreen
|
||||
# So now we get a sound when we hide and show the pointer
|
||||
def on_hide_cursor(self,widget):
|
||||
self.gscreen.audio.set_sound(self.data.alert_sound)
|
||||
self.gscreen.audio.run()
|
||||
self.gscreen.on_hide_cursor(None)
|
||||
|
||||
# every 100 milli seconds this gets called
|
||||
# we add calls to the regular functions for the widgets we are using.
|
||||
# and add any extra calls/code
|
||||
def periodic(self):
|
||||
self.gscreen.update_mdi_spindle_button()
|
||||
self.gscreen.update_spindle_bar()
|
||||
self.gscreen.update_active_gcodes()
|
||||
self.gscreen.update_active_mcodes()
|
||||
self.gscreen.update_aux_coolant_pins()
|
||||
self.gscreen.update_feed_speed_label()
|
||||
self.gscreen.update_tool_label()
|
||||
self.gscreen.update_coolant_leds()
|
||||
self.gscreen.update_estop_led()
|
||||
self.gscreen.update_machine_on_led()
|
||||
self.gscreen.update_limit_override()
|
||||
self.gscreen.update_override_label()
|
||||
self.gscreen.update_jog_rate_label()
|
||||
self.gscreen.update_mode_label()
|
||||
self.gscreen.update_units_button_label()
|
||||
|
||||
def get_handlers(halcomp,builder,useropts,gscreen):
|
||||
return [HandlerClass(halcomp,builder,useropts,gscreen)]
|
||||
2076
share/gscreen/skins/gaxis/gaxis.glade
Normal file
239
share/gscreen/skins/gaxis/gaxis_handler.py
Normal file
@@ -0,0 +1,239 @@
|
||||
# This is a component of LinuxCNC
|
||||
# Copyright 2013, 2014 Chris Morley <chrisinnanaimo@hotmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
import hal
|
||||
from gi.repository import Gtk as gtk
|
||||
|
||||
_X = 0;_Y = 1;_Z = 2;_A = 3;_B = 4;_C = 5;_U = 6;_V = 7;_W = 8
|
||||
# This is a handler file for using Gscreen's infrastructure
|
||||
# to load a completely custom glade screen
|
||||
# The only things that really matters is that it's saved as a GTK builder project,
|
||||
# the toplevel window is caller window1 (The default name) and you connect a destroy
|
||||
# window signal else you can't close down linuxcnc
|
||||
class HandlerClass:
|
||||
|
||||
# This will be pretty standard to gain access to everything
|
||||
# emc 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.emc = gscreen.emc
|
||||
self.data = gscreen.data
|
||||
self.widgets = gscreen.widgets
|
||||
self.gscreen = gscreen
|
||||
|
||||
def jog_x(self,widget,direction,state):
|
||||
self.gscreen.do_key_jog(_X,direction,state)
|
||||
def jog_y(self,widget,direction,state):
|
||||
self.gscreen.do_key_jog(_Y,direction,state)
|
||||
def jog_z(self,widget,direction,state):
|
||||
self.gscreen.do_key_jog(_Z,direction,state)
|
||||
|
||||
def on_scale_jog_value_changed(self,widget):
|
||||
self.gscreen.set_jog_rate(absolute=widget.get_value())
|
||||
|
||||
def on_jog_speed_changed(self,widget):
|
||||
self.data.current_jogincr_index = widget.get_active()
|
||||
|
||||
def on_show_alarm_page(self,widget):
|
||||
self.widgets.notebook_debug.set_show_tabs(self.widgets.menuitem5.get_active())
|
||||
self.widgets.notebook_debug.set_current_page(0)
|
||||
|
||||
def on_gremlin_radiobutton_toggled(self,widget):
|
||||
data = widget.get_active()
|
||||
if data:
|
||||
if widget == self.widgets.show_dro:
|
||||
state = dro = True
|
||||
offsets = False
|
||||
elif widget == self.widgets.show_offsets:
|
||||
dro = offsets = True
|
||||
state = False
|
||||
else:
|
||||
offsets = dro = False
|
||||
state = True
|
||||
self.widgets.gremlin.set_property('enable_dro', dro)
|
||||
self.widgets.gremlin.set_property('show_program', state)
|
||||
self.widgets.gremlin.set_property('show_limits', state)
|
||||
self.widgets.gremlin.set_property('show_extents_option', state)
|
||||
self.widgets.gremlin.set_property('show_live_plot', state)
|
||||
self.widgets.gremlin.set_property('show_tool', state)
|
||||
self.widgets.gremlin.show_offsets = offsets
|
||||
|
||||
def on_gremlin_view_toggled(self,widget):
|
||||
self.gscreen.toggle_view()
|
||||
label = self.data.plot_view[0].upper()
|
||||
widget.set_label('View %s'% label)
|
||||
|
||||
# erase the ready-to-home message on statusbar
|
||||
def on_hal_status_all_homed(self,widget):
|
||||
self.data.all_homed = True
|
||||
self.widgets.statusbar1.remove_message(self.gscreen.statusbar_id,self.gscreen.homed_status_message)
|
||||
|
||||
# when run is pressed, destroy the restart dialog if it's showing
|
||||
def on_toolbutton_run_toggled(self,widget):
|
||||
if not self.data.restart_dialog == None:
|
||||
self.data.restart_dialog.destroy()
|
||||
self.data.restart_dialog = None
|
||||
|
||||
# This connects signals without using glade's autoconnect method
|
||||
def connect_signals(self,handlers):
|
||||
signal_list = [ ["window1","destroy", "on_window1_destroy"],
|
||||
["restart","clicked", "launch_restart_dialog"],
|
||||
["metric_select","clicked","on_metric_select_clicked"],
|
||||
["s_run","clicked","on_button_spindle_controls_clicked"],
|
||||
["spindle_control","clicked", "on_spindle_control_clicked"],
|
||||
["spindle_preset","clicked", "on_preset_spindle"],
|
||||
["spindle_increase","clicked", "on_spindle_speed_adjust"],
|
||||
["spindle_decrease","clicked", "on_spindle_speed_adjust"],
|
||||
["run_halshow","clicked", "on_halshow"],
|
||||
["run_calibration","clicked", "on_calibration"],
|
||||
["run_status","clicked", "on_status"],
|
||||
["run_halmeter","clicked", "on_halmeter"],
|
||||
["run_halscope","clicked", "on_halscope"],
|
||||
["run_ladder","clicked", "on_ladder"],
|
||||
]
|
||||
for i in signal_list:
|
||||
if len(i) == 3:
|
||||
self.widgets[i[0]].connect(i[1], self.gscreen[i[2]])
|
||||
elif len(i) == 4:
|
||||
self.widgets[i[0]].connect(i[1], self.gscreen[i[2]],i[3])
|
||||
self.widgets.toolbutton_run.connect("toggled",self.on_toolbutton_run_toggled)
|
||||
self.widgets.scale_jog.connect("value_changed",self.on_scale_jog_value_changed)
|
||||
self.widgets.menuitem5.connect("activate",self.on_show_alarm_page)
|
||||
self.widgets.show_dro.connect('toggled',self.on_gremlin_radiobutton_toggled)
|
||||
self.widgets.show_offsets.connect('toggled',self.on_gremlin_radiobutton_toggled)
|
||||
self.widgets.show_clean.connect('toggled',self.on_gremlin_radiobutton_toggled)
|
||||
self.widgets.view.connect('clicked',self.on_gremlin_view_toggled)
|
||||
self.widgets.zoom_in.connect("clicked",lambda i:self.gscreen.zoom_in())
|
||||
self.widgets.zoom_out.connect("clicked",lambda i:self.gscreen.zoom_out())
|
||||
self.widgets.jog_speed.connect("changed",self.on_jog_speed_changed)
|
||||
self.widgets.sneg.connect("clicked",lambda i:self.gscreen.spindle_adjustment(False,True))
|
||||
self.widgets.spos.connect("clicked",lambda i:self.gscreen.spindle_adjustment(True,True))
|
||||
for i in('x','y','z'):
|
||||
self.widgets['touch_off'+i].connect("clicked", self.on_touch_off_clicked,i)
|
||||
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)
|
||||
|
||||
# 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 to be able to change the theme so:
|
||||
# We change the GTK theme to what's in gscreen's preference file.
|
||||
# gscreen.change_theme() is a method in gscreen that changes the GTK theme of window1
|
||||
# gscreen.data.theme_name is the name of the theme from the preference file
|
||||
# To truely be friendly, we should add a way to change the theme directly in the custom screen.
|
||||
# we also set up the statusbar and add a ready-to-home message
|
||||
def initialize_widgets(self):
|
||||
self.gscreen.init_show_windows()
|
||||
self.gscreen.init_dynamic_tabs()
|
||||
self.gscreen.init_embeded_terminal()
|
||||
#self.gscreen.change_theme(self.data.theme_name)
|
||||
settings = gtk.Settings.get_default()
|
||||
settings.set_string_property("gtk-theme-name", 'Link to gaxis_theme', "")
|
||||
self.gscreen.statusbar_id = self.widgets.statusbar1.get_context_id("Statusbar1")
|
||||
self.gscreen.homed_status_message = self.widgets.statusbar1.push(1,"Ready For Homing")
|
||||
model = self.widgets.jog_speed.get_model()
|
||||
for num,i in enumerate(self.data.jog_increments):
|
||||
model.append([i])
|
||||
if i == "continuous":
|
||||
self.data.current_jogincr_index = num
|
||||
self.widgets.jog_speed.set_active(num)
|
||||
self.gscreen.set_dro_units(self.data.dro_units)
|
||||
self.widgets.adjustment_jog.set_upper(self.data.jog_rate_max)
|
||||
self.widgets.adjustment_jog.set_value(self.data.jog_rate)
|
||||
self.widgets.notebook_debug.set_show_tabs(False)
|
||||
#self.gscreen.keylookup.add_conversion('F4','TEST2','on_keycall_POWER')
|
||||
self.widgets.show_dro.set_active(True)
|
||||
|
||||
# name widgets for theme visual control
|
||||
# with a modified theme gtkrc file these widgets can be visually modified
|
||||
self.widgets.button_estop.get_child().set_name('button_estop')
|
||||
self.widgets.button_machine_on.get_child().set_name('button_machine_on')
|
||||
|
||||
# If we need extra HAL pins here is where we do it.
|
||||
# Note you must import hal at the top of this script to build the pins here. or:
|
||||
# For gaxis there is only jog pins so we call gscreen to
|
||||
# add it's default jog pins
|
||||
def initialize_pins(self):
|
||||
self.gscreen.init_jog_pins()
|
||||
|
||||
# checks the current operating mode according to the UI
|
||||
def check_mode(self):
|
||||
string = []
|
||||
if self.data.mode_order[0] == self.data._MAN and self.widgets.notebook_main.get_current_page() == 1:
|
||||
string.append( self.data._MAN)
|
||||
string.append(self.data._JOG)
|
||||
return string
|
||||
|
||||
# keybinding calls
|
||||
def on_keycall_ESTOP(self,state,SHIFT,CNTRL,ALT):
|
||||
if state: # only activate when pushed not when released
|
||||
self.widgets.emc_toggle_estop.emit('activate')
|
||||
return True
|
||||
def on_keycall_POWER(self,state,SHIFT,CNTRL,ALT):
|
||||
if state:
|
||||
self.widgets.emc_toggle_power.emit('activate')
|
||||
return True
|
||||
def on_keycall_INCREMENTS(self,state,SHIFT,CNTRL,ALT):
|
||||
if state and self.data._MAN in self.check_mode(): # manual mode required
|
||||
if SHIFT:
|
||||
self.gscreen.set_jog_increments(index_dir = -1)
|
||||
else:
|
||||
self.gscreen.set_jog_increments(index_dir = 1)
|
||||
# update the combo box
|
||||
self.widgets.jog_speed.set_active(self.data.current_jogincr_index)
|
||||
return True
|
||||
|
||||
def on_touch_off_clicked(self,widget,axis):
|
||||
self.gscreen.launch_numerical_input("on_offset_origin_entry_return",axis,None,"Touch off %s"% axis.upper())
|
||||
|
||||
def on_offset_origin_entry_return(self,widget,result,calc,axis,userdata2):
|
||||
value = calc.get_value()
|
||||
if result == gtk.ResponseType.ACCEPT:
|
||||
if value == None:
|
||||
return
|
||||
if not axis == "s":
|
||||
if axis in('a','b','c'):
|
||||
pos = self.gscreen.get_qualified_input(value,switch=_DEGREE_INPUT)
|
||||
else:
|
||||
pos = self.gscreen.get_qualified_input(value)
|
||||
self.gscreen.mdi_control.set_axis(axis,pos)
|
||||
self.gscreen.reload_plot()
|
||||
widget.destroy()
|
||||
self.data.entry_dialog = None
|
||||
|
||||
def on_gremlin_line_clicked(self,widget,line):
|
||||
self.widgets.gcode_view.set_line_number(line)
|
||||
|
||||
# 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.
|
||||
# In this case we wish to call Gscreen's default function for units button update
|
||||
def periodic(self):
|
||||
self.gscreen.update_units_button_label()
|
||||
|
||||
def __getitem__(self, item):
|
||||
return getattr(self, item)
|
||||
def __setitem__(self, item, value):
|
||||
return setattr(self, item, value)
|
||||
|
||||
# standard handler call
|
||||
def get_handlers(halcomp,builder,useropts,gscreen):
|
||||
return [HandlerClass(halcomp,builder,useropts,gscreen)]
|
||||
1846
share/gscreen/skins/gaxis_no_plot/gaxis_no_plot.glade
Normal file
216
share/gscreen/skins/gaxis_no_plot/gaxis_no_plot_handler.py
Normal file
@@ -0,0 +1,216 @@
|
||||
# Copyright: 2014
|
||||
# Author: Chris Morley <chrisinnanaimo@hotmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
import hal
|
||||
import gtk
|
||||
_X = 0;_Y = 1;_Z = 2;_A = 3;_B = 4;_C = 5;_U = 6;_V = 7;_W = 8
|
||||
# This is a handler file for using Gscreen's infrastructure
|
||||
# to load a completely custom glade screen
|
||||
# The only things that really matters is that it's saved as a GTK builder project,
|
||||
# the toplevel window is caller window1 (The default name) and you connect a destroy
|
||||
# window signal else you can't close down linuxcnc
|
||||
class HandlerClass:
|
||||
|
||||
# This will be pretty standard to gain access to everything
|
||||
# emc 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.emc = gscreen.emc
|
||||
self.data = gscreen.data
|
||||
self.widgets = gscreen.widgets
|
||||
self.gscreen = gscreen
|
||||
|
||||
def jog_x(self,widget,direction,state):
|
||||
self.gscreen.do_key_jog(_X,direction,state)
|
||||
def jog_y(self,widget,direction,state):
|
||||
self.gscreen.do_key_jog(_Y,direction,state)
|
||||
def jog_z(self,widget,direction,state):
|
||||
self.gscreen.do_key_jog(_Z,direction,state)
|
||||
|
||||
def on_scale_jog_value_changed(self,widget):
|
||||
self.gscreen.set_jog_rate(absolute=widget.get_value())
|
||||
|
||||
def on_scale_fo_value_changed(self,widget):
|
||||
self.gscreen.set_feed_override((widget.get_value()/100),True)
|
||||
|
||||
def on_scale_so_value_changed(self,widget):
|
||||
self.gscreen.set_spindle_override((widget.get_value()/100),True)
|
||||
|
||||
def on_scale_mv_value_changed(self,widget):
|
||||
self.gscreen.set_velocity_override((widget.get_value()/100),True)
|
||||
|
||||
def on_jog_speed_changed(self,widget):
|
||||
self.data.current_jogincr_index = widget.get_active()
|
||||
|
||||
def on_show_alarm_page(self,widget):
|
||||
self.widgets.notebook_debug.set_show_tabs(self.widgets.menuitem5.get_active())
|
||||
self.widgets.notebook_debug.set_current_page(0)
|
||||
|
||||
|
||||
|
||||
# erase the ready-to-home message on statusbar
|
||||
def on_hal_status_all_homed(self,widget):
|
||||
print("all-homed")
|
||||
self.data.all_homed = True
|
||||
self.widgets.statusbar1.remove_message(self.gscreen.statusbar_id,self.gscreen.homed_status_message)
|
||||
|
||||
# when run is pressed, destroy the restart dialog if it's showing
|
||||
def on_toolbutton_run_toggled(self,widget):
|
||||
if not self.data.restart_dialog == None:
|
||||
self.data.restart_dialog.destroy()
|
||||
self.data.restart_dialog = None
|
||||
|
||||
# This connects signals without using glade's autoconnect method
|
||||
def connect_signals(self,handlers):
|
||||
signal_list = [ ["window1","destroy", "on_window1_destroy"],
|
||||
["restart","clicked", "launch_restart_dialog"],
|
||||
["metric_select","clicked","on_metric_select_clicked"],
|
||||
["s_run","clicked","on_button_spindle_controls_clicked"],
|
||||
["spindle_control","clicked", "on_spindle_control_clicked"],
|
||||
["spindle_preset","clicked", "on_preset_spindle"],
|
||||
["spindle_increase","clicked", "on_spindle_speed_adjust"],
|
||||
["spindle_decrease","clicked", "on_spindle_speed_adjust"],
|
||||
["run_halshow","clicked", "on_halshow"],
|
||||
["run_calibration","clicked", "on_calibration"],
|
||||
["run_status","clicked", "on_status"],
|
||||
["run_halmeter","clicked", "on_halmeter"],
|
||||
["run_halscope","clicked", "on_halscope"],
|
||||
["run_ladder","clicked", "on_ladder"],
|
||||
]
|
||||
for i in signal_list:
|
||||
if len(i) == 3:
|
||||
self.widgets[i[0]].connect(i[1], self.gscreen[i[2]])
|
||||
elif len(i) == 4:
|
||||
self.widgets[i[0]].connect(i[1], self.gscreen[i[2]],i[3])
|
||||
self.widgets.toolbutton_run.connect("toggled",self.on_toolbutton_run_toggled)
|
||||
self.widgets.scale_jog.connect("value_changed",self.on_scale_jog_value_changed)
|
||||
self.widgets.scale_fo.connect("value_changed",self.on_scale_fo_value_changed)
|
||||
self.widgets.scale_so.connect("value_changed",self.on_scale_so_value_changed)
|
||||
self.widgets.scale_mv.connect("value_changed",self.on_scale_mv_value_changed)
|
||||
self.widgets.menuitem5.connect("activate",self.on_show_alarm_page)
|
||||
self.widgets.jog_speed.connect("changed",self.on_jog_speed_changed)
|
||||
self.widgets.sneg.connect("clicked",lambda i:self.gscreen.spindle_adjustment(False,True))
|
||||
self.widgets.spos.connect("clicked",lambda i:self.gscreen.spindle_adjustment(True,True))
|
||||
for i in('x','y','z'):
|
||||
self.widgets['touch_off'+i].connect("clicked", self.on_touch_off_clicked,i)
|
||||
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)
|
||||
|
||||
# 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 to be able to change the theme so:
|
||||
# We change the GTK theme to what's in gscreen's preference file.
|
||||
# gscreen.change_theme() is a method in gscreen that changes the GTK theme of window1
|
||||
# gscreen.data.theme_name is the name of the theme from the preference file
|
||||
# To truely be friendly, we should add a way to change the theme directly in the custom screen.
|
||||
# we also set up the statusbar and add a ready-to-home message
|
||||
def initialize_widgets(self):
|
||||
self.gscreen.init_show_windows()
|
||||
self.gscreen.init_dynamic_tabs()
|
||||
self.gscreen.init_embeded_terminal()
|
||||
self.gscreen.change_theme(self.data.theme_name)
|
||||
self.gscreen.statusbar_id = self.widgets.statusbar1.get_context_id("Statusbar1")
|
||||
self.gscreen.homed_status_message = self.widgets.statusbar1.push(1,"Ready For Homing")
|
||||
model = self.widgets.jog_speed.get_model()
|
||||
for num,i in enumerate(self.data.jog_increments):
|
||||
model.append([i])
|
||||
if i == "continuous":
|
||||
self.data.current_jogincr_index = num
|
||||
self.widgets.jog_speed.set_active(num)
|
||||
# self.gscreen.set_dro_units(self.data.dro_units)
|
||||
self.widgets.adjustment_mv.set_value(self.data.maxvelocity*100)
|
||||
self.widgets.adjustment_jog.set_upper(self.data.jog_rate_max)
|
||||
self.widgets.adjustment_jog.set_value(self.data.jog_rate)
|
||||
self.widgets.adjustment_fo.set_upper(self.data.feed_override_max*100)
|
||||
self.widgets.adjustment_fo.set_value(self.data.feed_override*100)
|
||||
self.widgets.adjustment_so.set_upper(self.data.spindle_override_max*100)
|
||||
self.widgets.adjustment_so.set_value(self.data.spindle_override*100)
|
||||
self.widgets.notebook_debug.set_show_tabs(False)
|
||||
#self.gscreen.keylookup.add_conversion('F4','TEST2','on_keycall_POWER')
|
||||
|
||||
# If we need extra HAL pins here is where we do it.
|
||||
# Note you must import hal at the top of this script to build the pins here. or:
|
||||
# For gaxis there is only jog pins so we call gscreen to
|
||||
# add it's default jog pins
|
||||
def initialize_pins(self):
|
||||
self.gscreen.init_jog_pins()
|
||||
|
||||
# checks the current operating mode according to the UI
|
||||
def check_mode(self):
|
||||
string = []
|
||||
if self.data.mode_order[0] == self.data._MAN and self.widgets.notebook_main.get_current_page() == 1:
|
||||
string.append( self.data._MAN)
|
||||
string.append(self.data._JOG)
|
||||
return string
|
||||
|
||||
# keybinding calls
|
||||
def on_keycall_ESTOP(self,state,SHIFT,CNTRL,ALT):
|
||||
if state:
|
||||
self.widgets.emc_toggle_estop.emit('activate')
|
||||
return True
|
||||
def on_keycall_POWER(self,state,SHIFT,CNTRL,ALT):
|
||||
if state:
|
||||
self.widgets.emc_toggle_power.emit('activate')
|
||||
return True
|
||||
def on_keycall_INCREMENTS(self,state,SHIFT,CNTRL,ALT):
|
||||
if state and self.data._MAN in self.check_mode(): # manual mode required
|
||||
print('hi')
|
||||
if SHIFT:
|
||||
self.gscreen.set_jog_increments(index_dir = -1)
|
||||
else:
|
||||
self.gscreen.set_jog_increments(index_dir = 1)
|
||||
# update the combo box
|
||||
self.widgets.jog_speed.set_active(self.data.current_jogincr_index)
|
||||
return True
|
||||
|
||||
def on_touch_off_clicked(self,widget,axis):
|
||||
self.gscreen.launch_numerical_input("on_offset_origin_entry_return",axis,None,"Touch off %s"% axis.upper())
|
||||
|
||||
def on_offset_origin_entry_return(self,widget,result,calc,axis,userdata2):
|
||||
value = calc.get_value()
|
||||
if result == gtk.ResponseType.ACCEPT:
|
||||
if value == None:
|
||||
return
|
||||
if not axis == "s":
|
||||
if axis in('a','b','c'):
|
||||
pos = self.gscreen.get_qualified_input(value,switch=_DEGREE_INPUT)
|
||||
else:
|
||||
pos = self.gscreen.get_qualified_input(value)
|
||||
self.gscreen.mdi_control.set_axis(axis,pos)
|
||||
self.gscreen.reload_plot()
|
||||
widget.destroy()
|
||||
self.data.entry_dialog = None
|
||||
|
||||
# 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.
|
||||
# In this case we wish to call Gscreen's default function for units button update
|
||||
def periodic(self):
|
||||
self.gscreen.update_units_button_label()
|
||||
|
||||
def __getitem__(self, item):
|
||||
return getattr(self, item)
|
||||
def __setitem__(self, item, value):
|
||||
return setattr(self, item, value)
|
||||
|
||||
# standard handler call
|
||||
def get_handlers(halcomp,builder,useropts,gscreen):
|
||||
return [HandlerClass(halcomp,builder,useropts,gscreen)]
|
||||
4150
share/gscreen/skins/industrial/industrial.glade
Normal file
100
share/gscreen/skins/industrial/industrial2.glade
Normal file
@@ -0,0 +1,100 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.40.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.16"/>
|
||||
<requires lib="gladevcp" version="0.0"/>
|
||||
<object class="GtkWindow" id="window2">
|
||||
<property name="height-request">600</property>
|
||||
<property name="can-focus">False</property>
|
||||
<child>
|
||||
<object class="GtkTable" id="table1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="n-rows">3</property>
|
||||
<property name="n-columns">3</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HAL_Meter" id="s_display2">
|
||||
<property name="width-request">200</property>
|
||||
<property name="height-request">200</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="bg-color">#ffffffffffff</property>
|
||||
<property name="label">Spindle</property>
|
||||
<property name="majorscale">200</property>
|
||||
<property name="max">2000</property>
|
||||
<property name="sublabel">RPM</property>
|
||||
<property name="z0-color">#0000ffff0000</property>
|
||||
<property name="z1-color">#ffffffff0000</property>
|
||||
<property name="z2-color">#ffff00000000</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="right-attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">screen 2</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="right-attach">3</property>
|
||||
<property name="top-attach">1</property>
|
||||
<property name="bottom-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button1">
|
||||
<property name="label" translatable="yes">Custom
|
||||
Button</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<signal name="clicked" handler="on_button_press" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="right-attach">3</property>
|
||||
<property name="top-attach">2</property>
|
||||
<property name="bottom-attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
430
share/gscreen/skins/industrial/industrial_handler.py
Normal file
@@ -0,0 +1,430 @@
|
||||
# This is a component of LinuxCNC
|
||||
# Copyright 2013 Chris Morley <chrisinnanaimo@hotmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
import gi
|
||||
from gi.repository import Gtk as gtk
|
||||
from gi.repository import Gdk
|
||||
from gi.repository import Pango as pango
|
||||
|
||||
import hal
|
||||
import gladevcp.makepins # needed for the dialog's calulator widget
|
||||
|
||||
_MAN = 0;_MDI = 1;_AUTO = 2;_LOCKTOGGLE = 1
|
||||
|
||||
# This is a handler file for using Gscreen's infrastructure
|
||||
# to load a completely custom glade screen
|
||||
# The only things that really matters is that it's saved as a GTK builder project,
|
||||
# the toplevel window is caller window1 (The default name) and you connect a destroy
|
||||
# window signal else you can't close down linuxcnc
|
||||
class HandlerClass:
|
||||
|
||||
# This will be pretty standard to gain access to everything
|
||||
# emc 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.emc = gscreen.emc
|
||||
self.data = gscreen.data
|
||||
self.widgets = gscreen.widgets
|
||||
self.gscreen = gscreen
|
||||
|
||||
# This is a new method that calls a gscreen method to toggle the DRO units
|
||||
# Gscreen's regular unit button saves the state
|
||||
# for startup, This one just changes it for the session
|
||||
def on_metric_select_clicked(self,widget):
|
||||
data = (self.data.dro_units -1) * -1
|
||||
self.gscreen.set_dro_units(data,False)
|
||||
for i in ("1","2","3"):
|
||||
for letter in self.data.axis_list:
|
||||
axis = "dro_%s%s"% (letter,i)
|
||||
try:
|
||||
self.widgets[axis].set_property("display_units_mm",data)
|
||||
except:
|
||||
pass
|
||||
|
||||
def on_diameter_mode_pressed(self, widget):
|
||||
data = widget.get_active()
|
||||
print("switch diam mode",data)
|
||||
self.gscreen.set_diameter_mode(data)
|
||||
for i in ("1","2","3"):
|
||||
axis = "dro_x%s"% (i)
|
||||
if data:
|
||||
self.widgets[axis].set_to_diameter()
|
||||
else:
|
||||
self.widgets[axis].set_to_radius()
|
||||
|
||||
# This is a new method for our button
|
||||
# we selected this method name in the glade file as a signal callback
|
||||
def on_estop_clicked(self,*args):
|
||||
print("estop")
|
||||
if self.data.estopped:
|
||||
self.emc.estop_reset(1)
|
||||
self.gscreen.add_alarm_entry("Machine Estop Reset")
|
||||
else:
|
||||
self.emc.machine_off(1)
|
||||
self.emc.estop(1)
|
||||
self.widgets.on_label.set_text("Machine Off")
|
||||
self.gscreen.add_alarm_entry("Machine Estopped and Powered Off")
|
||||
return True
|
||||
|
||||
# This is a new method for our new button
|
||||
# we selected this method name in the glade file as a signal callback
|
||||
def on_machine_state_clicked(self,widget):
|
||||
if self.data.estopped:
|
||||
return
|
||||
elif not self.data.machine_on:
|
||||
self.emc.machine_on(1)
|
||||
self.widgets.on_label.set_text("Machine On")
|
||||
self.gscreen.add_alarm_entry("Machine powered on")
|
||||
else:
|
||||
self.emc.machine_off(1)
|
||||
self.widgets.on_label.set_text("Machine Off")
|
||||
self.gscreen.add_alarm_entry("Machine powered off")
|
||||
|
||||
# display the main tab and set the mode to setup
|
||||
def on_setup_button_clicked(self,widget):
|
||||
self.widgets.notebook_main.set_current_page(0)
|
||||
self.data.mode_order = _MAN,_MDI,_AUTO
|
||||
label = self.data.mode_labels
|
||||
self.widgets.button_mode.set_label(label[self.data.mode_order[0]])
|
||||
self.gscreen.mode_changed(self.data.mode_order[0])
|
||||
self.toggle_modes(widget)
|
||||
|
||||
# display the main tab and set the mode to run
|
||||
def on_run_button_clicked(self,widget):
|
||||
self.widgets.notebook_main.set_current_page(0)
|
||||
self.data.mode_order = _AUTO,_MAN,_MDI
|
||||
label = self.data.mode_labels
|
||||
self.widgets.button_mode.set_label(label[self.data.mode_order[0]])
|
||||
self.gscreen.mode_changed(self.data.mode_order[0])
|
||||
self.toggle_modes(widget)
|
||||
|
||||
# display the main tab and set the mode to MDI
|
||||
def on_mdi_button_clicked(self,widget):
|
||||
self.widgets.notebook_main.set_current_page(0)
|
||||
self.data.mode_order = _MDI,_MAN,_AUTO
|
||||
label = self.data.mode_labels
|
||||
self.widgets.button_mode.set_label(label[self.data.mode_order[0]])
|
||||
self.gscreen.mode_changed(self.data.mode_order[0])
|
||||
self.toggle_modes(widget)
|
||||
|
||||
# This is called when the system button is toggled
|
||||
# If the page is not showing it displays a unlock code dialog
|
||||
# unless you have already unlocked the page.
|
||||
# if that returns true then the page is shown
|
||||
# otherwise the button is untoggled and the page is not shown
|
||||
# if you press the system buttonn when the system page is already showing
|
||||
# it will relock the page
|
||||
def on_system_button_clicked(self,widget):
|
||||
if self.widgets.notebook_main.get_current_page() == 4:
|
||||
self.gscreen.block("system_button")
|
||||
widget.set_active(True)
|
||||
self.gscreen.unblock("system_button")
|
||||
global _LOCKTOGGLE
|
||||
_LOCKTOGGLE=1
|
||||
self.widgets.system_button.set_label(" System\n(Locked)")
|
||||
self.gscreen.add_alarm_entry("System page re-locked")
|
||||
self.on_setup_button_clicked(self.widgets.setup_button)
|
||||
return
|
||||
if not self.system_dialog():
|
||||
self.gscreen.block("system_button")
|
||||
widget.set_active(False)
|
||||
self.gscreen.unblock("system_button")
|
||||
return
|
||||
self.widgets.notebook_main.set_current_page(4)
|
||||
self.toggle_modes(widget)
|
||||
self.widgets.system_button.set_label(" System\n ")
|
||||
|
||||
# Display the tooledit tab
|
||||
def on_tooledit_button_clicked(self,widget):
|
||||
self.widgets.notebook_main.set_current_page(3)
|
||||
self.toggle_modes(widget)
|
||||
|
||||
# Display the offsetpage tab
|
||||
def on_offsetpage_button_clicked(self,widget):
|
||||
self.widgets.notebook_main.set_current_page(2)
|
||||
self.toggle_modes(widget)
|
||||
|
||||
# This toggles the buttons so only one is presses at any one time
|
||||
def toggle_modes(self,widget):
|
||||
temp = "setup_button","mdi_button","run_button","tooledit_button","system_button","offsetpage_button"
|
||||
for i in temp:
|
||||
state = False
|
||||
if self.widgets[i] == widget: state = True
|
||||
self.gscreen.block(i)
|
||||
self.widgets[i].set_active(state)
|
||||
self.gscreen.unblock(i)
|
||||
|
||||
def on_button_edit_clicked(self,widget):
|
||||
state = widget.get_active()
|
||||
if not state:
|
||||
self.gscreen.edited_gcode_check()
|
||||
self.widgets.notebook_main.set_current_page(0)
|
||||
self.widgets.notebook_main.set_show_tabs(not (state))
|
||||
self.gscreen.edit_mode(state)
|
||||
if not state and self.widgets.button_full_view.get_active():
|
||||
self.gscreen.set_full_graphics_view(True)
|
||||
if self.data.edit_mode:
|
||||
self.widgets.mode_select_box.hide()
|
||||
self.widgets.search_box.show()
|
||||
self.widgets.button_edit.set_label("Exit\nEdit")
|
||||
else:
|
||||
self.widgets.mode_select_box.show()
|
||||
self.widgets.search_box.hide()
|
||||
self.widgets.button_edit.set_label("Edit")
|
||||
self.widgets.notebook_main.set_show_tabs(False)
|
||||
|
||||
# This dialog is for unlocking the system tab
|
||||
# The unlock code number is defined at the top of the page
|
||||
def system_dialog(self):
|
||||
global _LOCKTOGGLE
|
||||
if _LOCKTOGGLE == 0: return True
|
||||
dialog = gtk.Dialog("Enter System Unlock Code",
|
||||
self.widgets.window1,
|
||||
gtk.DialogFlags.DESTROY_WITH_PARENT)
|
||||
label = gtk.Label("Enter System Unlock Code")
|
||||
label.modify_font(pango.FontDescription("sans 20"))
|
||||
calc = gladevcp.Calculator()
|
||||
dialog.vbox.pack_start(label,True,True,0)
|
||||
dialog.vbox.add(calc)
|
||||
calc.set_value("")
|
||||
calc.set_property("font","sans 20")
|
||||
calc.set_editable(True)
|
||||
calc.entry.connect("activate", lambda w : dialog.emit('response',gtk.ResponseType.ACCEPT))
|
||||
calc.integer_entry_only(True)
|
||||
calc.num_pad_only(True)
|
||||
dialog.parse_geometry("360x400")
|
||||
dialog.set_decorated(False)
|
||||
dialog.show_all()
|
||||
response = dialog.run()
|
||||
code = calc.get_value()
|
||||
dialog.destroy()
|
||||
if response == gtk.ResponseType.ACCEPT:
|
||||
if code == int(self.data.unlock_code):
|
||||
self.gscreen.add_alarm_entry("System page unlocked")
|
||||
_LOCKTOGGLE = 0
|
||||
return True
|
||||
_LOCKTOGGLE = 1
|
||||
return False
|
||||
|
||||
def _get_RGBA_color(self, color_raw):
|
||||
def convert_color(color):
|
||||
colortuple = ((int(color.red * 255.0), int(color.green * 255.0), int(color.blue * 255.0)))
|
||||
return ('#' + ''.join(f'{i:02X}' for i in colortuple))
|
||||
|
||||
# convert string RGB to 8bit RGBA
|
||||
if type(color_raw) == str:
|
||||
color = Gdk.RGBA()
|
||||
color.parse(color_raw)
|
||||
return convert_color(Gdk.RGBA(color.red, color.green, color.blue, color.alpha))
|
||||
|
||||
# convert old 16bit RGB to 8bit RGBA
|
||||
elif type(color_raw) == tuple:
|
||||
b = Gdk.RGBA(color_raw[0], color_raw[1], color_raw[2], 0)
|
||||
color = Gdk.RGBA()
|
||||
color.parse(b.to_string())
|
||||
return convert_color(Gdk.RGBA(color.red, color.green, color.blue, color.alpha))
|
||||
|
||||
def on_abs_colorbutton_color_set(self,widget):
|
||||
self.gscreen.set_abs_color()
|
||||
for i in self.data.axis_list:
|
||||
axis = "dro_%s1"% i
|
||||
color = self._get_RGBA_color(self.data.abs_color)
|
||||
self.widgets[axis].set_style("labelcolor", color )
|
||||
|
||||
def on_rel_colorbutton_color_set(self,widget):
|
||||
self.gscreen.set_rel_color()
|
||||
color = self._get_RGBA_color(self.data.rel_color)
|
||||
for i in self.data.axis_list:
|
||||
axis = "dro_%s2"% i
|
||||
self.widgets[axis].set_style("labelcolor", color )
|
||||
|
||||
def on_dtg_colorbutton_color_set(self,widget):
|
||||
self.gscreen.set_dtg_color()
|
||||
color = self._get_RGBA_color(self.data.dtg_color)
|
||||
for i in self.data.axis_list:
|
||||
axis = "dro_%s3"% i
|
||||
self.widgets[axis].set_style("labelcolor", color )
|
||||
|
||||
def on_hal_status_not_all_homed(self,widget,data):
|
||||
temp =[]
|
||||
for letter in self.data.axis_list:
|
||||
axnum = "xyzabcuvws".index(letter)
|
||||
if str(axnum) in data:
|
||||
self.widgets["home_%s"%letter].set_text(" ")
|
||||
temp.append(" %s"%letter.upper())
|
||||
self.gscreen.add_alarm_entry(_("There are unhomed axes: %s"%temp))
|
||||
|
||||
def on_hal_status_axis_homed(self,widget,data):
|
||||
for letter in self.data.axis_list:
|
||||
axnum = "xyzabcuvws".index(letter)
|
||||
if str(axnum) in data:
|
||||
self.widgets["home_%s"%letter].set_text("*")
|
||||
else:
|
||||
self.widgets["home_%s"%letter].set_text(" ")
|
||||
|
||||
def on_show_dtg_pressed(self, widget):
|
||||
data = widget.get_active()
|
||||
self.widgets.dtg_vbox.set_visible(data)
|
||||
self.gscreen.set_show_dtg(data)
|
||||
|
||||
# Connect to gscreens regular signals and add a couple more
|
||||
def connect_signals(self,handlers):
|
||||
self.gscreen.connect_signals(handlers)
|
||||
# connect to handler file callbacks:
|
||||
self.gscreen.widgets.metric_select.connect("clicked", self.on_metric_select_clicked)
|
||||
self.gscreen.widgets.diameter_mode.connect("clicked", self.on_diameter_mode_pressed)
|
||||
temp = "setup_button","mdi_button","run_button","tooledit_button","system_button","offsetpage_button"
|
||||
for cb in temp:
|
||||
i = "_sighandler_%s"% (cb)
|
||||
self.data[i] = int(self.widgets[cb].connect("toggled", self["on_%s_clicked"%cb]))
|
||||
self.widgets.hal_status.connect("not-all-homed",self.on_hal_status_not_all_homed)
|
||||
self.widgets.hal_status.connect("homed",self.on_hal_status_axis_homed)
|
||||
self.widgets.abs_colorbutton.connect("color-set", self.on_abs_colorbutton_color_set)
|
||||
self.widgets.rel_colorbutton.connect("color-set", self.on_rel_colorbutton_color_set)
|
||||
self.widgets.dtg_colorbutton.connect("color-set", self.on_dtg_colorbutton_color_set)
|
||||
self.widgets.unlock_number.connect("value-changed",self.gscreen.on_unlock_number_value_changed)
|
||||
self.widgets.show_dtg.connect("clicked", self.on_show_dtg_pressed)
|
||||
|
||||
# We don't want Gscreen to initialize ALL it's regular widgets because this custom
|
||||
# screen doesn't have them all -just most of them. So we call the ones we want
|
||||
def initialize_widgets(self):
|
||||
self.gscreen.init_show_windows()
|
||||
self.gscreen.init_dynamic_tabs()
|
||||
#self.gscreen.init_axis_frames()
|
||||
#self.gscreen.init_dro_colors()
|
||||
self.gscreen.init_screen2()
|
||||
self.gscreen.init_fullscreen1()
|
||||
self.gscreen.init_gremlin()
|
||||
self.gscreen.init_manual_spindle_controls()
|
||||
self.gscreen.init_dro_colors()
|
||||
self.init_dro() # local function
|
||||
self.gscreen.init_audio()
|
||||
self.gscreen.init_desktop_notify()
|
||||
self.gscreen.init_statusbar()
|
||||
self.gscreen.init_entry()
|
||||
self.gscreen.init_tooleditor()
|
||||
self.gscreen.init_offsetpage()
|
||||
self.gscreen.init_embeded_terminal()
|
||||
self.gscreen.init_themes()
|
||||
self.gscreen.init_screen1_geometry()
|
||||
self.gscreen.init_running_options()
|
||||
self.gscreen.init_hide_cursor()
|
||||
#self.gscreen.init_mode()
|
||||
self.gscreen.mode_changed(self.data.mode_order[0])
|
||||
self.gscreen.init_sensitive_on_off()
|
||||
self.gscreen.init_sensitive_run_idle()
|
||||
self.gscreen.init_sensitive_all_homed()
|
||||
self.gscreen.init_sensitive_override_mode()
|
||||
self.gscreen.init_sensitive_graphics_mode()
|
||||
self.gscreen.init_sensitive_origin_mode()
|
||||
self.init_sensitive_edit_mode() # local function
|
||||
for i in ("setup_button","mdi_button","run_button","tooledit_button","offsetpage_button","button_index_tool"):
|
||||
self.data.sensitive_override_mode.append(i)
|
||||
self.data.sensitive_graphics_mode.append(i)
|
||||
self.data.sensitive_origin_mode.append(i)
|
||||
self.widgets["spindle-at-speed"].set_property("on_color","black")
|
||||
self.gscreen.init_unlock_code()
|
||||
self.gscreen.init_state()
|
||||
for i in ('x','y','z','a','b','c','u','v','w'):
|
||||
if i in self.data.axis_list:
|
||||
self.widgets["dro_%s1"%i].show()
|
||||
self.widgets["dro_%s2"%i].show()
|
||||
self.widgets["dro_%s3"%i].show()
|
||||
self.widgets["axis_%s"%i].show()
|
||||
self.widgets["home_%s"%i].show()
|
||||
else:
|
||||
self.widgets["dro_%s1"%i].hide()
|
||||
self.widgets["dro_%s2"%i].hide()
|
||||
self.widgets["dro_%s3"%i].hide()
|
||||
self.widgets["axis_%s"%i].hide()
|
||||
self.widgets["home_%s"%i].hide()
|
||||
|
||||
#self.widgets.offsetpage1.set_highlight_color("lightblue")
|
||||
self.widgets.offsetpage1.set_font("sans 18")
|
||||
self.widgets.offsetpage1.set_row_visible("1",False)
|
||||
self.widgets.tooledit1.set_font("sans 18")
|
||||
|
||||
if self.data.embedded_keyboard:
|
||||
self.gscreen.launch_keyboard()
|
||||
|
||||
def init_sensitive_edit_mode(self):
|
||||
self.data.sensitive_edit_mode = ["button_graphics","button_override","button_restart","button_cycle_start","button_single_step",
|
||||
"run_button","setup_button","mdi_button","system_button","tooledit_button","ignore_limits",
|
||||
"offsetpage_button"]
|
||||
|
||||
def init_dro(self):
|
||||
self.on_abs_colorbutton_color_set(None)
|
||||
self.on_rel_colorbutton_color_set(None)
|
||||
self.on_dtg_colorbutton_color_set(None)
|
||||
self.widgets.show_dtg.set_active(self.data.show_dtg)
|
||||
self.on_show_dtg_pressed(self.widgets.show_dtg)
|
||||
self.gscreen.init_dro()
|
||||
data = self.data.dro_units
|
||||
for i in ("1","2","3"):
|
||||
for letter in self.data.axis_list:
|
||||
axis = "dro_%s%s"% (letter,i)
|
||||
try:
|
||||
self.widgets[axis].set_property("display_units_mm",data)
|
||||
except:
|
||||
pass
|
||||
|
||||
# every 100 milli seconds this gets called
|
||||
# we add calls to the regular functions for the widgets we are using.
|
||||
# and add any extra calls/code
|
||||
def periodic(self):
|
||||
self.update_mdi_spindle_button() # local method
|
||||
self.gscreen.update_spindle_bar()
|
||||
#self.gscreen.update_dro()
|
||||
self.gscreen.update_active_gcodes()
|
||||
self.gscreen.update_active_mcodes()
|
||||
self.gscreen.update_aux_coolant_pins()
|
||||
self.gscreen.update_feed_speed_label()
|
||||
self.gscreen.update_tool_label()
|
||||
self.gscreen.update_coolant_leds()
|
||||
self.gscreen.update_estop_led()
|
||||
self.gscreen.update_machine_on_led()
|
||||
self.gscreen.update_limit_override()
|
||||
self.gscreen.update_override_label()
|
||||
self.gscreen.update_jog_rate_label()
|
||||
self.gscreen.update_mode_label()
|
||||
self.gscreen.update_units_button_label()
|
||||
|
||||
# spindle controls
|
||||
def update_mdi_spindle_button(self):
|
||||
self.widgets.at_speed_label.set_label(_("%d RPM"%abs(self.data.spindle_speed)))
|
||||
label = self.widgets.spindle_control.get_label()
|
||||
speed = self.data.spindle_speed
|
||||
if speed == 0 and not label == _("Start"):
|
||||
temp = _("Start")
|
||||
self.widgets["spindle-at-speed"].set_property("on_color","black")
|
||||
elif speed and not label == _("Stop"):
|
||||
temp = _("Stop")
|
||||
self.widgets["spindle-at-speed"].set_property("on_color","green")
|
||||
else: return
|
||||
self.widgets.spindle_control.set_label(temp)
|
||||
|
||||
def __getitem__(self, item):
|
||||
return getattr(self, item)
|
||||
def __setitem__(self, item, value):
|
||||
return setattr(self, item, value)
|
||||
|
||||
# standard handler call
|
||||
def get_handlers(halcomp,builder,useropts,gscreen):
|
||||
return [HandlerClass(halcomp,builder,useropts,gscreen)]
|
||||
4328
share/gscreen/skins/silverdragon/silverdragon.glade
Normal file
1481
share/gscreen/skins/silverdragon/silverdragon_handler.py
Normal file
5120
share/gscreen/skins/spartan/spartan.glade
Normal file
471
share/gscreen/skins/spartan/spartan_handler.py
Normal file
@@ -0,0 +1,471 @@
|
||||
# This is a component of LinuxCNC
|
||||
# Copyright 2013 Chris Morley <chrisinnanaimo@hotmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
#############################################################################
|
||||
# This is a gscreen skin customized for a Bridgeport Interact Mill that used a
|
||||
# Heidenhain TNC 151a controller.
|
||||
# Chris Brady Oct 2015
|
||||
#
|
||||
|
||||
import gi
|
||||
from gi.repository import Gtk as gtk
|
||||
from gi.repository import Pango as pango
|
||||
|
||||
import hal
|
||||
import gladevcp.makepins # needed for the dialog's calulator widget
|
||||
import hal_glib
|
||||
|
||||
_MAN = 0;_MDI = 1;_AUTO = 2;_LOCKTOGGLE = 1
|
||||
|
||||
# This is a handler file for using Gscreen's infrastructure
|
||||
# to load a completely custom glade screen
|
||||
# The only things that really matters is that it's saved as a GTK builder project,
|
||||
# the toplevel window is caller window1 (The default name) and you connect a destroy
|
||||
# window signal else you can't close down linuxcnc
|
||||
class HandlerClass:
|
||||
|
||||
# This will be pretty standard to gain access to everything
|
||||
# emc 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.emc = gscreen.emc
|
||||
self.data = gscreen.data
|
||||
self.widgets = gscreen.widgets
|
||||
self.gscreen = gscreen
|
||||
|
||||
# Hide all menus at the bottom of the default gscreen page
|
||||
self.widgets.mode0.hide()
|
||||
self.widgets.mode1.hide()
|
||||
self.widgets.mode2.hide()
|
||||
self.widgets.mode3.hide()
|
||||
self.widgets.mode4.hide()
|
||||
self.widgets.button_mode.hide()
|
||||
self.widgets.diameter_mode.hide()
|
||||
self.widgets.aux_coolant_m7.hide()
|
||||
self.widgets.aux_coolant_m8.hide()
|
||||
self.widgets.show_dtg.hide()
|
||||
self.widgets.diameter_mode.hide()
|
||||
self.widgets.button_flood.hide()
|
||||
self.widgets.button_run.hide()
|
||||
|
||||
# Initialize variables
|
||||
self.data.lathe_mode=False
|
||||
self.data.graphic_ypos=0
|
||||
self.data.graphic_xpos=0
|
||||
self.data.view=0
|
||||
self.data.homed=0
|
||||
self.data.jog_rates=[30,50,80,120]
|
||||
self.data.jog_incrs=[0.0002,0.001,0.01,0.1]
|
||||
self.data.jog_rate_idx=2
|
||||
self.widgets.jog_r1.set_label("%5.4f"% self.data.jog_incrs[0])
|
||||
self.widgets.jog_r2.set_label("%4.3f"% self.data.jog_incrs[1])
|
||||
self.widgets.jog_r3.set_label("%3.2f"% self.data.jog_incrs[2])
|
||||
self.widgets.jog_r4.set_label("%2.1f"% self.data.jog_incrs[3])
|
||||
self.widgets.button_mode.hide()
|
||||
self.widgets.button_home_all.hide()
|
||||
|
||||
# every 100 milli seconds this gets called
|
||||
# we add calls to the regular functions for the widgets we are using.
|
||||
# and add any extra calls/code
|
||||
def periodic(self):
|
||||
self.gscreen.update_dro()
|
||||
self.gscreen.update_active_gcodes()
|
||||
self.gscreen.update_active_mcodes()
|
||||
self.gscreen.update_feed_speed_label()
|
||||
self.gscreen.update_tool_label()
|
||||
self.update_estop_led()
|
||||
self.gscreen.update_machine_on_led()
|
||||
self.gscreen.update_jog_rate_label()
|
||||
self.gscreen.update_mode_label()
|
||||
self.gscreen.update_units_button_label()
|
||||
self.update_override_label()
|
||||
self.update_spindle()
|
||||
|
||||
def update_spindle(self):
|
||||
# Actual speed from hal
|
||||
# Limit speed representation to 1 decimal point
|
||||
speed = int(self.gscreen.halcomp["spindle-spd-disp"]*10)/10
|
||||
self.widgets.meter_spindle_speed.set_property("value", speed)
|
||||
|
||||
# Initialize hal pins that we need access to
|
||||
def initialize_pins(self):
|
||||
self.gscreen.init_spindle_pins()
|
||||
self.gscreen.init_coolant_pins()
|
||||
self.gscreen.init_jog_pins()
|
||||
self.gscreen.init_override_pins()
|
||||
self.gscreen.init_control_pins()
|
||||
self.gscreen.halcomp.newpin("spindle-spd-disp", hal.HAL_FLOAT, hal.HAL_IN)
|
||||
self.gscreen.halcomp.newpin("jog-spd-out", hal.HAL_FLOAT, hal.HAL_OUT)
|
||||
self.gscreen.halcomp.newpin("jog-inc-out", hal.HAL_FLOAT, hal.HAL_OUT)
|
||||
self.data['ext-estop'] = hal_glib.GPin(self.gscreen.halcomp.newpin('ext-estop', hal.HAL_BIT, hal.HAL_IN))
|
||||
self.data['ext-estop'].connect('value-changed', self.on_estop_in)
|
||||
self.data['enc-fault-x'] = hal_glib.GPin(self.gscreen.halcomp.newpin('enc-fault-x', hal.HAL_BIT, hal.HAL_IN))
|
||||
self.data['enc-fault-x'].connect('value-changed', self.on_x_enc_fault)
|
||||
self.data['enc-fault-y'] = hal_glib.GPin(self.gscreen.halcomp.newpin('enc-fault-y', hal.HAL_BIT, hal.HAL_IN))
|
||||
self.data['enc-fault-y'].connect('value-changed', self.on_y_enc_fault)
|
||||
self.data['enc-fault-x'] = hal_glib.GPin(self.gscreen.halcomp.newpin('enc-fault-z', hal.HAL_BIT, hal.HAL_IN))
|
||||
self.data['enc-fault-x'].connect('value-changed', self.on_z_enc_fault)
|
||||
|
||||
def on_emc_off(self,*args):
|
||||
self.widgets.button_clear.show()
|
||||
self.widgets.button_mode.hide()
|
||||
self.widgets.button_home_all.hide()
|
||||
# Force mode to manual
|
||||
self.data.mode_order = (self.data._MAN,self.data._MDI,self.data._AUTO)
|
||||
label = self.data.mode_labels
|
||||
self.widgets.button_mode.set_label(label[self.data.mode_order[0]])
|
||||
self.mode_changed(self.data.mode_order[0])
|
||||
|
||||
def on_btn_clear(self,widget):
|
||||
if self.gscreen.halcomp["ext-estop"] == False:
|
||||
self.emc.estop_reset(1)
|
||||
self.emc.machine_on(1)
|
||||
self.widgets.button_clear.hide()
|
||||
self.widgets.button_home_all.show()
|
||||
|
||||
def on_estop_in(self,widget):
|
||||
self.widgets.mode0.hide()
|
||||
if self.gscreen.halcomp["ext-estop"] == True:
|
||||
self.emc.estop_reset(1)
|
||||
self.emc.machine_on(1)
|
||||
else:
|
||||
self.emc.machine_off(1)
|
||||
self.emc.estop(1)
|
||||
|
||||
def update_estop_led(self):
|
||||
if self.data.estopped:
|
||||
self.widgets.led_estop.set_active(False)
|
||||
else:
|
||||
self.widgets.led_estop.set_active(True)
|
||||
|
||||
def on_x_enc_fault(self,hal_object):
|
||||
print("X Encoder Fault")
|
||||
self.gscreen.add_alarm_entry(_("X Axis Encoder Error"))
|
||||
|
||||
def on_y_enc_fault(self,hal_object):
|
||||
print("Y Encoder Fault")
|
||||
self.gscreen.add_alarm_entry(_("Y Axis Encoder Error"))
|
||||
|
||||
def on_z_enc_fault(self,hal_object):
|
||||
print("Z Encoder Fault")
|
||||
self.gscreen.add_alarm_entry(_("Z Axis Encoder Error"))
|
||||
|
||||
def homing(self,*args):
|
||||
self.mode_changed(self.data._MAN)
|
||||
self.widgets.button_mode.hide()
|
||||
self.widgets.button_home_all.show()
|
||||
self.widgets.button_move_to.set_sensitive(0)
|
||||
|
||||
def on_hal_status_all_homed(self,widget):
|
||||
self.gscreen.on_hal_status_all_homed(1)
|
||||
self.data.homed=1
|
||||
self.widgets.button_home_all.hide()
|
||||
self.widgets.button_mode.show()
|
||||
self.widgets.jog_r3.set_active(1)
|
||||
self.on_jog_rate(self.widgets.jog_r3)
|
||||
self.gscreen.sensitize_widgets(self.data.sensitive_all_homed,1)
|
||||
self.widgets.button_move_to.set_sensitive(1)
|
||||
|
||||
def on_interp_run(self,*args):
|
||||
self.gscreen.sensitize_widgets(self.data.sensitive_run_idle,False)
|
||||
self.widgets.button_reload.set_sensitive(0)
|
||||
|
||||
def on_interp_idle(self,widget):
|
||||
self.gscreen.on_hal_status_interp_idle(widget)
|
||||
self.widgets.button_reload.set_sensitive(1)
|
||||
|
||||
def on_jog_rate(self,widget):
|
||||
if widget == self.widgets.jog_r1:
|
||||
self.data.jog_rate_idx=0
|
||||
speed = self.data.jog_rates[0]
|
||||
self.widgets.jog_r2.set_active(0)
|
||||
self.widgets.jog_r3.set_active(0)
|
||||
self.widgets.jog_r4.set_active(0)
|
||||
self.gscreen.halcomp["jog-spd-out"] = speed
|
||||
self.gscreen.halcomp["jog-inc-out"] = self.data.jog_incrs[0]
|
||||
elif widget == self.widgets.jog_r2:
|
||||
self.data.jog_rate_idx=1
|
||||
speed = self.data.jog_rates[1]
|
||||
self.widgets.jog_r1.set_active(0)
|
||||
self.widgets.jog_r3.set_active(0)
|
||||
self.widgets.jog_r4.set_active(0)
|
||||
self.gscreen.halcomp["jog-spd-out"] = speed
|
||||
self.gscreen.halcomp["jog-inc-out"] = self.data.jog_incrs[1]
|
||||
elif widget == self.widgets.jog_r3:
|
||||
self.data.jog_rate_idx=2
|
||||
speed = self.data.jog_rates[2]
|
||||
self.widgets.jog_r1.set_active(0)
|
||||
self.widgets.jog_r2.set_active(0)
|
||||
self.widgets.jog_r4.set_active(0)
|
||||
self.gscreen.halcomp["jog-spd-out"] = speed
|
||||
self.gscreen.halcomp["jog-inc-out"] = self.data.jog_incrs[2]
|
||||
elif widget == self.widgets.jog_r4:
|
||||
self.data.jog_rate_idx=3
|
||||
speed = self.data.jog_rates[3]
|
||||
self.widgets.jog_r1.set_active(0)
|
||||
self.widgets.jog_r2.set_active(0)
|
||||
self.widgets.jog_r3.set_active(0)
|
||||
self.gscreen.halcomp["jog-spd-out"] = speed
|
||||
self.gscreen.halcomp["jog-inc-out"] = self.data.jog_incrs[3]
|
||||
|
||||
def jog_point1(self,widget):
|
||||
if self.data.mode_order[0] == self.data._MAN: # if in manual mode
|
||||
print("jog point1")
|
||||
if widget == self.widgets.jog_plus:
|
||||
self.do_jog(True,True)
|
||||
else:
|
||||
self.do_jog(False,True)
|
||||
|
||||
def do_jog(self,direction,action):
|
||||
# if manual mode, if jogging
|
||||
# if only one axis button pressed
|
||||
# jog positive at selected rate
|
||||
if self.data.mode_order[0] == self.data._MAN:
|
||||
if len(self.data.active_axis_buttons) > 1:
|
||||
print(self.data.active_axis_buttons)
|
||||
elif self.data.active_axis_buttons[0][0] == None:
|
||||
self.gscreen.homed_status_message = self.widgets.statusbar1.push(1,"No axis selected to jog")
|
||||
else:
|
||||
if not self.data.active_axis_buttons[0][0] == "s":
|
||||
if not action: cmd = 0
|
||||
elif direction: cmd = 1
|
||||
else: cmd = -1
|
||||
self.emc.jogging(1)
|
||||
jogincr = self.data.jog_incrs[self.data.jog_rate_idx]
|
||||
self.emc.incremental_jog(self.data.active_axis_buttons[0][1],cmd,jogincr)
|
||||
|
||||
def on_mode_clicked(self,widget,event):
|
||||
# only change machine modes on click
|
||||
if event.type == gdk.BUTTON_PRESS:
|
||||
a,b,c = self.data.mode_order
|
||||
self.data.mode_order = b,c,a
|
||||
label = self.data.mode_labels
|
||||
self.widgets.button_mode.set_label(label[self.data.mode_order[0]])
|
||||
self.mode_changed(self.data.mode_order[0])
|
||||
|
||||
def mode_changed(self,mode):
|
||||
print("Mode Change", mode)
|
||||
if mode == self.data._MAN:
|
||||
self.widgets.notebook_mode.hide()
|
||||
self.widgets.hal_mdihistory.hide()
|
||||
self.widgets.dro_frame.show()
|
||||
self.widgets.vmode0.show()
|
||||
self.widgets.vmode1.hide()
|
||||
self.widgets.button_run.set_active(0)
|
||||
self.widgets.button_jog_mode.set_active(1)
|
||||
self.widgets.button_view.emit("clicked")
|
||||
elif mode == self.data._MDI:
|
||||
if self.data.plot_hidden:
|
||||
self.toggle_offset_view()
|
||||
self.emc.set_mdi_mode()
|
||||
self.widgets.hal_mdihistory.show()
|
||||
self.widgets.vmode0.show()
|
||||
self.widgets.vmode1.hide()
|
||||
self.widgets.button_run.set_active(0)
|
||||
self.widgets.notebook_mode.hide()
|
||||
self.widgets.button_jog_mode.set_active(0)
|
||||
elif mode == self.data._AUTO:
|
||||
self.widgets.vmode0.hide()
|
||||
self.widgets.vmode1.show()
|
||||
self.widgets.button_run.set_active(0)
|
||||
if self.data.full_graphics:
|
||||
self.widgets.notebook_mode.hide()
|
||||
else:
|
||||
self.widgets.notebook_mode.show()
|
||||
self.widgets.hal_mdihistory.hide()
|
||||
self.widgets.button_jog_mode.set_active(0)
|
||||
|
||||
def on_button_flood(self,widget):
|
||||
if self.widgets.button_flood.get_active():
|
||||
self.gscreen.halcomp["aux-coolant-m8-out"] = True
|
||||
else:
|
||||
self.gscreen.halcomp["aux-coolant-m8-out"] = False
|
||||
|
||||
def on_ign_toolc_pressed(self, widget):
|
||||
data = widget.get_active()
|
||||
|
||||
def on_tool_change(self,widget):
|
||||
if self.widgets.ignore_toolchange.get_active() == True:
|
||||
self.gscreen.halcomp["tool-changed"] = True
|
||||
else:
|
||||
h = self.gscreen.halcomp
|
||||
c = h['change-tool']
|
||||
n = h['tool-number']
|
||||
cd = h['tool-changed']
|
||||
print("tool change",c,cd,n)
|
||||
if c:
|
||||
message = _("Please change to tool # %s, then click OK."% n)
|
||||
self.gscreen.warning_dialog(message, True,pinname="TOOLCHANGE")
|
||||
else:
|
||||
h['tool-changed'] = False
|
||||
|
||||
def on_button_edit_clicked(self,widget):
|
||||
state = widget.get_active()
|
||||
if not state:
|
||||
self.gscreen.edited_gcode_check()
|
||||
self.widgets.notebook_main.set_current_page(0)
|
||||
self.widgets.notebook_main.set_show_tabs(not (state))
|
||||
self.edit_mode(state)
|
||||
if state:
|
||||
self.widgets.search_box.show()
|
||||
else:
|
||||
self.widgets.search_box.hide()
|
||||
|
||||
def edit_mode(self,data):
|
||||
print("edit mode pressed",data)
|
||||
self.gscreen.sensitize_widgets(self.data.sensitive_edit_mode,not data)
|
||||
if data:
|
||||
self.widgets.mode6.show()
|
||||
self.widgets.dro_frame.hide()
|
||||
self.widgets.gcode_view.set_sensitive(1)
|
||||
self.data.edit_mode = True
|
||||
self.widgets.show_box.hide()
|
||||
self.widgets.notebook_mode.show()
|
||||
self.widgets.display_btns.hide()
|
||||
else:
|
||||
self.widgets.mode6.hide()
|
||||
self.widgets.dro_frame.show()
|
||||
self.widgets.gcode_view.set_sensitive(0)
|
||||
self.data.edit_mode = False
|
||||
self.widgets.show_box.show()
|
||||
self.widgets.display_btns.show()
|
||||
|
||||
def on_button_full_view_clicked(self,widget):
|
||||
self.set_full_graphics_view(widget.get_active())
|
||||
|
||||
def on_manual_spindle(self,widget):
|
||||
if self.data.mode_order[0] == self.data._AUTO:
|
||||
return
|
||||
if self.widgets.button_man_spindle.get_active():
|
||||
self.widgets.button_man_spindle.set_label("Stop")
|
||||
self.emc.spindle_forward(1,self.data.spindle_start_rpm)
|
||||
else:
|
||||
print("Spindle stop")
|
||||
self.widgets.button_man_spindle.set_label("Start")
|
||||
self.emc.spindle_off(1)
|
||||
|
||||
def on_spindle_plus(self,widget):
|
||||
if self.data.mode_order[0] != self.data._AUTO:
|
||||
self.emc.spindle_faster(1)
|
||||
|
||||
def on_spindle_minus(self,widget):
|
||||
if self.data.mode_order[0] != self.data._AUTO:
|
||||
self.emc.spindle_slower(1)
|
||||
|
||||
def on_view_change(self,widget):
|
||||
mode = self.data.mode_order[0]
|
||||
if mode == self.data._AUTO:
|
||||
self.data.view = self.data.view+1
|
||||
if self.data.view > 3:
|
||||
self.data.view = 0
|
||||
view = self.data.view
|
||||
else:
|
||||
view = 0
|
||||
print("view", view)
|
||||
if view == 0:
|
||||
# Gremlin + Gcode + DRO
|
||||
self.data.full_graphics = False
|
||||
self.widgets.show_box.show()
|
||||
if mode == self.data._AUTO:
|
||||
self.widgets.notebook_mode.show()
|
||||
self.widgets.dro_frame.show()
|
||||
self.widgets.display_btns.show()
|
||||
self.widgets.gremlin.set_property('enable_dro',False)
|
||||
elif view == 1:
|
||||
# Gremlin style DRO
|
||||
self.data.full_graphics = True
|
||||
self.widgets.show_box.show()
|
||||
self.widgets.notebook_mode.hide()
|
||||
self.widgets.dro_frame.hide()
|
||||
self.widgets.gremlin.set_property('enable_dro',True)
|
||||
elif view == 2:
|
||||
# Gremlin + DRO
|
||||
self.data.full_graphics = True
|
||||
self.widgets.dro_frame.show()
|
||||
self.widgets.notebook_mode.hide()
|
||||
self.widgets.show_box.show()
|
||||
self.widgets.gremlin.set_property('enable_dro',False)
|
||||
elif view == 3:
|
||||
# DRO + Gcode
|
||||
self.data.full_graphics = False
|
||||
self.widgets.dro_frame.show()
|
||||
if mode == self.data._AUTO:
|
||||
self.widgets.notebook_mode.show()
|
||||
self.widgets.gcode_view.set_sensitive(0)
|
||||
self.widgets.show_box.hide()
|
||||
self.widgets.display_btns.hide()
|
||||
self.widgets.gremlin.set_property('enable_dro',False)
|
||||
|
||||
def update_override_label(self):
|
||||
self.widgets.fo.set_text("FO: %3d%%"%(round(self.data.feed_override,2)*100))
|
||||
self.widgets.mv.set_text("RO: %3d%%"%(round(self.data.rapid_override,2)*100))
|
||||
self.widgets.so.set_text("SO: %3d%%"%(round(self.data.spindle_override,2)*100))
|
||||
|
||||
# Gremlin display buttons
|
||||
def on_d_zoomp_pressed(self,widget):
|
||||
self.widgets.gremlin.zoom_in()
|
||||
def on_d_zoomm_pressed(self,widget):
|
||||
self.widgets.gremlin.zoom_out()
|
||||
def on_d_up_pressed(self,widget):
|
||||
self.data.graphic_ypos = self.data.graphic_ypos-8
|
||||
self.widgets.gremlin.pan(self.data.graphic_xpos,self.data.graphic_ypos)
|
||||
def on_d_down_pressed(self,widget):
|
||||
self.data.graphic_ypos = self.data.graphic_ypos+8
|
||||
self.widgets.gremlin.pan(self.data.graphic_xpos,self.data.graphic_ypos)
|
||||
def on_d_right_pressed(self,widget):
|
||||
self.data.graphic_xpos = self.data.graphic_xpos+8
|
||||
self.widgets.gremlin.pan(self.data.graphic_xpos,self.data.graphic_ypos)
|
||||
def on_d_left_pressed(self,widget):
|
||||
self.data.graphic_xpos = self.data.graphic_xpos-8
|
||||
self.widgets.gremlin.pan(self.data.graphic_xpos,self.data.graphic_ypos)
|
||||
|
||||
# Connect to gscreens regular signals and add a couple more
|
||||
def connect_signals(self,handlers):
|
||||
self.gscreen.connect_signals(handlers)
|
||||
# connect to handler file callbacks:
|
||||
self.gscreen.widgets.d_zoomp.connect("clicked", self.on_d_zoomp_pressed)
|
||||
self.gscreen.widgets.d_zoomm.connect("clicked", self.on_d_zoomm_pressed)
|
||||
self.gscreen.widgets.d_up.connect("clicked", self.on_d_up_pressed)
|
||||
self.gscreen.widgets.d_down.connect("clicked", self.on_d_down_pressed)
|
||||
self.gscreen.widgets.d_left.connect("clicked", self.on_d_left_pressed)
|
||||
self.gscreen.widgets.d_right.connect("clicked", self.on_d_right_pressed)
|
||||
self.gscreen.widgets.button_man_spindle.connect("clicked", self.on_manual_spindle)
|
||||
self.gscreen.widgets.button_spindle_plus.connect("clicked", self.on_spindle_plus)
|
||||
self.gscreen.widgets.button_spindle_minus.connect("clicked", self.on_spindle_minus)
|
||||
self.gscreen.widgets.button_view.connect("clicked", self.on_view_change)
|
||||
self.gscreen.widgets.button_mode.connect("button_press_event", self.on_mode_clicked)
|
||||
self.gscreen.widgets.button_edit.connect("clicked", self.on_button_edit_clicked)
|
||||
self.gscreen.widgets.button_flood.connect("clicked", self.on_button_flood)
|
||||
self.gscreen.widgets.ignore_toolchange.connect("clicked", self.on_ign_toolc_pressed)
|
||||
self.gscreen.widgets.jog_r1.connect("pressed", self.on_jog_rate)
|
||||
self.gscreen.widgets.jog_r2.connect("pressed", self.on_jog_rate)
|
||||
self.gscreen.widgets.jog_r3.connect("pressed", self.on_jog_rate)
|
||||
self.gscreen.widgets.jog_r4.connect("pressed", self.on_jog_rate)
|
||||
self.gscreen.widgets.jog_plus.connect("clicked", self.jog_point1)
|
||||
self.gscreen.widgets.jog_minus.connect("clicked", self.jog_point1)
|
||||
self.gscreen.widgets.button_homing.connect("clicked", self.homing)
|
||||
self.widgets.hal_status.connect("all-homed",self.on_hal_status_all_homed)
|
||||
self.widgets.hal_status.connect("state-off",self.on_emc_off)
|
||||
self.gscreen.widgets.button_clear.connect("clicked", self.on_btn_clear)
|
||||
self.widgets.hal_status.connect("interp-idle",self.on_interp_idle)
|
||||
self.widgets.hal_status.connect("interp-run",self.on_interp_run)
|
||||
|
||||
# standard handler call
|
||||
def get_handlers(halcomp,builder,useropts,gscreen):
|
||||
return [HandlerClass(halcomp,builder,useropts,gscreen)]
|
||||
40
share/gscreen/skins/tester/tester.glade
Normal file
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.40.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.16"/>
|
||||
<object class="GtkTextBuffer" id="textbuffer1">
|
||||
<property name="text" translatable="yes"> Tester Screen
|
||||
|
||||
Build a glade file and save it in:
|
||||
configs/sim/gscreen/gscreen_custom
|
||||
|
||||
The glade file must be called tester.glade
|
||||
The toplevel window must be called window1
|
||||
|
||||
Then it can be launched from the linuxcnc launcher menu:
|
||||
sim/gscreen/gscreen_custom/tester
|
||||
|
||||
tester uses a handler file found in:
|
||||
share/gscreen/skins/tester/tester_handler.py
|
||||
|
||||
tester_handler.py is a template of a
|
||||
handler file for adding python code for
|
||||
more sophisticated customizations.
|
||||
|
||||
If you wish to modify it for your screen it could be copied to:
|
||||
configs/sim/gscreen/gscreen_custom
|
||||
|
||||
See the linuxcnc documentations on Gscreen for more information.
|
||||
</property>
|
||||
</object>
|
||||
<object class="GtkWindow" id="window1">
|
||||
<property name="can-focus">False</property>
|
||||
<child>
|
||||
<object class="GtkTextView" id="textview1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="buffer">textbuffer1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
57
share/gscreen/skins/tester/tester_handler.py
Normal file
@@ -0,0 +1,57 @@
|
||||
import hal
|
||||
|
||||
# This is a handler file for using Gscreen's infrastructure
|
||||
# to load a completely custom glade screen.
|
||||
# The only things that really matters is that it's saved as a GTK builder project,
|
||||
# the toplevel window is caller window1 (The default name) and you connect a destroy
|
||||
# window signal else you can't close down linuxcnc
|
||||
|
||||
# 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
|
||||
# emc 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.emc = gscreen.emc
|
||||
self.data = gscreen.data
|
||||
self.widgets = gscreen.widgets
|
||||
self.gscreen = gscreen
|
||||
|
||||
# This connects siganals without using glade's autoconnect method
|
||||
# in this case to destroy the window
|
||||
# it calls the method in gscreen: gscreen.on_window_destroy()
|
||||
def connect_signals(self,handlers):
|
||||
signal_list = [ ["window1","destroy", "on_window1_destroy"],]
|
||||
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])
|
||||
|
||||
# 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()
|
||||
|
||||
# If we need extra HAL pins here is where we do it.
|
||||
# Note you must import hal at the top of this script to do it.
|
||||
# For gaxis there is no extra pins but since we don't want gscreen to
|
||||
# add it's default pins we added this dunmmy function
|
||||
def initialize_pins(self):
|
||||
pass
|
||||
|
||||
# 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):
|
||||
pass
|
||||
|
||||