TclTk - Divers exemples simples à comprendre
Rédigé par spheris
Aucun commentaire
Bonjour,
Aujourd'hui nous allons nous intéresser au langage interprété Tcl avec l'interface graphique Tk.
Ces outils nous permettent de créer de façon très simple et très rapide des interfaces pour linux, windows, mac et plein d'autre OS.
Introduction et pré requi.
Tout d'abord il vous faut installer le paquet Tcl pour utiliser le langage en ligne de commande.
Ensuite vous devez installer le paquet wish qui installera la dernière version de la librairie tk.
Pour exécuter les logiciels ci dessous, il vous suffit de copier le code source, le copier dans un fichier texte et l'enregistrer avec l'extention .tcl puis de l'exécuter en ligne de commande comme ceci :
wish myfile.tcl
A) Une calculatrice

Voici le code de l'application :
wm title . Calculator grid [entry .e -textvar e -just right] -columnspan 5 bind .e <Return> = set n 0 foreach row { {7 8 9 + -} {4 5 6 * /} {1 2 3 ( )} {C 0 . = } } { foreach key $row { switch -- $key { = {set cmd =} C {set cmd {set clear 1; set e ""}} default {set cmd "hit $key"} } lappend keys [button .[incr n] -text $key -command $cmd] } eval grid $keys -sticky we ;#-padx 1 -pady 1 set keys [list] } grid .$n -columnspan 2 ;# make last key (=) double wide proc = {} { regsub { =.+} $::e "" ::e ;# maybe clear previous result if [catch {set ::res [expr [string map {/ *1.0/} $::e]]}] { .e config -fg red } append ::e = $::res .e xview end set ::clear 1 } proc hit {key} { if $::clear { set ::e "" if ![regexp {[0-9().]} $key] {set ::e $::res} .e config -fg black .e icursor end set ::clear 0 } .e insert end $key } set clear 0 focus .e ;# allow keyboard input wm resizable . 0 0
B) Un calendrier

Voici le code de l'application :
#!/bin/sh # the next line restarts using wish exec wish "$0" "$@" # ------------------------------------------------------------------------------ # -- # -- calendar.tcl (Calendar for Linux/Unix & Windows) # -- # -- Copyright (C) 2004-2014 Stefan Euler # -- # -- This program is free software; you can redistribute it # -- and/or modify it under the terms of the GNU General Public # -- License as published by the Free Software Foundation; # -- either version 2 of the License, or (at your option) # -- any later version. # -- # -- This program is distributed in the hope that it will be # -- useful, but WITHOUT ANY WARRANTY; without even the implied # -- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR # -- PURPOSE. See the GNU General Public License for more details. # -- # -- You should have received a copy of the GNU General Public # -- License along with this program; if not, write to the Free # -- Software Foundation, Inc., 59 Temple Place, Suite 330, # -- Boston, MA 02111-1307, USA. # -- # ------------------------------------------------------------------------------ # -- # -- Usage : # -- calendar.tcl [winpos] [action on click] [show date] # -- # -- winpos = X and Y position for calendar window # -- (String of form '+100+150') # -- (defaults to '+200+150') # -- action on click = Action after selecting a date # -- 'close' -> Close window (exit 'calendar.tcl') # -- (= default) # -- 'hide' -> Hide window # -- 'icon' -> Iconify window # -- show date = open the month and year of the 'show date' # -- (String of form 'dd-mmm-yyyy') # -- (e.g. '02-Jul-2008') # -- # -- Output : # -- Cancel/Close : Empty string # -- Day button : Date string (dd.mm.yyyy) # -- # -- Keybindings : # -- Escape -> Close calendar (same as pressing 'Close' button) # -- Return -> Select active date (same as pressing day button) # -- Cursor up -> Go to the next month # -- Cursor down -> Go to the previous month # -- Cursor left -> Set active date to the previous day # -- Cursor right -> Set active date to the next day # -- Page up -> Go to the next year # -- Page down -> Go to the previous year # -- # ------------------------------------------------------------------------------ # -- # -- Last modified : 25-Mar-2014 # -- Version : 0.24 # -- Author : Stefan Euler # -- # ------------------------------------------------------------------------------ # -- global variables global tk_strictMotif; set tk_strictMotif 1 # ------------------------------------------------------------------------------ namespace eval CALENDAR { variable cal variable fheight variable htem variable os_type package require Tk set cal(col,0) "black" set cal(col,1) "white" set cal(col,2) "#e0e0e0" set cal(col,3) "#dfdfdf" set cal(col,4) "red" set cal(col,5) "blue" set cal(col,6) "#ffa0a0" set cal(col,7) "#ff2020" set cal(col,8) "#a0a0a0" set cal(sfont) -adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1 set cal(fheight) [font metrics $cal(sfont) -linespace] set cal(prg_vers) "V 0.24" set os_type $tcl_platform(platform) set cal(tcl,full) [info tclversion] set cal(tcl,maj) [lindex [split $cal(tcl,full) "."] 0] set cal(tcl,min) [lindex [split $cal(tcl,full) "."] 1] set cal(tcl,new) 0 if {$cal(tcl,maj) == 8} { if {$cal(tcl,min) >= 5} { set cal(tcl,new) 1 } } elseif {$cal(tcl,maj) > 8} { set cal(tcl,new) 1 } # -- ttk theme # set cal(ttk_theme) vista set cal(ttk_theme) aqua # -- Window size if {$tcl_platform(platform) == "windows"} { set cal(wsizex) 150 set cal(wsizey) 235 } else { set cal(wsizex) 180 set cal(wsizey) 230 } } # ------------------------------------------------------------------------------ # -- Procs # -- Check options proc CALENDAR::check_options { argv } { variable cal set opt_num [llength $argv] foreach argu $argv { if {$argu == "close" || $argu == "hide" || $argu == "icon"} { set cal(click) "$argu" } elseif {[string index $argu 0] == "+" || [string index $argu 0] == "-"} { set cal(winpos) "$argu" } else { if {$argu != ""} { set cal(sdate) "$argu" } } } return } # ------------------------------------------------------------------------------ # -- Initialize variables proc CALENDAR::init_all { args } { variable cal # -- Styles for ttk widgets ttk::style configure cal_days.TButton -background $cal(col,2) -foreground $cal(col,0) -font $cal(sfont) ttk::style configure cal_sat.TButton -background $cal(col,6) -foreground $cal(col,0) -font $cal(sfont) ttk::style configure cal_sun.TButton -background $cal(col,7) -foreground $cal(col,0) -font $cal(sfont) ttk::style configure cal_today.TButton -background $cal(col,5) -foreground $cal(col,5) -font $cal(sfont) ttk::style configure cal_active.TButton -background $cal(col,8) -foreground $cal(col,4) -font $cal(sfont) ttk::style configure cal_change.TButton -background $cal(col,2) -foreground $cal(col,0) -font $cal(sfont) -height 1 -padx 6 -pady 1 ttk::style configure cal_stand.TButton -background $cal(col,2) -foreground $cal(col,0) -font $cal(sfont) -height 1 ttk::style configure cal_stand.TFrame -background $cal(col,2) -relief ridge -borderwidth 2 -height $cal(fheight) ttk::style configure cal_flat.TFrame -background $cal(col,2) -relief flat -borderwidth 0 -height $cal(fheight) ttk::style configure cal_stand.TLabel -background $cal(col,2) -foreground $cal(col,0) -relief ridge -borderwidth 2 -height $cal(fheight) set cal(click) "close" set cal(winpos) "+200+150" # -- Get current date and define global calendar values set time [clock seconds] set cal(today) [clock format $time -format "%d-%b-%Y"] set cal(sdate) $cal(today) set month [string trimleft [clock format $time -format "%m"] 0] set year [clock format $time -format "%Y"] set cal(date) "$month/1/$year" set cal(dtext) [clock format [clock scan $cal(date)] -format "%B %Y"] return } # ------------------------------------------------------------------------------ # -- Exit calendar proc CALENDAR::exit_cal { args } { CALENDAR::Window destroy .cal exit } # ------------------------------------------------------------------------------ # -- Select the active date proc CALENDAR::select_active_date { args } { variable cal set selected_date [clock format [clock scan $cal(date)] -format "%d.%m.%Y"] puts "$selected_date" CALENDAR::select_action return } # ------------------------------------------------------------------------------ # -- Action after date selection proc CALENDAR::select_action { args } { variable cal if {$cal(click) == "close"} { CALENDAR::exit_cal } elseif {$cal(click) == "hide"} { CALENDAR::Window hide .cal } elseif {$cal(click) == "icon"} { CALENDAR::Window iconify .cal } return } # ------------------------------------------------------------------------------ # -- Display current time in 'HH:MM' format proc CALENDAR::set_time { win } { variable cal set time [clock seconds] set cal(today) [clock format $time -format "%b-%d-%Y"] if {$cal(tcl,new)} { set ctime [clock format $time -format "%H:%M" -timezone :localtime] } else { set ctime [clock format $time -format "%H:%M"] } append cal(today) " - $ctime" update after 1000 [list CALENDAR::set_time $win] return } # ------------------------------------------------------------------------------ # -- Change to current month proc CALENDAR::goto_today { win } { variable cal set time [clock seconds] set month [string trimleft [clock format $time -format "%m"] 0] set year [clock format $time -format "%Y"] set cal(date) "$month/1/$year" set cal(dtext) [clock format [clock scan $cal(date)] -format "%B %Y"] # -- Update calendar sheet CALENDAR::set_cal_sheet $win update return } # ------------------------------------------------------------------------------ # -- Change to month of 'show date' proc CALENDAR::goto_sdate { win } { variable cal set sdate_int [clock scan $cal(sdate)] set day [clock format $sdate_int -format "%d"] set month [string trimleft [clock format $sdate_int -format "%m"] 0] set year [clock format $sdate_int -format "%Y"] set cal(date) "$month/$day/$year" set cal(dtext) [clock format $sdate_int -format "%B %Y"] # -- Update calendar sheet CALENDAR::set_cal_sheet $win update return } # ------------------------------------------------------------------------------ # -- Display next (ri=+1) or previous (ri=-1) day, month or year proc CALENDAR::incr_dmy { what ri win } { variable cal set rich [expr $ri] set year [clock format [clock scan $cal(date)] -format "%Y"] set month [string trimleft [clock format [clock scan $cal(date)] -format "%m"] 0] set day [clock format [clock scan $cal(date)] -format "%d"] if {$cal(tcl,new)} { set nday [clock add [clock scan $cal(date)] $rich $what] } else { set nday [clock scan "$rich $what" -base [clock scan "$year-$month-$day"]] } set cal(date) [clock format $nday -format "%m/%d/%y"] set cal(dtext) [clock format [clock scan $cal(date)] -format "%B %Y"] # -- Update calendar sheet CALENDAR::set_cal_sheet $win update return } # ------------------------------------------------------------------------------ # -- Display days of the month and calendar weeks proc CALENDAR::set_cal_sheet { win } { variable cal variable htem # -- Check the current Tcl version set cal(tcl,new) 0 if {$cal(tcl,maj) == 8} { if {$cal(tcl,min) >= 5} { set cal(tcl,new) 1 } } elseif {$cal(tcl,maj) > 8} { set cal(tcl,new) 1 } set time [clock seconds] set now [clock format $time -format "%d.%m.%Y"] # -- Day of the active date set day [clock format [clock scan $cal(date)] -format "%d"] # -- Month of the active date set month [clock format [clock scan $cal(date)] -format "%m"] # -- Year of the active date set year [clock format [clock scan $cal(date)] -format "%Y"] # -- First day of the active month/year set cdate "$month/1/$year" # -- Active day set acday "$day.$month.$year" # -- Day of the week (1=Monday,...,7 or 0=Sunday) set wday [clock format [clock scan $cdate] -format "%u"] if {$wday == 0} { set wday 7 } incr wday # -- Effective current date for start of calendar sheet - 1 day set day_off [expr -1 * ($wday - 1)] if {$cal(tcl,new)} { set curr_date [clock add [clock scan $cdate] $day_off days] } else { set curr_date [clock scan $cdate] set curr_date "[expr $curr_date + ($day_off * 86400)]" } set c 0 foreach eintrag {"CW" "Mo" "Tu" "We" "Th" "Fr" "Sa" "Su"} { $win.fr_days.la_0$c configure -style cal_stand.TLabel -text "$eintrag" incr c } # -- Each line (calendar weeks) for {set r 1} {$r <= 6} {incr r} { set k 0 $win.fr_days.la_$r$k configure -text "11" # -- Each row (days of the week) for {set c 1} {$c <= 7} {incr c} { if {$cal(tcl,new)} { set curr_date [clock add $curr_date 1 day] } else { set curr_date [expr $curr_date + 86400] } set month2 [clock format $curr_date -format "%m"] if {$c == 1} { set kw [clock format $curr_date -format "%W"] $win.fr_days.la_$r$k configure -text "$kw" } if {$month2 == $month} { set day [string trimleft [clock format $curr_date -format "%d"] 0] set htem [clock format $curr_date -format "%d.%m.%Y"] if {$htem == $acday} { $win.fr_days.bu_$r$c configure -style cal_active.TButton } elseif {$htem == $now} { $win.fr_days.bu_$r$c configure -style cal_today.TButton } elseif {$c <= 5} { $win.fr_days.bu_$r$c configure -style cal_days.TButton } elseif {$c == 6} { $win.fr_days.bu_$r$c configure -style cal_sat.TButton } elseif {$c == 7} { $win.fr_days.bu_$r$c configure -style cal_sun.TButton } $win.fr_days.bu_$r$c configure -text "$day" -command "puts $CALENDAR::htem; CALENDAR::select_action" } elseif {$c >= 1} { $win.fr_days.bu_$r$c configure -style cal_days.TButton -text "" -command "" } } } CALENDAR::set_time $win return } # ------------------------------------------------------------------------------ # -- Check the window's position (should be completely inside screen) proc CALENDAR::check_win_pos { args } { variable cal variable os_type update # -- Get the X position set mxpos [lindex [split $cal(winpos) "+"] 1] set mypos [lindex [split $cal(winpos) "+"] 2] # -- Take care that the window is positioned within the screen set scr_width [winfo screenwidth .] set scr_height [winfo screenheight .] set win_width [winfo width .cal] set win_height [winfo height .cal] # -- Check the window's X position set wxpos [winfo x .cal] # -- stay at least within the screen area if {$wxpos < 0} { set wxpos 0 } elseif {[expr $wxpos + $win_width + 12] >= $scr_width} { set wxpos [expr $scr_width - $win_width - 12] } # -- Check the window's Y position set wypos [winfo y .cal] # -- stay at least within the screen area if {$wypos < 0} { set wypos 0 } elseif {[expr $wypos + $win_height + 60] >= $scr_height} { set wypos [expr $scr_height - $win_height - 60] } set cal(winpos) "+$wxpos+$wypos" if {$os_type == "windows"} { set pos "[expr [winfo width .cal.fr_days] + 40]" append pos "x$cal(wsizey)" append pos "$cal(winpos)" } else { set pos "[expr [winfo width .cal.fr_days] + 40]" append pos "x$cal(wsizey)" append pos "$cal(winpos)" } wm geometry .cal "$pos" return } # ------------------------------------------------------------------------------ # -- Window procedur proc CALENDAR::Window { args } { set cmd [lindex $args 0] set name [lindex $args 1] set newname [lindex $args 2] set rest [lrange $args 3 end] if {$name == "" || $cmd == ""} { return } if {$newname == ""} { set newname $name } set exists [winfo exists $newname] switch $cmd { show { if {$exists == "1" && $name != "."} { wm deiconify $name return } if {[info procs calWindow(pre)$name] != ""} { eval "calWindow(pre)$name $newname $rest" } if {[info procs calWindow$name] != ""} { eval "calWindow$name $newname $rest" } if {[info procs calWindow(post)$name] != ""} { eval "calWindow(post)$name $newname $rest" } } hide { if $exists { wm withdraw $newname return } } iconify { if $exists { wm iconify $newname return } } destroy { if $exists { destroy $newname return } } } return } # ------------------------------------------------------------------------------ # -- Root Window for Calendar proc CALENDAR::calWindow. { base } { if {$base == ""} { set base . } wm focusmodel $base passive wm geometry $base 1x1+0+0 wm maxsize $base 1137 834 wm minsize $base 1 1 wm overrideredirect $base 0 wm resizable $base 1 1 wm withdraw $base wm title $base "eu_calendar.tcl" return } # ------------------------------------------------------------------------------ # -- Calendar window proc CALENDAR::calWindow.cal { base } { global glob_var variable cal variable os_type if {$base == ""} { set base .cal } if {[winfo exists .cal]} { wm deiconify .cal return } toplevel $base -class Toplevel -background $cal(col,2) wm focusmodel $base passive if {$os_type == "windows"} { set pos "$cal(wsizex)" append pos "x$cal(wsizey)" append pos "$cal(winpos)" } else { set pos "$cal(wsizex)" append pos "x$cal(wsizey)" append pos "$cal(winpos)" } wm geometry $base $pos wm maxsize $base 400 400 wm minsize $base 1 1 wm overrideredirect $base 0 wm resizable $base 0 0 wm deiconify $base wm title $base "CALENDAR" wm protocol $base WM_DELETE_WINDOW {puts ""; CALENDAR::exit_cal} # -- Header frame with month and buttons to move in months and years set fr_month [ttk::frame $base.fr_month -style cal_stand.TFrame -relief flat] set yd_month [ttk::button $base.fr_month.bu_ydown -style cal_change.TButton -text "<<" -width 2 -command "CALENDAR::incr_dmy years -1 $base"] set md_month [ttk::button $base.fr_month.bu_mdown -style cal_change.TButton -text "<" -width 1 -command "CALENDAR::incr_dmy months -1 $base"] set la_month [ttk::label $base.fr_month.la_month -foreground $cal(col,0) -background $cal(col,2) -borderwidth 1 -relief ridge -textvariable CALENDAR::cal(dtext) -font $cal(sfont) -anchor c] if {$os_type == "windows"} { $base.fr_month.la_month configure -relief flat } set mu_month [ttk::button $base.fr_month.bu_mup -style cal_change.TButton -text ">" -width 1 -command "CALENDAR::incr_dmy months +1 $base"] set yu_month [ttk::button $base.fr_month.bu_yup -style cal_change.TButton -text ">>" -width 2 -command "CALENDAR::incr_dmy years +1 $base"] # -- Bottom frame with current date set fr_bottom [ttk::frame $base.fr_today -style cal_stand.TFrame] set la1_bottom [ttk::label $base.fr_today.la_today -foreground $cal(col,0) -background $cal(col,2) -borderwidth 0 -relief flat -text "Today :" -width 7 -font $cal(sfont) -anchor w] set la2_bottom [ttk::label $base.fr_today.la_todat -foreground $cal(col,0) -background $cal(col,2) -borderwidth 0 -relief flat -textvariable CALENDAR::cal(today) -width 20 -font $cal(sfont) -anchor w] # -- Frame with 'Close' button set fr_close [ttk::frame $base.fr_close -style cal_stand.TFrame] set bu_close [ttk::button $base.fr_close.bu_close -style cal_stand.TButton -text "Close" -command { puts "" CALENDAR::exit_cal }] # -- Frame for days set fr_days [ttk::frame $base.fr_days -style cal_flat.TFrame] # -- Header (CW, Mo, Tu, We, Th, Fr, Sa, Su) if {$os_type == "windows"} { set ypad 4 } else { set ypad 1 } set c 0 foreach eintrag {"CW" "Mo" "Tu" "We" "Th" "Fr" "Sa" "Su"} { ttk::label $base.fr_days.la_0$c -style cal_stand.TLabel -text "$eintrag" -font $cal(sfont) -anchor c incr c } # -- Define 6 * 8 buttons for {set r 1} {$r <= 6} {incr r} { set c 0 ttk::label $base.fr_days.la_$r$c -style cal_stand.TLabel -text "11" -width 2 -font $cal(sfont) -anchor c for {set c 1} {$c <= 7} {incr c} { ttk::button $base.fr_days.bu_$r$c -style cal_days.TButton -width 2 -text "" -command "" if {$c == 6} { $base.fr_days.bu_$r$c configure -style cal_sat.TButton } if {$c == 7} { $base.fr_days.bu_$r$c configure -style cal_sun.TButton } } } # -- Display header frame (<< < MONTH > >>) pack $base.fr_month -anchor c -expand 0 -fill x -side top -padx 2 -ipadx 2 -ipady 2 pack $base.fr_month.bu_ydown -side left pack $base.fr_month.bu_mdown -side left pack $base.fr_month.bu_yup -side right pack $base.fr_month.bu_mup -side right pack $base.fr_month.la_month -side left -expand 1 -fill x # -- Display frame with 'Close' button pack $base.fr_close -anchor c -expand 0 -fill x -side bottom -padx 2 -ipadx 2 -ipady 2 pack $base.fr_close.bu_close -padx 2 -anchor c -expand 1 -fill x -side left # -- Display bottom frame with current date pack $base.fr_today -anchor c -expand 0 -fill x -side bottom -padx 2 -ipadx 2 -ipady 2 pack $base.fr_today.la_today -anchor center -expand 0 -fill none -side left -padx 2 pack $base.fr_today.la_todat -anchor center -expand 0 -fill none -side left -padx 2 # -- Display frame with days pack $base.fr_days -anchor c -expand 1 -fill both -side left -padx 2 -ipadx 2 -ipady 2 grid rowconfig $base.fr_days all -weight 1 grid columnconfig $base.fr_days all -weight 1 # -- Display header (CW, Mo, Tu, We, Th, Fr, Sa, Su) for {set c 0} {$c <= 7} {incr c} { grid $base.fr_days.la_0$c -row 0 -column $c -columnspan 1 -rowspan 1 -ipadx 2 -ipady 2 -sticky nsew } # -- Display 6 * 8 buttons for {set r 1} {$r <= 6} {incr r} { set c 0 grid $base.fr_days.la_$r$c -row $r -column $c -rowspan 1 -columnspan 1 -ipadx 2 -ipady 2 -sticky nsew for {set c 1} {$c <= 7} {incr c} { grid $base.fr_days.bu_$r$c -row $r -column $c -rowspan 1 -columnspan 1 -ipadx 0 -ipady 0 -sticky nsew } } # -- Bindings bind $base.fr_today <ButtonRelease-1> "CALENDAR::goto_today $base" bind $base.fr_today.la_today <ButtonRelease-1> "CALENDAR::goto_today $base" bind $base.fr_today.la_todat <ButtonRelease-1> "CALENDAR::goto_today $base" bind $base <KeyRelease-Prior> "CALENDAR::incr_dmy years +1 $base" bind $base <KeyRelease-Next> "CALENDAR::incr_dmy years -1 $base" bind $base <KeyRelease-Up> "CALENDAR::incr_dmy months +1 $base" bind $base <KeyRelease-Down> "CALENDAR::incr_dmy months -1 $base" bind $base <KeyRelease-Left> "CALENDAR::incr_dmy days -1 $base" bind $base <KeyRelease-Right> "CALENDAR::incr_dmy days +1 $base" bind $base <KeyRelease-Home> "CALENDAR::goto_today $base" bind $base <KeyRelease-Escape> "$base.fr_close.bu_close invoke" bind $base <KeyRelease-Return> "CALENDAR::select_active_date" # ttk::setTheme $cal(ttk_theme) return } # ------------------------------------------------------------------------------ CALENDAR::init_all CALENDAR::check_options $argv CALENDAR::Window show . CALENDAR::Window show .cal CALENDAR::check_win_pos CALENDAR::goto_sdate .cal
C) Une horloge analogique

Voici le code source :
# Cadran d'horloge de Wolf-Dieter Busch (http://wiki.tcl.tk/1011) ... v. 1.8.2 - Sept 2010 # Avec quelques modifications cosmétiques : # Redimensionnement, graduations, transparence, paramétrage. # S'il trouve couleurs/vuecouleurs.tcl (noms de couleurs reconnus par tk) ou tcllib ::math::roman (chiffres romains), le script les utilise. # substexpands.tcl & hwdboptx.tcl permettent de personaliser les paramètres mais ne sont pas indispensables pour une utilisation régulière. # http://tratoxic.free.fr/t/tk.htm#scripts package require Tk # Variables utilisateur, voir aussi les dimensions dans la proc. initialisations. set hwdb(couleur_cadran) {old lace} set hwdb(couleur_chiffres) peru set hwdb(couleur_aiguilles) peru set hwdb(couleur_sec) chocolate4 set hwdb(couleur_ombres) gray83 set hwdb(format_titre) {%Okh%M %A %x} set hwdb(opacite) 1. ;# Un moins transparence (float [0:1]) set hwdb(electrique) 1 ; ;# 1 => saut à chaque minute, 0 => mécanique : sans à-coup (aiguille des minutes uniquement) set hwdb(premier_plan) 0 ;# topmost set hwdb(fond_transparent) 0 ;# ... Mais cadran visible. Sauf erreur de ma part, "wm aspect" n'est pas fonctionnel sous win xp, d'où set hwdb(bordure_systeme) 4 ;# la réalisation "en dur" de la configuration du rapport largeur/hauteur dans la proc autre_taille_cadran, set hwdb(delai_configure) 10 ;# avec un délai 5<d<50 ms limitant les ressources utilisées par le script lors des évennements "Configure". set hwdb(ombre_chiffres) 1 # Variables internes set hwdb(script) [winfo name .] set hwdb(config_en_cours) 0 ;# Sémaphore pour section exclusive (non ré-entrance dans la proc autre_taille_cadran) set hwdb(PI) [expr {acos(-1)}] set hwdb(romains) 0 ;# 0 : pour chiffres indo-arabes au démarrage. 1 : romains, n'agit qu'en présence de tcllib math::roman. set hwdb(noms_couleurs_tk) 0 ;# 0 : choix par la boîte standard -> valeur #rvb, 1 : choix avec vuecouleurs.tcl -> nom. set hwdb(console) 0 # Variables utilisateur proportionnelles aux dimensions du cadran de l'horloge, l'argument par défaut est le rayon au départ (float). # Sauf l'avant dernière, ces variables pourraient rester float. Elles sont castées int pour des raisons de performance. proc initialisations {{r 120.}} { global hwdb set hwdb(rayon) $r ;#demi-largeur du canvas conteneur (= coordonnées x=y du centre) set hwdb(bordure_cadran) [expr {int($r * .05)}] ;# marges entre le cadran et le bord du canvas set hwdb(rayon_chiffres) [expr {int($r * .83)}] set hwdb(rayon_graduations) [expr {int($r * .91)}] set hwdb(longueur_aiguille_sc) [expr {int($r * .85)}] set hwdb(longueur_aiguille_mn) [expr {int($r * .75)}] set hwdb(longueur_aiguille_hr) [expr {int($r * .60)}] set hwdb(largeur_aiguille_sc) [expr {int($r * .02)}] set hwdb(largeur_aiguille_mn) [expr {int($r * .05)}] set hwdb(largeur_aiguille_hr) [expr {int($r * .08)}] set hwdb(distance_ombre_sc) [expr {int($r * .035)}] set hwdb(distance_ombre_mn) [expr {int($r * .03)}] set hwdb(distance_ombre_hr) [expr {int($r * .025)}] set hwdb(police) "Helvetica [expr {int($r * .13)}] bold" set hwdb(rpgm) [expr {int($r / 80)}] ;# rayon d'un point de graduation des minutes return } # Détermine la forme des pointes de flêche d'aiguille. # La ligne en commentaire, "*2", "1.6" sont utilisés par la proc change_fleche dans hwdboptx.tcl proc fleche largeur { # return "[set a [expr {$largeur*2}]] $a [expr {$largeur/2}]" return "[set a [expr {int($largeur*1.6)}]] $a 1" } # Dessine le tout : Cadran, graduations, aiguilles et chiffres. proc dessine_le_tout {} { global hwdb set r $hwdb(rayon) # cadran set mbd [expr {2 * $r - $hwdb(bordure_cadran)}] ; # marge en bas et à droite .c create oval $hwdb(bordure_cadran) $hwdb(bordure_cadran) $mbd $mbd -fill $hwdb(couleur_cadran) -outline {} -tag cadran # graduations (12 x 4 points, sans le "if $i %5" pour 60 points) set rp [expr int($hwdb(rpgm))] for {set i 0} {$i < 60} {incr i} { if {[expr {$i % 5}]} { set a [expr {$hwdb(PI) / 30 * (30 - $i)}] set x [expr {int( sin( $a ) * $hwdb(rayon_graduations) + $hwdb(rayon) )}] set y [expr {int( cos( $a ) * $hwdb(rayon_graduations) + $hwdb(rayon) )}] if {$r < 100} { .c create line $x $y [incr x] [incr y] -tag graduations -fill $hwdb(couleur_sec) ;# 1 point } else { .c create oval [expr {$x - $rp}] [expr {$y - $rp}] [incr x $rp] [incr y $rp] -tag graduations -fill $hwdb(couleur_sec) -outline {} } } } # chiffres for {set i 1} {$i <= 12} {incr i} { set a [expr {$hwdb(PI) / 6 * (6 - $i)}] set x [expr {sin( $a ) * $hwdb(rayon_chiffres) + $r}] set y [expr {cos( $a ) * $hwdb(rayon_chiffres) + $r}] set t [expr {$hwdb(romains) ? [::math::roman::toroman $i] : $i }] if $hwdb(ombre_chiffres) {.c create text [expr {$x+$hwdb(distance_ombre_hr)/1.5}] [expr {$y+$hwdb(distance_ombre_hr)/1.5}] -text $t -font $hwdb(police) -fill $hwdb(couleur_ombres) -tag ombre_chiffres} .c create text $x $y -text $t -font $hwdb(police) -fill $hwdb(couleur_chiffres) -tag chiffres } # aiguilles au dessus de leurs ombres, axe de la trotteuse qui masque le bout carré des aiguilles h et mn (tracé initial de WDB à 3h00mn30s). .c create line $r $r [expr {$r + $hwdb(longueur_aiguille_hr)}] $r -tag ombre_hr -width $hwdb(largeur_aiguille_hr) -fill $hwdb(couleur_ombres) -arrow last -arrowshape [fleche $hwdb(largeur_aiguille_hr)] .c create line $r $r $r [expr {$r - $hwdb(longueur_aiguille_mn)}] -tag ombre_mn -width $hwdb(largeur_aiguille_mn) -fill $hwdb(couleur_ombres) -arrow last -arrowshape [fleche $hwdb(largeur_aiguille_mn)] .c create line $r $r $r [expr {$r + $hwdb(longueur_aiguille_sc)}] -tag ombre_sc -width $hwdb(largeur_aiguille_sc) -fill $hwdb(couleur_ombres) -arrow last -arrowshape [fleche $hwdb(largeur_aiguille_sc)] .c create line $r $r [expr {$r + $hwdb(longueur_aiguille_hr)}] $r -tag aiguille_hr -width $hwdb(largeur_aiguille_hr) -fill $hwdb(couleur_aiguilles) -arrow last -arrowshape [fleche $hwdb(largeur_aiguille_hr)] .c create line $r $r $r [expr {$r - $hwdb(longueur_aiguille_mn)}] -tag aiguille_mn -width $hwdb(largeur_aiguille_mn) -fill $hwdb(couleur_aiguilles) -arrow last -arrowshape [fleche $hwdb(largeur_aiguille_mn)] if {$hwdb(largeur_aiguille_sc) > $hwdb(largeur_aiguille_mn)} {set amx $hwdb(largeur_aiguille_sc)} else {set amx $hwdb(largeur_aiguille_mn)} if {$hwdb(largeur_aiguille_hr) > $amx} {set amx $hwdb(largeur_aiguille_hr)} set hg [expr {$r - $amx / 2}] ; set ohg [expr {$hg + $hwdb(distance_ombre_sc)}] set bd [expr {$r + $amx / 2}] ; set obd [expr {$bd + $hwdb(distance_ombre_sc)}] .c create oval $hg $hg $bd $bd -outline {} -fill $hwdb(couleur_sec) -tag axe .c create oval $ohg $ohg $obd $obd -outline {} -fill $hwdb(couleur_ombres) -tag ombre_axe .c create line $r $r $r [expr {$r + $hwdb(longueur_aiguille_sc)}] -tag aiguille_sc -width $hwdb(largeur_aiguille_sc) -fill $hwdb(couleur_sec) -arrow last -arrowshape [fleche $hwdb(largeur_aiguille_sc)] foreach i {ombre_axe ombre_hr ombre_mn ombre_sc} {.c lower $i graduations} return } # Rotation d'un angle a d'une aiguille et de son ombre spécifiées par leur tag d'une quantité # n d'unités (hr, mn, sec). Fournir aussi la longueur de l'aiguille et la distance avec son ombre. proc tourne_aiguille {tag_aig tag_omb n longueur d_omb} { global hwdb switch $tag_aig {aiguille_hr {set div 6} aiguille_mn {set div 30} aiguille_sc {set div 30}} set a [expr {$hwdb(PI) * ($div - $n) / $div}] set x [expr {$hwdb(rayon) + sin($a) * $longueur}] set y [expr {$hwdb(rayon) + cos($a) * $longueur}] .c coords $tag_aig $hwdb(rayon) $hwdb(rayon) $x $y set oc [expr {$hwdb(rayon) + $d_omb}] .c coords $tag_omb $oc $oc [expr {$x + $d_omb}] [expr {$y + $d_omb}] return } # Procédure auto-entretenue qui fait tourner les aiguilles. # Les aiguilles des heures et minutes sont positionnées quand un nouveau cadran est dessiné, ou seulement une fois par minute. # Cas particulier : mécanique, l'aiguille des mn avance à chaque seconde. proc une_fois_par_seconde {{init 0}} { global hwdb set hwdb(timer) [after 1000 une_fois_par_seconde] set secs [clock seconds] set l [clock format $secs -format {%H %M %S}] set hrs [regsub ^0 [lindex $l 0] {}] set min [regsub ^0 [lindex $l 1] {}] set sec [regsub ^0 [lindex $l 2] {}] set hrs [expr {$hrs + $min/60.}] if {$init || (!$sec && ![wm overrideredirect .])} { wm title . [clock format $secs -format $hwdb(format_titre) -locale current] } tourne_aiguille aiguille_sc ombre_sc $sec $hwdb(longueur_aiguille_sc) $hwdb(distance_ombre_sc) if $init { tourne_aiguille aiguille_mn ombre_mn $min $hwdb(longueur_aiguille_mn) $hwdb(distance_ombre_mn) tourne_aiguille aiguille_hr ombre_hr $hrs $hwdb(longueur_aiguille_hr) $hwdb(distance_ombre_hr) return } if !$hwdb(electrique) { tourne_aiguille aiguille_mn ombre_mn [expr {$min + $sec/60.}] $hwdb(longueur_aiguille_mn) $hwdb(distance_ombre_mn) } else { if !$sec {tourne_aiguille aiguille_mn ombre_mn $min $hwdb(longueur_aiguille_mn) $hwdb(distance_ombre_mn)} } if !$sec {tourne_aiguille aiguille_hr ombre_hr $hrs $hwdb(longueur_aiguille_hr) $hwdb(distance_ombre_hr)} return } # Basculements entre fenêtre sans et avec le cadre du système d'exploitation. # Le titre n'étant mis à jour qu'à chaque minute (secondes = 0), "avec cadre" se fait avec titre, sans transparence. # Le cadre supprimé, ombres et cadran deviennent transparents. proc toggle_visu {} { global hwdb ;# s'il n'y a pas de cadre, on le remet : if [wm overrideredirect .] { wm title . [clock format [clock seconds] -format $hwdb(format_titre) -locale current] wm overrideredirect . 0 wm attributes . -transparentcolor {} -alpha 1 .c itemconfigure cadran -fill $hwdb(couleur_cadran) if $hwdb(ombre_chiffres) {.c itemconfigure ombre_chiffres -fill $hwdb(couleur_ombres)} foreach i {ombre_hr ombre_mn ombre_sc ombre_axe} { .c itemconfigure $i -fill $hwdb(couleur_ombres) } } else { set c [.c cget -background] ;# la couleur du fond devient la "couleur transparente" wm overrideredirect . 1; wm withdraw .; wm deiconify . ;# on/off : pour les systèmes qui ne réagiraient pas, cf. doc. tk wm attributes . -transparentcolor $c -alpha $hwdb(opacite) update if $hwdb(ombre_chiffres) {.c itemconfigure ombre_chiffres -fill $c} foreach i {cadran ombre_hr ombre_mn ombre_sc ombre_axe} { .c itemconfigure $i -fill $c } } return } # Arrête le temporisateur le temps d'effacer tout et de redessiner, puis le redémarre. proc stop_change_redemarre {} { global hwdb after cancel $hwdb(timer) set rayon [expr {[set largeur [scan [wm geometry .] %f]] / 2.}] if $hwdb(ombre_chiffres) {.c delete ombre_chiffres} .c delete aiguille_sc ombre_axe axe aiguille_mn aiguille_hr ombre_sc ombre_mn ombre_hr chiffres graduations cadran initialisations $rayon .c configure -width $largeur -height $largeur if [wm overrideredirect .] {set c $hwdb(couleur_cadran) ; set hwdb(couleur_cadran) [.c cget -background]} dessine_le_tout if [wm overrideredirect .] {set hwdb(couleur_cadran) $c} une_fois_par_seconde 1 } # Dans une section non ré-entrante ... Si la largeur n'a pas changé, force une fenêtre carrée quand ce n'est pas le cas, # sinon fait redessiner le tout. proc autre_taille_cadran {} { global hwdb if $hwdb(config_en_cours) return ;# limite le nombre de réactions devant l'avalanche d'évennements "Configure" incr hwdb(config_en_cours) set g [split [wm geometry .] x+] set l [lindex $g 0] set h [lindex $g 1] set m [expr {($l > $h) ? $l : $h}] if {$m == [expr {2 * int($hwdb(rayon))}]} { if {$l != $h} {wm geometry . $mx$m ; update} ;# force une fenêtre carrée after $hwdb(delai_configure) set hwdb(config_en_cours) 0 return } if {$m > [winfo screenwidth .]} {set m [winfo screenwidth .]} ;# limitation : dans l'écran if {$m > [winfo screenheight .]} {set m [winfo screenheight .]} wm geometry . $mx$m ;# force une fenêtre carrée update if [winfo exist .o.f.f] {.o.f.f set $hwdb(rpgm)} ;# fait suivre le rayon des graduations dans hwdboptx.tcl. stop_change_redemarre if [winfo exist .o.f] elements_optx ;# évite que les curseurs aillent en butée en agrandissant le cadran dans hwdboptx.tcl. after $hwdb(delai_configure) set hwdb(config_en_cours) 0 return } # Fournit l'opposée d'une valeur #rvb quelqu'en soit la taille. proc diese_complementaire rvb { for {set i 1; set v #; set s [string length $rvb]} {$i < $s} {incr i} { append v [format %01x [expr {15 ^ [scan [string index $rvb $i] %x]}]] } return $v } # Boîte de choix de couleur d'un élément par l'utilisateur. # Limite à une seule boîte par élément en inhibant son bouton. proc choix_couleur {item bouton} { global hwdb $bouton config -state disabled if $hwdb(noms_couleurs_tk) { if [winfo exist .topvcoul] {$bouton config -state normal; focus .topvcoul; return} set ::dim $hwdb(couleur_$item) uplevel source couleurs/vuecouleurs.tcl tkwait window .topvcoul if [catch {clipboard get} choix] {set choix {}} else {set choix [string trim $choix {}]} } else { set choix [tk_chooseColor -initialcolor $hwdb(couleur_$item) -title "couleur $item"] } if {$choix == {}} {$bouton config -state normal; return} set hwdb(couleur_$item) $choix switch $item { aiguilles {set items {aiguille_hr aiguille_mn}} sec {set items {aiguille_sc axe graduations}} ombres {set items {ombre_axe ombre_sc ombre_mn ombre_hr} ; if $hwdb(ombre_chiffres) {lappend items ombre_chiffres}} default {set items $item} } foreach i $items {.c itemconfigure $i -fill $choix} $bouton config -bg $choix -state normal -text "[lindex [$bouton cget -text] 0] $choix" if {[string index $choix 0] == {#}} {$bouton config -fg [diese_complementaire $choix]} else {$bouton config -fg $hwdb(couleur_texte_bouton)} return } # Boîte de changement des paramètres par l'utilisateur. # Les options "chiffres romains" et nom de couleur reconnues par tk n'apparaissent que si les libs idoines sont installées. proc options {} { global hwdb set hwdb(config_en_cours) 1 if [winfo exists .o] {destroy .o; update ; set hwdb(config_en_cours) 0 ; return} toplevel .o wm title .o "options $hwdb(script)" frame .o.g ; frame .o.d label .o.g.a -text {format de la date} label .o.g.b -text {opacité} label .o.g.c -text {délai de redimensionnement} # label .o.g.c -text {épaisseur du cadre système} if [file readable couleurs/vuecouleurs.tcl] { checkbutton .o.g.d -text {couleur tk proche} -variable hwdb(noms_couleurs_tk) } else { label .o.g.d -text {} set hwdb(noms_couleurs_tk) 0 } button .o.g.e -text "cadran $hwdb(couleur_cadran)" -command {choix_couleur cadran .o.g.e} -bg $hwdb(couleur_cadran) button .o.g.f -text "ombres $hwdb(couleur_ombres)" -command {choix_couleur ombres .o.g.f} -bg $hwdb(couleur_ombres) button .o.g.g -text "aiguilles $hwdb(couleur_aiguilles)" -command {choix_couleur aiguilles .o.g.g} -bg $hwdb(couleur_aiguilles) button .o.g.h -text "trotteuse $hwdb(couleur_sec)" -command {choix_couleur sec .o.g.h} -bg $hwdb(couleur_sec) button .o.g.i -text "chiffres $hwdb(couleur_chiffres)" -command {choix_couleur chiffres .o.g.i} -bg $hwdb(couleur_chiffres) entry .o.d.a -textvariable hwdb(format_titre) -justify center spinbox .o.d.b -textvariable hwdb(opacite) -justify center -increment .05 -from 0. -to 1.05 -validate key -vcmd {catch {wm attributes . -alpha $hwdb(opacite)} ; string is double %P} spinbox .o.d.c -textvariable hwdb(delai_configure) -justify center -increment 10 -from 10 -to 500 -validate key -vcmd {string is integer %P} # spinbox .o.d.c -textvariable hwdb(bordure_systeme) -justify center -increment 1 -from 0 -to 20 -validate key -vcmd {string is integer %P} checkbutton .o.d.d -text {au premier plan} -variable hwdb(premier_plan) -command {wm attributes . -topmost $hwdb(premier_plan)} checkbutton .o.d.e -text {fond transparent} -variable hwdb(fond_transparent) -command {wm attributes . -transparentcolor [expr {$hwdb(fond_transparent) ? [.c cget -bg] : {}}]} if ![catch {package require math::roman}] { checkbutton .o.d.f -text {chiffres romains} -variable hwdb(romains) -command stop_change_redemarre } else { label .o.d.f -text {} } radiobutton .o.d.g -text {électrique (mn) } -value 1 -variable hwdb(electrique) radiobutton .o.d.h -text {mécanique (mn)} -value 0 -variable hwdb(electrique) checkbutton .o.d.i -text console -variable hwdb(console) -command { if $hwdb(console) { set tcl_prompt1 {puts -nonewline [history nextid] [file nativename [pwd]]> } catch {console title "console $hwdb(script)" ; console show} } else { unset tcl_prompt1 catch {console hide} } } set hwdb(couleur_texte_bouton) [.o.g.a cget -fg] bind .o.d.a <Return> {wm title . [clock format [clock seconds] -format $hwdb(format_titre) -locale current]} bind .o <F1> {tk_messageBox -title options $hwdb(script) -type ok -message " "couleur proche tk" : Choix d'un nom de couleur reconnu par tk plutôt que d'une valeur #rvb,n "mécanique" : L'aiguille des minutes progresse chaque seconde." ; focus .o} bind .o <Escape> {destroy .o} pack .o.g.a .o.g.b .o.g.c .o.g.d .o.g.e .o.g.f .o.g.g .o.g.h .o.g.i -side top -anchor nw -pady 4 -fill x pack .o.d.a .o.d.b .o.d.c .o.d.d .o.d.e .o.d.f .o.d.g .o.d.h .o.d.i -side top -anchor nw -pady 5 -fill x pack .o.g .o.d -side left -anchor nw -expand 1 -fill x if {[file readable substexpands.tcl] && [file readable hwdboptx.tcl]} {source hwdboptx.tcl} wm resizable .o 0 0 focus .o set hwdb(config_en_cours) 0 return } initialisations pack [canvas .c -width [expr {2 * $hwdb(rayon)}] -height [expr {2 * $hwdb(rayon)}]] -fill both -expand 1 dessine_le_tout update idletasks wm geometry . +[expr {[winfo screenwidth .] - [winfo reqwidth .] - 2 * $hwdb(bordure_systeme)}]+0 ;# à droite et en haut de l'écran wm protocol . WM_DELETE_WINDOW {after cancel $hwdb(timer); destroy .} ;# stoppe la temporisation auto-entretenue à la fermeture bind . <Alt-x> {destroy .} ; bind . <Control-q> {destroy .} ; bind . <Control-d> {destroy .} ; bind . <Control-c> {destroy .} bind . <F1> {tk_messageBox -title $hwdb(script) http://tratoxic.free.fr/t/tk.htm#scripts -type ok -message {Répond aux clics souris (droite ou gauche) dans les zones affichées}} bind .c <3> options bind .c <1> toggle_visu bind . <Configure> autre_taille_cadran une_fois_par_seconde 1 focus -force . # Bogues et limites : # L'affichage des ombres n'est pas indépendant. Pour en voir dans l'état transparent, il faut appeler les options # depuis cet état transparent. Parmi les 4 états possibles de transparence, deux sont plutôt des effets de bord. # Trotteuse et graduations ont la même couleur, ainsi que les aiguilles des heures et des minutes. # Opacité jusqu'à 1.05 fleure bon la compensation de bogue. # Dans la proc. choix_couleur, l'usage de vuecouleurs.tcl phagocite le contenu du presse-papiers. # Non, le script ne se modifie pas lui-même pour garder de nouveaux paramètres optionnels ! "parray hwdb" dans la console ? # L'étape suivante, un cadran ovale ? avec aiguilles qui changent de longueur au fil du temps :) # P.S. "Dessine moi un mouton !" Euh, j' sais pas dessiner les moutons, tu veux pas plutôt un cadran d'horloge ?
D) Un explorateur de fichiers

voici le code :
package require Tk global tcl_platform if {$tcl_platform(platform) == "windows"} { package require registry package require opt } else { package require opt } wm resizable . 0 0 wm title . "TkMC v1.0" ###################################### #Disable default Error messages proc bgerror {errmsg} { global errorInfo errorCode set msg [format "Error: %s." $errmsg $errorCode] tk_messageBox -parent . -title "Error" -type ok -icon error -message $msg } ######################### #Proc centering windows proc center_win {w} { set x [expr [winfo rootx .]+250] set y [expr [winfo rooty .]+150] wm geometry $w "+$x+$y" } ############################### #Proc entry history namespace eval history { proc add? {w} { variable $w variable n$w upvar 0 $w hist set s [set ::[$w cget -textvariable]] if {$s == ""} return if [string compare $s [lindex $hist end]] { lappend hist $s set n$w [llength $hist] } } proc move {w where} { variable $w variable n$w upvar 0 $w hist incr n$w $where if {[set n$w]<0} {set n$w 0} if {[set n$w]>=[llength $hist]+1} { set n$w [llength $hist] } set ::[$w cget -textvar] [lindex $hist [set n$w]] } proc for {type name args} { switch -- $type { entry { uplevel $type $name $args bind $name <Up> {history::move %W -1} bind $name <Down> {history::move %W 1} bind $name <Next> {history::move %W 99999} bind $name <Return> {history::add? %W} variable $name {} variable n$name 0 } default {error "usage: history::for entry <w> <args>"} } } } ############################## frame .top frame .top.f -relief groove -bd 2 pack .top.f -fill x -expand true -side left foreach x [file volume] { button .top.f.f$x -text [file native $x] -font {arial 8 {bold} } -relief groove -command "" pack .top.f.f$x -side left .top.f.f$x config -command "cd $x ; read_dir_l ; refresh_left" } ########################################### #Frame and entry areas for directory names frame .top2 entry .top2.e_l -relief groove -bg grey80 -cursor arrow -font {arial 8 {bold}} entry .top2.e_r -relief groove -bg grey80 -cursor arrow -font {arial 8 {bold}} pack .top2.e_l .top2.e_r -side left -fill x -expand true ########################################## #Fake entry (for some reason it should be exists to separate #readings from dif directories entry .fake_l entry .fake_r #pack .fake_l .fake_r -side top -fill x ################################################## #Buttons,entry, text,scrollbar for text on bottom frame .bot -relief groove -bd 2 frame .bot.2 -relief groove -bd 2 pack .bot.2 -fill x entry .bot.2.e_l -bg grey -relief groove -font {arial 8 {bold}} entry .bot.2.e_r -bg grey -relief groove -font {arial 8 {bold}} pack .bot.2.e_l .bot.2.e_r -side left -fill x -expand true text .bot.t -wrap none -height 10 -bg bisque -fg blue -font {monaco 12 {}} -cursor arrow -yscrollcommand [list .bot.scr set] scrollbar .bot.scr -orient vertical -command [list .bot.t yview] history::for entry .bot.comm -font {monaco 12} -bd 1 -bg bisque -cursor arrow -textvariable command_var pack .bot.scr -side right -fill y pack .bot.t .bot.comm -side top -fill x -expand true bind .bot.comm <Return> {+ ; .bot.t delete 1.0 end ; .bot.t insert end [exec_cmd [.bot.comm get]]; .bot.comm delete 0 end ; after 100 focus .bot.comm } bind .bot.comm <Enter> {focus .bot.comm} foreach bot {.b1 .b2 .b3 .b4 .b5 .b6 .b7 .b8 .b9 .b10} { button .bot$bot -relief groove pack .bot$bot -side left -fill x -expand true } .bot.b1 config -text "Help F1" -command About .bot.b2 config -text "Menu F2" -command {} .bot.b3 config -text "View F3" -command {} .bot.b4 config -text "Editor F4" -command {editor} .bot.b5 config -text "Copy F5" -command "" .bot.b6 config -text "RenMv F6" -command "" .bot.b7 config -text "MkDir F7" -command "" .bot.b8 config -text "Delete F8" -command "" .bot.b9 config -text "Run Tcl Code F9" -command {focus .bot.t ; run_tcl .bot.t} .bot.b10 config -text "Exit F10" -command exit pack .bot -side bottom -fill both -expand true ######################### ############################# #Right drive lists frame .top.f_r -relief groove -bd 2 pack .top.f_r -fill x -expand true -fill x -side left foreach x [file volume] { button .top.f_r.f$x -text [file native $x] -font {arial 8 {bold} } -relief groove -command "" pack .top.f_r.f$x -side left .top.f_r.f$x config -command "cd $x ; read_dir_r ; refresh_right" } pack .top -side top -fill x -expand true pack .top2 -side top -fill x -expand true ############################## ################################# #Left listboxes listbox .l -bg bisque -width 20 -export no -bd 0 -relief raised -selectmode browse -yscrollcom LBscroll -font {monaco 10} listbox .sz -bg bisque -width 8 -export no -bd 0 -selectmode browse -yscrollcom LBscroll -font {monaco 10} listbox .time -bg bisque -export no -width 15 -bd 0 -selectmode browse -yscrollcom LBscroll -font {monaco 10} pack .l .sz .time -side left -fill both -expand true ############################ #Right side listboxes listbox .l_r -bg bisque -width 20 -export no -bd 0 -relief raised -selectmode browse -yscrollcom LBscroll_r -font {monaco 10} listbox .sz_r -bg bisque -width 8 -export no -bd 0 -selectmode browse -yscrollcom LBscroll_r -font {monaco 10} listbox .time_r -bg bisque -export no -width 15 -bd 0 -selectmode browse -yscrollcom LBscroll_r -font {monaco 10} pack .l_r .sz_r .time_r -side left -fill both -expand true ################### #Fill all listboxes proc read_dir_l {} { #clean all listboxes .l delete 0 end .sz delete 0 end .time delete 0 end .l insert end ".." .sz insert end ".." .time insert end ".." ### set dir [glob -nocomplain ./*] set files [glob -nocomplain ./*] set dirs {} set others {} set dsize {} set dtime {} set fsize {} set ftime {} foreach f [lsort -dictionary $files] { if { ![file isdirectory $f] && ![file isfile $f] } { lappend others [file tail $f] lappend fsize "NOT A FILE" lappend ftime "------" } elseif [file isdirectory $f] { lappend dirs [file tail $f] lappend dsize "DIR" lappend dtime [clock format [file mtime $f] -format {%b-%d-%y %H:%M}] } else { lappend others [file tail $f] lappend fsize [file size $f] lappend ftime [clock format [file mtime $f] -format {%b-%d-%y %H:%M}] } } foreach f [concat $dirs $others] { .l insert end $f } foreach z [concat $dsize $fsize] { .sz insert end $z } foreach t [concat $dtime $ftime] { .time insert end $t } .top2.e_l delete 0 end .top2.e_l insert end [file native [pwd]] .fake_l delete 0 end .fake_l insert end [pwd] } ########################## #Fill right listboxes proc read_dir_r {} { #clean all listboxes .l_r delete 0 end .sz_r delete 0 end .time_r delete 0 end .l_r insert end ".." .sz_r insert end ".." .time_r insert end ".." ### set dir_r [glob -nocomplain ./*] set files_r [glob -nocomplain ./*] set dirs_r {} set others_r {} set dsize_r {} set dtime_r {} set fsize_r {} set ftime_r {} foreach f [lsort -dictionary $files_r] { if { ![file isdirectory $f] && ![file isfile $f] } { lappend others_r [file tail $f] lappend fsize_r "NOT A FILE" lappend ftime_r "------" } elseif [file isdirectory $f] { lappend dirs_r [file tail $f] lappend dsize_r "DIR" lappend dtime_r [clock format [file mtime $f] -format {%b-%d-%y %H:%M}] } else { lappend others_r [file tail $f] lappend fsize_r [file size $f] lappend ftime_r [clock format [file mtime $f] -format {%b-%d-%y %H:%M}] } } foreach f [concat $dirs_r $others_r] { .l_r insert end $f } foreach z [concat $dsize_r $fsize_r] { .sz_r insert end $z } foreach t [concat $dtime_r $ftime_r] { .time_r insert end $t } .top2.e_r delete 0 end .top2.e_r insert end [file native [pwd]] .fake_r delete 0 end .fake_r insert end [pwd] } ################################## read_dir_l read_dir_r ################################# ################################ #Left scroolbar and procs to scroll scrollbar .sy -orient v -command "LBset yview" pack .sy -fill y -after .time -side left proc LBset args { foreach lb {.l .sz .time} { eval $lb $args } } proc LBscroll args { eval .sy set $args LBset yview moveto [lindex $args 0] } foreach lb {.l .sz .time} { bind $lb <ButtonPress-1> { LBset select clear 0 end LBset select set [%W nearest %y] set show [.l curselection] .bot.2.e_l delete 0 end .bot.2.e_l insert end [.l get $show ] } bind $lb <B1-Motion> { LBset select clear 0 end LBset select set [%W nearest %y] LBset see [%W nearest %y] set show [.l curselection] .bot.2.e_l delete 0 end .bot.2.e_l insert end [.l get $show ] } bind $lb <ButtonRelease-1> { LBset select clear 0 end LBset select set [%W nearest %y] set show [.l curselection] .bot.2.e_l delete 0 end .bot.2.e_l insert end [.l get $show ] } } ################################################ #Right scroolbar and proc for scroll scrollbar .sy_r -orient v -command "LBset_r yview" pack .sy_r -fill y -after .time_r -side right proc LBset_r args { foreach lb_r {.l_r .sz_r .time_r} { eval $lb_r $args } } proc LBscroll_r args { eval .sy_r set $args LBset_r yview moveto [lindex $args 0] } foreach lb_r {.l_r .sz_r .time_r} { bind $lb_r <ButtonPress-1> { LBset_r select clear 0 end LBset_r select set [%W nearest %y] set show [.l_r curselection] .bot.2.e_r delete 0 end .bot.2.e_r insert end [.l_r get $show ] } bind $lb_r <B1-Motion> { LBset_r select clear 0 end LBset_r select set [%W nearest %y] LBset_r see [%W nearest %y] set show [.l_r curselection] .bot.2.e_r delete 0 end .bot.2.e_r insert end [.l_r get $show ] } bind $lb_r <ButtonRelease-1> { LBset_r select clear 0 end LBset_r select set [%W nearest %y] set show [.l_r curselection] .bot.2.e_r delete 0 end .bot.2.e_r insert end [.l_r get $show ] } } ####################################################### #Proc to show file names on bottom entry right and left #Scroll selected lines in all listboxes in left proc showItemDown {w w2} { set item [$w curselection] set item2 [expr $item+1] $w2 delete 0 end; $w2 insert end [$w get $item2] foreach sel {.l .sz .time} { $sel selection clear $item $sel selection set $item2 ; $sel selection clear $item } } proc showItemUp {w w2} { set item [$w curselection] set item2 [expr $item-1] $w2 delete 0 end; $w2 insert end [$w get $item2] foreach sel {.l .sz .time} { $sel selection clear $item $sel selection set $item2 ; $sel selection clear $item } } ##################### #Proc to scroll all selection in right side proc showItemDown_r {w w2} { set item [$w curselection] set item2 [expr $item+1] $w2 delete 0 end; $w2 insert end [$w get $item2] foreach sel {.l_r .sz_r .time_r} { $sel selection clear $item $sel selection set $item2 ; $sel selection clear $item } } proc showItemUp_r {w w2} { set item [$w curselection] set item2 [expr $item-1] $w2 delete 0 end; $w2 insert end [$w get $item2] foreach sel {.l_r .sz_r .time_r} { $sel selection clear $item $sel selection set $item2 ; $sel selection clear $item } } proc edit_file {w} { global fileex set fileex [$w get active] if [file isdirectory $fileex] { tk_messageBox -parent . -title "Error" -type ok -icon error -message "This is directory" } else { editor set openfile [open $fileex "r"] .ed.text.t delete 1.0 end .ed.text.t insert end [read $openfile] close $openfile } } ################## #Proc to change left directory list proc read_left {} { #focus .l global fileex set old_dir [.fake_l get] cd $old_dir set dir [.l get active] if [file isdirectory $dir] { cd $dir ; read_dir_l .l selection set 0; .sz selection set 0; .time selection set 0 .l activate 0 .top2.e_l delete 0 end .top2.e_l insert end [file native [pwd]] } else { set fileex [.l get active] if [file executable $fileex] { catch {exec $fileex &} result #.bot.t insert end [eval exec command /c $fileex] } if {[id_giffile] == 1} { img_view $fileex } if {[id_txtfile] == 1} { set openfile [open $fileex "r"] .bot.t delete 1.0 end .bot.t insert end [read $openfile] close $openfile } if {[id_tclfile] == 1} { set dir [pwd] showTcl $dir/$fileex } if {[id_htmlfile] == 1} { set dir [pwd] showHtml $dir/$fileex } } } proc read_right {} { # Get selected list item global fileex focus .l_r set old_dir [.fake_r get] cd $old_dir set dir_r [.l_r get active] if [file isdirectory $dir_r] { cd $dir_r ; read_dir_r .l_r selection set 0; .sz_r selection set 0; .time_r selection set 0 .top2.e_r delete 0 end .top2.e_r insert end [file native [pwd]] } else { set fileex [.l_r get active] if [file executable $fileex] { catch {exec $fileex &} result #.bot.t insert end [eval exec command /c $fileex] } if {[id_giffile] == 1} { img_view $fileex } if {[id_txtfile] == 1} { set openfile [open $fileex "r"] .bot.t delete 1.0 end .bot.t insert end [read $openfile] close $openfile } if {[id_tclfile] == 1} { set dir [pwd] showTcl $dir/$fileex } if {[id_htmlfile] == 1} { set dir [pwd] showHtml $dir/$fileex } } } proc copy_file_to_r {} { set file_l [.l get active] set left_dir [.fake_l get] set right_dir [.fake_r get] set choise [tk_messageBox -parent . -type yesno -default yes -message "Copyn [file native $left_dir/$file_l]nton [file native $right_dir]" -icon question] if {$choise == "yes"} { if [file isdirectory $file_l] { file copy -force $left_dir/$file_l $right_dir refresh_right ; refresh_left cd [.fake_l get] } else { file copy $left_dir/$file_l $right_dir after 100 refresh_left; refresh_right cd [.fake_l get] } } } proc copy_file_to_l {} { set file_r [.l_r get active] set left_dir [.fake_l get] set right_dir [.fake_r get] set choise [tk_messageBox -parent . -type yesno -default yes -message "Copyn [file native $right_dir/$file_r] nton [file native $left_dir]" -icon question] if {$choise == "yes"} { if [file isdirectory $file_r] { file copy $right_dir/$file_r $left_dir; refresh_left ; refresh_right cd [.fake_r get] } else { file copy $right_dir/$file_r $left_dir refresh_left cd [.fake_r get] } } } #################### #Rename move files and Directories proc ren_move {w} { catch [destroy .move] toplevel .move wm resizable .move 0 0 wm title .move "Rename" grab .move center_win .move global file_move set file_move [$w get active] label .move.l -text "Current name is: n$file_move nn Enter new name: " -relief groove -font {arial 8 {bold}} entry .move.e -font {arial 8 {bold}} .move.e insert end $file_move focus .move.e frame .move.ok -relief sunken -bd 2 button .move.ok.ok -text " Ok " -padx 10 -pady 5 -command {file rename $file_move [.move.e get]; after 1 "refresh_right; refresh_left; destroy .move"} button .move.cancel -text Cancel -command "destroy .move" pack .move.l .move.e -side top -fill x -expand true pack .move.ok .move.ok.ok .move.cancel -side left -padx 10 -pady 5 bind .move.e <Return> {file rename $file_move [.move.e get]; after 30 refresh_right; refresh_left; after 35 destroy .move } } ############## proc delete_file_l {} { set file_l [.l get active] set left_dir [.fake_l get] if [file isdirectory $file_l] { set cur [.l curselection] set question [tk_messageBox -type okcancel -default cancel -message " Delete directory and files in n [file native $left_dir/$file_l]" -icon question] switch -- $question { ok { file delete -force $file_l ; refresh_left ; refresh_right} } } else { set cur [.l curselection] set question [tk_messageBox -type okcancel -default cancel -message " Delete files n [file native $left_dir/$file_l]" -icon question] switch -- $question { ok { file delete $left_dir/$file_l; refresh_left; refresh_right} } #.l selection set $curent #.l see $curent } } proc delete_file_r {} { set file_r [.l_r get active] set right_dir [.fake_r get] if [file isdirectory $file_r] { set curent [.l_r curselection] set question [tk_messageBox -type okcancel -default cancel -message " Delete directory and files in n [file native $right_dir/$file_r] " -icon question] switch -- $question { ok { file delete -force $file_r ; refresh_left ; refresh_right } } } else { set curent [.l_r curselection] set question [tk_messageBox -type okcancel -default cancel -message " Delete files n [file native $right_dir/$file_r]" -icon question] switch -- $question { ok { file delete $right_dir/$file_r; refresh_right; refresh_left } } } } proc mk_dir {w} { catch [destroy .mkdir] toplevel .mkdir wm resizable .mkdir 0 0 wm title .mkdir "Create new Directory" grab .mkdir center_win .mkdir label .mkdir.l -text " Current directory is: n[file native [pwd]] nn Enter new directory name " -relief groove -font {arial 8 {bold}} entry .mkdir.e -font {arial 8 {bold}} focus .mkdir.e frame .mkdir.ok -relief sunken -bd 2 button .mkdir.ok.ok -text " Ok " -padx 10 -pady 5 -command {file mkdir [.mkdir.e get]; after 1 "refresh_right; refresh_left; destroy .mkdir"} button .mkdir.cancel -text Cancel -command "destroy .mkdir" pack .mkdir.l .mkdir.e -side top -fill x -expand true pack .mkdir.ok .mkdir.ok.ok .mkdir.cancel -side left -padx 10 -pady 5 bind .mkdir.e <Return> {file mkdir [.mkdir.e get]; after 30 refresh_right; refresh_left; after 35 destroy .mkdir } } #end mk_dir proc find_win {w} { catch [destroy .find] toplevel .find center_win .find wm title .find "Find" wm resizable .find 0 0 grab .find label .find.l -text "tCurrent directory is:tnt[file native [pwd]]ttnnSearch Filename:" -relief groove -font {arial 10 {bold}} entry .find.e pack .find.l .find.e -fill x focus .find.e frame .find.ok -relief sunken -bd 1 button .find.ok.ok -padx 10 -pady 5 -text Find -command {.bot.t delete 1.0 end ; find_file [pwd] [.find.e get] ; destroy .find} button .find.cancel -text Cancel -command "destroy .find" pack .find.ok .find.ok.ok .find.cancel -side left -padx 10 -pady 5 } ######################## #Proc find file proc find_file { startDir namePat} { #set namePat [.find.e get] set pwd [pwd] if [catch {cd $startDir} err] { puts stderr $err return } foreach match [glob -nocomplain -- $namePat] { .bot.t insert end "[file native $startDir/$match]n" if {$namePat != $match } { #.bot.t insert end "$startDir$matchn" #.bot.t insert end "no match" } else { #.bot.t insert end "no files found" } } foreach file [glob -nocomplain *] { if [file isdirectory $file] { find_file $startDir/$file $namePat update } } cd $pwd } #################################################### #Refresh left listbox after copy or deleting a file proc refresh_left {} { set left_dir [.fake_l get] set cur [.l curselection] if {$cur == "" } { focus .l after 3 ".l selection set 0 ; .sz selection set 0 ; .time selection set 0" .l see 0 .l activate 0 } else { cd $left_dir ; read_dir_l .l selection set $cur ; .sz selection set $cur ; .time selection set $cur .l see $cur .l activate $cur .top2.e_l delete 0 end .bot.2.e_l delete 0 end .top2.e_l insert end [file native [pwd]] } } refresh_left proc refresh_right {} { set right_dir [.fake_r get] set cur [.l_r curselection] if {$cur == ""} { .l_r selection set 0 ; .sz_r selection set 0; .time_r selection set 0 .l_r see 0 .l_r activate 0 } else { cd $right_dir ; read_dir_r .l_r selection set $cur; .sz_r selection set $cur; .time_r selection set $cur .l_r see $cur .l_r activate $cur .top2.e_r delete 0 end .bot.2.e_r delete 0 end .top2.e_r insert end [file native [pwd]] } } proc viewFile {w} { #global fileex set fileex [$w get active] if [file isdirectory $fileex] { tk_messageBox -parent . -title "Error" -type ok -icon error -message "This is directory" } else { set openfile [open $fileex "r"] .bot.t delete 1.0 end .bot.t insert end [read $openfile] close $openfile } } refresh_right ######################### ######################## #Bindings global #bind .bot.t <Enter> "focus .bot.t" bind . <F4> "editor" bind . <F9> {focus .bot.t ; run_tcl .bot.t} ######################### #Bindings keys for left side foreach bind_left { .l .sz .time} { bind $bind_left <Enter> {focus .l ; set old_dir [.fake_l get] ; cd $old_dir ; .bot.b2 config -command {}; .bot.b3 config -command {viewFile .l} ; .bot.b5 config -command copy_file_to_r ; .bot.b6 config -command {ren_move .l} ; .bot.b7 config -command {mk_dir .l} ; .bot.b8 config -command delete_file_l} } bind .l <Double-Button-1> "read_left;" bind .l <Return> {read_left} bind .l <Down> {showItemDown .l .bot.2.e_l} bind .l <Up> {showItemUp .l .bot.2.e_l} bind .l <KeyPress-r> "focus .l_r" bind .l <F3> {viewFile .l} bind .l <F5> copy_file_to_r bind .l <F6> {ren_move .l} bind .l <F7> {mk_dir .l} bind .l <F8> delete_file_l ############################################# #Bindings keys for right side bind .l_r <Double-Button-1> "read_right" bind .l_r <Return> {read_right} foreach bind_right {.l_r .sz_r .time_r} { bind $bind_right <Enter> {focus .l_r; set old_dir [.fake_r get] ; cd $old_dir ; .bot.b3 config -command {viewFile .l_r}; .bot.b8 config -command delete_file_r; .bot.b5 config -command copy_file_to_l ; .bot.b6 config -command {ren_move .l_r} ; .bot.b7 config -command {mk_dir .l_r}} } bind .l_r <KeyPress-r> "focus .l" bind .l_r <F3> {viewFile .l_r} bind .l_r <F5> copy_file_to_l bind .l_r <F6> {ren_move .l_r} bind .l_r <F7> {mk_dir .l_r} bind .l_r <F8> delete_file_r bind .l_r <Down> {showItemDown_r .l_r .bot.2.e_r} bind .l_r <Up> {showItemUp_r .l_r .bot.2.e_r} #################################### #Txt, ASCII and bat files viewer proc id_allfiles {} { global fileex set ext_txt [file extension $fileex] switch $ext_txt { .doc {return 1} .txt {return 1} .jpeg {return 1} .jpg {return 1} .txt {return 1} .htm {return 1} .html {return 1} } return 0 } proc id_txtfile {} { global fileex set ext_txt [file extension $fileex] switch $ext_txt { .txt {return 1} .TXT {return 1} .bat {return 1} .BAT {return 1} .c {return 1} .C {return 1} .h {return 1} .H {return 1} } return 0 } proc id_tclfile {} { global fileex set ext_tcl [file extension $fileex] switch $ext_tcl { .tcl {return 1} .TCL {return 1} .tk {return 1} .TK {return 1} } return 0 } ####################################### proc id_giffile {} { global fileex set ext_gif [file extension $fileex] switch $ext_gif { .gif {return 1} .GIF {return 1} .jpeg {return 1} .jpg {return 1} .JPEG {return 1} .JPG {return 1} .tif {return 1} } return 0 } proc id_htmlfile {} { global fileex set ext_html [file extension $fileex] switch $ext_html { .htm {return 1} .html {return 1} .HTM {return 1} .HTML {return 1} } return 0 } ############################# #Proc file atributes and properties proc fileprop pathname { set padx 6 if {$pathname=="."} {set pathname [pwd]} set pathname [file join [pwd] $pathname] set checkbuttons [list] file stat $pathname a ;# may error out if no such file set w .[clock clicks] set ::$w(dir) [file dir $pathname] set ::$w(file) [file tail $pathname] toplevel $w grab $w wm title $w [file nativename $pathname] wm resizable $w 0 0 wm geometry $w +300+150 set size [file size $pathname] if {$size < 0} { set size [format "%2.2f GB" [expr ($size/-1024.0)/-1024.0/-1024.0*10.0]] } else { if {$size > 1073741824.0} { set size [format "%2.2f GB" [expr ($size/1024.0)/1024.0/1024.0]] } else { if { $size > 1048576.0 } { set size [format "%2.2f MB" [expr ($size/1024.0) /1024.0 ]] } else { if {$size > 1024} { set size [ format "%2.2f KB" [expr $size / 1024.0 ]] } } } } set textual [list Name [file tail $pathname] Directory [file nativename [file dir $pathname]] Type [file type $pathname] Size $size Created [date,time $a(ctime)] "Last modified" [date,time $a(mtime)] "Last accessed" [date,time $a(atime)] ] foreach {name value} [file attr $pathname] { if [regexp {^[01]$} $value] { lappend checkbuttons $name $value } else { lappend textual $name [file nativename $value] } } set n 0 foreach {name value} $textual { grid [label $w.${n}n -text $name:] [label $w.${n}v -text $value] -sticky w -padx $padx incr n } grid [hr $w.$n] -sticky we -columnspan 2 -padx $padx -pady 6 set n0 [incr n] foreach {name value} $checkbuttons { incr n set ::$w($name) $value grid [checkbutton $w.$n -text $name -var $w($name) -borderwidth 0] -sticky w -col 1 -padx $padx } grid [label $w.att -text Attributes:] -row $n0 -sticky w -padx $padx grid [hbuttons $w.b [list OK "fileprop:apply $w; destroy $w; unset $w" Cancel "destroy $w; unset $w" Apply "fileprop:apply $w" ]] -col 1 -padx $padx wm protocol $w WM_DELETE_WINDOW "destroy $w; unset $w" focus $w } proc fileprop:apply {w} { upvar #0 $w a set cmd [list file attributes [file join $a(dir) $a(file)]] foreach {name value} [array get a] { if [regexp {^-} $name] {lappend cmd $name $value} } eval $cmd } proc hbuttons {w tc} { frame $w set n 1 foreach {t c} $tc { button $w.$n -text $t -command $c -width 8 incr n } eval pack [winfo children $w] -side left -padx 3 -pady 6 -fill x -anchor e return $w } proc hr {w} {frame $w -height 2 -borderwidth 1 -relief sunken} proc date,time {{when {}}} { if {$when == ""} {set when [clock seconds]} return [clock format $when -format "%Y-%m-%d,%H:%M:%S"] } ####################### #Proc popup menus proc pop_upmen_l {w} { global act set act [$w curselection] menu .popup_l -tearoff 0 .popup_l add separator .popup_l add command -label Info -command {fileprop [.bot.2.e_l get]} .popup_l add separator .popup_l add command -label View -command "viewFile .l" .popup_l add command -label Edit -command "edit_file .l" .popup_l add separator .popup_l add command -label Find -command {find_win .l} .popup_l add command -label Copy -command copy_file_to_r .popup_l add command -label NewDir -command "mk_dir .l" .popup_l add separator .popup_l add command -label Rename -command "ren_move .l" .popup_l add command -label Delete -command delete_file_l .popup_l add separator bind $w <ButtonPress-3> {tk_popup .popup_l %X %Y } } proc pop_upmen_r {w} { global act set act [$w curselection] menu .popup_r -tearoff 0 .popup_r add separator .popup_r add command -label Info -command {fileprop [.bot.2.e_r get]} .popup_r add separator .popup_r add command -label View -command "viewFile .l_r" .popup_r add command -label Edit -command "edit_file .l_r" .popup_r add separator .popup_r add command -label Find -command {find_win .r} .popup_r add command -label Copy -command copy_file_to_l .popup_r add command -label NewDir -command "mk_dir .l_r" .popup_r add separator .popup_r add command -label Rename -command "ren_move .l_r" .popup_r add command -label Delete -command delete_file_r .popup_r add separator bind $w <ButtonPress-3> {tk_popup .popup_r %X %Y } } pop_upmen_l .l pop_upmen_r .l_r ##################### #Image viewer procs #Var set set i 1 set im 1 ###################### #image viewer procedure proc img_view {fileex} { global i global im incr i incr im toplevel .img$i wm title .img$i $fileex #wm minsize .img$i 800 640 image create photo $im $im read $fileex set im_y [image height $im] set im_x [image width $im] wm minsize .img$i 200 100 canvas .img$i.c -relief groove -bd 2 -scrollregion {0 0 3000 3000} -yscrollcommand [list .img$i.scr set] -xscrollcommand [list .img$i.xscr set] scrollbar .img$i.scr -orient vertical -command [list .img$i.c yview] scrollbar .img$i.xscr -orient horizontal -command [list .img$i.c xview] .img$i.c create image 5 5 -image $im -anchor nw update pack .img$i.scr -side right -fill y pack .img$i.xscr -side bottom -fill x pack .img$i.c -side left -fill both -expand true } ###################################### #Procedure to run command from entry proc exec_cmd {command} { global tcl_platform set result " " set check_cmd [lindex $command 0] set cmd [info commands $check_cmd] if {[string length $cmd ] > 0} { .bot.t insert end [set result [eval $command]] refresh_left #refresh_right } else { if {$tcl_platform(platform) == "windows"} { eval exec command /c [.bot.comm get] } else { eval exec [.bot.comm get] } } } ############################# #Procedure for running tcl from text widgets proc run_tcl {w} { if {[interp exists eval_env]} { interp delete eval_env run_tcl $w } else { interp create eval_env load {} Tk eval_env set all [$w get 1.0 end] eval_env eval $all } } ########################## ############################################ #Registry procedure #Evaluate file extensions and execute applcation ::tcl::OptProc perSub { {string -string "" "String to work on"} {pattern -string "" "What to substitute for, e.g., %v"} {subst -string "" "What to put in for $pattern"} {args -list {} "More pattern/subst pairs"} } { # Add the required instances to the optional list set args [linsert $args 0 $pattern $subst] # Process the list foreach {pattern subst} $args { # Validate pattern if { ! [string match %* $pattern]} { error "Bad pattern <<$pattern>>: Should be %something" } # Escape dangerous characters ('' and '&') in substitution string regsub -all {\|&} $subst {\0} subst # Do substitutions on string regsub -all $pattern $string $subst string } # foreach return $string } proc showHtml {htmlFile} { global tcl_platform if {$tcl_platform(platform) == "windows"} { set root HKEY_CLASSES_ROOT set appKey [registry get $root\.html ""] set appCmd [registry get $root\$appKey\shell\open\command ""] set appCmd [perSub $appCmd %1 $htmlFile] regsub -all {\} $appCmd {\\} appCmd eval exec $appCmd & } else { } } proc showTcl {tclFile} { global tcl_platform if {$tcl_platform(platform) == "windows"} { set root HKEY_CLASSES_ROOT set appKey [registry get $root\.tcl ""] set appCmd [registry get $root\$appKey\shell\open\command ""] set appCmd [perSub $appCmd %1 $tclFile] regsub -all {\} $appCmd {\\} appCmd eval exec $appCmd & } else { } } ########################################## proc editor {} { catch [destroy .ed] toplevel .ed wm resizable .ed 0 0 wm title .ed "TclMC Editor" menu .ed.menubar -relief raised -borderwidth 1 menu .ed.menubar.file -tearoff 0 .ed.menubar add cascade -label "File" -menu .ed.menubar.file -underline 0 .ed.menubar.file add separator .ed.menubar.file add command -label "New" -command {clear_all .ed.text.t} .ed.menubar.file add separator .ed.menubar.file add command -label "Open" -command {clear_all .ed.text.t ; textOpen} .ed.menubar.file add separator .ed.menubar.file add command -label "Close" -command {clear_all .ed.text.t} .ed.menubar.file add separator .ed.menubar.file add command -label "Save as..." -command {textSaveAs} .ed.menubar.file add separator .ed.menubar.file add command -label "Print" -command {printFormat} .ed.menubar.file add separator .ed.menubar.file add command -label "Exit" -command {bell ; prompt_close .} ###################### .ed.menubar add cascade -label "Edit" -menu .ed.menubar.editt -underline 0 menu .ed.menubar.editt -tearoff 0 .ed.menubar.editt add separator .ed.menubar.editt add command -label "Select All" -command {.ed.text.t tag add sel 1.0 end} .ed.menubar.editt add separator .ed.menubar.editt add command -label "Copy" -command {tk_textCopy .ed.text.t} .ed.menubar.editt add separator .ed.menubar.editt add command -label "Paste" -command "tk_textPaste .ed.text.t" .ed.menubar.editt add separator .ed.menubar.editt add command -label "Cut" -command "tk_textCut .ed.text.t" .ed.menubar.editt add separator .ed.menubar.editt add command -label "Clear" -command "clear_all .ed.text.t" .ed.menubar.editt add separator #################################### .ed.menubar add cascade -label "Test Tcl" -menu .ed.menubar.run -underline 0 menu .ed.menubar.run -tearoff 0 .ed.menubar.run add separator .ed.menubar.run add command -label "Run Tcl" -command {run_tcl .ed.text.t} .ed.menubar.run add separator ############################ .ed.menubar add cascade -label "Font Size" -menu .ed.menubar.font -underline 0 menu .ed.menubar.font -tearoff 0 .ed.menubar.font add separator .ed.menubar.font add command -label "Small" -command ".ed.text.t config -font {Monaco 8 {}}" .ed.menubar.font add separator .ed.menubar.font add command -label "Medium" -command ".ed.text.t config -font {Monaco 9 {}}" .ed.menubar.font add separator .ed.menubar.font add command -label "Large" -command ".ed.text.t config -font {Monaco 12 {}}" ############################# .ed.menubar add cascade -label "Help" -menu .ed.menubar.help -underline 0 menu .ed.menubar.help -tearoff 0 .ed.menubar.help add separator .ed.menubar.help add command -label "Help" -command {About} .ed.menubar.help add separator .ed.menubar.help add command -label "About" -command {About} .ed conf -menu .ed.menubar proc clear_all { widgetname } { $widgetname delete 1.0 end } ##################################### proc textOpen { { fn ""} } { global .ed.text.t set types { {{All Files} *} {{Text Files} {.txt}} } if { [string match {} $fn] && ([catch {tk_getOpenFile -filetypes $types -title "Source File" -parent .ed} fn] || [string match {} $fn]) } { return } set fp [open $fn] while {![eof $fp]} { .ed.text.t insert end [read $fp] } close $fp } ##################################### # Handles window manager Close choice. proc prompt_close { widgetname } { # If main window, prompt. if { $widgetname == "." } { set result [tk_messageBox -parent .ed -title {Exit?} -type yesno -icon warning -message "Do you really want to quit?"] if { $result == "yes" } { destroy .ed } } else { # Not the main window, destroy it. destroy $widgetname } } wm protocol . WM_DELETE_WINDOW "prompt_close .ed" #################################### #save as command proc textSaveAs {} { global .ed.text.t set types { {{Tcl Files} {.tcl}} {{Text Files} {.txt}} {{All Files} *} } set filename [tk_getSaveFile -title "Save as..." -filetypes $types] if {$filename !=""} { set file_open [open $filename w] puts -nonewline $file_open [.ed.text.t get 1.0 end] close $file_open refresh_left refresh_right } } #################################### #Print using ms Write application proc printFormat {} { global tcl_platform if {$tcl_platform(platform) == "unix"} { } if {[file exists c:/windows/write.exe]} { set file [open c:/tmp/out.txt w] puts $file [.ed.text.t get 1.0 end] close $file exec start /m write /p c:/tmp/out.txt & } else { if {[file exists c:/progra~1/accessories/wordpad.exe]} { set file [open c:/tmp/out.txt w] puts $file [.ed.text.t get 1.0 end] close $file exec start /m c:/progra~1/accessories/wordpad.exe /p c:/tmp/out.txt & } else { if {[file exists c:/winnt/system32/write.exe]} { set file [open c:/tmp/out.txt w] puts $file [.ed.text.t get 1.0 end] close $file exec c:/winnt/system32/write.exe /p c:/tmp/out.txt & } else { ## catch [destroy .formated] toplevel .formated wm title .formated "" wm resizable .formated 0 0 label .formated.l -text "You need install MS Windows n WordPad application!n Press Ok button to continue" -relief groove button .formated.b -text Ok -command "destroy .formated" pack .formated.l -side top pack .formated.b -side bottom } } } } ############################### #Image Buttons set imnew { R0lGODlhEAAQAPcAAAAAAMbGxv////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////yH5BAEAAAEALAAAAAAQABAA AAhJAAMIHEiwIEEACBMiNCgQwL+HEBcadAjxoUMAEytaTFiQokaLHT9GDCnyH8aDJU2SFHlyoMeP LRumjBngpUaaCnNKZMizJ8+AAAA7 } #End New ################ #Open button image set imopen { R0lGODlhEAAPAPcAAAAAAMbGxv//AP////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////yH5BAEAAAEALAAAAAAQAA8A AAhMAAMIHEiwoMGDCBMSBMBQoUAAAv4JYEix4UKJAiJq/AegIESJIDV2vCiyoskAHydmXMmyIwCJ EFm2fKhS5sqRKGPanLjQ5EmHQIMGBAA7 } #End open image ####################################### #Save Image set imsave { R0lGODlhEAAQAPcAAAAAAAAAnAAA/8bGxs7Ozv////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////yH5BAEAAAMALAAAAAAQABAA AAhhAAcIHEiwoMGDBgEEECAAgMOHAgIAGKiQIYGLAQIQiDhRYEUBFwlk3CiR4sKGDx1yNMmwpcuG JlPKdBjzn82b/x7WxGlTp0eJPHvS/AkgaM6hAxQWDeozqUOjTWdKRUg1IAA7 } #End Save Image ######################### #image Select all set imselectall { R0lGODdhFAARAPcAAAAAALa2qtu2qrbbqtvbqrOzs7a2/9u2/7bb/9vb/////wBMWTQJAAAAAAAA AAAAAKgF9xcAABwANAkFAAAApG0/A1r4AgBk6wIACAAjAacrAAABAMk7AAAFAOA/AAAAAAAAAAAA AEAGAAAAAAAA9wPWFE4ifwMJAAAA1hRa+AIAkOwCAAAyVwQBAA5gAAAAAAAAVuvHMaj4twVQUiAD WAJABgEQAAAAAEAGAAAAAAAAAAAAABMBCeAABDAA1hQfBR8DWAUfAwAAAAACAOrrAgAIAB8BpysA AAEANQIBAQYAAQAAANYUZAAAAAIANQIAAC8AFAAaAFYAJwBlAAAAAAAAQPdeAAC3BSHsAAAAAAAA AADHMQAAAADc68cxqPi3BUIAnhcEAMjsxzEGAAEAJQAfAHoCSezg60nsTiOvBwgD3xOPEwwFSO0a AC8A///3/wAACAPfE8cDAAD//wAAHwAgAPLrCiavBxjsxzF6At8TUezHMeDsJwHXExjsxzGLax8B jxPg7EsB1xPc7McxSO3HMRjsxzEBAACAQXBwRXZlbnRzXFNjaGVtZXNcQXBwc1wuRGVmYXVsdFxN QUdJQ01lbnVDb21tYW5kXC5DdXJyZW50AAngAACDAP4ABgG3BbDsS3tXBKj4twVwLtcFIQDwAAEA BgAfAEMBAAAAACYAHwAAANYUBQDEFvcXWvisAx8DhAxDAR8AJgAlACcAHwAmACUAJwAAAK41AADE Na41jwcfAgAAAADHAP1VrjUCAAAAAgCvNQDzrjUGGwcL4uzAHZUG9xf7Bq41AABI7boAAAA27TgC SO3HMfTsxzEbA98TAACuNU1BR0lDTWVudUNvbW1hbmQAAwAAQO0tJG8YAAD+////BRAczyRFAgDH MSRFAgDC7gIAiwAAANYUDQBO9wAAACAFANztnQOTAAEQSO3HMQwF9xcAAAD///8FEBzPFAIkRQIA VAAM7hQL9zUAAP7///8FEBzPFAIQAhIAAAB+7RkAQwEYABkAPwwvASwAAAAAFAARAAAIiwALCBxI sKDBgwgPAlioQMFChg4XGgQQoKKAigEEXKwIYCLGjRk1ZuxYUMGAAwMMnEyZkkABBQYVJAgwsybN mzALUrRYcQDIACQJAkAgAEEAokaTAp04M6kAA0eLCgg6UAHGq1hzErQasifIAVoH7sz4kSdVgQCa RoVKFOrZAg8bPgQgV2LCu3jzBgQAOw== } #end image Select all ######################## #Copy Image set imcopy { R0lGODlhEAAQAPcAAAAAAM7Ozv////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////yH5BAEAAAEALAAAAAAQABAA AAhSAAEIHEhwYICDAP4pXMjwH4CDARISbOgQokSBFCsidDiQ4sONFxNyLChSoUiMDFGmdNhQpcmX KUuOdMlxoUyPJW+2zJnRJs+eM2m2hBiRZMGAAAA7 } #End Copy Image ############################ #Image Cut set imcut { R0lGODlhEAAQAPcAAAAAAMbGxv////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////yH5BAEAAAEALAAAAAAQABAA AAhEAAMIHCgQAMGDCA0iXBhAocB/DhMOhMiw4MOICw1SrFhwI8eGGAcCGEnSI8GIJBk6VBhS5EiX LSU2/DizJkeWNEEeDAgAOw== } #End Image Cut ####### #Image Paste set impaste { R0lGODlhEAAQAPcAAAAAAAAAY2NjY8bGxv////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////yH5BAEAAAMALAAAAAAQABAA AAhgAAcIHEiwoMEBABICOIhQIQABAhwuFAjgn8WHCSNa/DexIkeIIDVypHhRYsKLJDeqVNlxZYCX MF+m3BjAZYCZFmuqrHnTI81/MIHK9JlzZU6ENmPypOhQp8uDSmMyZBgQADs= } #End Image Past ####################### ######################## #Image Ptint set imprint { R0lGODdhEwATAPcAAAAAAP8AAABtAACSAG1tVZJtVW2SVZKSVW1tqpJtqm2SqpKSqra2qtu2qrbb qtvbqrOzs7a2/7bb/9v//////20/Azb1AgBk6wIACAD/AacrAAABAMk7AADzAuA/AAAAAAAAAAAA AEAGAAAAAAAA9wPWFE4ifwMJAAAA1hQ29QIAkOwCAAAyVwQBAA5gAAAAAAAAVuvHMYT1twVQUiAD WAJABgEQAAAAAEAGAAAAAAAAAAAAABMBCeAABDAA1hQfBR8DWAUfAwAAAAACAOrrAgAIAB8BpysA AAEANQIBAQYAAQAAANYUZAAAAAIANQIAAC8AFAAaAFYAJwBlAAAAAAAAQPdeAAC3BSHsAAAAAAAA AADHMQAAAADc68cxhPW3BUIAnhcEAMjsxzEGAAEAJQAfAHoCSezg60nsTiOvBwgD3xOPEwwFSO0a AC8A///3/wAACAPfE8cDAAD//wAAHwAgAPLrCiavBxjsxzF6At8TUezHMeDsJwHXExjsxzGLax8B jxPg7EsB1xPc7McxSO3HMRjsxzEBAACAQXBwRXZlbnRzXFNjaGVtZXNcQXBwc1wuRGVmYXVsdFxN QUdJQ01lbnVDb21tYW5kXC5DdXJyZW50AAngAACDAP4ABgG3BbDsS3tXBIT1twVwLtcFIQDwAAEA BgAfAEMBAAAAACYAHwAAANYUBQDEFvcXNvWsAx8DRAhDAR8AJgAlACcAHwAmACUAJwAAAK41AADE Na41jwcfAgAAAADHAP1VrjUCAAAAAgCvNQDzrjUGGwcL4uzAHZUG9xf7Bq41AABI7boAAAA27TgC SO3HMfTsxzEbA98TAACuNU1BR0lDTWVudUNvbW1hbmQAAwAAQO0tJG8YAAD+////BRAczyRFAgDH MSRFAgDC7gIAiwAAANYUDQBC9gAAACAFANzt9xcUAiRF9xddJrcHOwCBAFLtxzGEAAIAFAIFACsA GwNTAhQL9zUAAP7///8FEBzPFAKa7Q9Hnwc7AIEAJEUCAPcXgEUCACwAAAAAEwATAAAIjAAhCBxI sKDBgwgLAljIsOHCgwAoSJxIEQBECgspTrRoMCLFCRRAYrzokOHIjhJFauSoEGPJiCwHZpwIsqZL hS9LEly4gIACAgkIHEBQwEACAw8heNTIdKNSCgyiNmDgIOoAAQwCBIhqMWLUr2DBRnDQFWoDCQwi NFCL1kGEtA+65pwrkGFCpUnvJgwIADs= } #End Pint Image ########################### #Image Protocol set improtocol { R0lGODdhEgASAPcAAAAAAG0AAJIAAP8AAG0AVZIAVW1tVZJtVW2SVZKSVW0AqpIAqm1tqpJtqm2S qpKSqra2qtu2qrbbqrOzs7a2/9u2/7bb/9vb/9v//////6crAAABAMk7AADzAuA/AAAAAAAAAAAA AEAGAAAAAAAA9wPWFE4ifwMJAAAA1hQ6+gIAkOwCAAAyVwQBAA5gAAAAAAAAVuvHMYj6twVQUiAD WAJABgEQAAAAAEAGAAAAAAAAAAAAABMBCeAABDAA1hQfBR8DWAUfAwAAAAACAOrrAgAIAB8BpysA AAEANQIBAQYAAQAAANYUZAAAAAIANQIAAC8AFAAaAFYAJwBlAAAAAAAAQPdeAAC3BSHsAAAAAAAA AADHMQAAAADc68cxiPq3BUIAnhcEAMjsxzEGAAEAJQAfAHoCSezg60nsTiOvBwgD3xOPEwwFSO0a AC8A///3/wAACAPfE8cDAAD//wAAHwAgAPLrCiavBxjsxzF6At8TUezHMeDsJwHXExjsxzGLax8B jxPg7EsB1xPc7McxSO3HMRjsxzEBAACAQXBwRXZlbnRzXFNjaGVtZXNcQXBwc1wuRGVmYXVsdFxN QUdJQ01lbnVDb21tYW5kXC5DdXJyZW50AAngAACDAP4ABgG3BbDsS3tXBIj6twVwLtcFIQDwAAEA BgAfAEMBAAAAACYAHwAAANYUBQDEFvcXOvqsAx8DeAtDAR8AJgAlACcAHwAmACUAJwAAAK41AADE Na41jwcfAgAAAADHAP1VrjUCAAAAAgCvNQDzrjUGGwcL4uzAHZUG9xf7Bq41AABI7boAAAA27TgC SO3HMfTsxzEbA98TAACuNU1BR0lDTWVudUNvbW1hbmQAAwAAQO0tJG8YAAD+////BRAczyRFAgDH MSRFAgDC7gIAiwAAANYUDQBO9wAAACAFANztnQOTAAEQSO3HMQwF9xcAAAD///8FEBzPFAIkRQIA VAAM7hQL9zUAAP7///8FEBzPFAIQAhIAAAB+7RkAQwEYABkADwwvASwAAAAAEgASAAAItAAnCBxI sKDBgwMBAEB4EMCChQYVFnQIcaKAigoVVCQIQMAAhQofFICQQWJCAQoGPIDwwMACBxkwZIBgsmNK BywVMsjAM0MAAQI7LlBJcyXPCxAuLAA6oSOBAQcYJICA4AACqkMhOh1wFQIECV55mmyKkqtXChQg UBDLEaUAnF4thC3ZVsEBChEsRJCwl23CBSR7Zqjw4IDXjQICOEiwmMEBBw0cRN3YNMBPAZgx/wzA sPPAgAA7 } #Emd Img Protocol ########################### #Image Chart Loader set imchart { R0lGODdhFQATAPcAAAAAAG1tVZKSVW1tqpKSqra2qrbbqtvbqrOzs8zMzLa2/9vb/////xdkPrcH AACmAsABAgAFAIQKAgAFAAAApG0/Azr6AgBk6wIACAACAacrAAABAMk7AAAG6+A/AAAAAAAAAAAA AEAGAAAAAAAA9wPWFE4ifwMJAAAA1hQ6+gIAkOwCAAAyVwQBAA5gAAAAAAAAVuvHMYj6twVQUiAD WAJABgEQAAAAAEAGAAAAAAAAAAAAABMBCeAABDAA1hQfBR8DWAUfAwAAAAACAOrrAgAIAB8BpysA AAEANQIBAQYAAQAAANYUZAAAAAIANQIAAC8AFAAaAFYAJwBlAAAAAAAAQPdeAAC3BSHsAAAAAAAA AADHMQAAAADc68cxiPq3BUIAnhcEAMjsxzEGAAEAJQAfAHoCSezg60nsTiOvBwgD3xOPEwwFSO0a AC8A///3/wAACAPfE8cDAAD//wAAHwAgAPLrCiavBxjsxzF6At8TUezHMeDsJwHXExjsxzGLax8B jxPg7EsB1xPc7McxSO3HMRjsxzEBAACAQXBwRXZlbnRzXFNjaGVtZXNcQXBwc1wuRGVmYXVsdFxN QUdJQ01lbnVDb21tYW5kXC5DdXJyZW50AAngAACDAP4ABgG3BbDsS3tXBIj6twVwLtcFIQDwAAEA BgAfAEMBAAAAACYAHwAAANYUBQDEFvcXOvqsAx8DqAdDAR8AJgAlACcAHwAmACUAJwAAAK41AADE Na41jwcfAgAAAADHAP1VrjUCAAAAAgCvNQDzrjUGGwcL4uzAHZUG9xf7Bq41AABI7boAAAA27TgC SO3HMfTsxzEbA98TAACuNU1BR0lDTWVudUNvbW1hbmQAAwAAQO0tJG8YAAD+////BRAczyRFAgDH MSRFAgDC7gIAiwAAANYUDQBa+AAAACAFANztnQOTAAEQSO3HMQwF9xcAAAD///8FEBzPFAIkRQIA VAAM7hQL9zUAAP7///8FEBzPFAIQAhIAAAB+7RkAQwEYABkArwsvASwAAAAAFQATAAAIgQARCBxI sKDBgwgTEgTAkKHChQASSDyQAMBDBAAIHFCwcSMBiwoBFFBQYAGDkwUACEgI4ECBlxsLMBgJ8qDI Ai5fynxZ0yCABSWDAgXas2DLkUFJ0mQ5IChMnEV9EtCJ08DHqEZv8ryJNatDlTwvGp2aUuxCsl1Z BnBodiDbtgcDAgA7 } #End Loader ########################### #Image Image loader set imeye { R0lGODdhFAARAPcAAAAAAAAAVW1tVZKSVQAAqm1tqpKSqra2qtvbqrOzswAA/////7cFBwCu68cx XwA/ADr65gUAAHLrAAEFAAAApG0/A0L2AgBk6wIACAD/AacrAAABAMk7AADzAuA/AAAAAAAAAAAA AEAGAAAAAAAA9wPWFE4ifwMJAAAA1hRC9gIAkOwCAAAyVwQBAA5gAAAAAAAAVuvHMZD2twVQUiAD WAJABgEQAAAAAEAGAAAAAAAAAAAAABMBCeAABDAA1hQfBR8DWAUfAwAAAAACAOrrAgAIAB8BpysA AAEANQIBAQYAAQAAANYUZAAAAAIANQIAAC8AFAAaAFYAJwBlAAAAAAAAQPdeAAC3BSHsAAAAAAAA AADHMQAAAADc68cxkPa3BUIAnhcEAMjsxzEGAAEAJQAfAHoCSezg60nsTiOvBwgD3xOPEwwFSO0a AC8A///3/wAACAPfE8cDAAD//wAAHwAgAPLrCiavBxjsxzF6At8TUezHMeDsJwHXExjsxzGLax8B jxPg7EsB1xPc7McxSO3HMRjsxzEBAACAQXBwRXZlbnRzXFNjaGVtZXNcQXBwc1wuRGVmYXVsdFxN QUdJQ01lbnVDb21tYW5kXC5DdXJyZW50AAngAACDAP4ABgG3BbDsS3tXBJD2twVwLtcFIQDwAAEA BgAfAEMBAAAAACYAHwAAANYUBQDEFvcXQvasAx8DMApDAR8AJgAlACcAHwAmACUAJwAAAK41AADE Na41jwcfAgAAAADHAP1VrjUCAAAAAgCvNQDzrjUGGwcL4uzAHZUG9xf7Bq41AABI7boAAAA27TgC SO3HMfTsxzEbA98TAACuNU1BR0lDTWVudUNvbW1hbmQAAwAAQO0tJG8YAAD+////BRAczyRFAgDH MSRFAgDC7gIAiwAAANYUDQA6+gAAACAFANztnQOTAAEQSO3HMQwF9xcAAAD///8FEBzPFAIkRQIA VAAM7hQL9zUAAP7///8FEBzPFAIQAhIAAAB+7RkAQwEYABkA7wsvASwAAAAAFAARAAAIewATCBxI sKBBggASKlR4UODChwsNQgRQkCHCiQkvVlRooGJDjAkFCKD4UWEAAgE4ktyYkIBLAghUsjQgQMHJ kwUWRByocOQBlCgPLNCZ8SKAAzSDDt3pEABNAwAGGJBqAGpRowaQGihw4IBFiQsFFBhwtWECiGbB li0YEAA7 } ####################### #Image Help set imhelp { R0lGODdhDgARAPcAAAAAAAAAVQAAqgAA/wAkAAAkVQAkqgAk/wBJAABJVQBJqgBJ/wBtAABtVQBt qgBt/wCSAACSVQCSqgCS/wC2AAC2VQC2qgC2/wDbAADbVQDbqgDb/wD/AAD/VQD/qgD//yQAACQA VSQAqiQA/yQkACQkVSQkqiQk/yRJACRJVSRJqiRJ/yRtACRtVSRtqiRt/ySSACSSVSSSqiSS/yS2 ACS2VSS2qiS2/yTbACTbVSTbqiTb/yT/ACT/VST/qiT//0kAAEkAVUkAqkkA/0kkAEkkVUkkqkkk /0lJAElJVUlJqklJ/0ltAEltVUltqklt/0mSAEmSVUmSqkmS/0m2AEm2VUm2qkm2/0nbAEnbVUnb qknb/0n/AEn/VUn/qkn//20AAG0AVW0Aqm0A/20kAG0kVW0kqm0k/21JAG1JVW1Jqm1J/21tAG1t VW1tqm1t/22SAG2SVW2Sqm2S/222AG22VW22qm22/23bAG3bVW3bqm3b/23/AG3/VW3/qm3//5IA AJIAVZIAqpIA/5IkAJIkVZIkqpIk/5JJAJJJVZJJqpJJ/5JtAJJtVZJtqpJt/5KSAJKSVZKSqpKS /5K2AJK2VZK2qpK2/5LbAJLbVZLbqpLb/5L/AJL/VZL/qpL//7YAALYAVbYAqrYA/7YkALYkVbYk qrYk/7ZJALZJVbZJqrZJ/7ZtALZtVbZtqrZt/7aSALaSVbaSqraS/7a2ALa2Vba2qra2/7bbALbb Vbbbqrbb/7b/ALb/Vbb/qrb//9sAANsAVdsAqtsA/9skANskVdskqtsk/9tJANtJVdtJqttJ/9tt ANttVdttqttt/9uSANuSVduSqtuS/9u2ANu2Vdu2qtu2/9vbANvbVdvbqtvb/9v/ANv/Vdv/qtv/ //8AAP8AVf8Aqv8A//8kAP8kVf8kqv8k//9JAP9JVf9Jqv9J//9tAP9tVf9tqv9t//+SAP+SVf+S qv+S//+2AP+2Vf+2qv+2///bAP/bVf/bqv/b////AP//Vf//qv///yH5BAAAAAAALAAAAAAOABEA QAiLAP8JHEiwYJt/3/7x+zZgwEJbAApKNIjwX8OG3P5BFChnIDcBAxRqjPjv4L99/P5t+4etTaSB jQQ2lBly47+OCTP+85fSZhtbQIMKJSkpkqRGRd1IWkrwYMaEKb8BmCrQjcKZ/GbajCNSILcBAkYK jMltH8OQAm1aTfkPpFmx/7iy7Qp3qt27dv8FBAA7 } #End Image Help image create photo imnew -data $imnew -gamma 1 -height 16 -width 16 -palette 5/5/4 image create photo imopen -data $imopen -gamma 1 -height 16 -width 16 -palette 5/5/4 image create photo imsave -data $imsave -gamma 1 -height 16 -width 16 -palette 5/5/4 image create photo imselectall -data $imselectall #-gamma 1 -palette 5/5/4 image create photo imcopy -data $imcopy -gamma 1 -height 16 -width 16 -palette 5/5/4 image create photo imcut -data $imcut -gamma 1 -height 16 -width 16 -palette 5/5/4 image create photo impaste -data $impaste -gamma 1 -height 16 -width 16 -palette 5/5/4 image create photo imprint -data $imprint image create photo improtocol -data $improtocol image create photo imchart -data $imchart image create photo imeye -data $imeye image create photo imhelp -data $imhelp frame .ed.menubuttons -relief groove -borderwidth 1 pack .ed.menubuttons -side top -fill x -expand yes button .ed.menubuttons.new -image imnew -command {clear_all .ed.text.t} button .ed.menubuttons.open -image imopen -command "clear_all .ed.text.t ; textOpen" button .ed.menubuttons.save -image imsave -command "textSaveAs" button .ed.menubuttons.selectall -image imselectall -height 16 -width 16 -command {.ed.text.t tag add sel 1.0 end} button .ed.menubuttons.copy -image imcopy -command {tk_textCopy .ed.text.t} button .ed.menubuttons.cut -image imcut -command "tk_textCut .ed.text.t" button .ed.menubuttons.paste -image impaste -command "tk_textPaste .ed.text.t" button .ed.menubuttons.print -image imprint -command "printFormat" -width 16 -height 16 button .ed.menubuttons.run -image improtocol -command {run_tcl .ed.text.t} -width 16 -height 16 button .ed.menubuttons.help -image imhelp -command "About" -width 16 -height 16 label .ed.menubuttons.l -text "" -font {Arial 8 normal} pack .ed.menubuttons.new .ed.menubuttons.open .ed.menubuttons.save .ed.menubuttons.print .ed.menubuttons.selectall .ed.menubuttons.copy .ed.menubuttons.cut .ed.menubuttons.paste .ed.menubuttons.run .ed.menubuttons.help -side left -fill x pack .ed.menubuttons.l -side left -fill x ##################################### bind .ed.menubuttons.new <Enter> ".ed.menubuttons.l config -text {New}" bind .ed.menubuttons.new <Leave> ".ed.menubuttons.l config -text {}" bind .ed.menubuttons.open <Enter> ".ed.menubuttons.l config -text {Open File}" bind .ed.menubuttons.open <Leave> ".ed.menubuttons.l config -text {}" bind .ed.menubuttons.save <Enter> ".ed.menubuttons.l config -text {Save as...}" bind .ed.menubuttons.save <Leave> ".ed.menubuttons.l config -text {}" bind .ed.menubuttons.selectall <Enter> ".ed.menubuttons.l config -text {Select all}" bind .ed.menubuttons.selectall <Leave> ".ed.menubuttons.l config -text {}" bind .ed.menubuttons.copy <Enter> ".ed.menubuttons.l config -text {Copy selected text}" bind .ed.menubuttons.copy <Leave> ".ed.menubuttons.l config -text {}" bind .ed.menubuttons.cut <Enter> ".ed.menubuttons.l config -text {Cut selected text}" bind .ed.menubuttons.cut <Leave> ".ed.menubuttons.l config -text {}" bind .ed.menubuttons.paste <Enter> ".ed.menubuttons.l config -text {Paste selected text}" bind .ed.menubuttons.paste <Leave> ".ed.menubuttons.l config -text {}" bind .ed.menubuttons.print <Enter> ".ed.menubuttons.l config -text {Print formated text}" bind .ed.menubuttons.print <Leave> ".ed.menubuttons.l config -text {}" bind .ed.menubuttons.run <Enter> ".ed.menubuttons.l config -text {Run Tcl}" bind .ed.menubuttons.help <Enter> ".ed.menubuttons.l config -text {Help}" bind .ed.menubuttons.help <Leave> ".ed.menubuttons.l config -text {}" ##################################### #Text widget frame .ed.text text .ed.text.t -wrap none -font {monaco 12} -cursor arrow -yscrollcommand {.ed.text.scrl set} -xscrollcommand {.ed.text.scrl2 set} scrollbar .ed.text.scrl -command ".ed.text.t yview" scrollbar .ed.text.scrl2 -command ".ed.text.t xview" -orient hor pack .ed.text.scrl -side right -fill y pack .ed.text.scrl2 -side bottom -fill x pack .ed.text.t -fill both -expand yes pack .ed.text -side left -fill both -expand true bind .ed.text <Enter> "focus .ed.text" } proc About {} { catch [destroy .about] toplevel .about wm resizable .about 0 0 center_win .about grab .about label .about.l -relief groove -bd 3 -font {arial 11 {bold}} -text "n TkMC v1.0n Author: Grigoriy Abramovn System Administrator of The Center For Population Economics n The University of Chicagon Questions and bug report send to: n gabramov@cpe.uchicago.edun " pack .about.l bind .about <Enter> "destroy .about" }
E) Un bloc note

voici le code:
#! /usr/local/tcl/bin/wish # ---- faire le menage en cas de re-chargement catch {font delete textFont} catch {eval destroy [winfo children .]} catch {unset HiddenText} # ---- creer la fenetre d'edition de texte # font create textFont -family Courier -size 10 text .src -font textFont -width 80 -height 40 -relief sunken -yscrollcommand {.sb set} scrollbar .sb -orient vertical -command {.src yview} pack .src -side left -fill both -expand true pack .sb -side left -fill y # ---- creer la barre de menus # menu .bar .bar add cascade -label Fichier -menu .bar.text .bar add cascade -label Edition -menu .bar.edit #.bar add cascade -label Tcl -menu .bar.tcl . config -menu .bar menu .bar.text .bar.text add command -label Nouveau -command {NewText} .bar.text add command -label Charger -command {OpenFile} .bar.text add command -label Sauver -command {SaveFile} .bar.text add command -label "Sauver sous" -command {SaveAs} .bar.text add separator .bar.text add command -label Quit -command {Quit} menu .bar.edit .bar.edit add command -label Couper -command {event generate <<Cut>>} .bar.edit add command -label Copier -command {event generate <<Copy>>} .bar.edit add command -label Coller -command {event generate <<Paste>>} .bar.edit add separator .bar.edit add command -label "Outline selection" -command {CreateSelectOutline} .bar.edit add command -label "Outline Tcl proc" -command {CreateTclProcOutline} #menu .bar.tcl #.bar.tcl add command -label "Nouvel interpreteur" -command {NewInterp} #.bar.tcl add command -label Evaluer -command {EvalText} #.bar.tcl add command -label "Espionner variable" -command {SpyVar} # ---- procedures de gestion de fichiers # # Attention! on ne controle pas si le fichier en cours d'edition a ete modifie... # set fileName "" proc NewText {} { global fileName .src delete 1.0 end set fileName "" } proc OpenFile {} { global fileName set types { {{Text Files} {} TEXT} {{TCL Scripts} {.tcl}} } set fileName [tk_getOpenFile -filetypes $types] if {$fileName == ""} return if [catch {open $fileName r} fd] { tk_messageBox -title "Erreur" -type ok -icon error -message $fd return } .src delete 1.0 end .src insert end [read $fd [file size $fileName]] close $fd } proc SaveFile {} { global fileName if {$fileName == ""} { SaveAs return } if [catch {open $fileName w} fd] { tk_messageBox -title "Erreur" -type ok -icon error -message $fd return } catch {.src delete reply.first reply.last} puts -nonewline $fd [.src get 1.0 end] close $fd } proc SaveAs {} { global fileName set types { {{Text Files} {} TEXT} {{TCL Scripts} {.tcl}} } set fileName [tk_getSaveFile -filetypes $types] if {$fileName == ""} return if [catch {open $fileName w} fd] { tk_messageBox -title "Erreur" -type ok -icon error -message $fd return } catch {.src delete reply.first reply.last} puts -nonewline $fd [.src get 1.0 end] close $fd } proc Quit {} { destroy . } # --- boite de recherche # toplevel .find wm title .find Find entry .find.string button .find.show -text Show -command {ShowFindString [.find.string get]} button .find.reset -text Reset -command ResetFindString bind .find.string <Key-Return> {ShowFindString [.find.string get]} bind .find.string <Key> {AutoFind} proc AutoFind {} { global findId after cancel AutoFind after 500 {ShowFindString [.find.string get]} } pack .find.string -side top -fill x pack .find.show -side left -padx 5 -pady 5 pack .find.reset -side left -padx 5 -pady 5 proc ShowFindString {str} { set from 1.0 ResetFindString .src tag configure found -background green while { [set from [.src search -exact -count length -- $str $from end]] != {} } { set to [.src index "$from + $length chars"] .src tag add found $from $to set from $to } } proc ResetFindString {} { .src tag delete found } # ---- mode outline # set wid 0 proc CreateSelectOutline {} { set from [.src index sel.first] set to [.src index sel.last] if [.src compare $from == $to] { return } CreateOutline $from $from $to } proc CreateTclProcOutline {} { set from [.src search -back -regexp -- "^proc " insert 1.0] set to [.src search -forw -regexp -- "^}" insert end] if {$from == {} || $to == {}} { return } CreateOutline $from [.src index "$from lineend"] $to } proc CreateOutline {mark from to} { global wid incr wid set w [button .src.w$wid -text v -command "ToggleOutline $wid"] .src window create $mark -window $w .src mark set b$wid "$from +1char" .src mark set e$wid "$to + 1char" .src mark gravity b$wid left ToggleOutline $wid } proc ToggleOutline {wid} { global HiddenText if [info exists HiddenText($wid)] { .src insert b$wid $HiddenText($wid) unset HiddenText($wid) .src.w$wid config -text v } else { set HiddenText($wid) [.src get b$wid e$wid] .src delete b$wid e$wid .src.w$wid config -text > } }
F) Un logiciel de dessin façon paintbrush

voici le code :
# Name: ScratchPad.tcl # Author: Martin Eder, snofix@users.sourceforge.net # Description: A simple scratch pad which provides free-hand drawing and # basic geometric figures (lines, rectangels, circles). # The drawing can be saved as jpg or gif file. namespace eval spad { set currentmode "freehand" set thickness 1 set thicklist "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 22 24 26 28 30" set pcolor "black" set pbcolor "white" set canbg "white" set savename "" } proc spad::setcol {cvar widget} { set newcolor [tk_chooseColor -initialcolor $cvar -parent .ppad -title "Choose new fill color"] if {$newcolor != ""} { set $cvar $newcolor $widget configure -bg $newcolor return $newcolor } } proc spad::gui {} { if {[winfo exists .ppad]} {destroy .ppad} wm withdraw . toplevel .ppad -padx 5 -pady 5 wm protocol .ppad WM_DELETE_WINDOW exit wm title .ppad "Scratch Pad" frame .ppad.f -relief ridge -borderwidth 4 canvas .ppad.f.c -bg $spad::canbg -highlightthickness 0 -width 320 -height 240 frame .ppad.panel frame .ppad.dpanel frame .ppad.status label .ppad.status.pos -relief groove -width 9 label .ppad.status.size -relief groove -width 9 label .ppad.status.bar -relief groove -anchor w -width 10 label .ppad.panel.pcollab -text " Pen:" button .ppad.panel.pcol -width 3 -bg $spad::pcolor -relief ridge -command { set tmpcol [spad::setcol $spad::pcolor .ppad.panel.pcol] if {$tmpcol != ""} {set spad::pcolor $tmpcol} } label .ppad.panel.pbcollab -text " Fill:" button .ppad.panel.pbcol -width 3 -bg $spad::pbcolor -relief ridge -command { set tmpcol [spad::setcol $spad::pbcolor .ppad.panel.pbcol] if {$tmpcol != ""} {set spad::pbcolor $tmpcol} } label .ppad.panel.bgcollab -text " Background:" button .ppad.panel.bgcol -width 3 -bg $spad::canbg -relief ridge -command { set tmpcol [spad::setcol $spad::canbg .ppad.panel.bgcol] if {$tmpcol != ""} { .ppad.f.c configure -bg [set spad::bgcollab $tmpcol] } } spinbox .ppad.dpanel.thickness -values $spad::thicklist -command {set spad::thickness [.ppad.dpanel.thickness get]} -state readonly -width 3 button .ppad.dpanel.pointer -relief raised -command spad::pointer -image [image create photo -data { R0lGODlhEAAQAIMAAPwCBAQCBPz+xPz+BMTCBPz+/MTCxISChDQyNAAAAAAA AAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAREEMhJg6BYWhAG v5k2EKMXToSgEqc1DEIhvGAWpOvJFSXZyoXOxxY0BDahQDGg4xgOxmbgiWDq poeqlGrVcZuSbLfpjwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVy c2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJl c2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==}] button .ppad.dpanel.freehand -relief raised -command spad::draw_free -image [image create photo -data { R0lGODlhEgASAIAAAAAAAP///yH5BAEAAAEALAAAAAASABIAAAIjjI+pywgP moty1kTvyTpw/UHfRkGGqYhpt7Gn67GopMK2UgAAOw==}] button .ppad.dpanel.line -relief raised -command spad::draw_line -image [image create photo -data { R0lGODlhEgASAIAAAAAAAP///yH5BAEAAAEALAAAAAASABIAAAIdjI+py+0G wEtxUmlPzRDnzYGfN3KBaKGT6rDmGxQAOw==}] button .ppad.dpanel.rectangle -relief raised -command spad::draw_rectangle -image [image create photo -data { R0lGODlhEgASAIAAAAAAAP///yH5BAEAAAEALAAAAAASABIAAAImjI+py+3f gJxUqorB1csmv4Udh4AfeZglaqgpG7gtnFVbLUP6/hQAOw==}] button .ppad.dpanel.circle -relief raised -command spad::draw_circle -image [image create photo -data { R0lGODlhEgASAIAAAAAAAP///yH5BAEAAAEALAAAAAASABIAAAIrjI+pywkP X4sULKgw0tluz0iHGIIBeZlo9zWnarLjOnfxe+NVbuy8CwwWAAA7}] .ppad configure -menu [menu .ppad.padmenu] -padx 5 -pady 5 .ppad.padmenu add cascade -label "File" -menu [menu .ppad.padmenu.file -tearoff 0] .ppad.padmenu.file add command -label "Clear" -command {.ppad.f.c delete all} .ppad.padmenu.file add command -label "Save" -command {spad::save_can $spad::savename} .ppad.padmenu.file add command -label "Save As" -command {spad::save_can ""} .ppad.padmenu.file add separator .ppad.padmenu.file add command -label "About" -command {tk_messageBox -title "About" -message "Scratch Padn2006 by Martin Edern(snofix@users.sourceforge.net)"} .ppad.padmenu.file add command -label "Exit" -command exit pack .ppad.f.c -expand 1 -fill both pack .ppad.dpanel.pointer .ppad.dpanel.freehand .ppad.dpanel.line .ppad.dpanel.rectangle .ppad.dpanel.circle -padx 2 -side top -pady 1 -fill x pack .ppad.dpanel.thickness -side top -pady 10 -padx 2 -fill x pack .ppad.panel.pcollab .ppad.panel.pcol .ppad.panel.pbcollab .ppad.panel.pbcol .ppad.panel.bgcollab .ppad.panel.bgcol -side left pack .ppad.status.size .ppad.status.pos -side right pack .ppad.status.bar -side left -expand 1 -fill x pack .ppad.status -side bottom -fill x pack .ppad.panel -side bottom -fill x -pady 5 pack .ppad.dpanel -side left -fill y pack .ppad.f -side right -expand 1 -fill both bind .ppad.f.c <3> {.ppad.f.c delete current} bind .ppad.f.c <Configure> {.ppad.status.size configure -text "[winfo width .ppad.f.c]x[winfo height .ppad.f.c]"} bind posupdate <Motion> {spad::update_pos %x %y} bind posupdate <B1-Motion> {spad::update_pos %x %y} bindtags .ppad.f.c {posupdate .ppad.f.c .ppad} ### Help text bind .ppad.dpanel.pointer <Enter> {.ppad.status.bar configure -text "Magic wand. Move a figure by drag and drop."} bind .ppad.dpanel.freehand <Enter> {.ppad.status.bar configure -text "Tool for free-hand drawings. Press the left mouse button and keep it pressed."} bind .ppad.dpanel.line <Enter> {.ppad.status.bar configure -text "Draw lines. Keep the left mouse button pressed to draw the line."} bind .ppad.dpanel.rectangle <Enter> {.ppad.status.bar configure -text "Draw rectangeles. Keep the left mouse button pressed to draw the rectangle."} bind .ppad.dpanel.circle <Enter> {.ppad.status.bar configure -text "Draw ovals. Keep the left mouse button pressed to draw the oval."} bind .ppad.dpanel.thickness <Enter> {.ppad.status.bar configure -text "Change the thickness of the pen."} bind .ppad.panel.pcol <Enter> {.ppad.status.bar configure -text "Change the color of the pen."} bind .ppad.panel.pbcol <Enter> {.ppad.status.bar configure -text "Change the fill color for rectangles and ovals."} bind .ppad.f.c <Enter> {.ppad.status.bar configure -text "Scratch Pad. Right click to delete figures, left mouse button to draw figures."} bind .ppad.status.pos <Enter> {.ppad.status.bar configure -text "Shows x and y position of the pointer."} bind .ppad.status.size <Enter> {.ppad.status.bar configure -text "Shows canvas size in pixels."} } proc spad::pointer {} { spad::draw_mode pointer bind .ppad.f.c <ButtonPress-1> { set startx %x set starty %y set seltag [.ppad.f.c gettag current] puts $seltag} bind .ppad.f.c <B1-Motion> { .ppad.f.c move $seltag [expr %x - $startx] [expr %y - $starty] set startx %x set starty %y } bind .ppad.f.c <ButtonRelease-1> {} } proc spad::draw_free {} { spad::draw_mode freehand bind .ppad.f.c <ButtonPress-1> {set tempfree [.ppad.f.c create line %x %y %x %y -fill $spad::pcolor -width $spad::thickness]} bind .ppad.f.c <B1-Motion> {.ppad.f.c coords $tempfree [concat [.ppad.f.c coords $tempfree] %x %y]} bind .ppad.f.c <ButtonRelease-1> {} } proc spad::draw_line {} { spad::draw_mode line bind .ppad.f.c <ButtonPress-1> { set linestartx %x set linestarty %y set tline [.ppad.f.c create line $linestartx $linestarty %x %y -width $spad::thickness -fill $spad::pcolor] } bind .ppad.f.c <B1-Motion> {.ppad.f.c coord $tline $linestartx $linestarty %x %y} bind .ppad.f.c <ButtonRelease-1> {.ppad.f.c coord $tline $linestartx $linestarty %x %y} } proc spad::draw_rectangle {} { spad::draw_mode rectangle bind .ppad.f.c <ButtonPress-1> { set rectstartx %x set rectstarty %y set trect [.ppad.f.c create rectangle $rectstartx $rectstarty %x %y -width $spad::thickness -fill $spad::pbcolor -outline $spad::pcolor] } bind .ppad.f.c <B1-Motion> {.ppad.f.c coord $trect $rectstartx $rectstarty %x %y} bind .ppad.f.c <ButtonRelease-1> {.ppad.f.c coord $trect $rectstartx $rectstarty %x %y} } proc spad::draw_circle {} { spad::draw_mode circle bind .ppad.f.c <ButtonPress-1> { set circstartx %x set circstarty %y set tcirc [.ppad.f.c create oval $circstartx $circstarty %x %y -width $spad::thickness -fill $spad::pbcolor -outline $spad::pcolor] } bind .ppad.f.c <B1-Motion> {.ppad.f.c coord $tcirc $circstartx $circstarty %x %y} bind .ppad.f.c <ButtonRelease-1> {.ppad.f.c coord $tcirc $circstartx $circstarty %x %y} } proc spad::draw_mode {widget} { .ppad.dpanel.$::spad::currentmode configure -relief raised .ppad.dpanel.$widget configure -relief sunken set ::spad::currentmode $widget } proc spad::save_can {filename} { if {[catch {package require Img} err]} { tk_messageBox -message "Could not load package Img!" -icon error return } set canimg [image create photo -format window -data .ppad.f.c] if {$filename == ""} { set filename [tk_getSaveFile -title "Save Scratch Pad" -filetypes ""{GIF Image} {.gif}" "{JPEG Image} {.jpg}"" -initialdir [pwd] -initialfile "ScratchPad.gif"] } if {$filename != ""} { switch -- [file extension $filename] { ".gif" {set fformat "GIF"} ".jpg" {set fformat "JPEG"} default {tk_messageBox -title "Unsupported format" -message "Unsupported format.nPlease use gif or jpg extension.n" -icon error; return} } $canimg write $filename -format $fformat } set spad::savename $filename } proc spad::update_pos {xp yp} { set offset 0 set xpos [expr $xp - $offset] set ypos [expr $yp - $offset] .ppad.status.pos configure -text "$xpos,$ypos" } spad::gui spad::draw_free spad::update_pos 0 0 ### End of Script
G) Un convertisseur de base (binaire, décimal, octal, hexa,etc...)

Voici le code :
#!/bin/sh # # $Id: tkalc.tcl,v 1.4 2001/01/11 13:35:43 boris Exp $ # tkalc - Programmer's almighty pocket calculator # Copyright (C) 2000 Boris Folgmann # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # the next line restarts using wish exec wish "$0" "$@" # Globals set expression "" set VERSION "tkalc 1.0.2" set decimal "Welcome to tkalc!" set hexadecimal "Enter expression and press return." set octal "Press Esc to close window." set binary "Alt+C for Clear and so on" set ascii "Tab to change widget, space to push button" set ip "Check out http://www.folgmann.de" set bool "Email: boris@folgmann.de" set errormsg "tkalc (c) 2000-2001 by Boris Folgmann" # I use this as a constant for the widget width in characters set WIDTH 38 # Set window title # . is always the toplevel widget wm title . $VERSION wm grid . 45 20 10 10 wm minsize . 45 20 wm resizable . 1 0 # Set defaults . config -borderwidth 3 # Make main frame set m [frame .main] grid columnconf $m 1 -weight 1 # Make buttons frame set b [frame .buttons] # Center at top grid $m $b -sticky new # Use 5:1 for output against buttons grid columnconf . 0 -weight 5 grid columnconf . 1 -weight 1 # expression entry label $m.lexpression -text Expr -padx 0 # The increased borderwidth is needed so that the ridge border is as thick as the sunken border. entry $m.expression -width $WIDTH -relief ridge -borderwidth 3 -background white -textvariable expression grid $m.lexpression $m.expression -padx 3 -pady 1 -sticky news # Decimal label $m.ldec -text Dec -padx 0 label $m.dec -width $WIDTH -relief sunken -textvariable decimal grid $m.ldec $m.dec -padx 3 -pady 1 -sticky news # Use sticky west for left centered labels! # -sticky w # Hex label $m.lhex -text Hex -padx 0 label $m.hex -width $WIDTH -relief sunken -textvariable hexadecimal grid $m.lhex $m.hex -padx 3 -pady 1 -sticky news # Oct label $m.loct -text Oct -padx 0 label $m.oct -width $WIDTH -relief sunken -textvariable octal grid $m.loct $m.oct -padx 3 -pady 1 -sticky news # Bin label $m.lbin -text Bin -padx 0 label $m.bin -width $WIDTH -relief sunken -textvariable binary grid $m.lbin $m.bin -padx 3 -pady 1 -sticky news # ASCII label $m.lascii -text ASCII -padx 0 label $m.ascii -width $WIDTH -relief sunken -textvariable ascii grid $m.lascii $m.ascii -padx 3 -pady 1 -sticky news # IP label $m.lip -text IP -padx 0 label $m.ip -width $WIDTH -relief sunken -textvariable ip grid $m.lip $m.ip -padx 3 -pady 1 -sticky news # Bool label $m.lbool -text Bool -padx 0 label $m.bool -width $WIDTH -relief sunken -textvariable bool grid $m.lbool $m.bool -padx 3 -pady 1 -sticky news # Error label $m.lerr -text Status -padx 0 label $m.err -width $WIDTH -relief sunken -textvariable errormsg grid $m.lerr $m.err -padx 3 -pady 1 -sticky news # buttons button $b.eval -text Evaluate -underline 0 -command Eval button $b.clear -text Clear -underline 0 -command Clear button $b.nums -text Numbers -underline 0 -command Nums button $b.ops -text Operators -underline 0 -command Ops button $b.funcs -text Functions -underline 0 -command Funcs button $b.about -text About -underline 0 -command About button $b.quit -text Quit -underline 0 -command exit # Stick all to left and right edge, so they have the same width! grid columnconf $b 0 -weight 1 grid $b.eval -sticky new grid $b.clear -sticky new grid $b.nums -sticky new grid $b.ops -sticky new grid $b.funcs -sticky new grid $b.about -sticky new grid $b.quit -sticky new # Set keybindings and inital focus bind . <Escape> exit bind . <Alt-e> Eval bind . <Alt-c> Clear bind . <Alt-n> Nums bind . <Alt-o> Ops bind . <Alt-f> Funcs bind . <Alt-a> About bind . <Alt-q> exit bind $m.expression <Return> Eval # We need -force here, otherwise the main windows doesn't get active # when running on Win98 focus -force $m.expression # Procedures starting here proc Clear {} { global expression set expression "" } proc ip {ip} { if {[regexp "([^.]+)\.([^.]+)\.([^.]+)\.([^.]+)" $ip m a b c d]} { if {[string equal "$ip" "$m"]} { if {[expr {$a > 255 || $b > 255 || $c > 255 || $d > 255}]} { error "max component size of IP address is 255" } return [expr {$a << 24 | $b << 16 | $c << 8 | $d}] } } error "not a valid IP address" } proc bin {bin} { set result 0 for {set i 0} {$i < [string length $bin]} {incr i} { set digit [string index $bin $i] if {$digit == 0 || $digit == 1} { set result [expr {$result << 1 | $digit}] } elseif {$digit == "."} { #ignore } else { error "not a valid binary digit" } } return $result } # Evaluate expression proc Eval {} { # say what global vars you want to use # if you forget it here, you will use a local var global expression decimal hexadecimal octal binary ascii ip bool global errormsg m m.err if {[SafeExpr $expression]} { set decimal $result if {[SafeExpr int($result)]} { set hexadecimal [format "%#010x" [expr {$result}]] set octal [format "%#o" [expr {$result}]] set binary [DecToBin [expr {$result}]] set ascii [format ""%s%s%s%s"" [Char [expr {$result} >> 24 & 0xff]] [Char [expr {$result} >> 16 & 0xff]] [Char [expr {$result} >> 8 & 0xff]] [Char [expr {$result} & 0xff]]] set ip [format "%s.%s.%s.%s" [expr {$result} >> 24 & 0xff] [expr {$result} >> 16 & 0xff] [expr {$result} >> 8 & 0xff] [expr {$result} & 0xff]] if {int($result)} { set bool "True" } else { set bool "False" } } } else { set decimal "" } } proc SafeExpr {exp} { global expression decimal hexadecimal octal binary ascii ip bool global errormsg m m.err # uplevel is used to access callers result variable! if {[catch {uplevel "set result [expr $exp]"} errormsg]} { #catch returns non-zero on error $m.err config -foreground red bell set hexadecimal "" set octal "" set binary "" set ascii "" set ip "" set bool "" return 0 } else { #catch returns zero on success set errormsg "Ok" #default would be better than black! $m.err config -foreground black return 1 } } proc Char {byte} { if {$byte >= 32 && $byte <= 126} { return [format "%c" $byte] } else { return "." } } proc ByteToBin {byte} { for {set i 0} {$i < 8} {incr i} { append result [format "%d" [expr {($byte & 0x80) >> 7}]] set byte [expr {$byte << 1}] } return $result } proc DecToBin {dec} { append result [ByteToBin [expr {$dec >> 24 & 0xff}]] "." [ByteToBin [expr {$dec >> 16 & 0xff}]] "." [ByteToBin [expr {$dec >> 8 & 0xff}]] "." [ByteToBin [expr {$dec & 0xff}]] return $result } proc About {} { global tcl_platform set title "About" set text "tkalc (c) 2000 by Boris Folgmann. Released under the GPL (General Public License) For latest version check out http://www.folgmann.de Send bug reports and suggestions to: boris@folgmann.de " switch $tcl_platform(platform) { unix { DisplayText $title $text } windows { set choice [tk_messageBox -title "tkalc: About" -message $text] } } } proc DisplayText {name text} { global tcl_platform m # the w prefix is randomly choosen! if {[winfo exists .w$name]} { wm deiconify .w$name focus .w$name return } set numlines [regsub -all n $text {} ignore] switch $tcl_platform(platform) { unix { set font {fixed} } windows { set font {systemfixed} } } set w [toplevel .w$name -borderwidth 3] append title "tkcalc: " $name wm title $w $title focus .w$name bind $w <Escape> {destroy %W} bind $w <Destroy> {focus -force $m.expression} # Create connected text and scrollbar widget scrollbar $w.yscroll -command "$w.text yview" -orient vertical text $w.text -yscrollcommand "$w.yscroll set" -wrap word -font $font -width 54 -height $numlines # Pack scrollbar first! Otherwise its clipped for small windows pack $w.yscroll -side right -fill y pack $w.text -side left -fill both -expand true # set read only text $w.text config -state normal $w.text insert end $text $w.text config -state disabled } proc Nums {} { DisplayText "Numbers" "Valid numbers are: DescriptiontExample Decimaltt42 Floattt34.235 Scientifict45.12e5 Hextt0xdeadbeef Octaltt0774 (leading zero) Binarytt[bin 1000.1111] (place dots at will) IP addresst[ip 192.168.41.1] " } proc Ops {} { DisplayText "Operators" "Operators from highest to lowest precedence: * ~ !ttUnary minus, bitwise NOT, logical NOT * / %ttMultiply, divide, remainder + -ttAdd, subtract << >>ttLeft shift, right shift < > <= >=tLess, greater, less or equal, ttgreater or equal == !=ttEqual, not equal &ttBitwise AND ^ttBitwise XOR |ttBitwise OR &&ttLogical AND ||ttLogical OR x?y:zttIf x then y else z " } proc Funcs {} { DisplayText "Functions" "Available functions are: acos(x) asin(x) atan(x) atan2(y,x) ceil(x) cos(x) cosh(x) exp(x) floor(x) fmod(x,y) hypot(x,y) log(x) log10(x) pow(x,y) sin(x) sinh(x) sqrt(x) tan(x) tanh(x) abs(x) double(x) int(x) round(x) rand() srand(x) " }
Conclusion
Rien à voir avec gambas je vous l'accorde, mais je veux vous montrer que vous pouvez développer des applications de façon simple et rapide avec Linux.