Import LinuxCNC source tree
This commit is contained in:
294
tcl/bin/cbutton.tcl
Normal file
294
tcl/bin/cbutton.tcl
Normal file
@@ -0,0 +1,294 @@
|
||||
# ----------------------------------------------------------------------
|
||||
#
|
||||
# cbutton.tcl --
|
||||
#
|
||||
# Example of how to provide button-like behavior on canvas
|
||||
# items. (Posted on comp.lang.tcl by Kevin Kenny)
|
||||
#
|
||||
# source: https://wiki.tcl-lang.org/page/Canvas+Buttons
|
||||
|
||||
set ::RCSID([info script]) \
|
||||
{$Id: 1383,v 1.3 2006-09-24 06:00:06 jcw Exp $}
|
||||
|
||||
package provide canvasbutton 1.0
|
||||
|
||||
namespace eval canvasbutton {
|
||||
|
||||
# nexttag - Next unique tag number for a "button" being
|
||||
# created
|
||||
|
||||
variable nexttag 0
|
||||
|
||||
# command - command(tag#) contains the command to execute when
|
||||
# a "button" is selected.
|
||||
|
||||
variable command
|
||||
|
||||
# cursor - cursor(pathName) contains the (saved) cursor
|
||||
# symbol of the widget when the pointer is in
|
||||
# a "button"
|
||||
|
||||
variable cursor
|
||||
|
||||
# enteredButton - contains the tag number of the button
|
||||
# containing the pointer.
|
||||
|
||||
variable enteredButton {}
|
||||
|
||||
# pressedButton - contains the tag number of the "button"
|
||||
# in which the mouse button was pressed
|
||||
|
||||
variable pressedButton {}
|
||||
|
||||
namespace export canvasbutton
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
#
|
||||
# canvasbutton::canvasbutton --
|
||||
#
|
||||
# Create a button-like object on a canvas.
|
||||
#
|
||||
# Parameters:
|
||||
# w Path name of the canvas
|
||||
# x0 Canvas X coordinate of left edge
|
||||
# y0 Canvas Y coordinate of top edge
|
||||
# x1 Canvas X coordinate of right edge
|
||||
# y1 Canvas Y coordinate of bottom edge
|
||||
# text Text to display in the button
|
||||
# cmd Command to execute when the button is selected.
|
||||
#
|
||||
# Results:
|
||||
# Unique canvas tag assigned to the items that make
|
||||
# up the button.
|
||||
#
|
||||
# Side effects:
|
||||
# A rectangle and a text item are created in the canvas,
|
||||
# and bindings are established to give them button-like
|
||||
# behavior.
|
||||
#
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
proc canvasbutton::canvasbutton {w x0 y0 wd h text cmd state} {
|
||||
variable nexttag
|
||||
variable command
|
||||
|
||||
set btag [list canvasb# [incr nexttag]]
|
||||
|
||||
set command($btag) $cmd
|
||||
|
||||
|
||||
|
||||
set x [expr { $x0 + ($wd / 2) }]
|
||||
set y [expr { $y0 + ($h / 2) + 1}]
|
||||
|
||||
if {$state} {
|
||||
|
||||
$w create rectangle $x0 $y0 [expr {$x0 + $wd}] [expr {$y0 + $h}] \
|
||||
-fill lightgray -outline black -width 1 \
|
||||
-tags [list canvasb $btag [linsert $btag end frame]]
|
||||
|
||||
$w create text $x $y -anchor center -justify center \
|
||||
-text $text \
|
||||
-tags [list canvasb $btag [linsert $btag end text]]
|
||||
|
||||
$w bind canvasb <Enter> [list [namespace current]::enter %W]
|
||||
$w bind canvasb <Leave> [list [namespace current]::leave %W]
|
||||
$w bind canvasb <ButtonPress-1> \
|
||||
[list [namespace current]::press %W]
|
||||
$w bind canvasb <ButtonRelease-1> \
|
||||
[list [namespace current]::release %W]
|
||||
} else {
|
||||
$w create rectangle $x0 $y0 [expr {$x0 + $wd}] [expr {$y0 + $h}] \
|
||||
-fill lightgray -outline grey65 -width 1
|
||||
$w create text $x $y -anchor center -justify center \
|
||||
-text $text -fill grey65
|
||||
}
|
||||
|
||||
return $btag
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
#
|
||||
# canvasbutton::enter --
|
||||
#
|
||||
# Process the <Enter> event on a canvas-button.
|
||||
#
|
||||
# Parameters:
|
||||
# w Path name of the canvas
|
||||
#
|
||||
# Results:
|
||||
# None.
|
||||
#
|
||||
# Side effects:
|
||||
# When the mouse pointer is in a button, the button is
|
||||
# highlighted with a broad outline and the cursor
|
||||
# symbol changes to an arrow. When the active button
|
||||
# is pressed, it is highlighted in green.
|
||||
#
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
proc canvasbutton::enter {w} {
|
||||
variable enteredButton
|
||||
variable pressedButton
|
||||
variable cursor
|
||||
|
||||
set enteredButton [findBtag $w]
|
||||
set frame [linsert $enteredButton end frame]
|
||||
set cursor($w) [$w cget -cursor]
|
||||
$w configure -cursor arrow
|
||||
#$w itemconfigure $frame -width 3
|
||||
$w itemconfigure $frame -fill grey93
|
||||
if {![string compare $enteredButton $pressedButton]} {
|
||||
$w itemconfigure $frame -fill grey60
|
||||
}
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
#
|
||||
# canvasbutton::leave --
|
||||
#
|
||||
# Process the <Leave> event on a canvas-button.
|
||||
#
|
||||
# Parameters:
|
||||
# w Path name of the canvas
|
||||
#
|
||||
# Results:
|
||||
# None.
|
||||
#
|
||||
# Side effects:
|
||||
# Reverts the cursor symbol, the border width
|
||||
# if needed, the highlight color of the button.
|
||||
#
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
proc canvasbutton::leave {w} {
|
||||
variable enteredButton
|
||||
variable pressedButton
|
||||
variable cursor
|
||||
if {[string compare $enteredButton {}]} {
|
||||
set btag [findBtag $w]
|
||||
set frame [linsert $btag end frame]
|
||||
#$w itemconfigure $frame -width 1
|
||||
$w itemconfigure $frame -fill lightgray
|
||||
$w configure -cursor $cursor($w)
|
||||
unset cursor($w)
|
||||
if {![string compare $btag $pressedButton]} {
|
||||
$w itemconfigure $frame -fill white
|
||||
}
|
||||
set enteredButton {}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
#
|
||||
# canvasbutton::press --
|
||||
#
|
||||
# Process the <ButtonPress-1> event on a canvas-button.
|
||||
#
|
||||
# Parameters:
|
||||
# w Path name of the canvas
|
||||
#
|
||||
# Results:
|
||||
# None.
|
||||
#
|
||||
# Side effects:
|
||||
# Highlights the selected button in green.
|
||||
#
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
proc canvasbutton::press {w} {
|
||||
variable pressedButton
|
||||
set pressedButton [findBtag $w]
|
||||
$w itemconfigure [linsert $pressedButton end frame] \
|
||||
-fill grey60
|
||||
return
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
#
|
||||
# canvasbutton::release --
|
||||
#
|
||||
# Process the <ButtonRelease-1> event on a canvas-button.
|
||||
#
|
||||
# Parameters:
|
||||
# w Path name of the canvas
|
||||
#
|
||||
# Results:
|
||||
# None.
|
||||
#
|
||||
# Side effects:
|
||||
# Reverts the highlight color on the button. If the
|
||||
# mouse has not left the button, invokes the button's
|
||||
# command.
|
||||
#
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
proc canvasbutton::release {w} {
|
||||
variable enteredButton
|
||||
variable pressedButton
|
||||
variable command
|
||||
|
||||
set pressedButtonWas $pressedButton
|
||||
set pressedButton {}
|
||||
|
||||
$w itemconfigure [linsert $pressedButtonWas end frame] \
|
||||
-fill grey93
|
||||
|
||||
if {![string compare $enteredButton $pressedButtonWas]} {
|
||||
uplevel #0 $command($pressedButtonWas)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
#
|
||||
# canvasbutton::btag --
|
||||
#
|
||||
# Locate the unique tag of a canvas-button
|
||||
#
|
||||
# Parameters:
|
||||
# w Path name of the canvas
|
||||
#
|
||||
# Results:
|
||||
# Button tag, or the null string if the current
|
||||
# item is not a canvas-button
|
||||
#
|
||||
# Side effects:
|
||||
# Searches the tag list of the current canvas item
|
||||
# for a tag that begins with the string, `canvasb#',
|
||||
# and returns the first two elements of the tag
|
||||
# interpreted as a Tcl list.
|
||||
#
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
proc canvasbutton::findBtag {w} {
|
||||
foreach tag [$w itemcget current -tags] {
|
||||
if {[regexp {^canvasb#} [lindex $tag 0]]} {
|
||||
return [lrange $tag 0 1]
|
||||
}
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
if {![string compare $argv0 [info script]]} {
|
||||
|
||||
grid [canvas .c -width 300 -height 200 -cursor crosshair]
|
||||
|
||||
namespace import canvasbutton::*
|
||||
|
||||
.c create text 150 150 -anchor n -tags label \
|
||||
-font {Helvetica 10 bold}
|
||||
|
||||
canvasbutton .c 10 60 90 140 "First\nButton" {
|
||||
.c itemconfigure label -text One
|
||||
}
|
||||
canvasbutton .c 110 60 190 140 "Second\nButton" {
|
||||
.c itemconfigure label -text Two
|
||||
}
|
||||
canvasbutton .c 210 60 290 140 "Third\nButton" {
|
||||
.c itemconfigure label -text Three
|
||||
}
|
||||
canvasbutton .c 240 160 290 190 "Quit" exit
|
||||
}
|
||||
568
tcl/bin/emccalib.tcl
Executable file
568
tcl/bin/emccalib.tcl
Executable file
@@ -0,0 +1,568 @@
|
||||
#!/bin/sh
|
||||
# the next line restarts using emcsh \
|
||||
exec $LINUXCNC_EMCSH "$0" "$@"
|
||||
|
||||
###############################################################
|
||||
# Description: emccalib.tcl
|
||||
# A Tcl/Tk script that interfaces with LinuxCNC
|
||||
# through GUIs. It configures ini tuning variables
|
||||
# on the fly and saves if desired.
|
||||
#
|
||||
# Author: Ray Henry
|
||||
# License: GPL Version 2
|
||||
#
|
||||
# Copyright (c) 2003-2009 All rights reserved.
|
||||
###############################################################
|
||||
# EMC parameter setting application
|
||||
# Needs emcsh to run
|
||||
# Saves changes to ini file if requested
|
||||
###############################################################
|
||||
|
||||
|
||||
# FIXME allow multiple reads of ini var.
|
||||
# this is a one way system. It finds ini referenced variable in hal files
|
||||
# and builds widgets to display and manipulate their values
|
||||
# it does not and will not sort on hal components.
|
||||
|
||||
source [file join [file dirname [info script]] .. linuxcnc.tcl]
|
||||
eval emc_init $argv
|
||||
|
||||
source [file join $::env(HALLIB_DIR) hal_procs_lib.tcl]
|
||||
|
||||
package require BWidget
|
||||
|
||||
# add a few default characteristics to the display
|
||||
foreach class { Button Checkbutton Entry Label Listbox Menu Menubutton \
|
||||
Message Radiobutton Scale } {
|
||||
option add *$class.borderWidth 1 100
|
||||
}
|
||||
|
||||
set ::EC(numjoints) [emc_ini "JOINTS" "KINS"]
|
||||
set ::EC(numspindles) 10 ;# currently 8 spindles allowed (0..7)
|
||||
;# but legacy configs may have [SPINDLE_9]
|
||||
;# so allow up to 10 (0..9)
|
||||
|
||||
#--------------------------------------------------------------
|
||||
# Tuning stanzas
|
||||
set ::EC(stanzas) [list TUNE JOINT_ AXIS_ SPINDLE_]
|
||||
|
||||
# Specify a stanza for tuning with:
|
||||
# ::EC(stanza_name,howmany) == number of allowed names
|
||||
# ::EC(stanza_name,suffixes) == list of allowed suffixes
|
||||
#
|
||||
# Special case: howmany==1 and items=="", no allowed suffixes
|
||||
#
|
||||
# Examples:
|
||||
# item==JOINT_ specifies name/value pairs like:
|
||||
# [JOINT_n]name=value
|
||||
# where n is a suffix in {0 1 ...}
|
||||
#
|
||||
# item==TUNE using howmany==1 and items=="" specifies
|
||||
# name/value pairs with no suffix like:
|
||||
# [TUNE]name=value
|
||||
|
||||
set ::EC(TUNE,howmany) 1
|
||||
set ::EC(TUNE,suffixes) ""
|
||||
|
||||
set ::EC(JOINT_,howmany) $::EC(numjoints)
|
||||
for {set i 0} {$i < $::EC(JOINT_,howmany)} {incr i} {
|
||||
lappend ::EC(JOINT_,suffixes) $i
|
||||
}
|
||||
|
||||
set ::EC(SPINDLE_,howmany) $::EC(numspindles)
|
||||
for {set i 0} {$i < $::EC(SPINDLE_,howmany)} {incr i} {
|
||||
lappend ::EC(SPINDLE_,suffixes) $i
|
||||
}
|
||||
set ::EC(AXIS_,suffixes) {X Y Z A B C U V W}
|
||||
set ::EC(AXIS_,howmany) [llength $::EC(AXIS_,suffixes)]
|
||||
#--------------------------------------------------------------
|
||||
|
||||
# Find the name of the ini file used for this run.
|
||||
set ::EC(thisinifile) "$::EMC_INIFILE"
|
||||
set ::EC(thisconfigdir) [file dirname $::EC(thisinifile)]
|
||||
|
||||
|
||||
#----------start toplevel----------
|
||||
#
|
||||
# trap mouse click on window manager delete
|
||||
# might add a test for up to date ini before closing
|
||||
wm protocol . WM_DELETE_WINDOW askKill
|
||||
proc askKill {} {
|
||||
destroy .
|
||||
exit
|
||||
}
|
||||
|
||||
wm title . [msgcat::mc "LinuxCNC Calibration"]
|
||||
set ::EC(main) [frame .main ]
|
||||
set ::EC(nbook) [NoteBook .main.top]
|
||||
pack $::EC(main) -side left -expand yes -fill both \
|
||||
-padx 18 -pady 18 -anchor n
|
||||
pack $::EC(nbook) -side top -fill both -expand yes
|
||||
set terminate [frame $::EC(main).bot]
|
||||
pack $terminate -side top -fill x
|
||||
button $terminate.save -text [msgcat::mc "Save To File"] -command {saveIni tune}
|
||||
button $terminate.quit -text [msgcat::mc "Quit"] -command {saveIni quit}
|
||||
pack $terminate.save $terminate.quit \
|
||||
-pady 4 -side left -fill both -expand yes
|
||||
|
||||
# remove slider
|
||||
# slider process is used for several widgets
|
||||
proc sSlide {f a b} {
|
||||
$f.sc set $a $b
|
||||
}
|
||||
|
||||
# Build menu
|
||||
# fixme clean up the underlines so they are unique under each set
|
||||
set menubar [menu $::EC(nbook).menubar -tearoff 0]
|
||||
#. configure -menu $menubar
|
||||
set filemenu [menu $menubar.file -tearoff 0]
|
||||
$menubar add cascade -label [msgcat::mc "File"] \
|
||||
-menu $filemenu
|
||||
$filemenu add command -label [msgcat::mc "Refresh"] \
|
||||
-command {refreshHAL}
|
||||
$filemenu add command -label [msgcat::mc "Save"] \
|
||||
-command {saveHAL save}
|
||||
|
||||
# Make a text widget to hold the ini file
|
||||
set ::EC(initext) [text $::EC(nbook).initext]
|
||||
set ::EC(haltext) [text $::EC(nbook).haltext]
|
||||
$::EC(initext) config -state normal
|
||||
$::EC(initext) delete 1.0 end
|
||||
set programin [open $::EC(thisinifile)]
|
||||
$::EC(initext) insert end [read $programin]
|
||||
close $programin
|
||||
|
||||
# setup array with section names and line numbers
|
||||
set ::EC(sectionlist) {}
|
||||
scan [$::EC(initext) index end] %d nl
|
||||
set inilastline $nl
|
||||
for {set i 1} {$i < $nl} {incr i} {
|
||||
if { [$::EC(initext) get $i.0] == "\[" } {
|
||||
set inisectionname [$::EC(initext) get $i.1 $i.end]
|
||||
set tab " "
|
||||
set spc " "
|
||||
set inisectionname [string trimright $inisectionname "$spc$tab]" ]
|
||||
set ::EC(sectionline,$inisectionname) $i
|
||||
lappend ::EC(sectionlist) $inisectionname
|
||||
}
|
||||
}
|
||||
|
||||
set ::EC(sectionline,END_OF_INI_FILE) [expr $nl-1]
|
||||
lappend ::EC(sectionlist) END_OF_INI_FILE
|
||||
|
||||
# Find the HALFILE names between HAL and the next section
|
||||
set startline $::EC(sectionline,HAL)
|
||||
set endline $::EC(sectionline,[lindex $::EC(sectionlist) \
|
||||
[expr [lsearch -exact $::EC(sectionlist) HAL] + 1 ]])
|
||||
|
||||
set ::EC(halfilelist) ""
|
||||
|
||||
for {set i $startline} {$i < $endline} {incr i} {
|
||||
set thisstring [string trim [$::EC(initext) get $i.0 $i.end]]
|
||||
if { ([string first "HALFILE" "$thisstring"] == 0)
|
||||
|| ([string first "POSTGUI_HALFILE" "$thisstring"] == 0)
|
||||
} {
|
||||
set arglist [lindex [split $thisstring =] 1]
|
||||
set thishalname [lindex $arglist 0]
|
||||
lappend ::EC(halfilelist) [find_file_in_hallib_path $thishalname $::EC(thisinifile)]
|
||||
}
|
||||
}
|
||||
|
||||
proc find_ini_refs {stanza} {
|
||||
# find the ini references in this hal and build widgets
|
||||
scan [$::EC(haltext) index end] %d nl
|
||||
for {set i 1} { $i < $nl } {incr i} {
|
||||
set tmpstring [string trim [$::EC(haltext) get $i.0 $i.end]]
|
||||
if {[string match *${stanza}* $tmpstring] && ![string match *#* $tmpstring]} {
|
||||
set halcommand [split $tmpstring " \t"]
|
||||
if { [lindex $halcommand 0] == "setp" || [lindex $halcommand 1] == "\=" } {
|
||||
if { [lindex $halcommand 1] == "\=" } {
|
||||
set tmpstring "setp [lindex $halcommand 0] [lindex $halcommand 2]"
|
||||
}
|
||||
# tunable item is the setp value (3rd token); ignore ini refs
|
||||
# that only appear inside the pin name (issue #4165)
|
||||
set valuestring [lindex $tmpstring 2]
|
||||
for {set sfx 0} {$sfx < $::EC($stanza,howmany)} {incr sfx} {
|
||||
set tabno $::EC($stanza,$sfx,tabno)
|
||||
set itag [lindex $::EC($stanza,suffixes) $sfx]
|
||||
if {[string match *${stanza}${itag}* $valuestring]} {
|
||||
# this is a hal file search ordered loop
|
||||
set thisininame [lindex [split $valuestring "\]" ] end ]
|
||||
set thisininame [string map {( "" ) ""} $thisininame]
|
||||
set lowername "[string tolower $thisininame]"
|
||||
set thishalcommand [lindex $tmpstring 1]
|
||||
set tmpval [string trim [hal getp [halcmdSubstitute $thishalcommand]]]
|
||||
set ::EC(value,$tabno,$lowername) $tmpval
|
||||
set ::EC(value,$tabno,$lowername,next) $tmpval
|
||||
if { [catch { set thisname [label $::EC(tab,$tabno).label-$itag-$lowername \
|
||||
-text "$thisininame: " -width 20 -anchor e] } msg ] } {
|
||||
#puts msg=$msg
|
||||
} else {
|
||||
set thisval [label $::EC(tab,$tabno).entry-$lowername -width 8 \
|
||||
-textvariable ::EC(value,$tabno,$lowername) -anchor e -foreg firebrick4 ]
|
||||
set thisentry [entry $::EC(tab,$tabno).next-$lowername -width 8 \
|
||||
-width 12 -textvariable ::EC(value,$tabno,$lowername,next) ]
|
||||
grid $thisname $thisval x $thisentry
|
||||
}
|
||||
lappend ::EC(ininamearray,$tabno) $lowername
|
||||
lappend ::EC(commandarray,$tabno) $thishalcommand
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} ;# find_ini_refs
|
||||
|
||||
proc makeIniTune {} {
|
||||
set tabno 0
|
||||
foreach stanza $::EC(stanzas) {
|
||||
for {set sfx 0} {$sfx < $::EC($stanza,howmany)} {incr sfx} {
|
||||
set ::EC($stanza,$sfx,tabno) $tabno
|
||||
set ::EC($tabno,stanza) $stanza ;# cross reference tabno-->stanza
|
||||
set itag [lindex $::EC($stanza,suffixes) $sfx]
|
||||
|
||||
if {($::EC($stanza,howmany) == 1) && ($::EC($stanza,suffixes)=="")} {
|
||||
set tablabel ${stanza}
|
||||
} else {
|
||||
set tablabel ${stanza}$itag
|
||||
}
|
||||
|
||||
set ::EC(tab,$tabno) [$::EC(nbook) insert [expr $tabno+3] page$tabno \
|
||||
-text $tablabel -raisecmd "selectTab $tabno" ]
|
||||
set col0 [label $::EC(tab,$tabno).collabel0 -text [msgcat::mc "INI Name"]]
|
||||
set col1 [label $::EC(tab,$tabno).collabel1 -text [msgcat::mc "HAL's Value"]]
|
||||
set col2 [label $::EC(tab,$tabno).space -text " "]
|
||||
set col3 [label $::EC(tab,$tabno).collabel3 -text [msgcat::mc "Next Value"]]
|
||||
grid $col0 $col1 $col2 $col3 -ipady 5
|
||||
grid rowconfigure $::EC(tab,$tabno) 9999 -weight 1
|
||||
incr tabno
|
||||
}
|
||||
}
|
||||
|
||||
foreach fname $::EC(halfilelist) {
|
||||
$::EC(haltext) config -state normal
|
||||
$::EC(haltext) delete 1.0 end
|
||||
if {[catch {open $fname} programin]} {
|
||||
continue
|
||||
} else {
|
||||
$::EC(haltext) insert end [read $programin]
|
||||
catch {close $programin}
|
||||
}
|
||||
foreach stanza $::EC(stanzas) {
|
||||
find_ini_refs $stanza
|
||||
}
|
||||
}
|
||||
if {[array names ::EC ininamearray,*] == ""} {
|
||||
incompatible_ini_file
|
||||
return
|
||||
}
|
||||
|
||||
# build the buttons to control variables.
|
||||
foreach stanza $::EC(stanzas) {
|
||||
for {set sfx 0} {$sfx < $::EC($stanza,howmany)} {incr sfx} {
|
||||
set itag [lindex $::EC($stanza,suffixes) $sfx]
|
||||
set tabno $::EC($stanza,$sfx,tabno)
|
||||
if ![info exists ::EC(startpagenum)] {
|
||||
set ::EC(startpagenum) $tabno
|
||||
}
|
||||
if ![info exists ::EC(ininamearray,$tabno)] {
|
||||
$::EC(nbook) delete page$tabno
|
||||
if {$tabno == $::EC(startpagenum)} {
|
||||
unset ::EC(startpagenum)
|
||||
}
|
||||
continue
|
||||
}
|
||||
set bframe [frame $::EC(tab,$tabno).buttons]
|
||||
grid configure $bframe -columnspan 4 -sticky nsew
|
||||
set tmptest [button $bframe.test -text [msgcat::mc "Test"] \
|
||||
-command {iniTuneButtonpress test}]
|
||||
set tmpok [button $bframe.ok -text [msgcat::mc "OK"] \
|
||||
-command {iniTuneButtonpress ok} -state disabled ]
|
||||
set tmpcancel [button $bframe.cancel -text [msgcat::mc "Cancel"] \
|
||||
-command {iniTuneButtonpress cancel} -state disabled ]
|
||||
set tmprefresh [button $bframe.refresh -text [msgcat::mc "Refresh"] \
|
||||
-command {iniTuneButtonpress refresh}]
|
||||
pack $tmpok $tmptest $tmpcancel $tmprefresh -side left -fill both -expand yes -pady 5
|
||||
}
|
||||
}
|
||||
} ;# makeIniTune
|
||||
|
||||
proc incompatible_ini_file {} {
|
||||
set progname [file tail $::argv0]
|
||||
set fname [file tail $::EMC_INIFILE]
|
||||
set answer [tk_messageBox \
|
||||
-title "Ini file not compatible with $progname" \
|
||||
-message [msgcat::mc "\
|
||||
No Tuneable items in ini file:\n\
|
||||
$fname\n\n\
|
||||
Sections supported are:\n\
|
||||
\[JOINT_N\]name=value\n\
|
||||
\[AXIS_L\]name=value\n\
|
||||
\[SPINDLE_S\]name=value\n\
|
||||
\[TUNE\]name=value\n\n\
|
||||
N is a joint number\n\
|
||||
L is an axis letter\n\
|
||||
S is a spindle number\n\n\
|
||||
A Halfile must include a setp\n\
|
||||
for a supported section item\n\n\
|
||||
Inifile example:\n\
|
||||
\[JOINT_0\]\n\
|
||||
PGAIN=1\n\
|
||||
...\n\
|
||||
\[TUNE\]\n\
|
||||
SPEED=100\n\
|
||||
...\n\n\
|
||||
Halfile example:\n\
|
||||
setp pid.0.Pgain \[JOINT_0\]PGAIN\n\
|
||||
setp mux2.0.in1 \[TUNE\]SPEED\n\
|
||||
...\n\n\
|
||||
\n\
|
||||
" ] \
|
||||
-type ok \
|
||||
-icon info]
|
||||
exit 1
|
||||
} ;# incompatible_ini_file
|
||||
|
||||
proc selectTab {which} {
|
||||
set ::curtab $which ;# current tab number
|
||||
}
|
||||
|
||||
proc iniTuneButtonpress {which} {
|
||||
set labelname ".main.top.fpage$::curtab.next"
|
||||
set basename ".main.top.fpage$::curtab.buttons"
|
||||
# which can be (test, ok, cancel)
|
||||
switch -- $which {
|
||||
test {
|
||||
$basename.test configure -state disabled
|
||||
$basename.ok configure -state normal
|
||||
$basename.cancel configure -state normal
|
||||
set entrystate "disabled"
|
||||
}
|
||||
cancel {
|
||||
$basename.test configure -state normal
|
||||
$basename.ok configure -state disabled
|
||||
$basename.cancel configure -state disabled
|
||||
set entrystate "normal"
|
||||
}
|
||||
ok {
|
||||
$basename.test configure -state normal
|
||||
$basename.ok configure -state disabled
|
||||
$basename.cancel configure -state disabled
|
||||
set entrystate "normal"
|
||||
}
|
||||
refresh {
|
||||
$basename.test configure -state normal
|
||||
$basename.ok configure -state disabled
|
||||
$basename.cancel configure -state disabled
|
||||
set entrystate "normal"
|
||||
}
|
||||
default {
|
||||
}
|
||||
}
|
||||
foreach name $::EC(ininamearray,$::curtab) {
|
||||
$labelname-$name configure -state $entrystate
|
||||
}
|
||||
changeIni $which $::EC($::curtab,stanza)
|
||||
} ;# iniTuneButtonpress
|
||||
|
||||
proc changeIni {how stanza} {
|
||||
switch -- $how {
|
||||
cancel {-}
|
||||
test {
|
||||
set varnames $::EC(ininamearray,$::curtab)
|
||||
set varcommands $::EC(commandarray,$::curtab)
|
||||
set maxvarnum [llength $varnames]
|
||||
set swapvars $varnames
|
||||
# handle each variable and values inside loop
|
||||
for {set listnum 0} {$listnum < $maxvarnum} {incr listnum} {
|
||||
set vname [lindex $varnames $listnum]
|
||||
set var ::EC(value,$::curtab,$vname)
|
||||
set varnext ::EC(value,$::curtab,$vname,next)
|
||||
# remove this item from the "to be swapped" list
|
||||
set thisvar [lindex $swapvars 0]
|
||||
set swapvars [lrange $swapvars 1 end]
|
||||
# get the values
|
||||
set oldval [set $var]
|
||||
set newval [set $varnext]
|
||||
# get the parameter name string
|
||||
set tmpcmd [lindex $varcommands $listnum]
|
||||
# set new parameter value in hal
|
||||
set thisret [hal setp [halcmdSubstitute $tmpcmd] $newval]
|
||||
# see if we need to swap the new and old control values
|
||||
if {[lsearch -exact $swapvars $thisvar] < 0} {
|
||||
# set the current value for display
|
||||
set $var $newval
|
||||
# set the tmp value as next in display
|
||||
set $varnext $oldval
|
||||
}
|
||||
}
|
||||
}
|
||||
ok {
|
||||
set varnames $::EC(ininamearray,$::curtab)
|
||||
set varcommands $::EC(commandarray,$::curtab)
|
||||
set maxvarnum [llength $varnames]
|
||||
# handle each variable and values inside loop
|
||||
for {set listnum 0} {$listnum < $maxvarnum} {incr listnum} {
|
||||
set vname [lindex $varnames $listnum]
|
||||
set var ::EC(value,$::curtab,$vname)
|
||||
set varnext ::EC(value,$::curtab,$vname,next)
|
||||
# get the values
|
||||
set oldval [set $var]
|
||||
# set the tmp value as next in display
|
||||
set $varnext $oldval
|
||||
}
|
||||
}
|
||||
refresh {
|
||||
set varnames $::EC(ininamearray,$::curtab)
|
||||
set varcommands $::EC(commandarray,$::curtab)
|
||||
set maxvarnum [llength $varnames]
|
||||
# handle each variable and values inside loop
|
||||
for {set listnum 0} {$listnum < $maxvarnum} {incr listnum} {
|
||||
set vname [lindex $varnames $listnum]
|
||||
set var ::EC(value,$::curtab,$vname)
|
||||
set varnext ::EC(value,$::curtab,$vname,next)
|
||||
# get the parameter name string
|
||||
set tmpcmd [lindex $varcommands $listnum]
|
||||
# get parameter value from hal
|
||||
set val [string trim [hal getp [halcmdSubstitute $tmpcmd]]]
|
||||
set $var $val
|
||||
set $varnext $val
|
||||
}
|
||||
}
|
||||
quit {
|
||||
puts stderr "Unexpected changeIni quit"
|
||||
# was never called, removed deadcode here
|
||||
}
|
||||
default {}
|
||||
}
|
||||
} ;# changeIni
|
||||
|
||||
proc saveIni {which} {
|
||||
if {![file writable $::EC(thisinifile)]} {
|
||||
tk_messageBox -type ok -message [msgcat::mc "Not permitted to save here.\n\n \
|
||||
You need to copy a configuration to your home directory and work there."]
|
||||
}
|
||||
switch -- $which {
|
||||
tune {
|
||||
update_initext $::EC($::curtab,stanza)
|
||||
saveFile $::EC(thisinifile) $::EC(initext)
|
||||
}
|
||||
quit {destroy .; exit}
|
||||
}
|
||||
} ;# saveIni
|
||||
|
||||
proc update_initext {stanza} {
|
||||
set anames [array names ::EC ininamearray,*]
|
||||
foreach stanza $::EC(stanzas) {
|
||||
for {set sfx 0} {$sfx < $::EC($stanza,howmany)} {incr sfx} {
|
||||
set itag [lindex $::EC($stanza,suffixes) $sfx]
|
||||
set tabno $::EC($stanza,$sfx,tabno)
|
||||
if {[lsearch $anames ininamearray,$tabno] < 0} continue
|
||||
set varnames $::EC(ininamearray,$tabno)
|
||||
set upvarnames [string toupper $varnames]
|
||||
set varcommands $::EC(commandarray,$tabno)
|
||||
set maxvarnum [llength $varnames]
|
||||
set sectname "${stanza}$itag"
|
||||
# get the name of the next ini section
|
||||
set endsect [lindex $::EC(sectionlist) \
|
||||
[expr [lsearch -exact $::EC(sectionlist) $sectname] + 1 ]]
|
||||
set sectnum "[set ::EC(sectionline,$sectname)]"
|
||||
set nextsectnum "[set ::EC(sectionline,$endsect)]"
|
||||
$::EC(initext) configure -state normal
|
||||
for {set ind $sectnum} {$ind < $nextsectnum} {incr ind} {
|
||||
switch -- [$::EC(initext) get $ind.0] {
|
||||
"#" {}
|
||||
default {
|
||||
set tmpstr [$::EC(initext) get $ind.0 $ind.end]
|
||||
set tmpvar [lindex [split $tmpstr "="] 0]
|
||||
set tmpvar [string toupper [string trim $tmpvar]]
|
||||
set tmpindx [lsearch $upvarnames $tmpvar]
|
||||
if {$tmpindx != -1} {
|
||||
set cmd [lindex $varcommands $tmpindx]
|
||||
$::EC(initext) mark set insert $ind.0
|
||||
set newval [string trim [hal getp [halcmdSubstitute $cmd]]]
|
||||
set tmptest [string first "e" $newval]
|
||||
if {[string first "e" $newval] > 1} {
|
||||
set newval [format %f $newval]
|
||||
}
|
||||
regsub {(^.*=[ \t]*)[^ \t]*(.*)} $tmpstr "\\1$newval\\2" newvar
|
||||
$::EC(initext) delete insert "insert lineend"
|
||||
$::EC(initext) insert insert $newvar
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$::EC(initext) configure -state disabled
|
||||
}
|
||||
}
|
||||
} ;# update_initext
|
||||
|
||||
proc halcmdSubstitute {s} {
|
||||
set pat {\[([^]]+)\](\([^)]+\)|[^() \r\n\t]+)}
|
||||
set pos 0
|
||||
set result {}
|
||||
while {$pos < [string length $s]
|
||||
&& [regexp -start $pos -indices $pat $s indx]} {
|
||||
set start [lindex $indx 0]
|
||||
set end [lindex $indx 1]
|
||||
|
||||
append result [string range $s $pos [expr $start-1]]
|
||||
|
||||
set query [string range $s $start $end]
|
||||
regexp $pat $query - section var
|
||||
set var [regsub {\((.*)\)} $var {\1}]
|
||||
append result [emc_ini $var $section]
|
||||
|
||||
set pos [expr $end+1]
|
||||
}
|
||||
append result [string range $s $pos end]
|
||||
return $result
|
||||
} ;# halcmdSubstitute
|
||||
|
||||
proc saveFile {filename contents} {
|
||||
catch {file copy -force $filename $filename.bak}
|
||||
if { [catch {open $filename w} fileout] } {
|
||||
puts stdout [msgcat::mc "can't save %s" $halconfFilename($name)]
|
||||
return
|
||||
}
|
||||
if {-1 != [string first ".ini.expanded" $filename]} {
|
||||
set fname [file tail $filename]
|
||||
set answer [tk_messageBox \
|
||||
-title "Expanded File" \
|
||||
-message [msgcat::mc "\
|
||||
Save to: <$fname>\n\n\
|
||||
Expanded file for \#INCLUDEs\n\n\
|
||||
\#INCLUDE files (*.inc)\n\
|
||||
must be edited separately\n\
|
||||
\n\
|
||||
" ] \
|
||||
-type ok \
|
||||
-icon info]
|
||||
}
|
||||
switch -- [string index $contents 0] {
|
||||
"/" {
|
||||
# a filename
|
||||
puts "I got a filename"
|
||||
}
|
||||
"." {
|
||||
# "." means this is a widget name so get contents
|
||||
set lines [$contents count -lines 1.0 end]
|
||||
# was: puts $fileout [$contents get 1.0 end]
|
||||
# avoid writing empty lines at end of file:
|
||||
incr lines -1
|
||||
set last ${lines}.end
|
||||
puts $fileout [$contents get 1.0 $last]
|
||||
catch {close $fileout}
|
||||
}
|
||||
default {
|
||||
# assumes that contents is plain text so stuff it away
|
||||
puts $fileout $contents
|
||||
catch {close $fileout}
|
||||
}
|
||||
}
|
||||
} ;# saveFile
|
||||
|
||||
makeIniTune
|
||||
$::EC(nbook) raise page$::EC(startpagenum)
|
||||
|
||||
211
tcl/bin/emcdebug.tcl
Executable file
211
tcl/bin/emcdebug.tcl
Executable file
@@ -0,0 +1,211 @@
|
||||
#!/bin/sh
|
||||
# the next line restarts using emcsh \
|
||||
exec $LINUXCNC_EMCSH "$0" "$@"
|
||||
|
||||
###############################################################
|
||||
# Description: emcdebug.tcl
|
||||
# This file sets debug levesl from tkemc.
|
||||
#
|
||||
# Derived from a work by Fred Proctor & Will Shackleford
|
||||
# Author:
|
||||
# License: GPL Version 2
|
||||
#
|
||||
# Copyright (c) 2005-2009 All rights reserved.
|
||||
###############################################################
|
||||
#
|
||||
# Sets value of EMC_DEBUG, so you can turn on/off what you want dumped
|
||||
# Needs emcsh to run-- this is sourced by tkemc, but it can be run
|
||||
# standalone. Make sure directory containing emcsh is in your path,
|
||||
# or edit the exec line above with the path to emcsh.
|
||||
#
|
||||
###############################################################
|
||||
|
||||
source [file join [file dirname [info script]] .. linuxcnc.tcl]
|
||||
eval emc_init $argv
|
||||
|
||||
# check if any emc commands exist, and quit if not
|
||||
if {! [string length [info commands emc_plat]]} {
|
||||
error "emcdebug needs to run from \"emcsh\""
|
||||
}
|
||||
|
||||
proc distributeDebug {} {
|
||||
global debug_invalid
|
||||
global debug_config
|
||||
global debug_defaults
|
||||
global debug_versions
|
||||
global debug_task_issue
|
||||
global debug_io_points
|
||||
global debug_nml
|
||||
global debug_motion_time
|
||||
global debug_interp
|
||||
global debug_rcs
|
||||
global debug_traj
|
||||
global debug_interp_list
|
||||
|
||||
# get the debug level from the EMC
|
||||
set emc_debug_level [emc_debug]
|
||||
|
||||
# set the initial check boxes to correspond to current debug settings
|
||||
|
||||
set debug_invalid [expr $emc_debug_level % 2]
|
||||
|
||||
set emc_debug_level [expr $emc_debug_level >> 1]
|
||||
set debug_config [expr $emc_debug_level % 2]
|
||||
|
||||
set emc_debug_level [expr $emc_debug_level >> 1]
|
||||
set debug_defaults [expr $emc_debug_level % 2]
|
||||
|
||||
set emc_debug_level [expr $emc_debug_level >> 1]
|
||||
set debug_versions [expr $emc_debug_level % 2]
|
||||
|
||||
set emc_debug_level [expr $emc_debug_level >> 1]
|
||||
set debug_task_issue [expr $emc_debug_level % 2]
|
||||
|
||||
set emc_debug_level [expr $emc_debug_level >> 1]
|
||||
set debug_io_points [expr $emc_debug_level % 2]
|
||||
|
||||
set emc_debug_level [expr $emc_debug_level >> 1]
|
||||
set debug_nml [expr $emc_debug_level % 2]
|
||||
|
||||
set emc_debug_level [expr $emc_debug_level >> 1]
|
||||
set debug_motion_time [expr $emc_debug_level % 2]
|
||||
|
||||
set emc_debug_level [expr $emc_debug_level >> 1]
|
||||
set debug_interp [expr $emc_debug_level % 2]
|
||||
|
||||
set emc_debug_level [expr $emc_debug_level >> 1]
|
||||
set debug_rcs [expr $emc_debug_level % 2]
|
||||
|
||||
set emc_debug_level [expr $emc_debug_level >> 1]
|
||||
set debug_traj [expr $emc_debug_level % 2]
|
||||
|
||||
set emc_debug_level [expr $emc_debug_level >> 1]
|
||||
set debug_interp_list [expr $emc_debug_level % 2]
|
||||
}
|
||||
|
||||
proc collectDebug {} {
|
||||
global debug_invalid
|
||||
global debug_config
|
||||
global debug_defaults
|
||||
global debug_versions
|
||||
global debug_task_issue
|
||||
global debug_io_points
|
||||
global debug_nml
|
||||
global debug_motion_time
|
||||
global debug_interp
|
||||
global debug_rcs
|
||||
global debug_traj
|
||||
global debug_interp_list
|
||||
|
||||
set emc_debug_level $debug_interp_list
|
||||
|
||||
set emc_debug_level [expr $emc_debug_level << 1]
|
||||
set emc_debug_level [expr $emc_debug_level + $debug_traj]
|
||||
|
||||
set emc_debug_level [expr $emc_debug_level << 1]
|
||||
set emc_debug_level [expr $emc_debug_level + $debug_rcs]
|
||||
|
||||
set emc_debug_level [expr $emc_debug_level << 1]
|
||||
set emc_debug_level [expr $emc_debug_level + $debug_interp]
|
||||
|
||||
set emc_debug_level [expr $emc_debug_level << 1]
|
||||
set emc_debug_level [expr $emc_debug_level + $debug_motion_time]
|
||||
|
||||
set emc_debug_level [expr $emc_debug_level << 1]
|
||||
set emc_debug_level [expr $emc_debug_level + $debug_nml]
|
||||
|
||||
set emc_debug_level [expr $emc_debug_level << 1]
|
||||
set emc_debug_level [expr $emc_debug_level + $debug_io_points]
|
||||
|
||||
set emc_debug_level [expr $emc_debug_level << 1]
|
||||
set emc_debug_level [expr $emc_debug_level + $debug_task_issue]
|
||||
|
||||
set emc_debug_level [expr $emc_debug_level << 1]
|
||||
set emc_debug_level [expr $emc_debug_level + $debug_versions]
|
||||
|
||||
set emc_debug_level [expr $emc_debug_level << 1]
|
||||
set emc_debug_level [expr $emc_debug_level + $debug_defaults]
|
||||
|
||||
set emc_debug_level [expr $emc_debug_level << 1]
|
||||
set emc_debug_level [expr $emc_debug_level + $debug_config]
|
||||
|
||||
set emc_debug_level [expr $emc_debug_level << 1]
|
||||
set emc_debug_level [expr $emc_debug_level + $debug_invalid]
|
||||
|
||||
emc_debug $emc_debug_level
|
||||
}
|
||||
|
||||
proc popdownDebug {w} {
|
||||
destroy $w
|
||||
if {$w == "."} {
|
||||
exit
|
||||
}
|
||||
}
|
||||
|
||||
proc popupDebug {{w .debugwindow}} {
|
||||
global debug_invalid
|
||||
global debug_config
|
||||
global debug_defaults
|
||||
global debug_versions
|
||||
global debug_task_issue
|
||||
global debug_io_points
|
||||
global debug_nml
|
||||
global debug_motion_time
|
||||
global debug_interp
|
||||
global debug_rcs
|
||||
global debug_traj
|
||||
global debug_interp_list
|
||||
|
||||
# trap "." as window name, and erase it, so that widgets
|
||||
# don't begin with two dots. We'll refer to the passed-in
|
||||
# name "w" here; in code following this setup we'll use the
|
||||
# modified name "lw"
|
||||
if {$w == "."} {
|
||||
# we're running standalone
|
||||
set lw ""
|
||||
wm title $w [msgcat::mc "LinuxCNC Debug"]
|
||||
} else {
|
||||
# we were sourced into tkemc, and run as a popup
|
||||
set lw $w
|
||||
if {[winfo exists $w]} {
|
||||
wm deiconify $w
|
||||
raise $w
|
||||
focus $w
|
||||
return
|
||||
}
|
||||
toplevel $w
|
||||
wm title $w [msgcat::mc "LinuxCNC Debug"]
|
||||
}
|
||||
|
||||
# use "lw" as name of top level from now on
|
||||
|
||||
# set the debug variables so that they're initially checked properly
|
||||
distributeDebug
|
||||
|
||||
checkbutton $lw.b1 -text [msgcat::mc "Invalid INI file entries"] -variable debug_invalid -relief flat
|
||||
checkbutton $lw.b2 -text [msgcat::mc "Configuration information"] -variable debug_config -relief flat
|
||||
checkbutton $lw.b3 -text [msgcat::mc "Use of defaults"] -variable debug_defaults -relief flat
|
||||
checkbutton $lw.b4 -text [msgcat::mc "Version information"] -variable debug_versions -relief flat
|
||||
checkbutton $lw.b5 -text [msgcat::mc "Command issuing"] -variable debug_task_issue -relief flat
|
||||
checkbutton $lw.b6 -text [msgcat::mc "IO points"] -variable debug_io_points -relief flat
|
||||
checkbutton $lw.b7 -text [msgcat::mc "NML"] -variable debug_nml -relief flat
|
||||
checkbutton $lw.b8 -text [msgcat::mc "Motion time"] -variable debug_motion_time -relief flat
|
||||
checkbutton $lw.b9 -text [msgcat::mc "Interpreter"] -variable debug_interp -relief flat
|
||||
checkbutton $lw.b10 -text [msgcat::mc "RCS"] -variable debug_rcs -relief flat
|
||||
checkbutton $lw.b11 -text [msgcat::mc "Trajectory level"] -variable debug_traj -relief flat
|
||||
checkbutton $lw.b12 -text [msgcat::mc "Interpreter list"] -variable debug_interp_list -relief flat
|
||||
|
||||
pack $lw.b1 $lw.b2 $lw.b3 $lw.b4 $lw.b5 $lw.b6 $lw.b7 $lw.b8 $lw.b9 $lw.b10 $lw.b11 $lw.b12 -side top -pady 2 -anchor w
|
||||
|
||||
frame $lw.buttons
|
||||
button $lw.buttons.ok -text [msgcat::mc "OK"] -default active -command "collectDebug; popdownDebug $w"
|
||||
button $lw.buttons.cancel -text [msgcat::mc "Cancel"] -command "popdownDebug $w"
|
||||
pack $lw.buttons -side bottom -fill x -pady 2m
|
||||
pack $lw.buttons.ok $lw.buttons.cancel -side left -expand 1
|
||||
bind $w <Return> "emc_debug [collectDebug] ; popdownDebug $w"
|
||||
}
|
||||
|
||||
# if we're not running inside tkemc, then pop us up in root window
|
||||
if {! [info exists tkemc]} {
|
||||
popupDebug .
|
||||
}
|
||||
105
tcl/bin/emctesting.tcl
Executable file
105
tcl/bin/emctesting.tcl
Executable file
@@ -0,0 +1,105 @@
|
||||
#!/bin/sh
|
||||
# the next line restarts using emcsh \
|
||||
exec $LINUXCNC_EMCSH "$0" "$@"
|
||||
|
||||
source [file join [file dirname [info script]] .. linuxcnc.tcl]
|
||||
|
||||
###############################################################
|
||||
# Description: emctesting.tcl
|
||||
# EMC performance testing program
|
||||
#
|
||||
# Derived from a work by Fred Proctor & Will Shackleford
|
||||
# License: GPL Version 2
|
||||
#
|
||||
# Copyright (c) 2005-2009 All rights reserved.
|
||||
###############################################################
|
||||
# emctesting.tcl
|
||||
# EMC performance testing program
|
||||
# Needs emcsh to run-- this is sourced by tkemc, but it can be run
|
||||
# standalone. Make sure directory containing emcsh is in your path,
|
||||
# or edit the exec line above with the path to emcsh.
|
||||
|
||||
eval emc_init $argv
|
||||
|
||||
# check if any emc commands exist, and quit if not
|
||||
if {! [string length [info commands emc_plat]]} {
|
||||
error "emctesting needs to run from \"emcsh\""
|
||||
}
|
||||
|
||||
if {! [info exists activeAxis]} {
|
||||
set activeAxis 0
|
||||
}
|
||||
|
||||
proc popdownTesting {w} {
|
||||
destroy $w
|
||||
if {$w == "."} {
|
||||
exit
|
||||
}
|
||||
}
|
||||
|
||||
proc popupTesting {{w .testingwindow}} {
|
||||
global axisentry outvolts ampenable
|
||||
global activeAxis
|
||||
|
||||
# trap "." as window name, and erase it, so that widgets
|
||||
# don't begin with two dots. We'll refer to the passed-in
|
||||
# name "w" here; in code following this setup we'll use the
|
||||
# modified name "lw"
|
||||
if {$w == "."} {
|
||||
set lw ""
|
||||
wm title $w "EMC Testing"
|
||||
} else {
|
||||
set lw $w
|
||||
if {[winfo exists $w]} {
|
||||
wm deiconify $w
|
||||
raise $w
|
||||
focus $w
|
||||
return
|
||||
}
|
||||
toplevel $w
|
||||
wm title $w "EMC Testing"
|
||||
}
|
||||
|
||||
# use "lw" as name of top level from now on
|
||||
|
||||
# force the selected axis to be the active axis
|
||||
set axisentry $activeAxis
|
||||
# force the button to reflect actual state
|
||||
set ampenable [emc_axis_enable $activeAxis]
|
||||
# force the volts to 0, a valid entry
|
||||
set outvolts 0.0
|
||||
|
||||
frame $lw.axis
|
||||
label $lw.axis.lab -text "Axis:" -width 20 -anchor w
|
||||
entry $lw.axis.ent -width 10 -textvariable axisentry
|
||||
pack $lw.axis -side top -fill x
|
||||
pack $lw.axis.lab -side left
|
||||
pack $lw.axis.ent -side left
|
||||
|
||||
frame $lw.outvolts
|
||||
label $lw.outvolts.lab -text "Output Voltage:" -width 20 -anchor w
|
||||
entry $lw.outvolts.ent -width 10 -textvariable outvolts
|
||||
pack $lw.outvolts -side top -fill x
|
||||
pack $lw.outvolts.lab -side left
|
||||
pack $lw.outvolts.ent -side left
|
||||
|
||||
frame $lw.amp
|
||||
checkbutton $lw.amp.chk -text "Amp Enable" -variable ampenable -relief flat
|
||||
pack $lw.amp -side top -fill x
|
||||
pack $lw.amp.chk -side left
|
||||
bind $lw.amp.chk <ButtonRelease-1> "emc_axis_enable \$axisentry \$ampenable"
|
||||
|
||||
frame $lw.buttons
|
||||
button $lw.buttons.set -text Set -command "emc_axis_set_output \$axisentry \$outvolts"
|
||||
button $lw.buttons.done -default active -text Done -command "popdownTesting $w"
|
||||
|
||||
pack $lw.buttons -side bottom -fill x -pady 2m
|
||||
pack $lw.buttons.set -side left -expand 1
|
||||
pack $lw.buttons.done -side left -expand 1
|
||||
bind $w <Return> "popdownTesting $w"
|
||||
}
|
||||
|
||||
# if we're not running inside tkemc, then pop us up in root window
|
||||
if {! [info exists tkemc]} {
|
||||
popupTesting .
|
||||
}
|
||||
225
tcl/bin/emctuning.tcl
Executable file
225
tcl/bin/emctuning.tcl
Executable file
@@ -0,0 +1,225 @@
|
||||
#!/bin/sh
|
||||
# the next line restarts using emcsh \
|
||||
exec $LINUXCNC_EMCSH "$0" "$@"
|
||||
|
||||
|
||||
# Load the linuxcnc.tcl file, which defines variables for various useful paths
|
||||
source [file join [file dirname [info script]] .. linuxcnc.tcl]
|
||||
eval emc_init $argv
|
||||
|
||||
###############################################################
|
||||
# Description: emctuning.tcl
|
||||
# EMC system identification and autotuning program
|
||||
#
|
||||
# Derived from a work by Fred Proctor & Will Shackleford
|
||||
# License: GPL Version 2
|
||||
#
|
||||
# Copyright (c) 2005-2009 All rights reserved.
|
||||
###############################################################
|
||||
# emctuning.tcl
|
||||
# EMC system identification and autotuning program
|
||||
# Needs emcsh to run-- this is sourced by tkemc, but it can be run
|
||||
# standalone. Make sure directory containing emcsh is in your path,
|
||||
# or edit the exec line above with the path to emcsh.
|
||||
|
||||
# check if any emc commands exist, and quit if not
|
||||
if {! [string length [info commands emc_plat]]} {
|
||||
error "emctuning needs to run from \"emcsh\""
|
||||
}
|
||||
|
||||
# set cycle time for updating, using tkemc's displayCycleTime if
|
||||
# present or our own if not
|
||||
if {! [info exists displayCycleTime]} {
|
||||
set displayCycleTime 100
|
||||
}
|
||||
|
||||
if {! [info exists activeAxis]} {
|
||||
set activeAxis 0
|
||||
}
|
||||
|
||||
proc goManual {} {
|
||||
emc_machine off
|
||||
emc_estop off
|
||||
emc_mode manual
|
||||
}
|
||||
|
||||
proc setVoltage {} {
|
||||
global stepvolts
|
||||
global activeAxis
|
||||
emc_axis_enable $activeAxis 1
|
||||
emc_axis_set_output $activeAxis $stepvolts
|
||||
}
|
||||
|
||||
proc logIt {} {
|
||||
global stepsize
|
||||
global activeAxis
|
||||
global stepfilename
|
||||
global stepssaved
|
||||
emc_log_open $stepfilename$stepssaved pos_voltage $stepsize 0 $activeAxis
|
||||
emc_wait done
|
||||
emc_log_start
|
||||
}
|
||||
|
||||
proc getStep {} {
|
||||
goManual
|
||||
logIt
|
||||
setVoltage
|
||||
}
|
||||
|
||||
proc saveStep {} {
|
||||
global stepssaved
|
||||
global filestring
|
||||
global stepfilename
|
||||
append filestring "$stepfilename$stepssaved "
|
||||
set stepssaved [expr $stepssaved + 1]
|
||||
emc_log_stop
|
||||
emc_log_close
|
||||
}
|
||||
|
||||
proc doTune {} {
|
||||
global filestring
|
||||
global pgain
|
||||
global igain
|
||||
global dgain
|
||||
global lambda
|
||||
set string "$filestring$lambda"
|
||||
scan [exec -- /usr/local/nist/emc/system $string] %s%s%s pgain igain dgain
|
||||
}
|
||||
|
||||
# close the tuning window
|
||||
proc popdownTuning {w} {
|
||||
destroy $w
|
||||
if {$w == "."} {
|
||||
exit
|
||||
}
|
||||
}
|
||||
|
||||
# pop up the tuning window
|
||||
proc popupTuning {{w .logwindow}} {
|
||||
global activeAxis
|
||||
global ampenable
|
||||
global stepvolts
|
||||
global stepsize
|
||||
global stepssaved
|
||||
global stepfilename
|
||||
global filestring
|
||||
global lambda
|
||||
global pgain
|
||||
global igain
|
||||
global dgain
|
||||
|
||||
set pgain 0
|
||||
set igain 0
|
||||
set dgain 0
|
||||
|
||||
set c .tuning
|
||||
set stepssaved 0
|
||||
set filestring ""
|
||||
|
||||
# trap "." as window name, and erase it, so that widgets
|
||||
# don't begin with two dots. We'll refer to the passed-in
|
||||
# name "w" here; in code following this setup we'll use the
|
||||
# modified name "lw"
|
||||
if {$w == "."} {
|
||||
set lw ""
|
||||
wm title $w "EMC Tuning"
|
||||
} else {
|
||||
set lw $w
|
||||
if {[winfo exists $w]} {
|
||||
wm deiconify $w
|
||||
raise $w
|
||||
focus $w
|
||||
return
|
||||
}
|
||||
toplevel $w
|
||||
wm title $w "EMC Tuning"
|
||||
}
|
||||
|
||||
# use "lw" as name of top level from now on
|
||||
|
||||
# force the button to reflect actual state
|
||||
set ampenable [emc_axis_enable $activeAxis]
|
||||
|
||||
label $lw.title -text "Tuning Axis $activeAxis" -width 30 -anchor center
|
||||
|
||||
frame $lw.outvolts
|
||||
label $lw.outvolts.lab -text "Step Voltage:" -anchor w
|
||||
entry $lw.outvolts.ent -width 10 -textvariable stepvolts
|
||||
|
||||
frame $lw.size
|
||||
label $lw.size.lab -text "Number of Samples:" -anchor w
|
||||
entry $lw.size.ent -width 10 -textvariable stepsize
|
||||
|
||||
frame $lw.name
|
||||
label $lw.name.lab -text "filename:" -anchor w
|
||||
entry $lw.name.ent -width 10 -textvariable stepfilename
|
||||
|
||||
frame $lw.stepssaved
|
||||
label $lw.stepssaved.lab -text "Number of steps:" -anchor w
|
||||
label $lw.stepssaved.value -width 2 -textvariable stepssaved
|
||||
|
||||
frame $lw.step
|
||||
button $lw.step.start -text "getStep" -command getStep
|
||||
button $lw.step.save -text "saveStep" -command saveStep
|
||||
button $lw.step.jogback -text "jogBack"
|
||||
bind $lw.step.jogback <ButtonPress-1> {jogNeg $activeAxis}
|
||||
bind $lw.step.jogback <ButtonRelease-1> {jogStop}
|
||||
frame $lw.lambda
|
||||
label $lw.lambda.lab -text "Lambda:" -anchor w
|
||||
entry $lw.lambda.ent -width 10 -textvariable lambda
|
||||
|
||||
button $lw.dotune -text "doTune" -command doTune
|
||||
|
||||
frame $lw.p
|
||||
frame $lw.i
|
||||
frame $lw.d
|
||||
|
||||
label $lw.p.desc -text "P gain"
|
||||
label $lw.i.desc -text "I gain"
|
||||
label $lw.d.desc -text "D gain"
|
||||
|
||||
label $lw.p.value -textvariable pgain
|
||||
label $lw.i.value -textvariable igain
|
||||
label $lw.d.value -textvariable dgain
|
||||
|
||||
button $lw.done -text "OK" -default active -command "popdownTuning $w"
|
||||
|
||||
pack $lw.title -side top -fill x
|
||||
pack $lw.outvolts -side top -fill x
|
||||
pack $lw.outvolts.lab -side left
|
||||
pack $lw.outvolts.ent -side right
|
||||
pack $lw.size -side top -fill x
|
||||
pack $lw.size.lab -side left
|
||||
pack $lw.size.ent -side right
|
||||
pack $lw.name -side top -fill x
|
||||
pack $lw.name.lab -side left
|
||||
pack $lw.name.ent -side right
|
||||
pack $lw.stepssaved -side top -fill x
|
||||
pack $lw.stepssaved.lab -side left
|
||||
pack $lw.stepssaved.value -side left
|
||||
pack $lw.step -side top -fill x
|
||||
pack $lw.step.start -side left
|
||||
pack $lw.step.save -side left
|
||||
pack $lw.step.jogback -side left
|
||||
pack $lw.lambda -side top -fill x
|
||||
pack $lw.lambda.lab -side left
|
||||
pack $lw.lambda.ent -side right
|
||||
pack $lw.dotune -side top
|
||||
pack $lw.p -side top -fill x
|
||||
pack $lw.p.desc -side left
|
||||
pack $lw.p.value -side left
|
||||
pack $lw.i -side top -fill x
|
||||
pack $lw.i.desc -side left
|
||||
pack $lw.i.value -side left
|
||||
pack $lw.d -side top -fill x
|
||||
pack $lw.d.desc -side left
|
||||
pack $lw.d.value -side left
|
||||
pack $lw.done -side top
|
||||
|
||||
bind $w <Return> "popdownTuning $w"
|
||||
}
|
||||
|
||||
# if we're not running inside tkemc, then pop us up in root window
|
||||
if {! [info exists tkemc]} {
|
||||
popupTuning .
|
||||
}
|
||||
522
tcl/bin/genedit.tcl
Executable file
522
tcl/bin/genedit.tcl
Executable file
@@ -0,0 +1,522 @@
|
||||
#!/bin/sh
|
||||
# the next line restarts using wish \
|
||||
exec wish "$0" "$@"
|
||||
|
||||
###############################################################
|
||||
# Description: genedit.tcl
|
||||
# This is a simple TK text editor.
|
||||
#
|
||||
# Derived from a work by Fred Proctor & Will Shackleford
|
||||
# License: GPL Version 2
|
||||
#
|
||||
# Copyright (c) 2005-2009 All rights reserved.
|
||||
###############################################################
|
||||
# genedit.tcl
|
||||
#
|
||||
# geneditStart <name> ?<initial file>? ?<browser types>? runs an editor
|
||||
# named <name>. Optional parameters are the <initial file> to open,
|
||||
# default "untitled.txt", and the <browser types>, default
|
||||
# {{"All files" *} {Text files} {.txt}}
|
||||
#
|
||||
# geneditStart creates a top-level window named ".<name>", so if you call
|
||||
# "geneditStart myeditor", you'll have ".myeditor" as a top-level window.
|
||||
# You can have as many as you want. Sub-widgets include:
|
||||
# .<name>.textframe.textwin
|
||||
# .<name>.textframe.scrolly
|
||||
# .<name>.menubar.file
|
||||
# .<name>.menubar.edit
|
||||
# .<name>.menubar.help
|
||||
#
|
||||
# You can pack additional widgets in .<name>, and access the widgets above
|
||||
# by name to extract things like the insertion point, selected text, etc.
|
||||
# Mods to fix copy, paste, delete add find and line number by rh 12/1999
|
||||
# Mods to add line numbering and find and replace by rh 12/1999.
|
||||
# Mod for a script menu that looks for *.ncw files in $linuxcnc::TCL_SCRIPT_DIR directory.
|
||||
###############################################################
|
||||
|
||||
# Load the linuxcnc.tcl file, which defines variables for various useful paths
|
||||
source [file join [file dirname [info script]] .. linuxcnc.tcl]
|
||||
|
||||
proc geneditStart {name {ifilename "untitled.txt"} {itypes { {"All files" *} {"Text files" {.txt} }}}} {
|
||||
|
||||
global geneditFilename geneditTypes textwin TCLSCRIPTS
|
||||
|
||||
if {[winfo exists .$name]} {
|
||||
wm deiconify .$name
|
||||
raise .$name
|
||||
focus .$name
|
||||
return
|
||||
}
|
||||
|
||||
set ed .$name
|
||||
toplevel $ed
|
||||
|
||||
# initialize filename and browser types
|
||||
set geneditFilename($name) $ifilename
|
||||
set geneditTypes($name) $itypes
|
||||
|
||||
wm title $ed [set geneditFilename($name)]
|
||||
|
||||
set textframe $ed.textframe
|
||||
frame $textframe
|
||||
set textwin $textframe.textwin
|
||||
# rh replaced -setgrid true with padx 4 for easier left margin read.
|
||||
text $textwin -width 80 -height 24 -padx 4 -wrap word -yscrollcommand \
|
||||
"geneditScrolltext $textframe"
|
||||
set scrolly $textframe.scrolly
|
||||
scrollbar $scrolly -orient vert -command "$textwin yview"
|
||||
pack $scrolly -side right -fill y
|
||||
pack $textwin -side top -fill both -expand true
|
||||
pack $textframe -side top
|
||||
|
||||
set menubar $ed.menubar
|
||||
menu $menubar -tearoff 0
|
||||
|
||||
set filemenu $menubar.file
|
||||
menu $filemenu -tearoff 0
|
||||
$menubar add cascade -label [msgcat::mc "File"] -menu $filemenu -underline 0
|
||||
$filemenu add command -label [msgcat::mc "New"] -underline 0 \
|
||||
-command "geneditNewFile $name" -accelerator "Ctrl+N"
|
||||
$filemenu add command -label [msgcat::mc "Open..."] -underline 0 \
|
||||
-command "geneditOpenFile $name" -accelerator "Ctrl+O"
|
||||
$filemenu add command -label [msgcat::mc "Save"] -underline 0 \
|
||||
-command "geneditSaveFile $name" -accelerator "Ctrl+S"
|
||||
$filemenu add command -label [msgcat::mc "Save As..."] -underline 5 \
|
||||
-command "geneditSaveFileAs $name"
|
||||
$filemenu add separator
|
||||
$filemenu add command -label [msgcat::mc "Exit"] -command "destroy $ed" -underline 1
|
||||
|
||||
set editmenu $menubar.edit
|
||||
menu $editmenu -tearoff 0
|
||||
$menubar add cascade -label [msgcat::mc "Edit"] -menu $editmenu -underline 0
|
||||
$editmenu add command -label [msgcat::mc "Cut"] -underline 2 \
|
||||
-command "geneditCutIt $textwin" -accelerator "Ctrl+X"
|
||||
$editmenu add command -label [msgcat::mc "Copy"] -underline 0 \
|
||||
-command "geneditCopyIt $textwin" -accelerator "Ctrl+C"
|
||||
$editmenu add command -label [msgcat::mc "Paste"] -underline 0 \
|
||||
-command "geneditPasteIt $textwin" -accelerator "Ctrl+V"
|
||||
$editmenu add separator
|
||||
$editmenu add command -label [msgcat::mc "Select All"] -underline 7 \
|
||||
-command "focus $textwin; geneditSelectAll $textwin" -accelerator "Ctrl+A"
|
||||
|
||||
set helpmenu $menubar.help
|
||||
menu $helpmenu -tearoff 0
|
||||
$menubar add cascade -label [msgcat::mc "Help"] -menu $helpmenu -underline 0
|
||||
$helpmenu add command -label [msgcat::mc "About..."] -underline 0 \
|
||||
-command "geneditShowAbout $name"
|
||||
|
||||
$ed configure -menu $menubar
|
||||
|
||||
bind $ed <Control-n> "geneditNewFile $name; break"
|
||||
bind $ed <Control-o> "geneditOpenFile $name; break"
|
||||
bind $ed <Control-s> "geneditSaveFile $name; break"
|
||||
bind $ed <Control-h> "geneditShowAbout $name; break"
|
||||
|
||||
bind $textwin <Control-c> "geneditCopyIt $textwin; break"
|
||||
bind $textwin <Control-v> "geneditPasteIt $textwin; break"
|
||||
bind $textwin <Control-x> "geneditCutIt $textwin; break"
|
||||
bind $textwin <Control-a> "geneditSelectAll $textwin; break"
|
||||
|
||||
# insert contents of filename, if it exists
|
||||
if {! [catch {open $geneditFilename($name)} filein]} {
|
||||
$ed.textframe.textwin delete 1.0 end
|
||||
$ed.textframe.textwin insert end [read $filein]
|
||||
catch {close $filein}
|
||||
}
|
||||
|
||||
# Extra menu items for program editor
|
||||
if {$name == "programEditor"} {
|
||||
$filemenu add separator
|
||||
$filemenu add command -label [msgcat::mc "Save and Reload"] -command "geneditSaveFile $name; loadProgramText" -underline 1
|
||||
|
||||
$editmenu add separator
|
||||
$editmenu add command -label [msgcat::mc "Find..."] -underline 0 \
|
||||
-command "geneditEnterText $textwin"
|
||||
$editmenu add command -label [msgcat::mc "Renumber File..."] -underline 0 \
|
||||
-command "geneditNumber"
|
||||
|
||||
set settingsmenu $menubar.settings
|
||||
menu $settingsmenu -tearoff 0
|
||||
$menubar add cascade -label [msgcat::mc "Settings"] -menu $settingsmenu -underline 0
|
||||
$settingsmenu add command -label [msgcat::mc "No Numbering"] -underline 0 \
|
||||
-command "set startnumbering 0"
|
||||
$settingsmenu add separator
|
||||
$settingsmenu add command -label [msgcat::mc "Line Numbering..."] -underline 0 \
|
||||
-command "geneditSetLineNumber"
|
||||
|
||||
# adds a script menu that looks for *.ncw files and adds their filename to script menu
|
||||
set scriptmenu $menubar.script
|
||||
menu $scriptmenu
|
||||
$menubar add cascade -label [msgcat::mc "Scripts"] -menu $scriptmenu -underline 1
|
||||
#replaced scriptdir
|
||||
#set scriptdir tcl/scripts
|
||||
set files [exec /bin/ls $linuxcnc::TCL_SCRIPT_DIR]
|
||||
foreach file $files {
|
||||
if {[string match *.ncw $file]} {
|
||||
set geneditfname [file rootname $file]
|
||||
$scriptmenu add command -label $geneditfname -command "source $linuxcnc::TCL_SCRIPT_DIR/$file"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc geneditScrolltext {tf a b} {
|
||||
$tf.scrolly set $a $b
|
||||
}
|
||||
|
||||
proc geneditShowAbout {name} {
|
||||
set ed .$name
|
||||
|
||||
if {[winfo exists $ed.about]} {
|
||||
wm deiconify $ed.about
|
||||
raise $ed.about
|
||||
focus $ed.about
|
||||
return
|
||||
}
|
||||
toplevel $ed.about
|
||||
wm title $ed.about [msgcat::mc "About TkEditor"]
|
||||
message $ed.about.msg -aspect 1000 -justify center -font {Helvetica 12 bold} \
|
||||
-text [msgcat::mc "TkEditor\n\nSimple Tcl/Tk Text Editor\n\nGPL Version 2"]
|
||||
button $ed.about.ok -text [msgcat::mc "OK"] -command "destroy $ed.about"
|
||||
pack $ed.about.msg $ed.about.ok -side top
|
||||
bind $ed.about <Return> "destroy $ed.about"
|
||||
}
|
||||
|
||||
proc geneditOpenFile {name} {
|
||||
global geneditFilename geneditTypes programEntry
|
||||
set ed .$name
|
||||
set fname [tk_getOpenFile -initialdir [file dirname $geneditFilename($name)] -filetypes $geneditTypes($name)]
|
||||
set geneditFileDirectory [file dirname $fname]
|
||||
set geneditFilename($name) [file dirname $fname]
|
||||
if {[string length $fname] == 0} {
|
||||
return
|
||||
}
|
||||
|
||||
$ed.textframe.textwin delete 1.0 end
|
||||
if {[catch {open $fname} filein]} {
|
||||
puts stdout [msgcat::mc "can't open %s" $fname]
|
||||
} else {
|
||||
$ed.textframe.textwin insert end [read $filein]
|
||||
catch {close $filein}
|
||||
set geneditFilename($name) $fname
|
||||
wm title $ed [set geneditFilename($name)]
|
||||
}
|
||||
}
|
||||
|
||||
proc geneditSaveFile {name} {
|
||||
global geneditFilename
|
||||
set ed .$name
|
||||
catch {file copy -force $geneditFilename($name) $geneditFilename($name).bak}
|
||||
if {[catch {open $geneditFilename($name) w} fileout]} {
|
||||
puts stdout [msgcat::mc "can't save %s" $geneditFilename($name)]
|
||||
return
|
||||
}
|
||||
puts $fileout [$ed.textframe.textwin get 1.0 end]
|
||||
catch {close $fileout}
|
||||
}
|
||||
|
||||
proc geneditNewFile {name} {
|
||||
set ed .$name
|
||||
if {[string length [geneditSaveFileAs $name]]} {
|
||||
$ed.textframe.textwin delete 1.0 end
|
||||
}
|
||||
}
|
||||
|
||||
proc geneditSaveFileAs {name} {
|
||||
global geneditFilename geneditTypes
|
||||
set ed .$name
|
||||
set fname [tk_getSaveFile -filetypes $geneditTypes($name) \
|
||||
-initialfile $geneditFilename($name)]
|
||||
if {[string length $fname] == 0} {
|
||||
return
|
||||
}
|
||||
set geneditFilename($name) $fname
|
||||
wm title $ed [set geneditFilename($name)]
|
||||
geneditSaveFile $name
|
||||
return $fname
|
||||
}
|
||||
|
||||
proc geneditCutIt {w} {
|
||||
global selecttext
|
||||
set selecttext [selection get STRING]
|
||||
$w delete "insert - [string length $selecttext] chars" insert
|
||||
}
|
||||
|
||||
proc geneditCopyIt {w} {
|
||||
global selecttext
|
||||
set selecttext [selection get STRING]
|
||||
# should drop text tags here
|
||||
# should disable copy until a paste
|
||||
}
|
||||
|
||||
proc geneditPasteIt {w} {
|
||||
global selecttext
|
||||
$w insert insert $selecttext
|
||||
# should set copy menubutton to normal here
|
||||
}
|
||||
|
||||
proc geneditSelectAll {w} {
|
||||
event generate $w <Control-slash>
|
||||
}
|
||||
|
||||
# Find text processes - geneditEnterText includes hard location from top right.
|
||||
proc geneditEnterText {ed} {
|
||||
global textwin
|
||||
toplevel $ed.find
|
||||
grab $ed.find
|
||||
wm title $ed.find [msgcat::mc "Find"]
|
||||
wm geometry $ed.find 325x150-50+100
|
||||
|
||||
label $ed.find.label1 -text [msgcat::mc "Find:"] -anchor e
|
||||
place $ed.find.label1 -x 5 -y 5 -width 80 -height 20
|
||||
|
||||
entry $ed.find.entry1 -relief sunken -textvariable sword
|
||||
place $ed.find.entry1 -x 90 -y 5 -width 110 -height 20
|
||||
|
||||
label $ed.find.label2 -text [msgcat::mc "Replace:"] -anchor e
|
||||
place $ed.find.label2 -x 5 -y 30 -width 80 -height 20
|
||||
|
||||
entry $ed.find.entry2 -relief sunken -textvariable rword
|
||||
place $ed.find.entry2 -x 90 -y 30 -width 110 -height 20
|
||||
|
||||
button $ed.find.button1 -text [msgcat::mc "Find All"] -command {geneditFindAll $sword}
|
||||
place $ed.find.button1 -x 5 -y 70 -width 150 -height 30
|
||||
|
||||
button $ed.find.button2 -text [msgcat::mc "Replace All"] -command {geneditReplaceAll $sword $rword}
|
||||
place $ed.find.button2 -x 5 -y 110 -width 150 -height 30
|
||||
|
||||
button $ed.find.button3 -text [msgcat::mc "Skip This"] -command {geneditSkipWord $sword}
|
||||
place $ed.find.button3 -x 170 -y 70 -width 150 -height 30
|
||||
|
||||
button $ed.find.button4 -text [msgcat::mc "Replace This"] -command {geneditReplaceWord $sword $rword}
|
||||
place $ed.find.button4 -x 170 -y 110 -width 150 -height 30
|
||||
|
||||
button $ed.find.button5 -text [msgcat::mc "Cancel"] -command "focus -force $textwin; destroy $ed.find"
|
||||
place $ed.find.button5 -x 220 -y 5 -width 100 -height 30
|
||||
|
||||
button $ed.find.button6 -text [msgcat::mc "Clear"] -command {
|
||||
$textwin tag delete $sword
|
||||
$textwin tag delete q
|
||||
}
|
||||
place $ed.find.button6 -x 220 -y 35 -width 100 -height 30
|
||||
|
||||
# set focus to entry widget 1
|
||||
focus $ed.find.entry1
|
||||
|
||||
}
|
||||
|
||||
proc geneditFindAll {sword} {
|
||||
global textwin
|
||||
set firstplace 1.0
|
||||
set l1 [string length $sword]
|
||||
scan [$textwin index end] %d nl
|
||||
set thisplace [$textwin index insert]
|
||||
for {set i 1} {$i < $nl} {incr i} {
|
||||
$textwin mark set last $i.end
|
||||
set lastplace [$textwin index last]
|
||||
set thisplace [$textwin search -forwards -nocase $sword $thisplace $lastplace]
|
||||
if {$thisplace != ""} {
|
||||
$textwin mark set insert $thisplace
|
||||
scan [$textwin index "insert + $l1 chars"] %f lastplace
|
||||
$textwin tag add $sword $thisplace $lastplace
|
||||
$textwin tag configure $sword -background lightblue
|
||||
$textwin mark set insert "insert + $l1 chars"
|
||||
set thisplace $lastplace
|
||||
} else {
|
||||
set thisplace $lastplace
|
||||
}
|
||||
}
|
||||
$textwin mark set insert 1.0
|
||||
geneditNextWord $sword
|
||||
}
|
||||
|
||||
proc geneditNextWord {sword} {
|
||||
global textwin
|
||||
set findnext [$textwin tag nextrange $sword insert]
|
||||
if {$findnext == ""} {
|
||||
$textwin mark set insert 1.0
|
||||
$textwin see insert
|
||||
return
|
||||
}
|
||||
set start [lindex $findnext 0]
|
||||
set last [lindex $findnext end]
|
||||
catch {$textwin mark set insert $start}
|
||||
$textwin tag add q $start $last
|
||||
$textwin tag raise q
|
||||
$textwin tag configure q -background darkred -foreground white
|
||||
$textwin see "insert + 5 lines"
|
||||
}
|
||||
|
||||
proc geneditSkipWord {sword} {
|
||||
global textwin
|
||||
set l1 [string length $sword]
|
||||
$textwin tag remove q insert "insert + $l1 chars"
|
||||
$textwin tag remove $sword insert "insert + $l1 chars"
|
||||
geneditNextWord $sword
|
||||
}
|
||||
|
||||
proc geneditReplaceWord {sword rword} {
|
||||
global textwin
|
||||
set l1 [string length $sword]
|
||||
set l2 [string length $rword]
|
||||
$textwin tag remove q insert "insert + $l1 chars"
|
||||
$textwin tag remove $sword insert "insert + $l1 chars"
|
||||
$textwin delete insert "insert + $l1 chars"
|
||||
$textwin insert insert $rword
|
||||
$textwin mark set insert "insert + $l2 chars"
|
||||
geneditNextWord $sword
|
||||
}
|
||||
|
||||
proc geneditReplaceAll {sword rword} {
|
||||
global textwin
|
||||
set l1 [string length $sword]
|
||||
set l2 [string length $rword]
|
||||
scan [$textwin index end] %d nl
|
||||
set thisplace [$textwin index 1.0]
|
||||
for {set i 1} {$i < $nl} {incr i} {
|
||||
$textwin mark set last $i.end
|
||||
set lastplace [$textwin index last]
|
||||
set thisplace [$textwin search -forwards -nocase $sword $thisplace $lastplace]
|
||||
if {$thisplace != ""} {
|
||||
$textwin mark set insert $thisplace
|
||||
$textwin delete insert "insert + $l1 chars"
|
||||
$textwin insert insert $rword
|
||||
$textwin mark set insert "insert + $l2 chars"
|
||||
set thisplace [$textwin index insert]
|
||||
} else {
|
||||
set thisplace $lastplace
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# These are three variables used by the line numbering routine.
|
||||
# They can be changed for a run by using the settings menu.
|
||||
# If you want to set a default value different from what comes up change these here.
|
||||
|
||||
# Any positive integer can be used for lineincrement.
|
||||
# Values of 1,2,5,10 show and can be accessed from settings menu radiobuttons.
|
||||
# A 0 startnumbering value means lines will not be numbered when enter is pressed.
|
||||
set startnumbering 0
|
||||
|
||||
# Space refers to the distance between n words and other text. Tab space is set
|
||||
# here but could be single or double space. Change what's between the "".
|
||||
set space " "
|
||||
|
||||
# Number refers to the start up value of line numbering.
|
||||
set number 0
|
||||
set lineincrement 10
|
||||
|
||||
proc geneditLineIncrement {} {
|
||||
global startnumbering number lineincrement space textwin
|
||||
if {$startnumbering != 0} {
|
||||
$textwin insert insert "n$number$space"
|
||||
incr number $lineincrement
|
||||
}
|
||||
}
|
||||
|
||||
# geneditSetLineNumber also uses a hard coded popup location from top right.
|
||||
proc geneditSetLineNumber {} {
|
||||
global startnumbering number lineincrement textwin
|
||||
toplevel $textwin.linenumber
|
||||
wm title $textwin.linenumber [msgcat::mc "Set Line Numbering"]
|
||||
wm geometry $textwin.linenumber 280x160-50+100
|
||||
label $textwin.linenumber.label1 -text [msgcat::mc "Increment"]
|
||||
place $textwin.linenumber.label1 -x 5 -y 5
|
||||
radiobutton $textwin.linenumber.incr1 -text [msgcat::mc "One"] \
|
||||
-variable lineincrement -value 1 -anchor w
|
||||
place $textwin.linenumber.incr1 -x 10 -y 25 -width 80 -height 20
|
||||
radiobutton $textwin.linenumber.incr2 -text [msgcat::mc "Two"] \
|
||||
-variable lineincrement -value 2 -anchor w
|
||||
place $textwin.linenumber.incr2 -x 10 -y 45 -width 80 -height 20
|
||||
radiobutton $textwin.linenumber.incr5 -text [msgcat::mc "Five"] \
|
||||
-variable lineincrement -value 5 -anchor w
|
||||
place $textwin.linenumber.incr5 -x 10 -y 65 -width 80 -height 20
|
||||
radiobutton $textwin.linenumber.incr10 -text [msgcat::mc "Ten"] \
|
||||
-variable lineincrement -value 10 -anchor w
|
||||
place $textwin.linenumber.incr10 -x 10 -y 85 -width 80 -height 20
|
||||
|
||||
label $textwin.linenumber.label2 -text [msgcat::mc "Space"]
|
||||
place $textwin.linenumber.label2 -x 130 -y 5
|
||||
radiobutton $textwin.linenumber.space1 -text [msgcat::mc "Single Space"] \
|
||||
-variable space -value { } -anchor w
|
||||
place $textwin.linenumber.space1 -x 140 -y 25
|
||||
radiobutton $textwin.linenumber.space2 -text [msgcat::mc "Double Space"] \
|
||||
-variable space -value { } -anchor w
|
||||
place $textwin.linenumber.space2 -x 140 -y 45
|
||||
radiobutton $textwin.linenumber.space3 -text [msgcat::mc "Tab Space"] \
|
||||
-variable space -value { } -anchor w
|
||||
place $textwin.linenumber.space3 -x 140 -y 65
|
||||
button $textwin.linenumber.ok -text [msgcat::mc "OK"] -command "destroy $textwin.linenumber" \
|
||||
-height 1 -width 9
|
||||
place $textwin.linenumber.ok -x 180 -y 127
|
||||
label $textwin.linenumber.label3 -text [msgcat::mc "Next Number:"] -anchor e
|
||||
place $textwin.linenumber.label3 -x 5 -y 130 -width 95
|
||||
entry $textwin.linenumber.entry -width 6 -textvariable number
|
||||
place $textwin.linenumber.entry -x 100 -y 130
|
||||
|
||||
tkwait visibility $textwin.linenumber
|
||||
grab $textwin.linenumber
|
||||
focus -force $textwin.linenumber.entry
|
||||
set temp [expr $number - $lineincrement]
|
||||
if {$temp > 0} {
|
||||
set number $temp
|
||||
} else {
|
||||
set number 0
|
||||
}
|
||||
set startnumbering 1
|
||||
bind $textwin <KeyRelease-Return> {geneditLineIncrement}
|
||||
}
|
||||
|
||||
proc geneditNumber {} {
|
||||
global textwin
|
||||
geneditSetLineNumber
|
||||
button $textwin.linenumber.renumber -text [msgcat::mc "Renumber"] -command geneditReNumber \
|
||||
-height 1 -width 9
|
||||
place $textwin.linenumber.renumber -x 160 -y 96
|
||||
}
|
||||
|
||||
|
||||
# String match with a while loop [0-9 tab space] 1 if true 0 if no match
|
||||
proc geneditReNumber {} {
|
||||
global textwin number lineincrement space
|
||||
scan [$textwin index end] %d nl
|
||||
for {set i 1} {$i < $nl} {incr i} {
|
||||
if {$number > 99999} {set number 0}
|
||||
$textwin insert $i.0 n$number$space
|
||||
set l1 [string length n$number$space]
|
||||
$textwin mark set insert "$i.$l1"
|
||||
set character [$textwin get insert]
|
||||
if {$character == "/"} {
|
||||
$textwin insert $i.0 "/"
|
||||
$textwin delete insert
|
||||
}
|
||||
set character [$textwin get insert]
|
||||
if {$character == "n" || $character == "N"} {
|
||||
set firstplace [$textwin index insert]
|
||||
|
||||
# find the last number in the n word
|
||||
$textwin mark set insert "insert + 1 chars"
|
||||
set character [$textwin get insert]
|
||||
while {[string match {[0-9]} $character] == 1} {
|
||||
$textwin mark set insert "insert + 1 chars"
|
||||
set character [$textwin get insert]
|
||||
}
|
||||
|
||||
# find the first character of the next word using space and tab
|
||||
while {$character == " " || $character == " "} {
|
||||
$textwin mark set insert "insert + 1 chars"
|
||||
set character [$textwin get insert]
|
||||
}
|
||||
$textwin delete "$firstplace" "insert"
|
||||
}
|
||||
incr number $lineincrement
|
||||
}
|
||||
set startnumbering 0
|
||||
}
|
||||
|
||||
# if we're not running inside tkemc, then pop us up in root window
|
||||
if {! [info exists tkemc]} {
|
||||
geneditStart genEditor
|
||||
}
|
||||
|
||||
1284
tcl/bin/halconfig.tcl
Executable file
1284
tcl/bin/halconfig.tcl
Executable file
File diff suppressed because it is too large
Load Diff
1513
tcl/bin/halshow.tcl
Executable file
1513
tcl/bin/halshow.tcl
Executable file
File diff suppressed because it is too large
Load Diff
943
tcl/bin/pickconfig.tcl
Executable file
943
tcl/bin/pickconfig.tcl
Executable file
@@ -0,0 +1,943 @@
|
||||
#!/bin/sh
|
||||
# this line restarts using wish \
|
||||
exec wish "$0" "$@"
|
||||
|
||||
###############################################################
|
||||
# Description: pickconfig.tcl
|
||||
# This file validates a LinuxCNC configuration
|
||||
# passed to it, or prompts the user to choose
|
||||
# one.
|
||||
#
|
||||
# Author: John Kasunich
|
||||
# License: GPL Version 2
|
||||
#
|
||||
# Copyright (c) 2005-2009 All rights reserved.
|
||||
###############################################################
|
||||
#
|
||||
# usage:
|
||||
# pickconfig <config-path>
|
||||
#
|
||||
# <config-path> is one or more directories (separated with
|
||||
# colons) in which pickconfig should search for configs.
|
||||
# pickconfig will open a GUI window displaying all configs
|
||||
# that it finds and ask the user to choose one, then print
|
||||
# the path to the chosen config and exit.
|
||||
#
|
||||
###############################################################
|
||||
|
||||
# Load the linuxcnc.tcl file, which defines variables for various useful paths
|
||||
source [file join [file dirname [info script]] .. linuxcnc.tcl]
|
||||
|
||||
set logo [linuxcnc::image_search linuxcnc-wizard]
|
||||
image create photo machinelogo
|
||||
|
||||
option add *font [linuxcnc::standard_font]
|
||||
option add *Text.font [linuxcnc::standard_fixed_font]
|
||||
option add *Entry*background white
|
||||
option add *Listbox*background white
|
||||
option add *Tree*background white
|
||||
|
||||
|
||||
################### MAINTENANCE ITEMS #####################
|
||||
|
||||
# flat structure:
|
||||
# Ini files should always refer to ../../nc_files so
|
||||
# that hey will work in run-in-place and deb-installed
|
||||
# systems.
|
||||
# Config subdirs can be moved with little impact when
|
||||
# ../../nc_files relative link is used.
|
||||
#
|
||||
# hierarchical structure:
|
||||
# Ini files must refer to appropriate nc_files by
|
||||
# relative links so that they will work in run-in-place
|
||||
# and deb-installed systems.
|
||||
# Ini files must be edited if config subdirs are moved to
|
||||
# a different depth in the tree to update the relative
|
||||
# links
|
||||
#
|
||||
set ::make_flat_user_dirs 1 ;# 0 ==> hierarchical
|
||||
|
||||
# start on this node if no ~/.linuxcncrc:
|
||||
set ::default_start_node sim/axis/axis.ini
|
||||
|
||||
# exclude directories that should never be offered
|
||||
set ::exclude_list [list common]
|
||||
|
||||
# exclude files with special names
|
||||
set ::exclude_file_list _panelui.ini
|
||||
|
||||
# support filenames that are never copied to user:
|
||||
set ::never_copy_list [list maintainer.txt nodemocopy]
|
||||
|
||||
# emphasize sim ini configs that have the most support by reordering
|
||||
# reorder: priority low to high:
|
||||
set ::preferred_names [list \
|
||||
low_graphics \
|
||||
gmoccapy \
|
||||
gscreen \
|
||||
touchy \
|
||||
ngcgui \
|
||||
axis \
|
||||
by_machine \
|
||||
by_interface \
|
||||
sim \
|
||||
]
|
||||
|
||||
# support creation of links for newly added _lib dirs in nc_files
|
||||
set ::always_update_nc_files 1
|
||||
|
||||
################### PROCEDURE DEFINITIONS #####################
|
||||
|
||||
set desktopdir [exec bash -c {test -f ${XDG_CONFIG_HOME:-~/.config}/user-dirs.dirs && . ${XDG_CONFIG_HOME:-~/.config}/user-dirs.dirs; echo ${XDG_DESKTOP_DIR:-$HOME/Desktop}}]
|
||||
|
||||
# use initialize_config for bwidget and .linuxcncrc
|
||||
proc initialize_config {} {
|
||||
# need bwidget
|
||||
set result [catch {package require BWidget 1.7}]
|
||||
if {$result != 0} {
|
||||
puts stderr $result
|
||||
tk_messageBox -icon error -type ok -message [msgcat::mc "Can't find the bwidget 1.7 package. There is a debian bwidget package; install \nit with sudo apt-get install bwidget."]
|
||||
exit
|
||||
destroy .
|
||||
} else {
|
||||
if {[catch {open $::env(HOME)/.linuxcncrc} programin]} {
|
||||
return
|
||||
} else {
|
||||
set rcstring [read $programin]
|
||||
catch {close $programin}
|
||||
set ret [getVal $rcstring PICKCONFIG LAST_CONFIG ]
|
||||
set ::openmode 1
|
||||
return $ret
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# FIXME add trap for comment on the first of a line.
|
||||
proc getVal {stringa sect var} {
|
||||
set varval ""
|
||||
set x [regexp -indices -- "$sect.*$var *= *" $stringa indexes]
|
||||
if {$x } {
|
||||
set startindex [lindex $indexes 1]
|
||||
set x [regexp -start $startindex -linestop -- ".*" \
|
||||
$stringa varval ]
|
||||
set varval [string trim $varval]
|
||||
}
|
||||
return $varval
|
||||
}
|
||||
|
||||
proc setVal {stringb sect var newval} {
|
||||
set x [regexp -indices -- "$sect.*$var *= *" $stringb start ]
|
||||
if {$x } {
|
||||
set startindex [expr [lindex $start 1] +1]
|
||||
set x [regexp -indices -start $startindex -linestop -- ".*" $stringb end ]
|
||||
set endindex [lindex $end 1]
|
||||
set newstring [string replace $stringb $startindex $endindex $newval]
|
||||
return $newstring
|
||||
}
|
||||
}
|
||||
|
||||
# main button callback, it assigns the button name to '::choice'
|
||||
|
||||
proc button_pushed { button_name } {
|
||||
|
||||
set ::choice $button_name
|
||||
}
|
||||
|
||||
# slider process is used for several widgets
|
||||
proc sSlide {f a b} {
|
||||
$f.sc set $a $b
|
||||
}
|
||||
|
||||
proc title {node} {
|
||||
if [file isfile $node] {
|
||||
set txt "CURRENT: [file tail $::selected_node]"
|
||||
} else {
|
||||
set txt ""
|
||||
}
|
||||
wm title . "[msgcat::mc "LinuxCNC Configuration Selector"] $txt"
|
||||
}
|
||||
|
||||
proc find_usable_nodes {startdir} {
|
||||
return [exec find -L $startdir -type f \
|
||||
-name "*.ini" -o -name "*.demo" ]
|
||||
} ;# find_usable_nodes
|
||||
|
||||
proc name_is_usable_nodename {node} {
|
||||
if { [ regexp {.*\.ini$} $node ] == 1 \
|
||||
|| [ regexp {.*\.demo$} $node ] == 1 \
|
||||
} {
|
||||
if {[lsearch $::exclude_file_list [file tail $node]] >= 0} {
|
||||
return 0
|
||||
}
|
||||
return 1 ;# ok
|
||||
}
|
||||
return 0 ;# fail
|
||||
} ;# name_is_usable_nodename {node}
|
||||
|
||||
proc ok_to_copy_config {filename} {
|
||||
# The following tests determines when to copy files to a user directory:
|
||||
# 1) If the directory for the selected file is not writable,
|
||||
# then it is presumed to be a system dir running from an install (by
|
||||
# a deb install typically) so copy the configuration to user directory.
|
||||
#
|
||||
# 2) For non-RIP builds, if the file is not under the user's
|
||||
# myconfigs_node, force copy regardless of filesystem writability.
|
||||
# This catches distros where installed sample-configs happen to be
|
||||
# writable by the running user (e.g. Gentoo system-wide installs to
|
||||
# a group-writable path).
|
||||
#
|
||||
# 3) if the directory is included in ::user_aux_dirs (as
|
||||
# specified by the environmental variable LINUXCNC_AUX_EXAMPLES),
|
||||
# then the config is copied to user directory to avoid overwriting
|
||||
# a developmental source directory.
|
||||
#
|
||||
# Otherwise, it is presumed to be a Run-In-Place directory and
|
||||
# copying to another directory is not wanted.
|
||||
#
|
||||
# For convenience in testing pickconfig by itself in rip builds:
|
||||
# export debug_pickconfig=1
|
||||
# This forces copying to the user directory so that the copied
|
||||
# configs can be tested.
|
||||
|
||||
set forcecopy 0
|
||||
if { [info exists ::env(debug_pickconfig)] \
|
||||
&& [string first $::myconfigs_node $filename]} {
|
||||
set forcecopy 1
|
||||
}
|
||||
|
||||
set is_rip [expr {[info exists ::linuxcnc::RUN_IN_PLACE]
|
||||
&& $::linuxcnc::RUN_IN_PLACE eq "yes"}]
|
||||
if {!$is_rip && [string first $::myconfigs_node $filename] != 0} {
|
||||
set forcecopy 1
|
||||
}
|
||||
|
||||
if { [info exists ::user_aux_dirs] } {
|
||||
foreach dir $::user_aux_dirs {
|
||||
if {[file dirname $filename] == "$dir" } {
|
||||
set forcecopy 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if { ![file writable [file dirname $filename]]
|
||||
|| $forcecopy
|
||||
} {
|
||||
set filetype [file extension $filename]
|
||||
if {$filetype == ".ini"} { return 1 ;# ok }
|
||||
if {$filetype == ".demo"} {
|
||||
set nocopyfile [file join [file dirname $filename] nodemocopy]
|
||||
if {![file exists $nocopyfile]} { return 1 ;# ok }
|
||||
}
|
||||
}
|
||||
return 0 ;# not ok
|
||||
} ;# ok_to_copy
|
||||
|
||||
# Notes on text displayed in detail_box widget:
|
||||
# if node is usable (an ini file named xxx.ini or xxx.demo), then:
|
||||
# show xxx.txt if it exists
|
||||
# else
|
||||
# show README if it exists in the directory for node
|
||||
# else
|
||||
# show "No Details available"
|
||||
#
|
||||
# if node is a directory, then:
|
||||
# show README if it exists in the directory for node
|
||||
|
||||
# called when user clicks tree node
|
||||
proc node_clicked {} {
|
||||
|
||||
set node [$::tree selection get]
|
||||
set ::selected_node $node
|
||||
title $node
|
||||
if {$node == ""} return
|
||||
set node [lindex $node 0]
|
||||
|
||||
$::tree selection set $node
|
||||
$::tree see $node
|
||||
|
||||
set readme ""
|
||||
if [name_is_usable_nodename $node] {
|
||||
# acceptable name
|
||||
# enable changes to the details widget
|
||||
set node [format %s $node]
|
||||
set dir [ file dirname $node]
|
||||
set name [ file rootname [file tail $node ] ]
|
||||
set readme [file join $dir $name.txt]
|
||||
if { ![ file exists $readme ] } {
|
||||
set readme [file join [ file dirname $node ] README ]
|
||||
}
|
||||
set image [file join $dir $name.gif]
|
||||
if { ![ file exists $image ] } {
|
||||
set image [ file join [ file dirname $node ] logo.gif ]
|
||||
}
|
||||
if { [ file readable $image ] } {
|
||||
machinelogo blank
|
||||
machinelogo read $image
|
||||
puts stderr "using image $image"
|
||||
$::detail_box image create end -image machinelogo
|
||||
$::detail_box insert end "\n"
|
||||
$::detail_box tag configure centered -justify center
|
||||
$::detail_box tag add centered 0.0 0.end
|
||||
}
|
||||
# save selection
|
||||
set ::inifile $node
|
||||
|
||||
# enable the OK button
|
||||
$::button_ok configure -state normal
|
||||
bind . <Return> {button_pushed OK}
|
||||
bind . <KP_Enter> {button_pushed OK}
|
||||
} else {
|
||||
if {[file isdirectory $node]} {
|
||||
set readme [file join $node README]
|
||||
# clear selection
|
||||
set ::inifile ""
|
||||
# disable the OK button
|
||||
$::button_ok configure -state disabled
|
||||
bind . <Return> ""
|
||||
bind . <KP_Enter> ""
|
||||
}
|
||||
}
|
||||
|
||||
# remove old text
|
||||
$::detail_box configure -state normal
|
||||
$::detail_box delete 1.0 end
|
||||
if { [ file readable $readme ] } {
|
||||
# description found, read it
|
||||
set descr [ read -nonewline [ open $readme ]]
|
||||
# expect file with unbroken paragraphs
|
||||
$::detail_box insert end $descr
|
||||
} else {
|
||||
if [file isdirectory $node] {
|
||||
if {"$node" == "$::myconfigs_node"} {
|
||||
$::detail_box insert end "Your existing configs"
|
||||
} elseif { "$node" == "$::sampleconfigs_node"} {
|
||||
$::detail_box insert end "Available configs"
|
||||
}
|
||||
# else leave detail_box empty
|
||||
} else {
|
||||
# no description, gotta tell the user something
|
||||
$::detail_box insert end [msgcat::mc "No details available."]
|
||||
}
|
||||
}
|
||||
# lock it again
|
||||
$::detail_box configure -state disabled
|
||||
}
|
||||
|
||||
################ MAIN PROGRAM STARTS HERE ####################
|
||||
set ::configs_dir_list $linuxcnc::CONFIG_DIR
|
||||
set ::myconfigs_node $linuxcnc::USER_CONFIG_DIR
|
||||
# order convention for items in the linuxcnc::USER_CONFIG_DIR list:
|
||||
set ::sampleconfigs [lindex $::configs_dir_list end] ;# last item
|
||||
|
||||
# check for auxiliary applications example configs installed in
|
||||
# known directory defined by: linuxcnc::LINUXCNC_AUX_ExAMPLES
|
||||
set aux_examples $linuxcnc::LINUXCNC_AUX_EXAMPLES
|
||||
set ::aux_dir_list {}
|
||||
if [file isdirectory $aux_examples] {
|
||||
foreach auxdir [glob $aux_examples/*] {
|
||||
puts stderr "pickconfig: installed aux examples: $auxdir"
|
||||
lappend ::configs_dir_list $auxdir
|
||||
lappend ::aux_dir_list $auxdir
|
||||
}
|
||||
}
|
||||
# user may specify auxiliary config directories using the environmental
|
||||
# variable LINUXCNC_AUX_CONFIGS (a colon (:) separated path)
|
||||
# This is useful for testing auxiliary apps without using a deb install
|
||||
if [info exists ::env(LINUXCNC_AUX_CONFIGS)] {
|
||||
foreach auxdir [split $::env(LINUXCNC_AUX_CONFIGS) :] {
|
||||
if { [file isdirectory $auxdir] \
|
||||
&& [file readable $auxdir] } {
|
||||
set normauxdir [file normalize $auxdir]
|
||||
puts stderr "pickconfig: user aux examples: $normauxdir"
|
||||
lappend ::configs_dir_list $normauxdir
|
||||
lappend ::user_aux_dirs $normauxdir ;# forcecopy
|
||||
} else {
|
||||
puts stderr "pickconfig: LINUXCNC_AUX_CONFIGS invalid directory:"
|
||||
puts stderr " $auxdir"
|
||||
puts stderr "continuing"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set ::last_ini "none"
|
||||
set ::last_ini [initialize_config]
|
||||
|
||||
set ::openmode 0
|
||||
if { [file exists [file join $::sampleconfigs $::default_start_node]]
|
||||
|| "$::last_ini" != ""
|
||||
} {
|
||||
set ::openmode 1
|
||||
}
|
||||
|
||||
# set options that are common to all widgets
|
||||
foreach class { Button Entry Label Listbox Scale Text } {
|
||||
option add *$class.borderWidth 1 100
|
||||
}
|
||||
|
||||
# make a toplevel and a master frame.
|
||||
title ""
|
||||
set logo [label .logo -image $logo]
|
||||
set top [frame .main -borderwidth 0 -relief flat ]
|
||||
pack $logo -side left -anchor nw
|
||||
pack $top -side left -expand yes -fill both
|
||||
|
||||
wm geo . 780x480
|
||||
wm minsize . 780 480
|
||||
|
||||
proc SW { args } {
|
||||
set res [eval ScrolledWindow $args]
|
||||
$res.vscroll configure -relief flat
|
||||
::${res}:cmd configure -highlightthickness 1
|
||||
return $res
|
||||
}
|
||||
# a frame for packing the top window
|
||||
set f1 [ frame $top.f1 ]
|
||||
|
||||
set message [msgcat::mc "Welcome to LinuxCNC.\n\nSelect a machine configuration from the list on the left.\nDetails about the selected configuration will appear in the display on the right.\nClick 'OK' to run the selected configuration"]
|
||||
|
||||
set lbl [ label $f1.lbl -text $message -justify left -padx 15 -pady 10 -wraplength 600 ]
|
||||
pack $lbl -anchor w
|
||||
|
||||
# a subframe for the tree/detail box
|
||||
set f2 [ frame $f1.f2 -borderwidth 0 -relief flat -padx 15 ]
|
||||
|
||||
# Let the tree scroll
|
||||
set s1 [ SW $f2.f3 -auto both]
|
||||
$s1 configure -relief sunken -borderwidth 2
|
||||
# get the font height to scale the height of the tree rows
|
||||
set font_linespace [font metrics [linuxcnc::standard_font] -linespace]
|
||||
# the tree
|
||||
set ::tree [Tree $s1.tree -highlightthickness 0 \
|
||||
-width [expr {int($font_linespace * 1.33)}] -relief flat -padx 4 \
|
||||
-deltay $font_linespace\
|
||||
]
|
||||
$s1 setwidget $::tree
|
||||
pack $s1 -fill y -expand n -side left
|
||||
|
||||
# pack the tree into its subframe
|
||||
bind $::tree <<TreeSelect>> { node_clicked }
|
||||
$::tree bindText <Double-1> { $f5.ok invoke ;# }
|
||||
|
||||
# bwidget 1.7.0 does not generate <<TreeSelect>> events for keyboard navigation.
|
||||
# These bindings fix that.
|
||||
bind $::tree.c <KeyPress-Up> [list +event generate $::tree <<TreeSelect>>]
|
||||
bind $::tree.c <KeyPress-Down> [list +event generate $::tree <<TreeSelect>>]
|
||||
|
||||
# Let the text scroll
|
||||
set f4 [ SW $f2.f4 -scrollbar vertical]
|
||||
$s1 configure
|
||||
# a text box to display the details
|
||||
set tb [ text $f4.tb -width 30 -wrap word -padx 6 -pady 6 \
|
||||
-takefocus 0 -state disabled \
|
||||
-relief flat -borderwidth 0 -height 12]
|
||||
$f4.vscroll configure -takefocus 1
|
||||
$f4 setwidget $tb
|
||||
set ::detail_box $tb
|
||||
# pack the subframe into the main frame
|
||||
pack $f2 -side top -fill both -expand y
|
||||
pack $f4 -side left -padx 3 -fill both -expand y
|
||||
|
||||
|
||||
# a subframe for the buttons
|
||||
set f5 [ frame $f1.f5 ]
|
||||
button $f5.ok -text [msgcat::mc "OK"] -command "button_pushed OK" -width 8 -default active
|
||||
set ::button_ok $f5.ok
|
||||
$::button_ok configure -state disabled
|
||||
button $f5.cancel -text [msgcat::mc "Cancel"] -command "button_pushed Cancel" -width 8 -default normal
|
||||
pack $f5.cancel -side right -padx 4 -pady 4
|
||||
pack $f5.ok -side right -padx 4 -pady 4
|
||||
pack $f5 -side bottom -anchor e -fill x -expand n -padx 15
|
||||
|
||||
pack $f1 -fill both -expand y
|
||||
|
||||
set ::config_count 0
|
||||
|
||||
proc describe {dir} {
|
||||
if {"$dir" == "$::myconfigs_node"} {
|
||||
return [msgcat::mc "My Configurations"]
|
||||
}
|
||||
if {"$dir" == "$::sampleconfigs"} {
|
||||
set ::sampleconfigs_node $dir
|
||||
return [msgcat::mc "Sample Configurations"]
|
||||
}
|
||||
if {[lsearch $::aux_dir_list $dir] >= 0} {
|
||||
return [file tail $dir]
|
||||
} else {
|
||||
return $dir
|
||||
}
|
||||
}
|
||||
|
||||
proc treeopen {args} {
|
||||
set beforevisible [$::tree visible $::selected_node]
|
||||
update
|
||||
set visible [$::tree visible $::selected_node]
|
||||
if {!$beforevisible && $visible && [info exists ::restorebox] } {
|
||||
set state [$::detail_box cget -state]
|
||||
$::detail_box configure -state normal
|
||||
$::detail_box insert end $::restorebox
|
||||
$::detail_box configure -state $state
|
||||
unset ::restorebox
|
||||
}
|
||||
} ;# treeopen
|
||||
|
||||
proc treeclose {args} {
|
||||
set visible [$::tree visible $::selected_node]
|
||||
if {!$visible && ![info exists ::restorebox] } {
|
||||
set ::restorebox [$::detail_box get 1.0 end]
|
||||
set state [$::detail_box cget -state]
|
||||
$::detail_box configure -state normal
|
||||
$::detail_box delete 1.0 end
|
||||
$::detail_box configure -state $state
|
||||
}
|
||||
} ;# treeclose
|
||||
|
||||
proc walktree {dir} {
|
||||
if ![info exists ::openmode] {set ::openmode 0}
|
||||
if ![$::tree exists $dir] {
|
||||
set ::lvl $dir
|
||||
$::tree insert end root $dir -text [describe $dir] -open $::openmode
|
||||
}
|
||||
set bothlist [lsort [glob -nocomplain $dir/*]]
|
||||
if { [info exists ::sampleconfigs_node]
|
||||
&& "$dir" == "$::sampleconfigs_node"} {
|
||||
set bothlist [rearrange $bothlist]
|
||||
}
|
||||
set sortedlist {}
|
||||
set filelist {}
|
||||
set dirlist {}
|
||||
# display files before directories
|
||||
foreach item $bothlist {
|
||||
if [file isdirectory $item] {
|
||||
lappend dirlist $item
|
||||
} else {
|
||||
lappend sortedlist $item
|
||||
}
|
||||
}
|
||||
foreach f $dirlist { lappend sortedlist $f }
|
||||
|
||||
foreach f $sortedlist {
|
||||
if [file isdirectory $f] {
|
||||
if {[lsearch $::exclude_list [file tail $f]] == 0} continue
|
||||
set foundini [find_usable_nodes $f]
|
||||
if {"$foundini" == ""} {
|
||||
verbose "no usable files, skipping directory: $f"
|
||||
continue
|
||||
}
|
||||
|
||||
set text [file tail $f]
|
||||
$::tree insert end $::lvl $f -text $text -open $::openmode
|
||||
set restore $::lvl
|
||||
set ::lvl $f
|
||||
walktree $f ;# recursion
|
||||
set ::lvl $restore
|
||||
} else {
|
||||
if [name_is_usable_nodename $f] {
|
||||
set text [file rootname [file tail $f]]
|
||||
$::tree insert end $::lvl $f -text $text -open $::openmode
|
||||
incr ::config_count
|
||||
continue
|
||||
} else {
|
||||
verbose "skipping non-start_node file: $f"
|
||||
}
|
||||
}
|
||||
}
|
||||
} ;# walktree
|
||||
|
||||
proc rearrange l {
|
||||
set taillist {}
|
||||
foreach item $l {
|
||||
lappend taillist [file tail $item]
|
||||
}
|
||||
foreach name $::preferred_names {
|
||||
set idx [lsearch $taillist $name]
|
||||
if {$idx < 0} continue
|
||||
set found [lindex $l $idx]
|
||||
set taillist [lreplace $taillist $idx $idx]
|
||||
set taillist [linsert $taillist 0 $name]
|
||||
set l [lreplace $l $idx $idx]
|
||||
set l [linsert $l 0 $found]
|
||||
}
|
||||
return $l
|
||||
} ;# rearrange
|
||||
|
||||
proc verbose {msg} {
|
||||
if ![info exists ::env(verbose_pickconfig)] return
|
||||
puts stderr "pickconfig:$msg"
|
||||
}
|
||||
|
||||
proc minimal_tree {node} {
|
||||
if {"$node" == "root"} return
|
||||
set p [$::tree parent $node]
|
||||
foreach c [$::tree nodes $p] {
|
||||
if {"$c" == "$node"} continue
|
||||
$::tree closetree $c 1 ;# 1 ==> recurse
|
||||
}
|
||||
minimal_tree $p ;#recursion
|
||||
} ;# minimal_tree
|
||||
|
||||
foreach dir $::configs_dir_list {
|
||||
if {[info exists visited($dir)]} continue
|
||||
if {![file isdirectory $dir]} {
|
||||
verbose "pickconfig: skipping <$dir>, not a directory"
|
||||
continue
|
||||
}
|
||||
set visited($dir) {}
|
||||
walktree $dir
|
||||
}
|
||||
|
||||
if { $::config_count == 0 } {
|
||||
puts stderr [msgcat::mc "ERROR: no configurations found in path '%s'" $configs_dir_list]
|
||||
exit 1
|
||||
}
|
||||
|
||||
bind . <Escape> {button_pushed Cancel}
|
||||
bind . <Return> ""
|
||||
bind . <KP_Enter> ""
|
||||
|
||||
wm protocol . WM_DELETE_WINDOW {button_pushed Cancel}
|
||||
|
||||
proc wait_and_see {node {wait 10}} {
|
||||
set yv [$::tree yview]
|
||||
if {![winfo viewable $::tree] || [lindex $yv 0] == [lindex $yv 1]} {
|
||||
after $wait [list wait_and_see $node [expr $wait*2]]
|
||||
} else {
|
||||
$::tree see $node
|
||||
$::tree xview moveto 0.0
|
||||
minimal_tree $node
|
||||
node_clicked
|
||||
}
|
||||
}
|
||||
|
||||
proc get_file_contents {f} {
|
||||
set fd [open $f]
|
||||
set contents [read $fd]
|
||||
close $fd
|
||||
return $contents
|
||||
}
|
||||
|
||||
proc put_file_contents {f c} {
|
||||
set fd [open $f w]
|
||||
puts -nonewline $fd $c
|
||||
close $fd
|
||||
}
|
||||
|
||||
proc fail_if_linkname_exists {linkname} {
|
||||
if { [file exists $linkname] \
|
||||
&& [file type $linkname] != "link"} {
|
||||
set type [file type $linkname]
|
||||
tk_messageBox -title "Make link fail" \
|
||||
-icon error -type ok \
|
||||
-message "Cannot create link for\n$linkname\n\
|
||||
because of existing $type with same name\n\n\
|
||||
Remove (or rename) $linkname"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
proc prompt_copy configname {
|
||||
|
||||
set res [tk_dialog .d [msgcat::mc "Copy Configuration?"] [msgcat::mc "Would you like to copy the %s configuration to your home directory so you can customize it?" $configname] warning 0 [msgcat::mc "Yes"] [msgcat::mc "Cancel"]]
|
||||
|
||||
if {$res == -1 || $res == 1} { return "" }
|
||||
set chosendir [format %s [file dirname $configname]]
|
||||
foreach d $::configs_dir_list {
|
||||
if {"$d" == "$chosendir"} {
|
||||
# found chosendir at level 0 of a directory in the ::configs_dir_list
|
||||
set copytodir [format %s [file join $::myconfigs_node [file tail $chosendir]]]
|
||||
break
|
||||
}
|
||||
# if chosendir not found at level 0, try subdirs
|
||||
# note: expect $d ($::configs_dir_list) in normalized form
|
||||
if {0 != [string first "$d/" $configname]} {
|
||||
continue
|
||||
} else {
|
||||
# found chosendir as a subdir
|
||||
set idx [expr 1 + [string length $d]] ;#
|
||||
set hiername [string range $chosendir $idx end]
|
||||
if $::make_flat_user_dirs {
|
||||
# Flat dir structure for copied configs
|
||||
# create copytodir at one level below ::myconfigs_node
|
||||
set flatname [string map {/ .} $hiername]
|
||||
set copytodir [format %s [file join $::myconfigs_node $flatname]]
|
||||
} else {
|
||||
# Hierarchical dir structure for copied configs
|
||||
# create copytodir following hierarchy
|
||||
set copytodir [format %s [file join $::myconfigs_node $hiername]]
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
set copybase $copytodir
|
||||
|
||||
set i 0
|
||||
# distribution config ini files expect nc_files at same level as configs dir
|
||||
set ncfiles [file normalize [file join $::myconfigs_node ../nc_files]]
|
||||
file mkdir [file join $::myconfigs_node]
|
||||
|
||||
set obsoletedir [file normalize [file join $::env(HOME) emc2]]
|
||||
if [file isdir $obsoletedir] {
|
||||
tk_messageBox -title "Copy Configuration Notice" \
|
||||
-message "A directory named:\n \
|
||||
$obsoletedir\n \
|
||||
exists \n\n \
|
||||
You may want to copy items to the new directory:\n \
|
||||
[file normalize [file join $::myconfigs_node ..]]" \
|
||||
-type ok
|
||||
}
|
||||
|
||||
if {$::always_update_nc_files || ![file exists $ncfiles]} {
|
||||
file mkdir $ncfiles ;# tcl: ok if it exists
|
||||
set refname $linuxcnc::NCFILES_DIR
|
||||
set linkname [file join $ncfiles examples]
|
||||
fail_if_linkname_exists $linkname
|
||||
|
||||
# tcl wont overwrite any existing link, so remove
|
||||
catch {file delete $linkname}
|
||||
file link -symbolic $linkname $refname
|
||||
|
||||
# liblist: libs used in inifiles for [RS274NGC]SUBROUTINE_PATH
|
||||
# example: ngcgui uses lib named ngcgui_lib
|
||||
|
||||
set _libs [glob [file join $linuxcnc::NCFILES_DIR *_lib]]
|
||||
foreach lib $_libs {
|
||||
if ![file isdir $lib] continue
|
||||
lappend liblist $lib
|
||||
}
|
||||
foreach lib $liblist {
|
||||
set refname [file join $linuxcnc::NCFILES_DIR $lib]
|
||||
set linkname [file join $ncfiles [file tail $lib]]
|
||||
fail_if_linkname_exists $linkname
|
||||
|
||||
if {[file exists $linkname]} {
|
||||
# tcl wont overwrite any existing link, so remove
|
||||
file delete $linkname
|
||||
}
|
||||
# avoid error if no target
|
||||
if [file exists $refname] {
|
||||
file link -symbolic $linkname $refname
|
||||
}
|
||||
}
|
||||
set dir [file tail $ncfiles]
|
||||
set date [clock format [clock seconds] -format "%d%b%Y %T"]
|
||||
set fd [open [file join $ncfiles readme.ngc] w]
|
||||
puts $fd "(info: readme.ngc)"
|
||||
set msg "(debug, readme.ngc autogenerated by:)\n"
|
||||
set msg "${msg}(debug, $::argv0)\n"
|
||||
set msg "${msg}(debug, $date)\n"
|
||||
set msg "${msg}(debug, LinuxCNC vmajor=#<_vmajor> vminor=#<_vminor>)\n"
|
||||
set msg "${msg}(debug, User writable directory: $dir)\n"
|
||||
set msg "${msg}(debug, Example files: $dir/examples)\n"
|
||||
foreach lib $liblist {
|
||||
set msg "${msg}(debug, $lib subroutines: $dir/${lib}_lib)\n"
|
||||
}
|
||||
puts $fd $msg
|
||||
# make readme.ngc compatible with ngcgui:
|
||||
# (repeat the debug prints within the subroutine)
|
||||
puts $fd "o<readme> sub"
|
||||
puts $fd $msg
|
||||
puts $fd " #<parm1> = #1 (=123 pvalue)"
|
||||
puts $fd " (debug, readme.ngc: pvalue = #<parm1>)"
|
||||
puts $fd "o<readme> endsub"
|
||||
# include m2 to preclude message:
|
||||
# "File ended with no percent sign or program end"
|
||||
puts $fd "m2"
|
||||
close $fd
|
||||
}
|
||||
while {1} {
|
||||
if [file exists $copytodir] {
|
||||
incr i
|
||||
set copytodir "$copybase-$i" ;# user may have protected directory, so bump name
|
||||
# limit attempts to avoid infinite loop for hard error
|
||||
if {$i > 1000} {
|
||||
puts stderr "$::argv0:$msg"
|
||||
tk_messageBox -icon error -type ok \
|
||||
-message [msgcat::mc "Failed to mkdir for $copytodir\n<$msg>"]
|
||||
destroy .
|
||||
exit
|
||||
}
|
||||
continue ;# try again
|
||||
} else {
|
||||
# note: file mkdir will make parents as required
|
||||
if [catch { file mkdir $copytodir } msg] {
|
||||
continue ;# try again
|
||||
}
|
||||
}
|
||||
# A hierarchy of directories is allowed.
|
||||
# User selects an offered ini file.
|
||||
# All files in same directory are copied.
|
||||
# The target of a linked file is copied
|
||||
foreach f [glob -directory $chosendir *] {
|
||||
# nc_files (as a symlink) may be present for rip testing
|
||||
# nc_files (as a symlink) not copied here (handled elsewhere)
|
||||
if { [file tail $f] == "nc_files"
|
||||
&& [file type $f] == "link" } {
|
||||
verbose "pickconfig: not copying link: $f"
|
||||
continue
|
||||
}
|
||||
if {[lsearch $::never_copy_list [file tail $f]] >= 0} continue
|
||||
# is_special: subdir is to be copied
|
||||
set is_special 0
|
||||
if { "" == [find_usable_nodes $f] } {
|
||||
# ok: no usable child files so the directory can be copied
|
||||
set is_special 1
|
||||
}
|
||||
|
||||
switch [file type $f] {
|
||||
link {
|
||||
if {$is_special} {
|
||||
# since is link, require:
|
||||
# -r recursive, -L dereference
|
||||
exec cp -rL [file join $chosendir $f] $copytodir
|
||||
} else {
|
||||
# to follow sym links correctly, use system cp:
|
||||
exec cp [file join $chosendir $f] $copytodir
|
||||
}
|
||||
}
|
||||
file {file copy "$f" $copytodir}
|
||||
directory { # recursive copy of subdirs
|
||||
if {$is_special } {
|
||||
# -r recursive
|
||||
exec cp -r [file join $chosendir $f] $copytodir
|
||||
}
|
||||
}
|
||||
default {puts stderr \
|
||||
"prompt_copy:unsupported type=[file type $f] for $f"}
|
||||
}
|
||||
}
|
||||
foreach f [glob -directory $copytodir *] {
|
||||
file attributes $f -permissions u+w
|
||||
if {[file extension $f] == ".ini"} {
|
||||
set c [get_file_contents $f]
|
||||
# note: the following regsub _typically_ forces:
|
||||
# PROGRAM_PREFIX=/home/username/linuxcnc/nc_files
|
||||
regsub {(?n)^(PROGRAM_PREFIX\s*=\s*).*$} $c "\\1$ncfiles" c
|
||||
put_file_contents $f $c
|
||||
}
|
||||
if {$::tcl_platform(platform) == "unix"} {
|
||||
file attributes $f -permissions u+w
|
||||
}
|
||||
}
|
||||
|
||||
# make convenience link to HALLIB_DIR:
|
||||
file link -symbolic [file join $copytodir hallib] $::env(HALLIB_DIR)
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
tk_dialog .d [msgcat::mc "Configuration Copied"] [msgcat::mc "The configuration file has been copied to %s. Next time, choose this location when starting LinuxCNC." $copytodir] info 0 [msgcat::mc "OK"]
|
||||
|
||||
return $copytodir/[file tail $configname]
|
||||
}
|
||||
|
||||
|
||||
# add the selection set if a ::last_ini has been found in ~/.linuxcncrc
|
||||
|
||||
if { $::last_ini != -1
|
||||
&& [file exists $::last_ini]
|
||||
&& ![catch {$::tree index $::last_ini}]} {
|
||||
set start_node $::last_ini
|
||||
} else {
|
||||
set start_node ${::sampleconfigs}/$::default_start_node
|
||||
}
|
||||
if [catch {
|
||||
$::tree selection set $start_node
|
||||
wait_and_see $start_node
|
||||
}] {
|
||||
set ::openmode 0
|
||||
puts stderr "pickconfig: cannot find expected start_node <$start_node>, continuing"
|
||||
}
|
||||
# update and enable commands after initial setup of tree
|
||||
update
|
||||
set ::selected_node [$::tree selection get]
|
||||
title $::selected_node
|
||||
$::tree configure \
|
||||
-closecmd {after cancel treeclose; after idle treeclose} \
|
||||
-opencmd {after cancel treeopen; after idle treeopen}
|
||||
|
||||
|
||||
proc make_shortcut {inifile} {
|
||||
if {[catch {open $inifile} inifd]} { return }
|
||||
set inistring [read $inifd]
|
||||
close $inifd
|
||||
switch [file extension $inifile] {
|
||||
".ini" {set name [getVal $inistring EMC MACHINE]}
|
||||
".demo" {set name [lindex [split [file tail $inifile] "."] 0]
|
||||
}
|
||||
default {set name linuxcnc-other}
|
||||
}
|
||||
if {"$name" == ""} {set name LinuxCNC-other}
|
||||
set filename0 [file join $::desktopdir [file rootname [file tail $inifile]]]
|
||||
set filename ${filename0}.desktop
|
||||
set i 0
|
||||
while {[file exists $filename]} {
|
||||
incr i
|
||||
set filename $filename0${i}.desktop
|
||||
}
|
||||
exec linuxcncmkdesktop $inifile $name > $filename
|
||||
file attributes $filename -permissions +x
|
||||
tk_dialog .d [msgcat::mc "Shortcut Created"] [msgcat::mc "A shortcut to this configuration file has been created on your desktop. You can use it to automatically launch this configuration."] info 0 [msgcat::mc "OK"]
|
||||
}
|
||||
|
||||
set make_shortcut 0
|
||||
if {[file isdir $::desktopdir]} {
|
||||
checkbutton $f5.c -variable make_shortcut \
|
||||
-text [msgcat::mc "Create Desktop Shortcut"] \
|
||||
-state normal
|
||||
pack $f5.c -side left -expand 1 -anchor w
|
||||
}
|
||||
|
||||
while {1} {
|
||||
focus $::tree
|
||||
vwait ::choice
|
||||
|
||||
if { $::choice == "OK" } {
|
||||
if [ok_to_copy_config $::inifile] {
|
||||
set copied_inifile [prompt_copy $::inifile]
|
||||
if {$copied_inifile == ""} {
|
||||
continue ;# user canceled
|
||||
} else {
|
||||
set ::inifile $copied_inifile
|
||||
}
|
||||
}
|
||||
if {$make_shortcut} { make_shortcut $::inifile }
|
||||
puts $::inifile ;# this is the result for this script (to stdout)
|
||||
|
||||
# test for ~/.linuxcncrc file and modify if needed.
|
||||
# or make this file and add the var.
|
||||
|
||||
if {[file exists $::env(HOME)/.linuxcncrc]} {
|
||||
if {$::inifile == $::last_ini} {
|
||||
exit
|
||||
} else {
|
||||
if {[catch {open $::env(HOME)/.linuxcncrc} programin]} {
|
||||
return
|
||||
} else {
|
||||
set rcstring [read $programin]
|
||||
catch {close $programin}
|
||||
}
|
||||
set ret [setVal $rcstring PICKCONFIG LAST_CONFIG $::inifile ]
|
||||
catch {file copy -force $name $name.bak}
|
||||
if {[catch {open $::env(HOME)/.linuxcncrc w} fileout]} {
|
||||
puts stdout [msgcat::mc "can't save %s" $::env(HOME)/.linuxcncrc ]
|
||||
exit
|
||||
}
|
||||
puts $fileout $ret
|
||||
catch {close $fileout}
|
||||
exit
|
||||
}
|
||||
}
|
||||
set newfilestring "# .linuxcncrc is a startup configuration file for LinuxCNC. \n# format is INI like. \n# \[SECTION_NAME\] \n# VARNAME = varvalue \n# where section name is the name of the system writing to this file \n\n# written by pickconfig.tcl \n\[PICKCONFIG\]\nLAST_CONFIG = $::inifile\n"
|
||||
|
||||
if {[catch {open $::env(HOME)/.linuxcncrc w+} fileout]} {
|
||||
puts stderr [msgcat::mc "can't save %s" $::env(HOME)/.linuxcncrc ]
|
||||
exit
|
||||
}
|
||||
|
||||
puts $fileout $newfilestring
|
||||
catch {close $fileout}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
exit
|
||||
82
tcl/bin/popimage
Executable file
82
tcl/bin/popimage
Executable file
@@ -0,0 +1,82 @@
|
||||
#!/bin/sh
|
||||
# the next line restarts using wish \
|
||||
exec ${LINUXCNC_EMCSH-wish} "$0" "$@"
|
||||
|
||||
###############################################################
|
||||
# Description: popimage
|
||||
# A Tcl/Tk script that displays the image listed
|
||||
# in the relevant ini file for the time listed in
|
||||
# that file.
|
||||
#
|
||||
# Derived from a work by Fred Proctor & Will Shackleford
|
||||
# Author:
|
||||
# License: GPL Version 2
|
||||
#
|
||||
# Copyright (c) 2005 All rights reserved.
|
||||
#
|
||||
# Last change:
|
||||
###############################################################
|
||||
# INI variables include
|
||||
# [DISPLAY]
|
||||
# Introductory graphic
|
||||
# INTRO_GRAPHIC = emc2.gif
|
||||
# INTRO_TIME = 5
|
||||
# If time is set to zero no image is used
|
||||
###############################################################
|
||||
|
||||
|
||||
if {$argc < 1} {
|
||||
puts stderr "syntax: popimage <image file>"
|
||||
exit
|
||||
}
|
||||
|
||||
load [file join [file dirname [info script]] .. linuxcnc.so]
|
||||
|
||||
. configure -borderwidth 0 -highlightthickness 0
|
||||
|
||||
set img [lindex $argv 0]
|
||||
|
||||
set imgtime 5
|
||||
if {$argc > 1} {
|
||||
set imgtime [lindex $argv 1]
|
||||
}
|
||||
if {$imgtime <= 0} {
|
||||
set imgtime 5
|
||||
}
|
||||
# now convert imgtime to milliseconds
|
||||
set imgtime [expr {int($imgtime * 1000)}]
|
||||
|
||||
if {! [file exists $img]} {
|
||||
puts stderr "can't find file $img"
|
||||
exit
|
||||
}
|
||||
|
||||
if {[catch {image create photo -file $img} image]} {
|
||||
puts stderr "bad image file $img"
|
||||
exit
|
||||
}
|
||||
|
||||
set w [image width $image]
|
||||
set h [image height $image]
|
||||
canvas .c -width $w -height $h -borderwidth 0 -highlightthickness 0
|
||||
.c create image 0 0 -anchor nw -image $image
|
||||
.c create text 4 [expr $h-4] -anchor sw \
|
||||
-text $env(LINUXCNCVERSION) -fill white -font {Helvetica 18}
|
||||
|
||||
pack .c
|
||||
|
||||
# Center popup in screen.
|
||||
|
||||
set si [lindex [multihead] 0]
|
||||
set x0 [lindex $si 0]
|
||||
set y0 [lindex $si 1]
|
||||
set x1 [lindex $si 2]
|
||||
set y1 [lindex $si 3]
|
||||
set cx [expr {($x0+$x1)/2}]
|
||||
set cy [expr {($y0+$y1)/2}]
|
||||
set x [expr {$cx-$w/2}]
|
||||
set y [expr {$cy-$h/2}]
|
||||
wm geometry . "+$x+$y"
|
||||
wm overrideredirect . 1
|
||||
|
||||
after $imgtime exit
|
||||
516
tcl/bin/tkbackplot.tcl
Executable file
516
tcl/bin/tkbackplot.tcl
Executable file
@@ -0,0 +1,516 @@
|
||||
#!/bin/sh
|
||||
# the next line restarts using emcsh \
|
||||
exec $LINUXCNC_EMCSH "$0" "$@"
|
||||
|
||||
###############################################################
|
||||
# Description: genedit.tcl
|
||||
# This file dumps info to a logging file from tkmc.
|
||||
#
|
||||
# Authors: Ray Henry & Paul Corner
|
||||
# License: GPL Version 2
|
||||
#
|
||||
# Copyright (c) 2009 All rights reserved.
|
||||
###############################################################
|
||||
# This is plot processes for tkemc popup under the view menu
|
||||
# of tkemc. The fixed size of the canvas viewing area is 500x250
|
||||
# pixels less scrollbars. The full canvas could be much larger.
|
||||
# Several local variables may be set below to match machines.
|
||||
###############################################################
|
||||
|
||||
# Load the linuxcnc.tcl file, which defines variables for various useful paths
|
||||
source [file join [file dirname [info script]] .. linuxcnc.tcl]
|
||||
|
||||
# These offset plot zero from canvas zero.
|
||||
set xoffset 0
|
||||
set yoffset 0
|
||||
set zoffset 0
|
||||
|
||||
# These set the axis directions. +1 one plots like graph
|
||||
# paper with positive up and to the right. The canvas widgets orient so that
|
||||
# xy plot is looking down on the work area from the operator position.
|
||||
# x is left right and y is up down.
|
||||
# xz plot is looking into the work area along the axis of y
|
||||
# yz plot is looking into the work area along the axis of x
|
||||
# to reverse as axis change its value to -1 (don't put other numbers here)
|
||||
set xdir 1
|
||||
set ydir 1
|
||||
set zdir 1
|
||||
|
||||
# These set the size of the canvas widget behind the viewing area.
|
||||
# Set for the size of your machine or larger. They can also be set so that you
|
||||
# place your machine home about the same location in canvas space that it has on the
|
||||
# real machine.
|
||||
# They need not be the same for each axis.
|
||||
# the value used is pixels so multiply your machine workspace size in inches by 72.
|
||||
|
||||
# the default shipped here is for a center zero'd machine with 1000 pixels both left/right
|
||||
# and 500 pixels both top/bottom in all axis.
|
||||
# Read variable names (xytopx) as "xy plot topleft x" value etc.
|
||||
|
||||
# If your machine were top right homed on xy, you might use
|
||||
# xy -1900 -100 100 900
|
||||
# xz -1900 -100 100 900
|
||||
# yz -100 -100 1900 900
|
||||
|
||||
# These set top left and bottom right of xy canvas
|
||||
set xytopx -1000
|
||||
set xytopy -500
|
||||
set xybotx 1000
|
||||
set xyboty 500
|
||||
|
||||
# These set top left and bottom right of xz canvas
|
||||
set xztopx -1000
|
||||
set xztopz -500
|
||||
set xzbotx 1000
|
||||
set xzbotz 500
|
||||
|
||||
# These set top left and bottom right of yz canvas
|
||||
set yztopy -1000
|
||||
set yztopz -500
|
||||
set yzboty 1000
|
||||
set yzbotz 500
|
||||
|
||||
# This variable sets the default size of the plot and can be thought of as number of
|
||||
# pixels per inch of machine motion. The default (40) will give about .55 screen
|
||||
# inch per inch moved.
|
||||
|
||||
set size 40
|
||||
|
||||
#These variables set the default angles used for the 3d plot. in this release,
|
||||
#only the xyangle is used though the others are also shown on the setup screen
|
||||
|
||||
# These three can go.
|
||||
set xyangle 30
|
||||
set xangle 30
|
||||
set yangle 30
|
||||
set zangle 60
|
||||
set xycosangle 0
|
||||
set xysinangle 0
|
||||
|
||||
# I used these in the latest edit - Paul.
|
||||
|
||||
# pop up the plot window
|
||||
proc popupPlot {} {
|
||||
global screen tab
|
||||
global xytopx xytopy xybotx xyboty
|
||||
global xztopx xztopz xzbotx xzbotz
|
||||
global yztopy yztopz yzboty yzbotz
|
||||
global xycenterx xycentery xzcenterx xzcenterz yzcentery yzcenterz
|
||||
|
||||
|
||||
set d .plot
|
||||
|
||||
if {[winfo exists $d]} {
|
||||
wm deiconify $d
|
||||
raise $d
|
||||
focus $d
|
||||
return
|
||||
}
|
||||
toplevel $d
|
||||
wm title $d [msgcat::mc "TkLinuxCNC BackPlot"]
|
||||
|
||||
# use "pw" as name of top level from now on
|
||||
set pw .plot
|
||||
|
||||
set tab [frame $pw.tabs]
|
||||
button $tab.xy -relief flat -font {Helvetica -10 bold} -anchor n -width 8 \
|
||||
-text {X - Y} -command {selectPlot xy} -borderwidth 0
|
||||
button $tab.xz -relief flat -font {Helvetica -10 bold} -anchor n -width 8 \
|
||||
-text {X - Z} -command {selectPlot xz} -borderwidth 0
|
||||
button $tab.yz -relief flat -font {Helvetica -10 bold} -anchor n -width 8 \
|
||||
-text {Y - Z} -command {selectPlot yz} -borderwidth 0
|
||||
button $tab.3d -relief flat -font {Helvetica -10 bold} -anchor n -width 8 \
|
||||
-text { 3D } -command {selectPlot 3d} -borderwidth 0
|
||||
button $tab.config -relief raised -font {Helvetica -10 bold} -anchor n -width 8 \
|
||||
-text [msgcat::mc "SETUP"] -command {selectPlot config} -borderwidth 1
|
||||
button $tab.reset -relief raised -font {Helvetica -10 bold} -anchor n -width 8 \
|
||||
-text [msgcat::mc "RESET"] -command {erasePlot} -borderwidth 1
|
||||
button $tab.can -relief raised -font {Helvetica -10 bold} -anchor n -width 8 \
|
||||
-text [msgcat::mc "CANCEL"] -command {destroy .plot} -borderwidth 1
|
||||
pack $tab.xy $tab.xz $tab.yz $tab.3d $tab.config $tab.reset $tab.can -side left \
|
||||
-fill both
|
||||
pack $tab -side top -fill x
|
||||
|
||||
|
||||
set xlast 0
|
||||
set ylast 0
|
||||
set zlast 0
|
||||
set 3dxnext 0
|
||||
set 3dyrnext 0
|
||||
set plotcolor black
|
||||
|
||||
# Computes (0,0) and attempts to center it in view.
|
||||
# Computation for xy plot
|
||||
set xytotalx [expr {abs($xytopx) + abs($xybotx)}]
|
||||
set xylowerx [expr {abs($xytopx) - 270}]
|
||||
if {$xylowerx <= 0} {
|
||||
set xycenterx 0
|
||||
} else {
|
||||
set xycenterx [expr {double($xylowerx) / double($xytotalx)} * 1.1 ]
|
||||
}
|
||||
|
||||
set xytotaly [expr {abs($xytopy) + abs($xyboty)}]
|
||||
set xylowery [expr {abs($xytopy) - 125}]
|
||||
if {$xylowery <= 0} {
|
||||
set xycentery 0
|
||||
} else {
|
||||
set xycentery [expr {double($xylowery) / double($xytotaly)} * .8 ]
|
||||
}
|
||||
|
||||
# Computation for xz plot
|
||||
set xztotalx [expr {abs($xztopx) + abs($xzbotx)}]
|
||||
set xzlowerx [expr {abs($xztopx) - 270}]
|
||||
if {$xzlowerx <= 0} {
|
||||
set xzcenterx 0
|
||||
} else {
|
||||
set xzcenterx [expr {double($xzlowerx) / double($xztotalx)} * 1.1]
|
||||
}
|
||||
|
||||
set xztotalz [expr {abs($xztopz) + abs($xzbotz)}]
|
||||
set xzlowerz [expr {abs($xztopz) - 125}]
|
||||
if {$xzlowerz <= 0} {
|
||||
set xzcenterz 0
|
||||
} else {
|
||||
set xzcenterz [expr {double($xzlowerz) / double($xztotalz)} * .8]
|
||||
}
|
||||
|
||||
# Computation for yz plot
|
||||
set yztotaly [expr {abs($yztopy) + abs($yzboty)}]
|
||||
set yzlowery [expr {abs($yztopy) - 270}]
|
||||
if {$yzlowery <= 0} {
|
||||
set yzcentery 0
|
||||
} else {
|
||||
set yzcentery [expr {double($yzlowery) / double($yztotaly)} * 1.1]
|
||||
}
|
||||
|
||||
set yztotalz [expr {abs($yztopz) + abs($yzbotz)}]
|
||||
set yzlowerz [expr {abs($yztopz) - 125}]
|
||||
if {$yzlowerz <= 0} {
|
||||
set yzcenterz 0
|
||||
} else {
|
||||
set yzcenterz [expr {double($yzlowerz) / double($yztotalz)} * .8]
|
||||
}
|
||||
|
||||
set screen [frame $pw.frame -width 500 -height 260 ]
|
||||
|
||||
frame $screen.xyplot
|
||||
canvas $screen.xyplot.canv -borderwidth 0 -scrollregion "$xytopx $xytopy $xybotx $xyboty" \
|
||||
-relief flat -xscrollcommand "$screen.xyplot.hscroll set" \
|
||||
-yscrollcommand "$screen.xyplot.vscroll set" \
|
||||
-xscrollincrement 10 -yscrollincrement 10 -width 500 -height 260
|
||||
scrollbar $screen.xyplot.hscroll -orient horizontal -command "$screen.xyplot.canv xview"
|
||||
scrollbar $screen.xyplot.vscroll -orient vertical -command "$screen.xyplot.canv yview"
|
||||
grid $screen.xyplot.canv -row 0 -column 0 -sticky nsew
|
||||
grid $screen.xyplot.vscroll -row 0 -column 1 -sticky ns
|
||||
grid $screen.xyplot.hscroll -row 1 -column 0 -sticky ew
|
||||
grid rowconfigure $screen.xyplot 0 -weight 1
|
||||
grid columnconfigure $screen.xyplot 0 -weight 1
|
||||
|
||||
frame $screen.xzplot
|
||||
canvas $screen.xzplot.canv -borderwidth 0 -scrollregion "$xztopx $xztopz $xzbotx $xzbotz" \
|
||||
-relief flat -xscrollcommand "$screen.xzplot.hscroll set" \
|
||||
-yscrollcommand "$screen.xzplot.vscroll set" \
|
||||
-xscrollincrement 10 -yscrollincrement 10 -width 500 -height 260
|
||||
scrollbar $screen.xzplot.hscroll -orient horizontal -command "$screen.xzplot.canv xview"
|
||||
scrollbar $screen.xzplot.vscroll -orient vertical -command "$screen.xzplot.canv yview"
|
||||
grid $screen.xzplot.canv -row 0 -column 0 -sticky nsew
|
||||
grid $screen.xzplot.vscroll -row 0 -column 1 -sticky ns
|
||||
grid $screen.xzplot.hscroll -row 1 -column 0 -sticky ew
|
||||
grid rowconfigure $screen.xzplot 0 -weight 1
|
||||
grid columnconfigure $screen.xzplot 0 -weight 1
|
||||
|
||||
frame $screen.yzplot
|
||||
canvas $screen.yzplot.canv -borderwidth 0 -scrollregion "$yztopy $yztopz $yzboty $yzbotz" \
|
||||
-relief flat -xscrollcommand "$screen.yzplot.hscroll set" \
|
||||
-yscrollcommand "$screen.yzplot.vscroll set" \
|
||||
-xscrollincrement 10 -yscrollincrement 10 -width 500 -height 260
|
||||
scrollbar $screen.yzplot.hscroll -orient horizontal -command "$screen.yzplot.canv xview"
|
||||
scrollbar $screen.yzplot.vscroll -orient vertical -command "$screen.yzplot.canv yview"
|
||||
grid $screen.yzplot.canv -row 0 -column 0 -sticky nsew
|
||||
grid $screen.yzplot.vscroll -row 0 -column 1 -sticky ns
|
||||
grid $screen.yzplot.hscroll -row 1 -column 0 -sticky ew
|
||||
grid rowconfigure $screen.yzplot 0 -weight 1
|
||||
grid columnconfigure $screen.yzplot 0 -weight 1
|
||||
|
||||
frame $screen.3dplot
|
||||
canvas $screen.3dplot.canv -borderwidth 0 -scrollregion "$yztopy $yztopz $yzboty $yzbotz" \
|
||||
-relief flat -xscrollcommand "$screen.3dplot.hscroll set" \
|
||||
-yscrollcommand "$screen.3dplot.vscroll set" \
|
||||
-xscrollincrement 10 -yscrollincrement 10 -width 500 -height 260
|
||||
scrollbar $screen.3dplot.hscroll -orient horizontal -command "$screen.3dplot.canv xview"
|
||||
scrollbar $screen.3dplot.vscroll -orient vertical -command "$screen.3dplot.canv yview"
|
||||
grid $screen.3dplot.canv -row 0 -column 0 -sticky nsew
|
||||
grid $screen.3dplot.vscroll -row 0 -column 1 -sticky ns
|
||||
grid $screen.3dplot.hscroll -row 1 -column 0 -sticky ew
|
||||
grid rowconfigure $screen.3dplot 0 -weight 1
|
||||
grid columnconfigure $screen.3dplot 0 -weight 1
|
||||
|
||||
set cft [frame $screen.config ]
|
||||
|
||||
label $cft.label1 -text [msgcat::mc "AXIS"] -anchor e
|
||||
label $cft.label2 -text [msgcat::mc "OFFSET"]
|
||||
label $cft.label3 -text [msgcat::mc "ANGLE"]
|
||||
label $cft.label4 -text [msgcat::mc "DIRECTION"]
|
||||
|
||||
label $cft.labelx -text "X :" -anchor e
|
||||
entry $cft.exo -relief sunken -textvariable xoffset -width 8
|
||||
entry $cft.exa -relief sunken -textvariable xangle -width 8
|
||||
button $cft.bxd -textvariable xdir -command {changeDirection xdir} -width 10
|
||||
|
||||
label $cft.labely -text "Y :" -anchor e
|
||||
entry $cft.eyo -relief sunken -textvariable yoffset -width 8
|
||||
entry $cft.eya -relief sunken -textvariable yangle -width 8
|
||||
button $cft.byd -textvariable ydir -command {changeDirection ydir} -width 10
|
||||
|
||||
label $cft.labelz -text "Z :" -anchor e
|
||||
entry $cft.ezo -relief sunken -textvariable zoffset -width 8
|
||||
entry $cft.eza -relief sunken -textvariable zangle -width 8
|
||||
button $cft.bzd -textvariable zdir -command {changeDirection zdir} -width 10
|
||||
|
||||
label $cft.elabel -text [msgcat::mc "SIZE :"] -anchor e -width 8
|
||||
entry $cft.esize -relief sunken -textvariable size -width 8
|
||||
|
||||
grid $cft.label1 $cft.label2 $cft.label3 $cft.label4 $cft.elabel -padx 6
|
||||
grid $cft.labelx $cft.exo $cft.exa $cft.bxd $cft.esize -padx 6 -pady 2
|
||||
grid $cft.labely $cft.eyo $cft.eya $cft.byd -padx 6 -pady 2
|
||||
grid $cft.labelz $cft.ezo $cft.eza $cft.bzd -padx 6 -pady 2
|
||||
|
||||
pack $cft -side top -pady 10 -fill both -expand yes
|
||||
pack $screen -side top -fill both -expand yes
|
||||
|
||||
erasePlot
|
||||
selectPlot 3d
|
||||
|
||||
}
|
||||
|
||||
proc selectPlot {which} {
|
||||
global screen tab
|
||||
switch -- $which {
|
||||
xy {
|
||||
pack $screen.xyplot -side top -fill both -expand yes
|
||||
pack forget $screen.xzplot $screen.yzplot $screen.3dplot $screen.config
|
||||
$tab.xy configure -borderwidth 0 -relief flat
|
||||
$tab.xz configure -borderwidth 1 -relief sunken
|
||||
$tab.yz configure -borderwidth 1 -relief sunken
|
||||
$tab.3d configure -borderwidth 1 -relief sunken
|
||||
}
|
||||
xz {
|
||||
pack $screen.xzplot -side top -fill both -expand yes
|
||||
pack forget $screen.xyplot $screen.yzplot $screen.3dplot $screen.config
|
||||
$tab.xy configure -borderwidth 1 -relief sunken
|
||||
$tab.xz configure -borderwidth 0 -relief flat
|
||||
$tab.yz configure -borderwidth 1 -relief sunken
|
||||
$tab.3d configure -borderwidth 1 -relief sunken
|
||||
}
|
||||
yz {
|
||||
pack $screen.yzplot -side top -fill both -expand yes
|
||||
pack forget $screen.xyplot $screen.xzplot $screen.3dplot $screen.config
|
||||
$tab.xy configure -borderwidth 1 -relief sunken
|
||||
$tab.xz configure -borderwidth 1 -relief sunken
|
||||
$tab.yz configure -borderwidth 0 -relief flat
|
||||
$tab.3d configure -borderwidth 1 -relief sunken
|
||||
}
|
||||
3d {
|
||||
pack $screen.3dplot -side top -fill both -expand yes
|
||||
pack forget $screen.xyplot $screen.xzplot $screen.yzplot $screen.config
|
||||
$tab.xy configure -borderwidth 1 -relief sunken
|
||||
$tab.xz configure -borderwidth 1 -relief sunken
|
||||
$tab.yz configure -borderwidth 1 -relief sunken
|
||||
$tab.3d configure -borderwidth 0 -relief flat
|
||||
}
|
||||
config {
|
||||
pack $screen.config -side top -fill both -expand yes
|
||||
pack forget $screen.xyplot $screen.xzplot $screen.yzplot $screen.3dplot
|
||||
$tab.xy configure -borderwidth 1 -relief sunken
|
||||
$tab.xz configure -borderwidth 1 -relief sunken
|
||||
$tab.yz configure -borderwidth 1 -relief sunken
|
||||
$tab.3d configure -borderwidth 1 -relief sunken
|
||||
}
|
||||
default {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc changeDirection {axisvariable} {
|
||||
global xdir ydir zdir
|
||||
if {$axisvariable == "xdir"} {
|
||||
if {$xdir == 1} {
|
||||
set xdir -1
|
||||
} else {
|
||||
set xdir 1
|
||||
}
|
||||
} elseif {$axisvariable == "ydir"} {
|
||||
if {$ydir == 1} {
|
||||
set ydir -1
|
||||
} else {
|
||||
set ydir 1
|
||||
}
|
||||
} elseif {$axisvariable == "zdir"} {
|
||||
if {$zdir == 1} {
|
||||
set zdir -1
|
||||
} else {
|
||||
set zdir 1
|
||||
}
|
||||
}
|
||||
erasePlot
|
||||
}
|
||||
|
||||
set xnext 0; set ynext 0; set znext 0; set yrnext 0; set zrnext 0
|
||||
set 3dxnext 0; set 3dynext 0; set 3dznext 0; set 3dyrnext 0
|
||||
set 3dylast 0; set 3dxlast 0; set 3dzlast 0; set 3dyrlast 0
|
||||
|
||||
proc backPlot {} {
|
||||
global screen
|
||||
global size xoffset yoffset zoffset xdir ydir zdir
|
||||
global xnext ynext znext yrnext zrnext 3dxnext 3dyrnext
|
||||
$screen.xyplot.canv create oval [expr $xnext -2] [expr $yrnext -2] \
|
||||
[expr $xnext + 2] [expr $yrnext +2] -outline red -tags xytool
|
||||
$screen.xzplot.canv create line $xnext $zrnext $xnext [expr $zrnext - 20] \
|
||||
-fill red -arrow first -tags xzarrow
|
||||
$screen.yzplot.canv create line $ynext $zrnext $ynext [expr $zrnext - 20] \
|
||||
-fill red -arrow first -tags yzarrow
|
||||
$screen.3dplot.canv create line $3dxnext $3dyrnext [expr $3dxnext + 10] [expr $3dyrnext -15] \
|
||||
-fill red -arrow first -tags 3darrow
|
||||
}
|
||||
|
||||
proc erasePlot {} {
|
||||
global screen
|
||||
$screen.xyplot.canv addtag all all
|
||||
$screen.xyplot.canv delete all
|
||||
$screen.xzplot.canv addtag all all
|
||||
$screen.xzplot.canv delete all
|
||||
$screen.yzplot.canv addtag all all
|
||||
$screen.yzplot.canv delete all
|
||||
$screen.3dplot.canv addtag all all
|
||||
$screen.3dplot.canv delete all
|
||||
backPlot
|
||||
markPlot
|
||||
}
|
||||
|
||||
# Process markPlot shows initial conditions and display for plots
|
||||
proc markPlot {} {
|
||||
global xdir ydir zdir xoffset yoffset zoffset 3dxyangle xycosangle xysinangle
|
||||
global xycenterx xycentery xzcenterx xzcenterz yzcentery yzcenterz xyangle
|
||||
global xangle yangle zangle
|
||||
global screen
|
||||
$screen.xyplot.canv create line 0 0 [expr $xdir * 50] 0 -arrow last -fill blue
|
||||
$screen.xyplot.canv create text [expr $xdir * (50 + 10)] 2 -text X+ -fill blue
|
||||
$screen.xyplot.canv create line 0 0 0 [expr $ydir * -50] -arrow last -fill blue
|
||||
$screen.xyplot.canv create text -2 [expr $ydir * -(50 + 10)] -text Y+ -fill blue
|
||||
$screen.xyplot.canv xview moveto $xycenterx
|
||||
$screen.xyplot.canv yview moveto $xycentery
|
||||
|
||||
$screen.xzplot.canv create line 0 0 [expr $xdir * 50] 0 -arrow last -fill blue
|
||||
$screen.xzplot.canv create text [expr $xdir * (50 + 10)] 2 -text X+ -fill blue
|
||||
$screen.xzplot.canv create line 0 0 0 [expr $zdir * -50] -arrow last -fill blue
|
||||
$screen.xzplot.canv create text -2 [expr $zdir * -(50 + 10)] -text Z+ -fill blue
|
||||
$screen.xzplot.canv xview moveto $xzcenterx
|
||||
$screen.xzplot.canv yview moveto $xzcenterz
|
||||
$screen.yzplot.canv create line 0 0 [expr $ydir * 50] 0 -arrow last -fill blue
|
||||
$screen.yzplot.canv create text [expr $ydir * (50 + 10)] 2 -text Y+ -fill blue
|
||||
$screen.yzplot.canv create line 0 0 0 [expr $zdir * -50] -arrow last -fill blue
|
||||
$screen.yzplot.canv create text -2 [expr $zdir * -(50 + 10)] -text Z+ -fill blue
|
||||
$screen.yzplot.canv xview moveto $yzcentery
|
||||
$screen.yzplot.canv yview moveto $yzcenterz
|
||||
|
||||
set xyangle $xangle
|
||||
set 3dxyangle [expr $xyangle * 0.017453]
|
||||
set xycosangle [expr cos($3dxyangle)]
|
||||
set xysinangle [expr sin($3dxyangle)]
|
||||
|
||||
$screen.3dplot.canv create line 0 0 [expr $xdir * $xycosangle * 50] \
|
||||
[expr $xdir * $xysinangle * -50] -arrow last -fill blue
|
||||
$screen.3dplot.canv create text [expr $xdir * $xycosangle * 60]\
|
||||
[expr $xdir * $xysinangle * -60] -text X+ -fill blue
|
||||
$screen.3dplot.canv create line 0 0 [expr $ydir * $xycosangle * -50] \
|
||||
[expr $ydir * $xysinangle * -50] -arrow last -fill blue
|
||||
$screen.3dplot.canv create text [expr $ydir * $xycosangle * -60] \
|
||||
[expr $ydir * $xysinangle * -60] -text Y+ -fill blue
|
||||
$screen.3dplot.canv create line 0 0 0 [expr $zdir * -50] -arrow last -fill blue
|
||||
$screen.3dplot.canv create text -2 [expr $zdir * - 60] -text Z+ -fill blue
|
||||
$screen.3dplot.canv xview moveto $xycenterx
|
||||
$screen.3dplot.canv yview moveto $xycentery
|
||||
}
|
||||
|
||||
# this process plots the motion of the tool center
|
||||
# it is commanded by a line [if winfo exists .plot] in updateStatus
|
||||
|
||||
set xlast 0
|
||||
set ylast 0
|
||||
set zlast 0
|
||||
set plotcolor brown
|
||||
|
||||
proc updatePlot {} {
|
||||
global size screen unitsetting
|
||||
global xdir ydir zdir
|
||||
global xnext ynext znext yrnext zrnext xlast ylast zlast
|
||||
global xoffset yoffset zoffset xycosangle xysinangle
|
||||
global programfiletext posdigit0 posdigit1 posdigit2 activeLine plotcolor
|
||||
global 3dxnext 3dynext 3dznext 3dyrnext 3dylast 3dxlast 3dzlast 3dyrlast
|
||||
|
||||
# hack to divide scale for mm plotting
|
||||
if {$unitsetting == "(mm)" } {
|
||||
set scaler 25.4
|
||||
} else {
|
||||
set scaler 1
|
||||
}
|
||||
set posdigitx0 [expr $posdigit0 / $scaler]
|
||||
set posdigitx1 [expr $posdigit1 / $scaler]
|
||||
set posdigitx2 [expr $posdigit2 / $scaler]
|
||||
|
||||
# Color plot line by setting active line to upcase thisstring
|
||||
set thisstring [string toupper [$programfiletext get $activeLine.0 $activeLine.end]]
|
||||
# Search thisstring for g0-3 but make modal with no else
|
||||
if { [string first G2 $thisstring] != -1 || \
|
||||
[string first G02 $thisstring] != -1 } {
|
||||
set plotcolor red
|
||||
} elseif { [string first G3 $thisstring] != -1 || \
|
||||
[string first G03 $thisstring] != -1 } {
|
||||
set plotcolor blue
|
||||
} elseif { [string first G1 $thisstring] != -1 || \
|
||||
[string first G01 $thisstring] != -1 } {
|
||||
set plotcolor black
|
||||
} elseif { [string first G$screen $thisstring] != -1 } {
|
||||
continue
|
||||
} elseif { [string first G0 $thisstring] != -1 } {
|
||||
set plotcolor lightgreen
|
||||
}
|
||||
|
||||
if {$size < 1} {set size 1} {
|
||||
set xnext [expr $xoffset + ($posdigitx0 * $size * $xdir)]
|
||||
set ynext [expr $yoffset + ($posdigitx1 * $size * $ydir)]
|
||||
set znext [expr $zoffset + ($posdigitx2 * $size * $zdir)]
|
||||
|
||||
if {$xlast != $xnext || $ylast != $ynext || $zlast != $znext} {
|
||||
# these routines reverse y direction, plot xy and move tool
|
||||
set yrlast [expr -1 * $ylast]
|
||||
set yrnext [expr -1 * $ynext]
|
||||
$screen.xyplot.canv create line $xlast $yrlast $xnext $yrnext -fill $plotcolor
|
||||
$screen.xyplot.canv move xytool [expr $xnext - $xlast] [expr $yrnext - $yrlast]
|
||||
|
||||
# these routines reverse z direction plot xz and yz and move arrows
|
||||
set zrlast [expr -1 * $zlast]
|
||||
set zrnext [expr -1 * $znext]
|
||||
$screen.xzplot.canv create line $xlast $zrlast $xnext $zrnext -fill $plotcolor
|
||||
$screen.xzplot.canv move xzarrow [expr $xnext - $xlast] [expr $zrnext - $zrlast]
|
||||
$screen.yzplot.canv create line $ylast $zrlast $ynext $zrnext -fill $plotcolor
|
||||
$screen.yzplot.canv move yzarrow [expr $ynext - $ylast] [expr $zrnext - $zrlast]
|
||||
|
||||
# 3D plot calculations
|
||||
set 3dxnext [expr [expr $xnext * $xycosangle] + [expr $ynext * -1 * $xycosangle]]
|
||||
set 3dynext [expr [expr $xnext * $xysinangle] + [expr $ynext * $xysinangle] + $znext]
|
||||
# Plot 3D xy and move tool
|
||||
set 3dyrlast [expr -1 * $3dylast]
|
||||
set 3dyrnext [expr -1 * $3dynext]
|
||||
$screen.3dplot.canv create line $3dxlast $3dyrlast $3dxnext $3dyrnext -fill $plotcolor
|
||||
$screen.3dplot.canv move 3darrow [expr $3dxnext - $3dxlast] [expr $3dyrnext - $3dyrlast]
|
||||
|
||||
set 3dxlast $3dxnext
|
||||
set 3dylast $3dynext
|
||||
set 3dzlast $3dznext
|
||||
set xlast $xnext
|
||||
set ylast $ynext
|
||||
set zlast $znext
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user