The apave software provides a sort of geometry manager for Tcl/Tk.
The apave isn't designed to replace the existing Tk geometry managers (place, pack, grid). Rather the apave tries to simplify the window layout by using their best, by means of:
The apave is implemented as APaveBase oo::class, so that you can enhance it with your own inherited / mixin-ed class.
While APaveBase oo::class allows to layout highly sophisticated windows, you can also employ its more 'earthy' descendants:
APaveDialog oo::class and APave oo::class that allow you:
The theming facility of apave is enabled by ObjectTheming oo::class which embraces both ttk and non-ttk widgets.
Along with standard widgets, the mentioned apave classes provide a batch of following 'mega-widgets':
At last, a CLI stand-alone dialog allows not only to ask "OK/Cancel" or "Yes/No" returning 1/0 but also to set environment variables to use in shell scripts.
The apave originates from the old pave package, to comply with How to build good packages ("avoid simple, obvious names for your namespace").
Let it be a sort of a-pave.
The details are in Description.
Imitates Tcl's auto_execok.
| a command to find |
| file's extension (for Windows); optional, default "" |
If it doesn't get the command from Tcl's auto_execok, it tries to knock at its file by itself.
proc ::apave::autoexec {comm {ext {}}} { # Imitates Tcl's auto_execok. # comm - a command to find # ext - file's extension (for Windows) # If it doesn't get the command from Tcl's auto_execok, # it tries to knock at its file by itself. if {$ext ne {} && [::iswindows]} {append comm $ext} set res [auto_execok $comm] if {$res eq {} && [file exists $comm]} { set res $comm } return $res }
Binds an event on a canvas tag to a command.
| the widget's path |
| the tag |
| the event |
| the command |
proc ::apave::bindCantagToEvent {w tag event args} { # Binds an event on a canvas tag to a command. # w - the widget's path # tag - the tag # event - the event # args - the command ::baltip::my::BindCantagToEvent $w $tag $event {*}$args }
Binds an event on a text tag to a command.
| the widget's path |
| the tag |
| the event |
| the command |
proc ::apave::bindTextagToEvent {w tag event args} { # Binds an event on a text tag to a command. # w - the widget's path # tag - the tag # event - the event # args - the command ::baltip::my::BindTextagToEvent $w $tag $event {*}$args }
Binds an event on a widget to a command.
| the widget's path |
| the event |
| the command |
proc ::apave::bindToEvent {w event args} { # Binds an event on a widget to a command. # w - the widget's path # event - the event # args - the command ::baltip::my::BindToEvent $w $event {*}$args }
Makes a widget blink.
| the widget's path |
| normal foreground color; optional, default #000 |
| normal background color; optional, default #fff |
| blinking foreground color (if {}, stops the blinking); optional, default "" |
| blinking background color; optional, default red |
| pause in millisec between blinkings; optional, default 1000 |
| means how many times do blinking; optional, default -1 |
| for recursive calls; optional, default 1 |
proc ::apave::blinkWidget {w {fg #000} {bg #fff} {fg2 {}} {bg2 red} {pause 1000} {count -1} {mode 1}} { # Makes a widget blink. # w - the widget's path # fg - normal foreground color # bg - normal background color # fg2 - blinking foreground color (if {}, stops the blinking) # bg2 - blinking background color # pause - pause in millisec between blinkings # count - means how many times do blinking # mode - for recursive calls if {![winfo exists $w]} return if {$count==0 || $fg2 eq {}} { catch {after cancel $::apave::BLINKWIDGET1} catch {after cancel $::apave::BLINKWIDGET2} after idle "$w configure -foreground $fg; $w configure -background $bg" } elseif {$mode==1} { incr count -1 $w configure -foreground $fg2 $w configure -background $bg2 set ::apave::BLINKWIDGET1 [after $pause ::apave::blinkWidget $w $fg $bg $fg2 $bg2 $pause $count 2] } elseif {$mode==2} { $w configure -foreground $fg $w configure -background $bg set ::apave::BLINKWIDGET2 [after $pause ::apave::blinkWidget $w $fg $bg $fg2 $bg2 $pause $count 1] } }
Makes a widget's image blink.
| widget's path |
| main image |
| flashed image; optional, default alimg_none |
| count of flashes; optional, default 6 |
| millisec between flashes; optional, default 100 |
proc ::apave::blinkWidgetImage {w img1 {img2 alimg_none} {cnt 6} {ms 100}} { # Makes a widget's image blink. # w - widget's path # img1 - main image # img2 - flashed image # cnt - count of flashes # ms - millisec between flashes set imgcur $img1 if {$cnt>0} { if {$cnt % 2} {set imgcur $img2} after $ms "::apave::blinkWidgetImage $w $img1 $img2 [incr cnt -1] $ms" } $w configure -image $imgcur }
Checks a window's geometry.
| the geometry |
Returns a "normalized" geometry (+0+0 if input not correct).
proc ::apave::checkGeometry {geo} { # Checks a window's geometry. # geo - the geometry # Returns a "normalized" geometry (+0+0 if input not correct). if {!([regexp {^\d+x\d+\+-?\d+\+-?\d+$} $geo] || [regexp {^\+-?\d+\+-?\d+$} $geo] || [regexp {^\d+x\d+$} $geo])} { set geo +0+0 } return $geo }
For Tcl 9.0 & Windows: checks a command for "~".
| Not documented. |
proc ::apave::checkHomeDir {com} { # For Tcl 9.0 & Windows: checks a command for "~". set hd [HomeDir] set com [string map [list { ~/} " $hd/" \"~/ \"$hd/ '~/ '$hd/ \\n~/ \\n$hd/ \n~/ \n$hd/ \{~/ \{$hd/] $com] if {[string match ~/* $com]} {set com $hd[string range $com 1 end]} return $com }
Counts a character in a string.
| a string |
| a character |
Returns a number of non-escaped occurences of character ch in string str.
proc ::apave::countChar {str ch} { # Counts a character in a string. # str - a string # ch - a character # # Returns a number of non-escaped occurences of character *ch* in # string *str*. # # See also: # [wiki.tcl-lang.org](https://wiki.tcl-lang.org/page/Reformatting+Tcl+code+indentation) set icnt 0 while {[set idx [string first $ch $str]] >= 0} { set backslashes 0 set nidx $idx while {[string equal [string index $str [incr nidx -1]] \\]} { incr backslashes } if {$backslashes % 2 == 0} { incr icnt } set str [string range $str [incr idx] end] } return $icnt }
Gets/sets "is changing CS possible" flag for a whole application.
| Not documented; optional, default "" |
proc ::apave::cs_Active {{flag {}}} { # Gets/sets "is changing CS possible" flag for a whole application. if {[string is boolean -strict $flag]} { set ::apave::_CS_(isActive) $flag } return $::apave::_CS_(isActive) }
Gets a maximum index of available color schemes
proc ::apave::cs_Max {} { # Gets a maximum index of available color schemes expr {[llength $::apave::_CS_(ALL)] - 1} }
Gets a maximum index of basic color schemes
proc ::apave::cs_MaxBasic {} { # Gets a maximum index of basic color schemes return $::apave::_CS_(STDCS) }
Gets a minimum index of available color schemes
proc ::apave::cs_Min {} { # Gets a minimum index of available color schemes return $::apave::_CS_(MINCS) }
Gets non-existent CS index
proc ::apave::cs_Non {} { # Gets non-existent CS index return -3 }
Sets the cursor at the end of a field.
| the field's path |
proc ::apave::CursorAtEnd {w} { # Sets the cursor at the end of a field. # w - the field's path focus $w $w selection clear $w icursor end }
Sets the cursor to the real start/end of text line.
| text's path |
| where to set |
proc ::apave::CursorToBEOL {wt where} { # Sets the cursor to the real start/end of text line. # wt - text's path # where - where to set set idx [$wt index insert] ::tk::TextSetCursor $wt [$wt index "$idx $where"] }
Sets, gets or registers default options and attributes for widget type.
| widget type; optional, default "" |
| new default grid/pack options; optional, default "" |
| new default attributes; optional, default "" |
| Tcl/Tk command for the new registered widget type; optional, default "" |
proc ::apave::defaultAttrs {{type {}} {opts {}} {atrs {}} {widget {}}} { # Sets, gets or registers default options and attributes for widget type. # type - widget type # opts - new default grid/pack options # atrs - new default attributes # widget - Tcl/Tk command for the new registered widget type # See also: APaveBase::defaultATTRS obj defaultATTRS $type $opts $atrs $widget }
Gets default color scheme counting current background of Tk root window.
proc ::apave::DefaultCS {} { # Gets default color scheme counting current background of Tk root window. if {[catch {set ib [ttk::style config . -background]}] || [lindex [InvertBg $ib B] 0] eq {B}} { set res 5 ;# light } else { set res 23 ;# dark } return $res }
Does 'deiconify' for a window.
| the window's path |
proc ::apave::deiconify {w} { # Does 'deiconify' for a window. # w - the window's path # See also: iconifyOption switch -- [iconifyOption] { none { ; # no withdraw/deiconify actions } Linux { ; # do it for Linux catch {wm deiconify $w ; raise $w} } Windows { ; # do it for Windows if {[wm attributes $w -alpha] < 0.1} {wm attributes $w -alpha 1.0} catch {wm deiconify $w ; raise $w} } default { ; # do it depending on the platform if {[::iswindows]} { if {[wm attributes $w -alpha] < 0.1} {wm attributes $w -alpha 1.0} } catch {wm deiconify $w ; raise $w} } } }
Gets a current dialogue's path. In fact, it does the same as [my dlgPath], but it can be called outside of apave dialogue object (useful sometimes).
proc ::apave::dlgPath {} { # Gets a current dialogue's path. # In fact, it does the same as [my dlgPath], but it can be # called outside of apave dialogue object (useful sometimes). return $::apave::querydlg }
Finishes the window management by apave, closing and clearing all.
| if any set, means "ask if apave's WM is finished" |
proc ::apave::endWM {args} { # Finishes the window management by apave, closing and clearing all. # args - if any set, means "ask if apave's WM is finished" if {[llength $args]} {return [info exists ::apave::_CS_(endWM)]} set ::apave::_CS_(endWM) yes }
Ensures restoring an array at calling a proc.
| fully qualified array name |
| proc name & arguments |
proc ::apave::EnsureArray {arName args} { # Ensures restoring an array at calling a proc. # arName - fully qualified array name # args - proc name & arguments set arSave [array get $arName] {*}$args RestoreArray $arName $arSave }
Gets the error's message at reading/writing.
| if set, return a full error messageat opening file; optional, default "" |
proc ::apave::error {{fileName {}}} { # Gets the error's message at reading/writing. # fileName - if set, return a full error messageat opening file variable _PU_opts if {$fileName eq ""} { return $_PU_opts(_ERROR_) } return "Error of access to\n\"$fileName\"\n\n$_PU_opts(_ERROR_)" }
Generates an event on a text, saving its current index in hl_tcl.
| text widget's path |
| event |
The hl_tcl needs to call MemPos before any action changing the text.
proc ::apave::eventOnText {w ev} { # Generates an event on a text, saving its current index in hl_tcl. # w - text widget's path # ev - event # The hl_tcl needs to call MemPos before any action changing the text. catch {::hl_tcl::my::MemPos $w} if {[catch {$w tag ranges sel} sels]} {set sels [list]} switch -exact -- $ev { <<Cut>> - <<Copy>> { if {[set llen [expr {[llength $sels]-1}]] < 2} return # multiple ranges of selection: # first, copy all selections to clipboard clipboard clear -displayof $w foreach {pos1 pos2} $sels { clipboard append -displayof $w [$w get $pos1 $pos2] } if {$ev eq {<<Cut>>}} { # for Cut event: delete all selections for {set i $llen} {$i>0} {incr i -2} { set pos1 [lindex $sels $i-1] set pos2 [lindex $sels $i] $w delete $pos1 $pos2 } } return -code break } default { event generate $w $ev } } }
Gets options' values and removes the options from the input list.
| variable name for the list of options and values |
| list of "option / default value" pairs |
Returns a list of options' values, according to args.
proc ::apave::extractOptions {optsVar args} { # Gets options' values and removes the options from the input list. # optsVar - variable name for the list of options and values # args - list of "option / default value" pairs # Returns a list of options' values, according to args. # See also: parseOptions upvar 1 $optsVar opts set retlist [::apave::parseOptions $opts {*}$args] foreach {o v} $args { set opts [::apave::removeOptions $opts $o] } return $retlist }
Gets a base relative path. E.g. FileRelativeTail /a/b /a/b/cd/ef => ../ef
| base path |
| full path |
proc ::apave::FileRelativeTail {basepath fullpath} { # Gets a base relative path. # E.g. FileRelativeTail /a/b /a/b/cd/ef => ../ef # basepath - base path # fullpath - full path set tail [FileTail $basepath $fullpath] set lev [llength [file split $tail]] set base {} for {set i 1} {$i<$lev} {incr i} {append base ../} append base [file tail $tail] }
Extracts a tail path from a full file path. E.g. FileTail /a/b /a/b/cd/ef => cd/ef
| base path |
| full path |
proc ::apave::FileTail {basepath fullpath} { # Extracts a tail path from a full file path. # E.g. FileTail /a/b /a/b/cd/ef => cd/ef # basepath - base path # fullpath - full path set lbase [file split $basepath] set lfull [file split $fullpath] set ll [expr {[llength $lfull] - [llength $lbase] - 1}] if {$ll>-1} { return [file join {*}[lrange $lfull end-$ll end]] } return {} }
Saves (if win is set) or restores app's focus.
| focused window's path; optional, default "" |
In some DE, if app loses focus, restoring it focuses main window, ignores modal toplevel, locks keyboard. focusApp tries to focus on last modal window.
proc ::apave::focusApp {{win {}}} { # Saves (if *win* is set) or restores app's focus. # win - focused window's path # In some DE, if app loses focus, restoring it # focuses main window, ignores modal toplevel, locks keyboard. # focusApp tries to focus on last modal window. variable FOCUSED if {$win ne {}} { setProperty FOCW_$win [focus] return } catch { if {[set foc [focus]] ne {}} { set foc [winfo toplevel $foc] set modal 0 foreach fw $FOCUSED { if {$fw eq $foc} {set modal 1; break} } # if non-modal is currently focused, let it be so if {!$modal} { if {[focus] eq $foc} {catch {focus [getProperty FOCW_$foc]}} return } } # find and focus last open modal for {set i [llength $FOCUSED]} {$i} {} { set fw [lindex $FOCUSED [incr i -1]] if {[winfo exists $fw]} { if {$fw ne $foc} { focus -force $fw catch {focus [getProperty FOCW_$fw]} } break } set FOCUSED [lreplace $FOCUSED $i $i] } } }
Focuses a widget.
| widget's path |
| Not documented; optional, default 10 |
proc ::apave::focusByForce {foc {cnt 10}} { # Focuses a widget. # foc - widget's path if {[incr cnt -1]>0} { after idle after 5 ::apave::focusByForce $foc $cnt } else { catch {focus -force [winfo toplevel $foc]; focus $foc} } }
Gets a flag "is a widget can be focused".
| widget's path |
proc ::apave::focusedWidget {w} { # Gets a flag "is a widget can be focused". # w - widget's path set wclass [string tolower [winfo class $w]] foreach c [list entry text button box list view] { if {[string match *$c $wclass]} { if {[catch {set state [$w cget -state]}]} {set state normal} if {$state ne {disabled}} { if {[catch {set focus [$w cget -takefocus]}]} {set focus no} return [expr {![string is boolean -strict $focus] || $focus}] } break } } return no }
Sets a focus on a first widget of a parent widget.
| the parent widget |
| if no, means "only return the widget's path" optional, default yes |
| used for recursive call; optional, default "" |
Returns a path to a focused widget or "".
proc ::apave::focusFirst {w {dofocus yes} {res {}}} { # Sets a focus on a first widget of a parent widget. # w - the parent widget # dofocus - if no, means "only return the widget's path" # res - used for recursive call # Returns a path to a focused widget or "". if {$w ne {}} { foreach w [winfo children $w] { if {[focusedWidget $w]} { if {$dofocus} {after 200 "catch {focus -force $w}"} return $w } else { if {[set res [focusFirst $w $dofocus]] ne {}} break } } } return $res }
Gets application's icon.
proc ::apave::getAppIcon {} { # Gets application's icon. variable _AP_VARS return $_AP_VARS(APPICON) }
Gets a number from a string
| string containing a number |
| default value when sn is not a number; optional, default 0 |
| minimal value allowed; optional, default "" |
| maximal value allowed; optional, default "" |
proc ::apave::getN {sn {defn 0} {min {}} {max {}}} { # Gets a number from a string # sn - string containing a number # defn - default value when sn is not a number # min - minimal value allowed # max - maximal value allowed if {$sn eq "" || [catch {set sn [expr {$sn}]}]} {set sn $defn} if {$max ne ""} { set sn [expr {min($max,$sn)}] } if {$min ne ""} { set sn [expr {max($min,$sn)}] } return $sn }
Extracts one option from an option list.
| option name |
| option list |
set options [list -name some -value "any value" -tip "some tip"] set optvalue [::apave::getOption -tip {*}$options]
Returns an option value or "". Example:
proc ::apave::getOption {optname args} { # Extracts one option from an option list. # optname - option name # args - option list # Returns an option value or "". # Example: # set options [list -name some -value "any value" -tip "some tip"] # set optvalue [::apave::getOption -tip {*}$options] set optvalue [lindex [::apave::parseOptions $args $optname ""] 0] return $optvalue }
Gets a property's value as "application-wide".
| name of property |
| default value; optional, default "" |
If the property had been set, the method returns its value. Otherwise, the method returns the default value ($defvalue
).
proc ::apave::getProperty {name {defvalue {}}} { # Gets a property's value as "application-wide". # name - name of property # defvalue - default value # If the property had been set, the method returns its value. # Otherwise, the method returns the default value (`$defvalue`). variable _AP_Properties if {[info exists _AP_Properties($name)]} { return $_AP_Properties($name) } return $defvalue }
Gets upper & lower keys for a hot key.
| the hot key |
proc ::apave::getTextHotkeys {key} { # Gets upper & lower keys for a hot key. # key - the hot key variable _AP_VARS if {![info exist _AP_VARS(KEY,$key)]} {return [list]} set keys $_AP_VARS(KEY,$key) if {[llength $keys]==1} { if {[set i [string last - $keys]]>0} { set lt [string range $keys $i+1 end] if {[string length $lt]==1} { ;# for lower case of letters set keys "[string range $keys 0 $i][string toupper $lt]" lappend keys "[string range $keys 0 $i][string tolower $lt]" } } } return $keys }
For Tcl 9.0 & Windows: gets a home directory ("~").
proc ::apave::HomeDir {} { # For Tcl 9.0 & Windows: gets a home directory ("~"). if {[catch {set hd [file home]}]} { if {[info exists ::env(HOME)]} {set hd $::env(HOME)} {set hd ~} } return $hd }
Gets an icon's data.
| icon's name; optional, default info |
| one of small/middle/large; optional, default "" |
Returns data of the icon.
proc ::apave::iconData {{icon info} {iconset {}}} { # Gets an icon's data. # icon - icon's name # iconset - one of small/middle/large # Returns data of the icon. variable _AP_IMG iconImage -init if {$iconset ne {} && "_AP_IMG(img$icon-$iconset)" in [image names]} { return [set _AP_IMG($icon-$iconset)] } set _AP_IMG($icon) }
Gets/sets "-iconify" option.
| if contains no arguments, gets "-iconify" option; otherwise sets it |
Option values mean:
none | do nothing: no withdraw/deiconify |
Linux | do withdraw/deiconify for Linux |
Windows | do withdraw/deiconify for Windows |
default | do withdraw/deiconify depending on the platform |
proc ::apave::iconifyOption {args} { # Gets/sets "-iconify" option. # args - if contains no arguments, gets "-iconify" option; otherwise sets it # Option values mean: # none - do nothing: no withdraw/deiconify # Linux - do withdraw/deiconify for Linux # Windows - do withdraw/deiconify for Windows # default - do withdraw/deiconify depending on the platform # See also: withdraw, deiconify if {[llength $args]} { set iconify [::apave::obj setShowOption -iconify $args] } else { set iconify [::apave::obj getShowOption -iconify] } return $iconify }
Gets a defined icon's image or list of icons. If icon equals to "-init", initializes apave's icon set.
| icon's name; optional, default "" |
| one of small/middle/large; optional, default small |
| force the initialization; optional, default no |
Returns the icon's image or, if icon is blank, a list of icons available in apave.
proc ::apave::iconImage {{icon {}} {iconset small} {doit no}} { # Gets a defined icon's image or list of icons. # If *icon* equals to "-init", initializes apave's icon set. # icon - icon's name # iconset - one of small/middle/large # doit - force the initialization # Returns the icon's image or, if *icon* is blank, a list of icons # available in *apave*. variable _AP_IMG variable _AP_ICO if {$icon eq {}} {return $_AP_ICO} ; proc imagename {icon} { # Get a defined icon's image name return _AP_IMG(img$icon) } variable apaveDir if {![array size _AP_IMG] || $doit} { # Make images of icons source [file join $apaveDir apaveimg.tcl] if {$iconset ne "small"} { foreach ic $_AP_ICO { ;# small icons best fit for menus set _AP_IMG($ic-small) [set _AP_IMG($ic)] } if {$iconset eq "middle"} { source [file join $apaveDir apaveimg2.tcl] } else { source [file join $apaveDir apaveimg2.tcl] ;# TODO } } foreach ic $_AP_ICO { if {[catch {image create photo [imagename $ic] -data [set _AP_IMG($ic)]}]} { # some png issues on old Tk image create photo [imagename $ic] -data [set _AP_IMG(none)] } elseif {$iconset ne "small"} { image create photo [imagename $ic-small] -data [set _AP_IMG($ic-small)] } } } if {$icon eq "-init"} {return $_AP_ICO} ;# just to get to icons if {$icon ni $_AP_ICO} {set icon [lindex $_AP_ICO 0]} if {$iconset eq "small" && "_AP_IMG(img$icon-small)" in [image names]} { set icon $icon-small } return [imagename $icon] }
Searches data of a window in a list of registered windows.
| root window's path |
| yes, if the window is modal |
Returns: the window's path or "" if not found.
proc ::apave::InfoFind {w modal} { # Searches data of a window in a list of registered windows. # w - root window's path # modal - yes, if the window is modal # Returns: the window's path or "" if not found. # See also: InfoWindow variable _PU_opts foreach winfo [lrange $_PU_opts(_MODALWIN_) 1 end] { ;# skip 1st window incr i lassign $winfo w1 var1 modal1 if {[winfo exists $w1]} { if {$w eq $w1 && ($modal && $modal1 || !$modal && !$modal1)} { return $w1 } } else { catch {set _PU_opts(_MODALWIN_) [lreplace $_PU_opts(_MODALWIN_) $i $i]} } } return {} }
Registers/unregisters windows. Also sets/gets 'count of open modal windows'.
| current number of open modal windows; optional, default "" |
| root window's path; optional, default . |
| yes, if the window is modal; optional, default no |
| variable's name for tkwait; optional, default "" |
| yes or no for registering/unregistering; optional, default no |
proc ::apave::InfoWindow {{val {}} {w .} {modal no} {var {}} {regist no}} { # Registers/unregisters windows. Also sets/gets 'count of open modal windows'. # val - current number of open modal windows # w - root window's path # modal - yes, if the window is modal # var - variable's name for tkwait # regist - yes or no for registering/unregistering # See also: APaveBase::showWindow variable _PU_opts if {$modal || $regist} { set info [list $w $var $modal] set i [lsearch -exact $_PU_opts(_MODALWIN_) $info] catch {set _PU_opts(_MODALWIN_) [lreplace $_PU_opts(_MODALWIN_) $i $i]} if {$regist} { lappend _PU_opts(_MODALWIN_) $info } set res [IntStatus . MODALS $val] } else { set res [IntStatus . MODALS] } return $res }
Initializes the path to awthemes package.
| root directory of themes (where 'theme' subdirectory is) |
proc ::apave::InitAwThemesPath {libdir} { # Initializes the path to awthemes package. # libdir - root directory of themes (where 'theme' subdirectory is) global auto_path set awpath [file join $libdir theme awthemes-10.4.0] if {[lindex $auto_path 0] ne $awpath} { set auto_path [linsert $auto_path 0 $awpath] } }
Initializes baltip package.
proc ::apave::initBaltip {} { # Initializes baltip package. if {[info command ::baltip] eq {}} { if {$::apave::ISBALTIP} { source [file join $::apave::SRCDIR baltip baltip.tcl] } else { # disabling baltip facilities with stub proc (no source "baltip.src") namespace eval ::baltip { variable expproc [list configure cget tip update hide repaint optionlist tippath clear sleep showBalloon showTip] foreach _ $expproc { ; proc $_ {args} {return {}} namespace export $_ } namespace ensemble create namespace eval my { ; proc BindToEvent {args} {} } } } } }
Initializes system popup menu (if possible) to call it in a window.
| window's name |
proc ::apave::initPOP {w} { # Initializes system popup menu (if possible) to call it in a window. # w - window's name bind $w <KeyPress> { if {"%K" eq "Menu"} { if {[winfo exists [set w [focus]]]} { event generate $w <Button-3> -rootx [winfo pointerx .] -rooty [winfo pointery .] } } } }
Initializes a style for a widget type, e.g. button's.
| target widget type |
| base widget type |
| options of the style |
proc ::apave::initStyle {wt wbase args} { # Initializes a style for a widget type, e.g. button's. # wt - target widget type # wbase - base widget type # args - options of the style ttk::style configure $wt {*}[ttk::style configure $wbase] ttk::style configure $wt {*}$args ttk::style map $wt {*}[ttk::style map $wbase] ttk::style layout $wt [ttk::style layout $wbase] }
Initializes miscellaneous styles, e.g. button's.
proc ::apave::initStyles {} { # Initializes miscellaneous styles, e.g. button's. obj create_Fonts initStyle TButtonWest TButton -anchor w -font $::apave::FONTMAIN initStyle TButtonBold TButton -font $::apave::FONTMAINBOLD initStyle TButtonWestBold TButton -anchor w -font $::apave::FONTMAINBOLD initStyle TButtonWestHL TButton -anchor w -foreground [lindex [obj csGet] 4] initStyle TMenuButtonWest TMenubutton -anchor w -font $::apave::FONTMAIN -relief raised initStyle TreeNoHL Treeview -borderwidth 0 lassign [obj csGet] - - - - thlp tbgS tfgS - - bclr ttk::style map TreeNoHL {*}[ttk::style map Treeview] -foreground [list {selected focus} $tfgS {selected !focus} $tfgS] -background [list {selected focus} $tbgS {selected !focus} $tbgS] }
Initializes miscellaneous styles, e.g. button's.
| font options ("name value" pairs) |
proc ::apave::initStylesFS {args} { # Initializes miscellaneous styles, e.g. button's. # args - font options ("name value" pairs) ::apave::obj create_Fonts set font "$::apave::FONTMAIN $args" set fontB "$::apave::FONTMAINBOLD $args" initStyle TLabelFS TLabel -font $font initStyle TCheckbuttonFS TCheckbutton -font $font initStyle TComboboxFS TCombobox -font $font initStyle TRadiobuttonFS TRadiobutton -font $font initStyle TButtonWestFS TButton -anchor w -font $font initStyle TButtonBoldFS TButton -font $fontB initStyle TButtonWestBoldFS TButton -anchor w -font $fontB }
Initializes app's theme.
| name of the theme |
| root directory of themes (where 'theme' subdirectory is) |
Returns a list of theme name and label's border (for status bar). The returned values are used in ::apave::initWM procedure.
proc ::apave::InitTheme {intheme libdir} { # Initializes app's theme. # intheme - name of the theme # libdir - root directory of themes (where 'theme' subdirectory is) # Returns a list of theme name and label's border (for status bar). # The returned values are used in ::apave::initWM procedure. set theme {} switch -glob -- $intheme { azure* - sun-valley* { set i [string last - $intheme] set name [string range $intheme 0 $i-1] set type [string range $intheme $i+1 end] catch {source [file join $libdir theme $name $name.tcl]} catch { set_theme $type set theme $intheme } set lbd 0 } forest* { set i [string last - $intheme] set name [string range $intheme 0 $i-1] set type [string range $intheme $i+1 end] catch { source [file join $libdir theme $name $intheme.tcl] set theme $intheme } set lbd 0 } awdark - awlight { catch {package forget ttk::theme::$intheme} catch {namespace delete ttk::theme::$intheme} catch {package forget awthemes} catch {namespace delete awthemes} InitAwThemesPath $libdir package require awthemes package require ttk::theme::$intheme set theme $intheme set lbd 1 } plastik - lightbrown - darkbrown { set path [file join $libdir theme $intheme] source [file join $path $intheme.tcl] set theme $intheme set lbd 1 } default { set theme $intheme set lbd 1 } } list $theme $lbd }
Initializes Tcl/Tk session. Used to be called at the beginning of it.
| options ("name value" pairs) |
If args eq "?", return a flag "need to call initWM"
proc ::apave::initWM {args} { # Initializes Tcl/Tk session. Used to be called at the beginning of it. # args - options ("name value" pairs) # If args eq "?", return a flag "need to call initWM" if {$args eq {?}} {return $::apave::_CS_(initWM)} if {!$::apave::_CS_(initWM)} return ::apave::withdraw . ::apave::place . 0 0 center lassign [parseOptions $args -cursorwidth $::apave::cursorwidth -theme default -buttonwidth -8 -buttonborder 1 -labelborder 0 -padding 1 -cs -2 -isbaltip yes] cursorwidth theme buttonwidth buttonborder labelborder padding cs ::apave::ISBALTIP initBaltip if {$theme eq {}} {set theme default} if {$cs<-2 || $cs>47} {set cs -2} set ::apave::_CS_(initWM) 0 set ::apave::_CS_(CURSORWIDTH) $cursorwidth set ::apave::_CS_(LABELBORDER) $labelborder # for default theme: only most common settings set tfg1 $::apave::_CS_(!FG) set tbg1 $::apave::_CS_(!BG) if {$theme ne {} && [catch {ttk::style theme use $theme}]} { catch {ttk::style theme use default} } ttk::style map . -selectforeground [list !focus $tfg1 {focus active} $tfg1] -selectbackground [list !focus $tbg1 {focus active} $tbg1] ttk::style configure . -selectforeground $tfg1 -selectbackground $tbg1 # configure separate widget types ttk::style configure TButton -anchor center -width $buttonwidth -relief raised -borderwidth $buttonborder -padding $padding ttk::style configure TMenubutton -width 0 -padding 0 # TLabel's standard style saved for occasional uses initStyle TLabelSTD TLabel -anchor w # ... TLabel new style ttk::style configure TLabel -borderwidth $labelborder -padding $padding # ... Treeview colors set twfg [ttk::style map Treeview -foreground] set twfg [putOption selected $tfg1 {*}$twfg] set twbg [ttk::style map Treeview -background] set twbg [putOption selected $tbg1 {*}$twbg] ttk::style map Treeview -foreground $twfg ttk::style map Treeview -background $twbg # ... TCombobox colors ttk::style map TCombobox -fieldforeground [list {active focus} $tfg1 readonly $tfg1 disabled grey] ttk::style map TCombobox -fieldbackground [list {active focus} $tbg1 {readonly focus} $tbg1 {readonly !focus} white] initStyles initPOP . if {$cs!=-2} {obj csSet $cs} }
Inserts character(s) into a text at cursor's position.
| text's path |
| character(s) |
proc ::apave::InsertChar {wt ch} { # Inserts character(s) into a text at cursor's position. # wt - text's path # ch - character(s) $wt insert [$wt index insert] $ch }
Checks whether an integer is in min-max range.
| the integer |
| minimum of the range |
| maximum of the range |
proc ::apave::intInRange {int min max} { # Checks whether an integer is in min-max range. # int - the integer # min - minimum of the range # max - maximum of the range expr {[string is integer -strict $int] && $int>=$min && $int<=$max} }
Sets/gets a status of window. The status is an integer assigned to a name.
| window's path |
| name of status; optional, default status |
| if blank, to get a value of status; otherwise a value to set; optional, default "" |
Default value of status is 0.
Returns an old value of status.
proc ::apave::IntStatus {w {name status} {val {}}} { # Sets/gets a status of window. The status is an integer assigned to a name. # w - window's path # name - name of status # val - if blank, to get a value of status; otherwise a value to set # Default value of status is 0. # Returns an old value of status. # See also: WindowStatus set old [WindowStatus $w $name {} 0] if {$val ne {}} {WindowStatus $w $name $val 1} return $old }
Gets a "inverted" color (white/black) for an color.
| color (#hhh or #hhhhhh) |
| "black" color; optional, default #000000 |
| "white" color; optional, default #FFFFFF |
Returns a list of "black/white" and normalized input color
proc ::apave::InvertBg {clr {B #000000} {W #FFFFFF}} { # Gets a "inverted" color (white/black) for an color. # clr - color (#hhh or #hhhhhh) # B - "black" color # W - "white" color # Returns a list of "black/white" and normalized input color if {[string length $clr]==4} { lassign [split $clr {}] -> r g b set clr #$r$r$g$g$b$b } lassign [winfo rgb . $clr] r g b if {($r%256+$b%256)<15 && ($g%256)>180 || $r+1.5*$g+0.5*$b > 100000} { set res $B } else { set res $W } list $res $clr }
Checks whether an integer equals roundly to other integer.
| integer to compare |
| integer to be compared (rounded) to i1 |
proc ::apave::IsRoundInt {i1 i2} { # Checks whether an integer equals roundly to other integer. # i1 - integer to compare # i2 - integer to be compared (rounded) to i1 expr {$i1>($i2-3) && $i1<($i2+3)} }
Returns a key accelerator.
| key name, may contain 2 items (e.g. Control-D Control-d) |
Returns a key accelerator.
proc ::apave::KeyAccelerator {acc} { # Returns a key accelerator. # acc - key name, may contain 2 items (e.g. Control-D Control-d) set acc [lindex $acc 0] string map {Control Ctrl - + bracketleft [ bracketright ]} $acc }
Selects a listbox item.
| listbox's path |
| item index |
proc ::apave::LbxSelect {w idx} { # Selects a listbox item. # w - listbox's path # idx - item index $w activate $idx $w see $idx if {[$w cget -selectmode] in {single browse}} { $w selection clear 0 end $w selection set $idx event generate $w <<ListboxSelect>> } }
Logs messages to a log file.
| the message |
| maximum level for [info level] to introspect calls; optional, default 16 |
A log file's name is set by _PU_opts(_LOGFILE_). If it's blank, no logging is made.
proc ::apave::logMessage {msg {lev 16}} { # Logs messages to a log file. # msg - the message # lev - maximum level for [info level] to introspect calls # A log file's name is set by _PU_opts(_LOGFILE_). If it's blank, # no logging is made. variable _PU_opts; if {$_PU_opts(_LOGFILE_) eq {}} return set chan [open $_PU_opts(_LOGFILE_) a] set dt [clock format [clock seconds] -format {%d%b'%y %T}] set msg "$dt $msg" for {set i $lev} {$i>0} {incr i -1} { catch { lassign [info level -$i] p1 p2 if {$p1 eq {my}} {append p1 " $p2"} append msg " / $p1" } } puts $chan $msg close $chan puts "$_PU_opts(_LOGFILE_) - $msg" }
Sets a log file's name.
| file name |
If fname is {}, disables logging.
proc ::apave::logName {fname} { # Sets a log file's name. # fname - file name # If fname is {}, disables logging. variable _PU_opts; set _PU_opts(_LOGFILE_) [file normalize $fname] }
Searches a file name in a list, using normalized file names.
| list of file names |
| file name to find |
Returns an index of found file name or -1 if it's not found.
proc ::apave::lsearchFile {flist fname} { # Searches a file name in a list, using normalized file names. # flist - list of file names # fname - file name to find # Returns an index of found file name or -1 if it's not found. set i 0 set fname [file normalize $fname] foreach fn $flist { if {[file normalize $fn] eq $fname} { return $i } incr i } return -1 }
Sets/gets a main window of application.
| window's path; optional, default "" |
This should be run at application start, before opening any window.
proc ::apave::mainWindowOfApp {{win {}}} { # Sets/gets a main window of application. # win - window's path # This should be run at application start, before opening any window. WindowStatus . MAIN_WINDOW_OF_APP $win }
Gets a localized version of a message.
| the message |
proc ::apave::mc {msg} { # Gets a localized version of a message. # msg - the message variable _MC_ if {[info exists _MC_($msg)]} {return $_MC_($msg)} return $msg }
Places the mouse pointer on a widget.
| the widget's path |
proc ::apave::MouseOnWidget {w1} { # Places the mouse pointer on a widget. # w1 - the widget's path update set w2 [winfo parent $w1] set w3 [winfo parent $w2] lassign [split [winfo geometry $w1] +x] w h x1 y1 lassign [split [winfo geometry $w2] +x] - - x2 y2 event generate $w3 <Motion> -warp 1 -x [expr {$x1+$x2+int($w/2)}] -y [expr {$y1+$y2+int($h/2)}] }
Prepares localized messages used in dialogues.
proc ::apave::msgcatDialogs {} { # Prepares localized messages used in dialogues. variable msgarray foreach n [array names msgarray] { set msgarray($n) [msgcat::mc $msgarray($n)] } }
Useful when to do nothing is better than to do something.
| Optional arguments. |
proc ::apave::None {args} { # Useful when to do nothing is better than to do something. }
Removes spec.characters from a file/dir name (sort of normalizing it).
| the name of file/dir |
proc ::apave::NormalizeFileName {name} { # Removes spec.characters from a file/dir name (sort of normalizing it). # name - the name of file/dir set name [string trim $name] string map [list * _ ? _ ~ _ / _ \\ _ \{ _ \} _ \[ _ \] _ \t _ \n _ \r _ | _ < _ > _ & _ , _ : _ \; _ \" _ ' _ ` _] $name }
Removes spec.characters from a name (sort of normalizing it).
| the name |
proc ::apave::NormalizeName {name} { # Removes spec.characters from a name (sort of normalizing it). # name - the name string map [list \\ {} \{ {} \} {} \[ {} \] {} \t {} \n {} \r {} \" {}] $name }
Calls a method of APave class.
| a method |
| arguments of the method |
It can (and must) be used only for temporary tasks. For persistent tasks, use a "normal" apave object.
Returns the command's result.
proc ::apave::obj {com args} { # Calls a method of APave class. # com - a method # args - arguments of the method # It can (and must) be used only for temporary tasks. # For persistent tasks, use a "normal" apave object. # Returns the command's result. variable _OBJ_ if {$_OBJ_ eq {}} {set _OBJ_ [::apave::APave new]} if {[set exported [expr {$com eq "EXPORT"}]]} { set com [lindex $args 0] set args [lrange $args 1 end] oo::objdefine $_OBJ_ "export $com" } set res [$_OBJ_ $com {*}$args] if {$exported} { oo::objdefine $_OBJ_ "unexport $com" } return $res }
Opens a document.
| document's file name, www link, e-mail etc. |
proc ::apave::openDoc {url} { # Opens a document. # url - document's file name, www link, e-mail etc. set commands {xdg-open open start} foreach opener $commands { if {$opener eq "start"} { set command [list {*}[auto_execok start] {}] } else { set command [auto_execok $opener] } if {[string length $command]} { break } } if {[string length $command] == 0} { puts "ERROR: couldn't find any opener" } # remove the tailing " &" (as e_menu can set) set url [string trimright $url] if {[string match "* &" $url]} {set url [string range $url 0 end-2]} set url [string trim $url] if {[catch {exec -- {*}$command $url &} error]} { puts "ERROR: couldn't execute '$command':\n$error" } }
Sums two text positions straightforward: lines & columns separately.
| 1st position |
| 2nd position |
The lines may be with "-". Reasons for this: 1. expr $p1
+$p2
doesn't work, e.g. 309.10+1.4=310.5 instead of 310.14 2. do it without a text widget's path (for text's arithmetic)
proc ::apave::p+ {p1 p2} { # Sums two text positions straightforward: lines & columns separately. # p1 - 1st position # p2 - 2nd position # The lines may be with "-". # Reasons for this: # 1. expr $p1+$p2 doesn't work, e.g. 309.10+1.4=310.5 instead of 310.14 # 2. do it without a text widget's path (for text's arithmetic) lassign [split $p1 .] l11 c11 lassign [split $p2 .] l21 c21 foreach n {l11 c11 l21 c21} { if {![string is digit -strict [string trimleft [set $n] -]]} {set $n 0} } return [incr l11 $l21].[incr c11 $c21] }
Parses argument list containing options.
| list of options and values |
| list of "option / default value" pairs |
It's the same as parseOptionsFile, excluding the file name stuff.
Returns a list of options' values, according to args.
proc ::apave::parseOptions {opts args} { # Parses argument list containing options. # opts - list of options and values # args - list of "option / default value" pairs # It's the same as parseOptionsFile, excluding the file name stuff. # Returns a list of options' values, according to args. # See also: parseOptionsFile lassign [::apave::parseOptionsFile 0 $opts {*}$args] tmp foreach {nam val} $tmp { lappend retlist $val } return $retlist }
Parses argument list containing options and (possibly) a file name.
| if 1, only 'args' options are allowed, all the rest of inpargs to be a file name - if 2, the 'args' options replace the appropriate options of 'inpargs' |
| list of options, values and a file name |
| list of default options |
The inpargs list contains:
The args parameter contains the pairs:
If the args option value is equal to =NONE=, the inpargs option is considered to be a single option without a value and, if present in inpargs, its value is returned as "yes".
If any option of inpargs is absent in args and strict==1, the rest of inpargs is considered to be a file name.
The proc returns a list of two items:
Examples see in tests/obbit.test.
proc ::apave::parseOptionsFile {strict inpargs args} { # Parses argument list containing options and (possibly) a file name. # strict - if 0, 'args' options will be only counted for, # other options are skipped # strict - if 1, only 'args' options are allowed, # all the rest of inpargs to be a file name # - if 2, the 'args' options replace the # appropriate options of 'inpargs' # inpargs - list of options, values and a file name # args - list of default options # # The inpargs list contains: # - option names beginning with "-" # - option values following their names (may be missing) # - "--" denoting the end of options # - file name following the options (may be missing) # # The *args* parameter contains the pairs: # - option name (e.g., "-dir") # - option default value # # If the *args* option value is equal to =NONE=, the *inpargs* option # is considered to be a single option without a value and, # if present in inpargs, its value is returned as "yes". # # If any option of *inpargs* is absent in *args* and strict==1, # the rest of *inpargs* is considered to be a file name. # # The proc returns a list of two items: # - an option list got from args/inpargs according to 'strict' # - a file name from inpargs or {} if absent # # Examples see in tests/obbit.test. variable _PU_opts set actopts true array set argarray "$args yes yes" ;# maybe, tail option without value if {$strict==2} { set retlist $inpargs } else { set retlist $args } set retfile {} for {set i 0} {$i < [llength $inpargs]} {incr i} { set parg [lindex $inpargs $i] if {$actopts} { if {$parg eq "--"} { set actopts false } elseif {[catch {set defval $argarray($parg)}]} { if {$strict==1} { set actopts false append retfile $parg " " } else { incr i } } else { if {$strict==2} { if {$defval == $_PU_opts(-NONE)} { set defval yes } incr i } else { if {$defval == $_PU_opts(-NONE)} { set defval yes } else { set defval [lindex $inpargs [incr i]] } } set ai [lsearch -exact $retlist $parg] incr ai set retlist [lreplace $retlist $ai $ai $defval] } } else { append retfile $parg " " } } list $retlist [string trimright $retfile] }
Gets int part of text position, e.g. "4" for "4.end".
| position in text |
proc ::apave::pint {pos} { # Gets int part of text position, e.g. "4" for "4.end". # pos - position in text if {[set i [string first . $pos]]>0} {incr i -1} {set i end} expr {int([string range $pos 0 $i])} }
| Not documented. |
| Not documented. |
| Not documented. |
| Optional arguments. |
proc ::apave::place {path w h args} { update idletasks # If the window is not mapped, it may have any current size. # Then use required size, but bound it to the screen width. # This is mostly inexact, because any toolbars will still be removed # which may reduce size. if { $w == 0 && [winfo ismapped $path] } { set w [winfo width $path] } else { if { $w == 0 } { set w [winfo reqwidth $path] } set vsw [winfo vrootwidth $path] if { $w > $vsw } { set w $vsw } } if { $h == 0 && [winfo ismapped $path] } { set h [winfo height $path] } else { if { $h == 0 } { set h [winfo reqheight $path] } set vsh [winfo vrootheight $path] if { $h > $vsh } { set h $vsh } } set arglen [llength $args] if { $arglen > 3 } { return -code error "apave::place: bad number of argument" } if { $arglen > 0 } { set where [lindex $args 0] set list [list at center left right above below] set idx [lsearch $list $where] if { $idx == -1 } { return -code error "apave::place: bad position: $where $list" } if { $idx == 0 } { set err [catch { # purposely removed the {} around these expressions - [PT] set x [expr int([lindex $args 1])] set y [expr int([lindex $args 2])] } e] if { $err } { return -code error "apave::place: bad position: $e" } if {$::tcl_platform(platform) eq {windows}} { # handle windows multi-screen. -100 != +-100 if {[string index [lindex $args 1] 0] ne {-}} { set x +$x } if {[string index [lindex $args 2] 0] ne {-}} { set y +$y } } else { if { $x >= 0 } { set x +$x } if { $y >= 0 } { set y +$y } } } else { if { $arglen == 2 } { set widget [lindex $args 1] if { ![winfo exists $widget] } { return -code error "apave::place: \"$widget\" does not exist" } } else { set widget . } set sw [winfo screenwidth $path] set sh [winfo screenheight $path] if { $idx == 1 } { if { $arglen == 2 } { # center to widget set x0 [expr {[winfo rootx $widget] + ([winfo width $widget] - $w)/2}] set y0 [expr {[winfo rooty $widget] + ([winfo height $widget] - $h)/2}] } else { # center to screen set x0 [expr {($sw - $w)/2 - [winfo vrootx $path]}] set y0 [expr {($sh - $h)/2 - [winfo vrooty $path]}] } set x +$x0 set y +$y0 if {$::tcl_platform(platform) ne {windows}} { if { $x0+$w > $sw } {set x {-0}; set x0 [expr {$sw-$w}]} if { $x0 < 0 } {set x {+0}} if { $y0+$h > $sh } {set y {-0}; set y0 [expr {$sh-$h}]} if { $y0 < 0 } {set y {+0}} } } else { set x0 [winfo rootx $widget] set y0 [winfo rooty $widget] set x1 [expr {$x0 + [winfo width $widget]}] set y1 [expr {$y0 + [winfo height $widget]}] if { $idx == 2 || $idx == 3 } { set y +$y0 if {$::tcl_platform(platform) ne {windows}} { if { $y0+$h > $sh } {set y {-0}; set y0 [expr {$sh-$h}]} if { $y0 < 0 } {set y {+0}} } if { $idx == 2 } { # try left, then right if out, then 0 if out if { $x0 >= $w } { set x [expr {$x0-$w}] } elseif { $x1+$w <= $sw } { set x +$x1 } else { set x {+0} } } else { # try right, then left if out, then 0 if out if { $x1+$w <= $sw } { set x +$x1 } elseif { $x0 >= $w } { set x [expr {$x0-$w}] } else { set x {-0} } } } else { set x +$x0 if {$::tcl_platform(platform) ne {windows}} { if { $x0+$w > $sw } {set x {-0}; set x0 [expr {$sw-$w}]} if { $x0 < 0 } {set x {+0}} } if { $idx == 4 } { # try top, then bottom, then 0 if { $h <= $y0 } { set y [expr {$y0-$h}] } elseif { $y1+$h <= $sh } { set y +$y1 } else { set y {+0} } } else { # try bottom, then top, then 0 if { $y1+$h <= $sh } { set y +$y1 } elseif { $h <= $y0 } { set y [expr {$y0-$h}] } else { set y {-0} } } } } } ## If there's not a + or - in front of the number, we need to add one. if {[string is integer [string index $x 0]]} { set x +$x } if {[string is integer [string index $y 0]]} { set y +$y } wm geometry $path "${w}x${h}${x}${y}" } else { wm geometry $path "${w}x${h}" } update idletasks }
Adds a preceding name to a tail name of widget.
| widget's full name |
| preceding name |
Useful at getting a entry/button name of chooser.
proc ::apave::precedeWidgetName {widname prename} { # Adds a preceding name to a tail name of widget. # widname - widget's full name # prename - preceding name # Useful at getting a entry/button name of chooser. # Example: # set wentry [::apave::precedeWidgetName [$pobj DirToChoose] ent] # See also: APaveBase::Replace_chooser set p [string last . $widname] set res [string range $widname 0 $p] append res $prename [string range $widname $p+1 end] return $res }
Pushes an item in a list: deletes an old instance, inserts a new one.
| the list's variable name |
| item to push |
| position in the list to push in; optional, default 0 |
| maximum length of the list; optional, default 16 |
proc ::apave::PushInList {listName item {pos 0} {max 16}} { # Pushes an item in a list: deletes an old instance, inserts a new one. # listName - the list's variable name # item - item to push # pos - position in the list to push in # max - maximum length of the list upvar $listName ln if {[set i [lsearch -exact $ln $item]]>-1} { set ln [lreplace $ln $i $i] } set ln [linsert $ln $pos $item] catch {set ln [lreplace $ln $max end]} }
Replaces or adds one option to an option list.
| option name |
| option value |
| option list |
Returns an updated option list.
proc ::apave::putOption {optname optvalue args} { # Replaces or adds one option to an option list. # optname - option name # optvalue - option value # args - option list # Returns an updated option list. set optlist {} set doadd true foreach {a v} $args { if {$a eq $optname} { set v $optvalue set doadd false } lappend optlist $a $v } if {$doadd} {lappend optlist $optname $optvalue} return $optlist }
Reads a text file.
| file name |
| variable name for file content or "" optional, default "" |
| if 'true', exit at errors with error message; optional, default 0 |
| Optional arguments. |
Returns file contents or "".
proc ::apave::readTextFile {fname {varName {}} {doErr 0} args} { # Reads a text file. # fname - file name # varName - variable name for file content or "" # doErr - if 'true', exit at errors with error message # Returns file contents or "". variable _PU_opts if {$varName ne {}} {upvar $varName fvar} if {[catch {set chan [open $fname]} _PU_opts(_ERROR_)]} { if {$doErr} {error [::apave::error $fname]} set fvar {} } else { set enc [::apave::getOption -encoding {*}$args] set eol [string tolower [::apave::getOption -translation {*}$args]] if {$eol eq {}} {set eol auto} ;# let EOL be autodetected by default ::apave::textChanConfigure $chan $enc $eol set fvar [read $chan] close $chan logMessage "read $fname" } return $fvar }
Removes some options from a list of options.
| list of options and values |
| list of option names to remove |
The opts
may contain "key value" pairs and "alone" options without values. To remove "key value" pairs, key
should be an exact name. To remove an "alone" option, key
should be a glob pattern with *
.
proc ::apave::removeOptions {opts args} { # Removes some options from a list of options. # opts - list of options and values # args - list of option names to remove # The `opts` may contain "key value" pairs and "alone" options # without values. # To remove "key value" pairs, `key` should be an exact name. # To remove an "alone" option, `key` should be a glob pattern with `*`. foreach key $args { while {[incr maxi]<99} { if {[set i [lsearch -exact $opts $key]]>-1} { catch { # remove a pair "option value" set opts [lreplace $opts $i $i] set opts [lreplace $opts $i $i] } } elseif {[string first * $key]>=0 && [set i [lsearch -glob $opts $key]]>-1} { # remove an option only set opts [lreplace $opts $i $i] } else { break } } } return $opts }
Shows a window and, optionally, focuses on a widget of it.
| the window's path |
| the widget's path or a command to get it; optional, default "" |
Returns yes, if the window is shown successfully.
proc ::apave::repaintWindow {win {wfoc {}}} { # Shows a window and, optionally, focuses on a widget of it. # win - the window's path # wfoc - the widget's path or a command to get it # Returns yes, if the window is shown successfully. if {[winfo exists $win]} { # esp. for KDE if {[isKDE]} { ;# KDE is KDE, Tk is Tk, and never the twain shall meet wm withdraw $win wm deiconify $win wm attributes $win -topmost [wm attributes $win -topmost] } update if {$wfoc ne {}} { catch {set wfoc [{*}$wfoc]} focus $wfoc } return yes } return no }
Tries restoring an array 1:1.
| fully qualified array name |
| saved array's value (got with "array get") |
At restoring, new items of $arName
are deleted and existing items are updated, so that after restoring array get $arName
is equal to $arSave
. Note: "array unset $arName
*; array set $arName
$arSave
" doesn't ensure this equality.
proc ::apave::RestoreArray {arName arSave} { # Tries restoring an array 1:1. # arName - fully qualified array name # arSave - saved array's value (got with "array get") # At restoring, new items of $arName are deleted and existing items are updated, # so that after restoring *array get $arName* is equal to $arSave. # Note: "array unset $arName *; array set $arName $arSave" doesn't ensure this equality. set ar $arName array set artmp $arSave set tmp1 [array names artmp] set tmp2 [array names $arName] foreach n $tmp2 { if {$n ni $tmp1} {unset [set ar]($n)} {set [set ar]($n) $artmp($n)} } foreach n $tmp1 { # deleted items can break 1:1 equality (not the case with alited) if {$n ni $tmp2} {set [set ar]($n) $artmp($n)} } }
Gets a parent modal window for a given one.
| default parent |
proc ::apave::rootModalWindow {pwin} { # Gets a parent modal window for a given one. # pwin - default parent set root $pwin foreach w [winfo children $pwin] { if {[winfo ismapped $w] && [InfoFind $w yes] ne {}} { set root [winfo toplevel $w] } } return $root }
Sets application's icon.
| path to a window of application |
| data of icon; optional, default "" |
The winicon may be a contents of variable (as supposed by default) or a file's name containing th image data. If it fails to find an image in either, no icon is set.
proc ::apave::setAppIcon {win {winicon {}}} { # Sets application's icon. # win - path to a window of application # winicon - data of icon # The *winicon* may be a contents of variable (as supposed by default) or # a file's name containing th image data. # If it fails to find an image in either, no icon is set. variable _AP_VARS set _AP_VARS(APPICON) {} if {$winicon ne {}} { if {[catch {set _AP_VARS(APPICON) [image create photo -data $winicon]}]} { catch {set _AP_VARS(APPICON) [image create photo -file $winicon]} } } if {$_AP_VARS(APPICON) ne {}} {wm iconphoto $win -default $_AP_VARS(APPICON)} }
Sets a property's value as "application-wide".
| name of property |
| value of property |
If args is omitted, the method returns a property's value. If args is set, the method sets a property's value as $args
.
proc ::apave::setProperty {name args} { # Sets a property's value as "application-wide". # name - name of property # args - value of property # If *args* is omitted, the method returns a property's value. # If *args* is set, the method sets a property's value as $args. variable _AP_Properties switch -exact [llength $args] { 0 {return [getProperty $name]} 1 {return [set _AP_Properties($name) [lindex $args 0]]} } puts -nonewline stderr "Wrong # args: should be \"::apave::setProperty propertyname ?value?\"" return -code error }
Sets new key combinations for some operations on text widgets.
| ctrlD for "double selection", ctrlY for "delete line" operation |
| list of new key combinations |
proc ::apave::setTextHotkeys {key value} { # Sets new key combinations for some operations on text widgets. # key - ctrlD for "double selection", ctrlY for "delete line" operation # value - list of new key combinations variable _AP_VARS set _AP_VARS(KEY,$key) $value }
Sets an indenting for text widgets.
| length of indenting |
| indenting character; optional, default
|
proc ::apave::setTextIndent {len {padchar { }}} { # Sets an indenting for text widgets. # len - length of indenting # padchar - indenting character variable _AP_VARS if {$padchar ne "\t"} {set padchar { }} set _AP_VARS(INDENT) [string repeat $padchar $len] }
Gets widget's geometry components.
| geometry |
| default X-coordinate; optional, default +0 |
| default Y-coordinate; optional, default +0 |
Returns a list of width, height, X and Y (coordinates are always with + or -) and also a flag "negative coordinates, calculated from bottom right".
proc ::apave::splitGeometry {geom {X +0} {Y +0}} { # Gets widget's geometry components. # geom - geometry # X - default X-coordinate # Y - default Y-coordinate # Returns a list of width, height, X and Y (coordinates are always with + or -) # and also a flag "negative coordinates, calculated from bottom right". lassign [split $geom x+-] w h lassign [regexp -inline -all {([+-][[:digit:]]+)} $geom] -> x y if {$geom ne {}} { if {$x in {"" 0} || [catch {expr {$x+0}}]} {set x $X} if {$y in {"" 0} || [catch {expr {$y+0}}]} {set y $Y} } set neg [expr {[string first - $geom]>=0 && [string first + $geom]<0}] list $w $h $x $y $neg }
Configures a channel for text file.
| the channel |
| if set, defines encoding of the file; optional, default "" |
| if set, defines EOL of the file; optional, default "" |
proc ::apave::textChanConfigure {channel {coding {}} {eol {}}} { # Configures a channel for text file. # channel - the channel # coding - if set, defines encoding of the file # eol - if set, defines EOL of the file if {$coding eq {}} { chan configure $channel -encoding utf-8 } else { chan configure $channel -encoding $coding } if {$eol eq {}} { chan configure $channel {*}[::apave::textEOL translation] } else { chan configure $channel -translation $eol } }
Gets/sets End-of-Line for text reqding/writing.
| LF, CR, CRLF or {}; optional, default - |
If EOL omitted or equals to {} or "-", return the current EOL. If EOL equals to "translation", return -translation option or {}.
proc ::apave::textEOL {{EOL -}} { # Gets/sets End-of-Line for text reqding/writing. # EOL - LF, CR, CRLF or {} # If EOL omitted or equals to {} or "-", return the current EOL. # If EOL equals to "translation", return -translation option or {}. variable _PU_opts if {$EOL eq "-"} {return $_PU_opts(_EOL_)} if {$EOL eq "translation"} { if {$_PU_opts(_EOL_) eq ""} {return ""} return "-translation $_PU_opts(_EOL_)" } set _PU_opts(_EOL_) [string trim [string tolower $EOL]] }
Splits a text's contents by EOLs. Those inventors of EOLs...
| text's contents |
proc ::apave::textsplit {textcont} { # Splits a text's contents by EOLs. Those inventors of EOLs... # textcont - text's contents split [string map [list \r\n \n \r \n] $textcont] \n }
Cancels tracing of a variable.
| variable's name |
proc ::apave::traceRemove {v} { # Cancels tracing of a variable. # v - variable's name foreach t [trace info variable $v] { lassign $t o c trace remove variable $v $o $c } }
Selects a treeview item.
| treeview's path |
| item index |
proc ::apave::TreSelect {w idx} { # Selects a treeview item. # w - treeview's path # idx - item index set items [$w children {}] catch { set it [lindex $items $idx] $w see $it $w focus $it $w selection set $it ;# generates <<TreeviewSelect>> } }
Initializes Toolbutton's style, depending on CS. Creates also btt / brt / blt widget types to be paved, with images top / right / left accordingly.
Enters a block of undo/redo for a text widget.
| text widget's path |
Run before massive changes of the text, to have Undo/Redo done at one blow.
proc ::apave::undoIn {wtxt} { # Enters a block of undo/redo for a text widget. # wtxt - text widget's path # Run before massive changes of the text, to have Undo/Redo done at one blow. # See also: undoOut $wtxt configure -autoseparators no $wtxt edit separator }
Exits a block of undo/redo for a text widget.
| text widget's path |
Run after massive changes of the text, to have Undo/Redo done at one blow.
proc ::apave::undoOut {wtxt} { # Exits a block of undo/redo for a text widget. # wtxt - text widget's path # Run after massive changes of the text, to have Undo/Redo done at one blow. # See also: undoIn $wtxt edit separator $wtxt configure -autoseparators yes }
Makes a path "unix-like" to be good for Tcl.
| the path |
proc ::apave::UnixPath {path} { # Makes a path "unix-like" to be good for Tcl. # path - the path set path [string trim $path "\{\}"] ;# possibly braced if contains spaces set path [string map [list \\ / %H [HomeDir]] $path] checkHomeDir $path }
Sets/gets a status of window. The status is a value assigned to a name.
| window's path |
| name of status |
| if blank, to get a value of status; otherwise a value to set; optional, default "" |
| default value (actual if the status not set beforehand); optional, default "" |
Returns a value of status.
proc ::apave::WindowStatus {w name {val {}} {defval {}}} { # Sets/gets a status of window. The status is a value assigned to a name. # w - window's path # name - name of status # val - if blank, to get a value of status; otherwise a value to set # defval - default value (actual if the status not set beforehand) # Returns a value of status. # See also: IntStatus variable _AP_VARS if {$val eq {}} { ;# getting if {[info exist _AP_VARS($w,$name)]} { return $_AP_VARS($w,$name) } return $defval } set _AP_VARS($w,$name) $val ;# setting }
Does 'withdraw' for a window.
| the window's path |
proc ::apave::withdraw {w} { # Does 'withdraw' for a window. # w - the window's path # See also: iconifyOption switch -- [iconifyOption] { none { ; # no withdraw/deiconify actions } Linux { ; # do it for Linux wm withdraw $w } Windows { ; # do it for Windows wm withdraw $w wm attributes $w -alpha 0.0 } default { ; # do it depending on the platform wm withdraw $w if {[::iswindows]} { wm attributes $w -alpha 0.0 } } } }
Writes to a text file.
| file name |
| variable name for file content or "" optional, default "" |
| if 'true', exit at errors with error message; optional, default 0 |
| if 'true', saves an empty file, else deletes it; optional, default 1 |
| Optional arguments. |
Returns "yes" if the file was saved successfully.
proc ::apave::writeTextFile {fname {varName {}} {doErr 0} {doSave 1} args} { # Writes to a text file. # fname - file name # varName - variable name for file content or "" # doErr - if 'true', exit at errors with error message # doSave - if 'true', saves an empty file, else deletes it # Returns "yes" if the file was saved successfully. variable _PU_opts if {$varName ne {}} { upvar $varName contents } else { set contents {} } set res yes if {!$doSave && [string trim $contents] eq {}} { if {[catch {file delete $fname} _PU_opts(_ERROR_)]} { set res no } else { logMessage "delete $fname" } } elseif {[catch {set chan [open $fname w]} _PU_opts(_ERROR_)]} { set res no } else { set enc [::apave::getOption -encoding {*}$args] set eol [string tolower [::apave::getOption -translation {*}$args]] ::apave::textChanConfigure $chan $enc $eol puts -nonewline $chan $contents close $chan logMessage "write $fname" } if {!$res && $doErr} {error [::apave::error $fname]} return $res }
Creates APave object.
| additional arguments |
| window's name (path) |
method constructor {args} { # Creates APave object. # win - window's name (path) # args - additional arguments set _savedvv [list] if {[llength [self next]]} { next {*}$args } }
Clears variables used in the object.
method destructor {} { # Clears variables used in the object. my initInput unset _savedvv if {[llength [self next]]} next }
Edits or views a file with a set of main colors
| name of file |
| foreground color of text widget |
| background color of text widget |
| caret's color of text widget |
| a command performing before and after creating a dialog; optional, default "" |
| additional options (-readonly 1 for viewing the file). |
If fg isn't empty, all three colors are used to color a text.
method editfile {fname fg bg cc {prepcom {}} args} { # Edits or views a file with a set of main colors # fname - name of file # fg - foreground color of text widget # bg - background color of text widget # cc - caret's color of text widget # prepcom - a command performing before and after creating a dialog # args - additional options (`-readonly 1` for viewing the file). # If *fg* isn't empty, all three colors are used to color a text. # See also: # [aplsimple.github.io](https://aplsimple.github.io/en/tcl/pave/index.html) if {$fname eq {}} { return false } set newfile 0 if {[catch {set filetxt [::apave::readTextFile $fname {} yes]}]} { return false } lassign [::apave::parseOptions $args -rotext {} -readonly 1 -ro 1] rotext readonly ro lassign [::apave::extractOptions args -buttons {}] buttadd set btns {Close 0} ;# by default 'view' mode set oper VIEW if {$rotext eq {} && (!$readonly || !$ro)} { set btns {Save 1 Close 0} set oper EDIT } if {$fg eq {}} { set tclr {} } else { set tclr "-fg $fg -bg $bg -cc $cc" } if {$prepcom eq {}} {set aa {}} {set aa [$prepcom filetxt]} set res [my misc {} "$oper: $fname" "$filetxt" "$buttadd $btns" TEXT -text 1 -w {100 80} -h 32 {*}$tclr -post $prepcom {*}$aa {*}$args] set data [string range $res 2 end] if {[set res [string index $res 0]] eq "1"} { set data [string range $data [string first " " $data]+1 end] set data [string trimright $data] set res [::apave::writeTextFile $fname data] } elseif {$newfile} { file delete $fname } return $res }
Initializes input and clears variables made in previous session.
method initInput {} { # Initializes input and clears variables made in previous session. foreach {vn vv} $_savedvv { catch {unset $vn} } set _savedvv [list] set Widgetopts [list] }
Makes and runs an input dialog.
| icon (omitted if equals to "") |
| title of window |
| list of widgets and their attributes |
| list of dialog's attributes |
The iopts
contains lists of three items:
name | name of widgets |
prompt | prompt for entering data |
valopts | value options |
The valopts
is a list specific for a widget's type, however a first item of valopts
is always an initial input value.
method input {icon ttl iopts args} { # Makes and runs an input dialog. # icon - icon (omitted if equals to "") # ttl - title of window # iopts - list of widgets and their attributes # args - list of dialog's attributes # The `iopts` contains lists of three items: # name - name of widgets # prompt - prompt for entering data # valopts - value options # The `valopts` is a list specific for a widget's type, however # a first item of `valopts` is always an initial input value. if {$iopts ne {}} { my initInput ;# clear away all internal vars } set pady "-pady 2" if {[set focusopt [::apave::getOption -focus {*}$args]] ne {}} { set focusopt "-focus $focusopt" } lappend inopts [list fraM + T 1 98 "-st nsew $pady -rw 1"] set savedvv [list] set frameprev {} foreach {name prompt valopts} $iopts { if {$name eq {}} continue lassign $prompt prompt gopts attrs lassign [::apave::extractOptions attrs -method {} -toprev {}] ismeth toprev if {[string toupper $name 0] eq $name} { set ismeth yes ;# overcomes the above setting set name [string tolower $name 0] } set ismeth [string is true -strict $ismeth] set gopts "$pady $gopts" set typ [string tolower [string range $name 0 1]] if {$typ eq "v_" || $typ eq "se"} { lappend inopts [list fraM.$name - - - - "pack -fill x $gopts"] continue } set tvar "-tvar" switch -exact -- $typ { ch { set tvar "-var" } sp { set gopts "$gopts -expand 0 -side left"} } set framename fraM.fra$name if {$typ in {lb te tb}} { ;# the widgets sized vertically lappend inopts [list $framename - - - - "pack -expand 1 -fill both"] } else { lappend inopts [list $framename - - - - "pack -fill x"] } set vv [my varName $name] set ff [my FieldName $name] set Name [string toupper $name 0] if {$ismeth && $typ ni {ra}} { # -method option forces making "WidgetName" method from "widgetName" my MakeWidgetName $ff $Name - } if {$typ ne {la} && $toprev eq {}} { set takfoc [::apave::parseOptions $attrs -takefocus 1] if {$focusopt eq {} && $takfoc} { if {$typ in {fi di cl fo da}} { set _ en*$name ;# 'entry-like mega-widgets' } elseif {$typ eq "ft"} { set _ te*$name ;# ftx - 'text-like mega-widget' } else { set _ $name } set focusopt "-focus $_" } if {$typ in {lb tb te}} {set anc nw} {set anc w} lappend inopts [list fraM.fra$name.labB$name - - - - "pack -side left -anchor $anc -padx 3" "-t \"$prompt\" -font \"-family {[my basicTextFont]} -size [my basicFontSize]\""] } # for most widgets: # 1st item of 'valopts' list is the current value # 2nd and the rest of 'valopts' are a list of values if {$typ ni {fc te la}} { # curr.value can be set with a variable, so 'subst' is applied set vsel [lindex $valopts 0] catch {set vsel [subst -nocommands -nobackslashes $vsel]} set vlist [lrange $valopts 1 end] } if {[set msgLab [::apave::getOption -msgLab {*}$attrs]] ne {}} { set attrs [::apave::removeOptions $attrs -msgLab] } # define a current widget's info switch -exact -- $typ { lb - tb { set $vv $vlist lappend attrs -lvar $vv if {$vsel ni {{} -}} { lappend attrs -lbxsel "$::apave::UFF$vsel$::apave::UFF" } lappend inopts [list $ff - - - - "pack -side left -expand 1 -fill both $gopts" $attrs] lappend inopts [list fraM.fra$name.sbv$name $ff L - - "pack -fill y"] } cb { if {![info exist $vv]} {catch {set $vv $vsel}} lappend attrs -tvar $vv -values $vlist if {$vsel ni {{} -}} { lappend attrs -cbxsel $::apave::UFF$vsel$::apave::UFF } lappend inopts [list $ff - - - - "pack -side left -expand 1 -fill x $gopts" $attrs] } fc { if {![info exist $vv]} {catch {set $vv {}}} lappend inopts [list $ff - - - - "pack -side left -expand 1 -fill x $gopts" "-tvar $vv -values \{$valopts\} $attrs"] } op { set $vv $vsel lappend inopts [list $ff - - - - "pack -fill x $gopts" "$vv $vlist"] } ra { if {![info exist $vv]} {catch {set $vv $vsel}} set padx 0 foreach vo $vlist { set name $name set FF $ff[incr nnn] lappend inopts [list $FF - - - - "pack -side left $gopts -padx $padx" "-var $vv -value \"$vo\" -t \"$vo\" $attrs"] if {$ismeth} { my MakeWidgetName $FF $Name$nnn - } set padx [expr {$padx ? 0 : 9}] } } te { if {![info exist $vv]} { set valopts [string map [list \\n \n \\t \t] $valopts] set $vv [string map [list \\\\ \\ \\\} \} \\\{ \{] $valopts] } if {[dict exist $attrs -state] && [dict get $attrs -state] eq "disabled"} { # disabled text widget cannot be filled with a text, so we should # compensate this through a home-made attribute (-disabledtext) set disattr "-disabledtext \{[set $vv]\}" } elseif {[dict exist $attrs -readonly] && [dict get $attrs -readonly] || [dict exist $attrs -ro] && [dict get $attrs -ro]} { set disattr "-rotext \{[set $vv]\}" set attrs [::apave::removeOptions $attrs -readonly -ro] } else { set disattr {} } lappend inopts [list $ff - - - - "pack -side left -expand 1 -fill both $gopts" "$attrs $disattr"] lappend inopts [list fraM.fra$name.sbv$name $ff L - - "pack -fill y"] } la { if {$prompt ne {}} { set prompt "-t \"$prompt\" " } ;# prompt as -text lappend inopts [list $ff - - - - "pack -anchor w $gopts" "$prompt$attrs"] continue } bu - bt - ch { set prompt {} if {$toprev eq {}} { lappend inopts [list $ff - - - - "pack -side left -expand 1 -fill both $gopts" "$tvar $vv $attrs"] } else { lappend inopts [list $frameprev.$name - - - - "pack -side left $gopts" "$tvar $vv $attrs"] } if {$vv ne {}} { if {![info exist $vv]} { catch { if {$vsel eq {}} {set vsel 0} set $vv $vsel } } } } default { if {$vlist ne {}} {lappend attrs -values $vlist} lappend inopts [list $ff - - - - "pack -side left -expand 1 -fill x $gopts" "$tvar $vv $attrs"] if {$vv ne {}} { if {![info exist $vv]} {catch {set $vv $vsel}} } } } if {$msgLab ne {}} { lassign $msgLab lab msg attlab set lab [my parentWName [lindex $inopts end 0]].$lab if {$msg ne {}} {set msg "-t {$msg}"} append msg " $attlab" lappend inopts [list $lab - - - - "pack -side left -expand 1 -fill x" $msg] } if {![info exist $vv]} {set $vv {}} lappend _savedvv $vv [set $vv] set frameprev $framename } lassign [::apave::parseOptions $args -titleHELP {} -buttons {} -comOK 1 -titleOK OK -titleCANCEL Cancel -centerme {}] titleHELP buttons comOK titleOK titleCANCEL centerme if {$titleHELP eq {}} { set butHelp {} } else { lassign $titleHELP title command set butHelp [list butHELP $title $command] } if {$titleCANCEL eq {}} { set butCancel {} } else { set butCancel "butCANCEL $titleCANCEL destroy" } if {$centerme eq {}} { set centerme {-centerme 1} } else { set centerme "-centerme $centerme" } set args [::apave::removeOptions $args -titleHELP -buttons -comOK -titleOK -titleCANCEL -centerme -modal] lappend args {*}$focusopt if {[catch { lassign [my PrepArgs {*}$args] args set res [my Query $icon $ttl {} "$butHelp $buttons butOK $titleOK $comOK $butCancel" butOK $inopts $args {} {*}$centerme -input yes]} e] } then { catch {destroy $Dlgpath} ;# Query's window set under \n[string repeat _ 80]\n\n ::apave::obj ok err "ERROR" "\n$e$under $inopts$under $args$under $centerme" -t 1 -head "\nAPave error: \n" -hfg red -weight bold -w 80 return 0 } if {![lindex $res 0]} { ;# restore old values if OK not chosen foreach {vn vv} $_savedvv { # tk_optionCascade (destroyed now) was tracing its variable => catch catch {set $vn $vv} } } return $res }
Sets -topmost attribute for windows or gets a list of topmost windows.
| parent window's path |
| -topmost attribute's value |
| list of windows to process; optional, default - |
| used to get the result; optional, default "" |
Returns a list of "topmost=$top
" windows found on $wpar
path.
method onTop {wpar top {wtoplist -} {res {}}} { # Sets -topmost attribute for windows or gets a list of topmost windows. # wpar - parent window's path # top - -topmost attribute's value # wtoplist - list of windows to process # res - used to get the result # Returns a list of "topmost=$top" windows found on $wpar path. if {$wtoplist ne "-"} { # sets the attribute foreach w $wtoplist {wm attributes $w -topmost $top} } else { # gets a list of topmost windows if {$wpar ne {}} { set res [my onTop [winfo parent $wpar] $top - $res] catch { if {[wm attributes $wpar -topmost]==$top} {lappend res $wpar} } } } return $res }
Gets input variables' values.
method valueInput {} { # Gets input variables' values. set _values {} foreach {vnam -} [my varInput] { lappend _values [set $vnam] } return $_values }
Gets variables made and filled in a previous session as a list of "varname varvalue" pairs where varname is of form: namespace::var$widgetname
.
method varInput {} { # Gets variables made and filled in a previous session # as a list of "varname varvalue" pairs where varname # is of form: namespace::var$widgetname. return $_savedvv }
Views or edits a file.
| name of file |
| a command performing before and after creating a dialog; optional, default "" |
| additional options |
It's a sort of stub for calling editfile method.
method vieweditFile {fname {prepcom {}} args} { # Views or edits a file. # fname - name of file # prepcom - a command performing before and after creating a dialog # args - additional options # It's a sort of stub for calling *editfile* method. # See also: editfile my editfile $fname {} {} {} $prepcom {*}$args }
constructor | Constructor for the class. |
destructor | Destructor for the class. |
| See ObjectTheming.apaveTheme |
| See ObjectTheming.basicDefFont |
| See ObjectTheming.basicFontSize |
| See ObjectTheming.basicSmallFont |
| See ObjectTheming.basicTextFont |
bindGutter | Makes bindings for a text and its gutter. |
| See ObjectTheming.boldDefFont |
| See ObjectTheming.boldTextFont |
checkTimeoutButton | Checks if the timeout button is alive & focused; if not, cancels the timeout. |
checkXY | Checks the coordinates of window (against the screen). |
chooser | Chooser (for all available types). |
chooserGeomVars | Sets/gets variables to save/restore geometry of Tcl/Tk dir/file choosers (in Linux). |
chooserPath | Gets a path to chooser's entry or label. |
clearEntry | Clears entry-like widget's value, after calling a command. |
colorChooser | Color chooser. |
colorWindow | Initialize colors of a window. |
configure | Configures the apave object (all of options may be changed). |
| See ObjectTheming.create_Fonts |
| See ObjectTheming.create_FontsType |
| See ObjectTheming.csAdd |
| See ObjectTheming.csCurrent |
| See ObjectTheming.csDark |
| See ObjectTheming.csDeleteExternal |
| See ObjectTheming.csExport |
| See ObjectTheming.csFont |
| See ObjectTheming.csFontDef |
| See ObjectTheming.csFontMono |
| See ObjectTheming.csGet |
| See ObjectTheming.csGetName |
| See ObjectTheming.csMainColors |
| See ObjectTheming.csMapTheme |
| See ObjectTheming.csNewIndex |
| See ObjectTheming.csSet |
| See ObjectTheming.csToned |
dateChooser | Date chooser (calendar widget). |
defaultATTRS | Sets, gets or registers default options and attributes for widget type. |
displayTaggedText | Sets the text widget's contents using tags (ornamental details). |
displayText | Sets the text widget's contents. |
dlgPath | Gets a window name of apave open dialogue. |
fillGutter | Fills a gutter of text with the text's line numbers. |
findWidPath | Searches a widget's path among the active widgets. |
focusNext | Sets focus on a next widget (possibly, defined as my Widget ). |
fontChooser | Font chooser. |
getShowOption | Gets a default show option, used in showModal. |
getTextContent | Gets text content. |
getWidChildren | Gets children of a widget. |
gutterContents | Gets contents of a text's gutter |
iconA | Gets icon attributes for buttons, menus etc. |
initLinkFont | Gets/sets font attributes of links (labels & text tags with -link). |
| See ObjectTheming.initTooltip |
labelFlashing | Options of 'flashing' label: -file (or -data) {list of image files (or data variables)} -label {list of labels' texts} -incr {increment for -alpha option} -pause {pause in seconds for -alpha 1.0} -after {interval for 'after'} -squeeze {value for *-big.png} |
leadingSpaces | Returns a number of leading spaces of a line |
makeLabelLinked | Makes the linked label from a label. |
makePopup | Makes a popup menu for an editable widget. |
makeWindow | Creates a toplevel window that has to be paved. |
menuTips | Makes tip(s) for menu and its items. |
onKeyTextM | Processes indents and braces at pressing keys. |
optionCascadeText | Rids a tk_optionCascade item of braces. |
ownWName | Gets a tail (last part) of widget's name |
parentWName | Gets parent name of widget. |
pavedPath | Gets the currently paved window's path. |
paveoptionValue | Gets an option's value. |
paveWindow | Processes "win / list_of_widgets" pairs. |
readonlyWidget | Switches on/off a widget's readonly state for a text widget. |
res | Gets/sets a variable for vwait command. |
resetText | Resets a text widget to edit/view from scratch. |
scrolledFrame | Retrieves the path where the scrollable contents of frame go. |
setShowOption | Sets / gets a default show option, used in showModal. |
setTextBinds | Returns bindings for a text widget. |
showModal | Shows a window as modal. |
showWindow | Displays a windows and goes in tkwait cycle to interact with a user. |
sourceKlnd | Loads klnd package at need. |
textLink | Gets a label's path of a link in a text widget. |
| See ObjectTheming.thDark |
| See ObjectTheming.themeExternal |
| See ObjectTheming.themeMandatory |
| See ObjectTheming.themeNonThemed |
themePopup | Applies a color scheme to a popup menu. |
| See ObjectTheming.themeWindow |
timeoutButton | Invokes a button's action after a timeout. |
tk_optionCascade | A bit modified tk_optionCascade widget made by Richard Suchenwirth. |
toolbarItem_Attrs | Gets default attributes of toolbar button. |
| See ObjectTheming.touchWidgets |
| See ObjectTheming.untouchWidgets |
validateColorChoice | Displays a current color of color chooser's entry. |
waitWinVar | Tk waiting for variable's change. |
widgetType | Gets the widget type based on 3 initial letters of its name. Also fills the grid/pack options and attributes of the widget. |
window | Obsolete version of paveWindow (remains for compatibility). |
Creates APaveBase object.
| color scheme (CS); optional, default -2 |
| additional arguments |
If cs>-2, the appropriate CS is set for the created APaveBase object. Makes few procedures in the object's namespace to access from event handlers:
This trick with proc inside an object is discussed at proc-in-tcl-ooclass
method constructor {{cs -2} args} { # Creates APaveBase object. # cs - color scheme (CS) # args - additional arguments # If cs>-2, the appropriate CS is set for the created APaveBase object. # Makes few procedures in the object's namespace to access from # event handlers: # - ListboxHandle # - ListboxSelect # - WinResize # This trick with *proc* inside an object is discussed at # [proc-in-tcl-ooclass](https://stackoverflow.com/questions/54804964/proc-in-tcl-ooclass) # keep the 'important' data of Pave object in array array set PV [list] set Moveall 1 set Initialcolor {} set Modalwin . set Fgbut [ttk::style lookup TButton -foreground]; if {$Fgbut eq {}} {set Fgbut #000000} set Bgbut [ttk::style lookup TButton -background]; if {$Bgbut eq {}} {set Bgbut #d9d9d9} set Fgtxt [ttk::style lookup TEntry -foreground] ; if {$Fgtxt eq {}} {set Fgtxt #000000} set Prepost [list] set Widgetopts [list] set Edge @@ if {$Fgtxt in {black #000000}} { set Bgtxt white } else { set Bgtxt [ttk::style lookup TEntry -background] } # set/reset a color scheme if it is/was requested if {$cs>=-1} {my csSet $cs} {my initTooltip} # object's procedures ; proc ListboxHandle {W offset maxChars} { set list {} foreach index [$W curselection] { lappend list [$W get $index] } set text [join $list \n] return [string range $text $offset [expr {$offset+$maxChars-1}]] } ; proc ListboxSelect {W} { # This code had been taken from Tcl's wiki: # https://wiki.tcl-lang.org/page/listbox+selection selection clear -displayof $W selection own -command {} $W selection handle -type UTF8_STRING $W [list [namespace current]::ListboxHandle $W] selection handle $W [list [namespace current]::ListboxHandle $W] return } ; proc WinResize {win} { # Restricts the window's sizes (thus fixing Tk's issue with a menubar) # win - path to a window to be of restricted sizes if {[$win cget -menu] ne {}} { lassign [::apave::splitGeometry [wm geometry $win]] w h lassign [wm minsize $win] wmin hmin if {$w<$wmin && $h<$hmin} { set corrgeom ${wmin}x$hmin } elseif {$w<$wmin} { set corrgeom ${wmin}x$h } elseif {$h<$hmin} { set corrgeom ${w}x$hmin } else { return } wm geometry $win $corrgeom } return } # the end of APaveBase constructor if {[llength [self next]]} { next {*}$args } return }
Clears variables used in the object.
method destructor {} { # Clears variables used in the object. array unset PV * if {[llength [self next]]} next }
Makes bindings for a text and its gutter.
| path to the text widget |
| canvas of the gutter |
| width of the gutter, in chars; optional, default 5 |
| addition to the width (to shift from the left side); optional, default 3 |
method bindGutter {txt canvas {width 5} {shift 3}} { # Makes bindings for a text and its gutter. # txt - path to the text widget # canvas - canvas of the gutter # width - width of the gutter, in chars # shift - addition to the width (to shift from the left side) set bind [list [self] fillGutter $txt $canvas $width $shift] bind $txt <Configure> $bind bind $txt <Motion> [list after idle $bind] if {[trace info execution $txt] eq {}} { trace add execution $txt leave $bind } }
Checks if the timeout button is alive & focused; if not, cancels the timeout.
| button's path |
| timeout in sec. |
| label widget, where seconds to wait are displayed |
| original text of label; optional, default "" |
method checkTimeoutButton {w tmo lbl {lbltext {}}} { # Checks if the timeout button is alive & focused; if not, cancels the timeout. # w - button's path # tmo - timeout in sec. # lbl - label widget, where seconds to wait are displayed # lbltext - original text of label if {[winfo exists $lbl]} { if {[focus] in [list $w {}]} { if {$w in $::apave::_AP_VARS(TIMW)} { my timeoutButton $w $tmo $lbl $lbltext } } else { $lbl configure -text $lbltext } } }
Checks the coordinates of window (against the screen).
| width of window |
| height of window |
| window's X coordinate |
| window's Y coordinate |
Returns new coordinates in +X+Y form.
method checkXY {w h x y} { # Checks the coordinates of window (against the screen). # w - width of window # h - height of window # x - window's X coordinate # y - window's Y coordinate # Returns new coordinates in +X+Y form. # check for left/right edge of screen (accounting decors) set scrw [expr {[winfo vrootwidth .] - 12}] set scrh [expr {[winfo vrootheight .] - 36}] if {($x + $w) > $scrw } { set x [expr {$scrw - $w}] } if {($y + $h) > $scrh } { set y [expr {$scrh - $h}] } if {![string match -* $x]} {set x +[string trimleft $x +]} if {![string match -* $y]} {set y +[string trimleft $y +]} return $x$y }
Chooser (for all available types).
| name of chooser |
| name of variable containing an input/output value |
| options of the chooser |
The chooser names are:
tk_getOpenFile | choose a file to open |
tk_getSaveFile | choose a file to save |
tk_chooseDirectory | choose a directory |
fontChooser | choose a font |
dateChooser | choose a date |
colorChooser | choose a color |
ftx_OpenFile | (internal) choose a file for ftx widget |
Returns a selected value.
method chooser {nchooser tvar args} { # Chooser (for all available types). # nchooser - name of chooser # tvar - name of variable containing an input/output value # args - options of the chooser # The chooser names are: # tk_getOpenFile - choose a file to open # tk_getSaveFile - choose a file to save # tk_chooseDirectory - choose a directory # fontChooser - choose a font # dateChooser - choose a date # colorChooser - choose a color # ftx_OpenFile - (internal) choose a file for ftx widget # Returns a selected value. set isfilename [set rootname 0] lassign [apave::extractOptions args -ftxvar {} -tname {} -bname {} -parent {}] ftxvar tname bname parent if {$parent ne {}} { set parent "-parent $parent" } else { set parent [my ParentOpt] } lassign $parent -> wpar set wtoplist [my onTop $wpar 1] my onTop $wpar 0 $wtoplist ;# do not overlap choosers lassign [my chooserGeomVars] dirvar filvar if {$dirvar eq {}} { set [set dirvar ::apave::APaveDirVar] {} set [set filvar ::apave::APaveFilVar] {} my chooserGeomVars $dirvar $filvar } set vargeo {} if {$nchooser eq {ftx_OpenFile}} { set nchooser tk_getOpenFile } set widname {} set choosname $nchooser if {$choosname in {fontChooser colorChooser dateChooser}} { set nchooser "my $choosname $tvar $parent $args" if {$choosname eq {fontChooser}} { append nchooser " -topmost [llength $wtoplist]" } } elseif {$choosname in {tk_getOpenFile tk_getSaveFile}} { set vargeo $filvar set widname [my AuxSetChooserGeometry $vargeo $dirvar $parent __tk_filedialog] if {[set fn [set $tvar]] eq {}} { set dn [pwd] } else { set dn [file dirname $fn] set fn [file tail $fn] } lassign [apave::extractOptions args -initialdir $dn] dn if {[string match -* $dn]} { set rootname 1 set dn [string range $dn 1 end] } set args [list -initialfile $fn -initialdir $dn {*}$parent {*}$args] incr isfilename } elseif {$nchooser eq {tk_chooseDirectory}} { set vargeo $dirvar set widname [my AuxSetChooserGeometry $vargeo $filvar $parent __tk_choosedir] set args [list -initialdir [set $tvar] {*}$parent {*}$args] incr isfilename } if {[::isunix] && $choosname ne {dateChooser}} { my themeExternal *.foc.* *f1.demo ;# don't touch tkcc's boxes } set res [{*}$nchooser {*}$args] my onTop $wpar 1 $wtoplist if {"$res" ne {} && "$tvar" ne {}} { if {$rootname} {set res [file rootname [file tail $res]]} if {$isfilename} { lassign [my SplitContentVariable $ftxvar] -> txtnam wid if {[info exist $ftxvar] && [file exist [set res [file nativename $res]]]} { set $ftxvar [apave::readTextFile $res] if {[winfo exist $txtnam]} { my readonlyWidget $txtnam no my displayTaggedText $txtnam $ftxvar my readonlyWidget $txtnam yes set wid [string range $txtnam 0 [string last . $txtnam]]$wid $wid configure -text "$res" ::tk::TextSetCursor $txtnam 1.0 update } } } set $tvar $res } if {$vargeo ne {} && $widname ne {} && [::isunix]} { catch { set $vargeo [list $widname [wm geometry $widname]] ;# 1st item for possible usage only } } if {$tname ne {}} { set tname [my [my ownWName $tname]] if {$bname ne {}} { # re-focus to fire invalidation of the entry (esp. for Windows) set ent [my ownWName $tname] set but [my ownWName $bname] set bname [string map [list .$ent .$but] $tname] focus $bname } focus $tname after idle "catch {$tname selection range 0 end ; $tname icursor end}" } return $res }
Sets/gets variables to save/restore geometry of Tcl/Tk dir/file choosers (in Linux).
| variable's name for geometry of directory chooser; optional, default "" |
| variable's name for geometry of file chooser; optional, default "" |
method chooserGeomVars {{dirvar {}} {filevar {}}} { # Sets/gets variables to save/restore geometry of Tcl/Tk dir/file choosers (in Linux). # dirvar - variable's name for geometry of directory chooser # filevar - variable's name for geometry of file chooser # See also: chooser if {$dirvar eq {}} { return [::apave::getProperty DirFilGeoVars] } ::apave::setProperty DirFilGeoVars [list $dirvar $filevar] }
Gets a path to chooser's entry or label.
| widget/method name (e.g. Fil, Dir) |
| ent / lab for entry / label; optional, default ent |
method chooserPath {W {w ent}} { # Gets a path to chooser's entry or label. # W - widget/method name (e.g. Fil, Dir) # w - ent / lab for entry / label ::apave::precedeWidgetName [my $W] $w }
Clears entry-like widget's value, after calling a command.
| widget's path |
| a command to call, can have %w for w (widget's path) |
method clearEntry {w clearcom} { # Clears entry-like widget's value, after calling a command. # w - widget's path # clearcom - a command to call, can have %w for *w* (widget's path) if {$clearcom ne {}} { {*}[string map [list %w $w %p [self]] $clearcom] } #! perhaps, needs refactoring: if {[catch {$w delete 0 end}]} { ;# entry if {[catch {$w set {}}]} { ;# combobox # others } } }
Color chooser.
| name of variable containing a color |
| options of tk_chooseColor |
The tvar sets the value of -initialcolor option. Also it gets a color selected in the chooser.
Returns a selected color.
method colorChooser {tvar args} { # Color chooser. # tvar - name of variable containing a color # args - options of *tk_chooseColor* # The *tvar* sets the value of *-initialcolor* option. Also # it gets a color selected in the chooser. # Returns a selected color. if {$Initialcolor eq {} && [::isunix]} { source [file join $::apave::apaveDir pickers color clrpick.tcl] } lassign [apave::extractOptions args -entry {} -inifile {} -ontop 0] ent ini top if {$ent ne {}} { set ent [my [my ownWName $ent]] set x [winfo rootx $ent] set y [expr {[winfo rooty $ent]+32}] dict set args -geometry +$x+$y ;# the same as with date picker } if {[set _ [string trim [set $tvar]]] ne {}} { set ic $_ set _ [. cget -background] if {[catch {. configure -background $ic}]} { set ic "#$ic" if {[catch {. configure -background $ic}]} {set ic black} } set Initialcolor $ic . configure -background $_ } else { set Initialcolor black } if {[catch {lassign [tk_chooseColor -moveall $Moveall -initialcolor $Initialcolor {*}$args -inifile $ini -ontop $top] res Moveall}]} { set args [apave::removeOptions $args -moveall -tonemoves -geometry] set res [tk_chooseColor -initialcolor $Initialcolor {*}$args] } if {$res ne {}} { set Initialcolor [set $tvar $res] } return $res }
Initialize colors of a window.
| window's path |
| arguments for csSet |
method colorWindow {win args} { # Initialize colors of a window. # win - window's path # args - arguments for csSet if {[my apaveTheme]} { my csSet [my csCurrent] $win {*}$args if {$args ne {-doit}} {my themeNonThemed $win} } else { my themeNonThemed $win } }
Configures the apave object (all of options may be changed).
| list of pairs name/value of options |
Example:
pobj configure edge "@@"
method configure {args} { # Configures the apave object (all of options may be changed). # args - list of pairs name/value of options # Example: # pobj configure edge "@@" foreach {optnam optval} $args {set $optnam $optval} }
Date chooser (calendar widget).
| name of variable containing a date |
| options of ::klnd::calendar |
Returns a selected date.
method dateChooser {tvar args} { # Date chooser (calendar widget). # tvar - name of variable containing a date # args - options of *::klnd::calendar* # Returns a selected date. my sourceKlnd {} if {![catch {set ent [my [my ownWName [apave::getOption -entry {*}$args]]]}]} { dict set args -entry $ent set res [::klnd::calendar {*}$args -tvar $tvar -parent [winfo toplevel $ent]] } else { set res [::klnd::calendar {*}$args -tvar $tvar] } return $res }
Sets, gets or registers default options and attributes for widget type.
| widget type; optional, default "" |
| new default grid/pack options; optional, default "" |
| new default attributes; optional, default "" |
| Tcl/Tk command for the new registered widget type; optional, default "" |
The type should be a three letter unique string. If the type is absent in the registered types and opts and/or atrs is not set to "", defaultATTRS registers the new type with its grid/pack options and attributes. At that widget is a command for the new widget type. For example, to register "toolbutton" widget: my defaultATTRS tbt {} {-style Toolbutton -compound top} ttk::button Options and attributes may contain data (variables and commands) to be processed by [subst]. Returns:
method defaultATTRS {{type {}} {opts {}} {atrs {}} {widget {}}} { # Sets, gets or registers default options and attributes for widget type. # type - widget type # opts - new default grid/pack options # atrs - new default attributes # widget - Tcl/Tk command for the new registered widget type # The *type* should be a three letter unique string. # If the *type* is absent in the registered types and *opts* and/or *atrs* # is not set to "", defaultATTRS registers the new *type* with its grid/pack # options and attributes. At that *widget* is a command for the new widget # type. For example, to register "toolbutton" widget: # my defaultATTRS tbt {} {-style Toolbutton -compound top} ttk::button # Options and attributes may contain data (variables and commands) # to be processed by [subst]. # Returns: # - if not set *type*: a full list of options and attributes of all types # - if set *type* only: a list of options, attributes and *widget* # - else: a list of updated options, attributes and *widget* if {$type eq {}} {return $::apave::_Defaults} set optatr "$opts$atrs" if {[catch {set def1 [dict get $::apave::_Defaults $type]}]} { if {$optatr eq {}} { set err "[self method]: \"$type\" widget type not registered." puts -nonewline stderr $err return -code error $err } set def1 [list $opts $atrs $widget] } if {$optatr eq {}} {return [subst $def1]} lassign $def1 defopts defatrs widget if {[catch {set defopts [dict replace $defopts {*}$opts]}]} { set defopts [string trim "$defopts $opts"] } if {[catch {set defatrs [dict replace $defatrs {*}$atrs]}]} { set defatrs [string trim "$defatrs $atrs"] } set newval [list $defopts $defatrs $widget] dict set ::apave::_Defaults $type $newval return $newval }
Sets the text widget's contents using tags (ornamental details).
| text widget's name |
| variable name for contents to be set in the widget |
| list of tags to be applied to the text; optional, default "" |
The lines in text contents are divided by \n and can include tags like in a html layout, e.g.
method displayTaggedText {w contsName {tags {}}} { # Sets the text widget's contents using tags (ornamental details). # w - text widget's name # contsName - variable name for contents to be set in the widget # tags - list of tags to be applied to the text # The lines in *text contents* are divided by \n and can include # *tags* like in a html layout, e.g. <red>RED ARMY</red>. # The *tags* is a list of "name/value" pairs. 1st is a tag's name, 2nd # is a tag's value. # The tag's name is "pure" one (without <>) so e.g.for <b>..</b> the tag # list contains "b". # The tag's value is a string of text attributes (-font etc.). # If the tag's name is FG, FG2, BG or BG2, then it is really a link color. upvar $contsName conts if {$tags eq {}} { my displayText $w $conts return } lassign [my csGet] fg fg2 bg bg2 if { [set state [$w cget -state]] ne {normal}} { $w configure -state normal } set taglist [set tagpos [set taglen [list]]] foreach tagi $tags { lassign $tagi tag opts if {$tag in {FG FG2 BG BG2} } { set [string tolower $tag] $opts } elseif {![string match link* $tag]} { $w tag config $tag {*}$opts } lappend tagpos 0 lappend taglen [string length $tag] } set tLen [llength $tags] set disptext {} set irow 1 foreach line [split $conts \n] { if {$irow > 1} { append disptext \n } set newline {} while 1 { set p [string first \< $line] if {$p < 0} { break } append newline [string range $line 0 $p-1] set line [string range $line $p end] set i 0 set nrnc $irow.[string length $newline] foreach tagi $tags pos $tagpos len $taglen { lassign $tagi tag if {[string first <$tag> $line]==0} { if {$pos ne {0}} { error "\napave: mismatched <$tag> in line $irow.\n" } lset tagpos $i $nrnc set line [string range $line $len+2 end] break } elseif {[string first </$tag> $line]==0} { if {$pos eq {0}} { error "\napave: mismatched </$tag> in line $irow.\n" } lappend taglist [list $i $pos $nrnc] lset tagpos $i 0 set line [string range $line $len+3 end] break } incr i } if {$i == $tLen} { # tag not found after "<" - shift by 1 character append newline [string index $line 0] set line [string range $line 1 end] } } append disptext $newline $line incr irow } $w replace 1.0 end $disptext set lfont [$w cget -font] catch {set lfont [font actual $lfont]} foreach {o v} [my initLinkFont] {dict set lfont $o $v} set ::apave::__TEXTLINKS__($w) [list] for {set it [llength $taglist]} {[incr it -1]>=0} {} { set tagli [lindex $taglist $it] lassign $tagli i p1 p2 lassign [lindex $tags $i] tag opts if {[string match link* $tag] && [set ist [lsearch -exact -index 0 $tags $tag]]>=0} { set txt [$w get $p1 $p2] set lab ${w}l[incr ::apave::__linklab__] ttk::label $lab -text $txt -font $lfont -foreground $fg -background $bg set ::apave::__TEXTLINKS__($w) [linsert $::apave::__TEXTLINKS__($w) 0 $lab] $w delete $p1 $p2 $w window create $p1 -window $lab set v [lindex $tags $ist 1] my makeLabelLinked $lab $v $fg $bg $fg2 $bg2 } else { $w tag add $tag $p1 $p2 } } my resetText $w $state }
Sets the text widget's contents.
| text widget's name |
| contents to be set in the widget |
| Not documented; optional, default 1.0 |
method displayText {w conts {pos 1.0}} { # Sets the text widget's contents. # w - text widget's name # conts - contents to be set in the widget if {[set state [$w cget -state]] ne {normal}} { $w configure -state normal } $w replace 1.0 end $conts $w edit reset; $w edit modified no if {$state eq {normal}} { ::tk::TextSetCursor $w $pos } else { $w configure -state $state } }
Gets a window name of apave open dialogue.
method dlgPath {} { # Gets a window name of apave open dialogue. if {[catch {set res $Dlgpath}] || $Dlgpath eq {}} { set res $::apave::MODALWINDOW } return $res }
Fills a gutter of text with the text's line numbers.
| path to the text widget |
| canvas of the gutter; optional, default "" |
| width of the gutter, in chars; optional, default "" |
| addition to the width (to shift from the left side); optional, default "" |
| additional arguments for tracing |
The code is borrowed from open source tedit project.
method fillGutter {txt {canvas {}} {width {}} {shift {}} args} { # Fills a gutter of text with the text's line numbers. # txt - path to the text widget # canvas - canvas of the gutter # width - width of the gutter, in chars # shift - addition to the width (to shift from the left side) # args - additional arguments for tracing # The code is borrowed from open source tedit project. set savedcont [namespace current]::gc$txt if {![winfo exists $txt] || ![winfo ismapped $txt]} { unset -nocomplain $savedcont return } if {$canvas eq {}} { catch {{*}[bind $txt <Configure>]} ;# update gutter return } set oper [lindex $args 0 1] if {![llength $args] || [lindex $args 0 4] eq {-elide} || $oper in {configure delete insert see yview}} { set i [$txt index @0,0] set gcont [list] while true { set dline [$txt dlineinfo $i] if {[llength $dline] == 0} break set height [lindex $dline 3] set y [expr {[lindex $dline 1]}] set linenum [format "%${width}d" [lindex [split $i .] 0]] set i [$txt index "$i +1 lines linestart"] lappend gcont [list $y $linenum] } # update the gutter at changing its contents/config if {[::apave::cs_Active]} { lassign [my csGet] - - - bg - - - - fg ::apave::setProperty _GUTTER_FGBG [list $fg $bg] } else { lassign [::apave::getProperty _GUTTER_FGBG] fg bg } set cwidth [expr {$shift + [font measure apaveFontMono -displayof $txt [string repeat 0 $width]]}] set newbg [expr {$bg ne [$canvas cget -background]}] set newwidth [expr {$cwidth ne [$canvas cget -width]}] if {![llength $args] || $newbg || $newwidth || ![info exists $savedcont] || $gcont ne [set $savedcont]} { if {$newbg} {$canvas config -background $bg} if {$newwidth} {$canvas config -width $cwidth} $canvas delete all foreach g $gcont { lassign $g y linenum $canvas create text 2 $y -anchor nw -text $linenum -font apaveFontMono -fill $fg } set $savedcont $gcont } } }
Searches a widget's path among the active widgets.
| Not documented. |
| if "exact", searches .wid; if "globe", searches wid*; optional, default exact |
| Not documented; optional, default yes |
| widget name, set partially e.g. "wid" instead of ".win.wid" |
Returns the widget's full path or "" if the widget isn't active.
method findWidPath {wid {mode exact} {visible yes}} { # Searches a widget's path among the active widgets. # w - widget name, set partially e.g. "wid" instead of ".win.wid" # mode - if "exact", searches *.wid; if "globe", searches *wid* # Returns the widget's full path or "" if the widget isn't active. my getWidChildren . tree if {$mode eq {exact}} { set i [lsearch -glob $tree "*.$wid"] } else { set i [lsearch -glob $tree "*$wid*"] } if {$i>-1} {return [lindex $tree $i]} return {} }
Sets focus on a next widget (possibly, defined as my Widget
).
| parent window name |
| next widget's name |
| core next name (used internally, for recursive search); optional, default "" |
method focusNext {w wnext {wnext0 {}}} { # Sets focus on a next widget (possibly, defined as `my Widget`). # w - parent window name # wnext - next widget's name # wnext0 - core next name (used internally, for recursive search) if {$wnext eq {}} return if {[winfo exist $wnext]} { focus $wnext ;# direct path to the next widget return } # try to find the next widget in hierarchy of widgets set ws $wnext if {$wnext0 eq {}} { # get the real next widget (wnext can be uppercased or calculated) catch {set wnext [subst $wnext]} if {![string match {my *} $wnext]} { catch {set wnext [my [my ownWName $wnext]]} } my focusNext $w $wnext $wnext } else { set wnext $wnext0 } foreach wn [winfo children $w] { my focusNext $wn $wnext $wnext0 if {[string match "*.$wnext" $wn] || [string match "*.$ws" $wn]} { focus $wn return } } }
Font chooser.
| name of variable containing a font |
| options of tk fontchooser |
The tvar sets the value of -font option. Also it gets a font selected in the chooser.
Returns a selected font.
method fontChooser {tvar args} { # Font chooser. # tvar - name of variable containing a font # args - options of *tk fontchooser* # The *tvar* sets the value of *-font* option. Also # it gets a font selected in the chooser. # Returns a selected font. set top [apave::extractOptions args -topmost 0] set parw [apave::parseOptions $args -parent [::apave::rootModalWindow .]] ; proc [namespace current]::applyFont {font} " set $tvar \[font actual \$font\]; focus -force $parw" set font [set $tvar] if {$font eq {}} { catch {font create fontchoose {*}$::apave::FONTMAIN} } else { catch {font delete fontchoose} catch {font create fontchoose {*}[font actual $font]} } tk fontchooser configure -font fontchoose {*}[my ParentOpt] {*}$args -command [namespace current]::applyFont tk fontchooser show # core Tk font chooser is bad with focusing in and out, it isn't modal if {[set foc [info commands *__tk__fontchooser.ok]] ne {}} { after idle [list after 0 [list catch "focus -force $foc"]] catch {wm attributes [winfo toplevel $foc] -topmost $top} } set $tvar }
Gets a default show option, used in showModal.
| name of option |
| default value; optional, default "" |
method getShowOption {name {defval {}}} { # Gets a default show option, used in showModal. # name - name of option # defval - default value # See also: showModal ::apave::getProperty [my ShowOption $name] $defval }
Gets text content.
| text variable |
Uses an internal text variable to extract the text contents.
Returns the content of text.
method getTextContent {tvar} { # Gets text content. # tvar - text variable # Uses an internal text variable to extract the text contents. # Returns the content of text. lassign [my SplitContentVariable [my GetContentVariable $tvar]] -> txtnam wid string trimright [$txtnam get 1.0 end] }
Gets children of a widget.
| widget's path |
| name of variable to hold the result. |
| Not documented; optional, default yes |
method getWidChildren {wid treeName {init yes}} { # Gets children of a widget. # wid - widget's path # treeName - name of variable to hold the result. upvar $treeName tree if {$init} {set tree [list]} foreach ch [winfo children $wid] { lappend tree $ch my getWidChildren $ch $treeName no } }
Gets contents of a text's gutter
| text's path |
method gutterContents {txt} { # Gets contents of a text's gutter # txt - text's path set savedcont [namespace current]::gc$txt if {[info exists $savedcont]} { return [set $savedcont] } return {} }
Gets icon attributes for buttons, menus etc.
| name of icon |
| one of small/middle/large; optional, default small |
| value of -compound option; optional, default left |
The iconset is "small" for menus (recommended and default).
method iconA {icon {iconset small} {cmpd left}} { # Gets icon attributes for buttons, menus etc. # icon - name of icon # iconset - one of small/middle/large # cmpd - value of -compound option # The *iconset* is "small" for menus (recommended and default). return "-image [::apave::iconImage $icon $iconset] -compound $cmpd" }
Gets/sets font attributes of links (labels & text tags with -link).
| font attributes ("-underline 1" by default) |
Returns the current value of these attributes.
method initLinkFont {args} { # Gets/sets font attributes of links (labels & text tags with -link). # args - font attributes ("-underline 1" by default) # Returns the current value of these attributes. if {[set ll [llength $args]]} { if {$ll%2} { ;# clear the attributes, if called with "" set ::apave::_AP_VARS(LINKFONT) [list] } else { lassign [::apave::extractOptions args -foreground {} -background {}] ::apave::_AP_VARS(LINKFG) ::apave::_AP_VARS(LINKBG) set ::apave::_AP_VARS(LINKFONT) $args } } return $::apave::_AP_VARS(LINKFONT) }
Options of 'flashing' label: -file (or -data) {list of image files (or data variables)} -label {list of labels' texts} -incr {increment for -alpha option} -pause {pause in seconds for -alpha 1.0} -after {interval for 'after'} -squeeze {value for *-big.png}
| Not documented. |
| Not documented. |
| Not documented. |
| Optional arguments. |
method labelFlashing {w1 w2 first args} { # Options of 'flashing' label: # -file (or -data) {list of image files (or data variables)} # -label {list of labels' texts} # -incr {increment for -alpha option} # -pause {pause in seconds for -alpha 1.0} # -after {interval for 'after'} # -squeeze {value for *-big.png} if {![winfo exists $w1]} return if {$first} { lassign [::apave::parseOptions $args -file {} -data {} -label {} -incr 0.01 -pause 3.0 -after 10 -squeeze {} -static 0] ofile odata olabel oincr opause oafter osqueeze ostatic if {$osqueeze ne {}} {set osqueeze "-subsample $osqueeze"} lassign {0 -2 0 1} idx incev waitev direv } else { lassign $args ofile odata olabel oincr opause oafter osqueeze ostatic idx incev waitev direv } set llf [llength $ofile] set lld [llength $odata] if {[set llen [expr {max($llf,$lld)}]]==0} return incr incev $direv set alphaev [expr {$oincr*$incev}] if {$alphaev>=1} { set alpha 1.0 if {[incr waitev -1]<0} { set direv -1 } } elseif {$alphaev<0} { set alpha 0.0 set idx [expr {$idx%$llen+1}] set direv 1 set incev 0 set waitev [expr {int($opause/$oincr)}] } else { set alpha $alphaev } if {$llf} { set png [list -file [lindex $ofile $idx-1]] } elseif {[info exists [set datavar [lindex $odata $idx-1]]]} { set png [list -data [set $datavar]] } else { set png [list -data $odata] } set NS [namespace current] if {$ostatic} { image create photo ${NS}::ImgT$w1 {*}$png $w1 configure -image ${NS}::ImgT$w1 } else { image create photo ${NS}::ImgT$w1 {*}$png -format "png -alpha $alpha" image create photo ${NS}::Img$w1 ${NS}::Img$w1 copy ${NS}::ImgT$w1 {*}$osqueeze $w1 configure -image ${NS}::Img$w1 } if {$w2 ne {}} { if {$alphaev<0.33 && !$ostatic} { set fg [$w1 cget -background] } else { if {[info exists ::apave::_AP_VISITED(FG,$w2)]} { set fg $::apave::_AP_VISITED(FG,$w2) } else { set fg [$w1 cget -foreground] } } $w2 configure -text [lindex $olabel $idx-1] -foreground $fg } after $oafter [list [self] labelFlashing $w1 $w2 0 $ofile $odata $olabel $oincr $opause $oafter $osqueeze $ostatic $idx $incev $waitev $direv] }
Returns a number of leading spaces of a line
| the line |
Returns a number of leading spaces of a line
method leadingSpaces {line} { # Returns a number of leading spaces of a line # line - the line expr {[string length $line]-[string length [string trimleft $line]]} }
Makes the linked label from a label.
| label's path |
| data of the link: command, tip, visited |
| foreground unhovered |
| background unhovered |
| foreground hovered |
| background hovered |
| flag "register the label in the list of visited" optional, default yes |
| flag "invert the meaning of colors" optional, default no |
method makeLabelLinked {lab v fg bg fg2 bg2 {doadd yes} {inv no}} { # Makes the linked label from a label. # lab - label's path # v - data of the link: command, tip, visited # fg - foreground unhovered # bg - background unhovered # fg2 - foreground hovered # bg2 - background hovered # doadd - flag "register the label in the list of visited" # inv - flag "invert the meaning of colors" set txt [$lab cget -text] lassign [split [string map [list $Edge $::apave::UFF] $v] $::apave::UFF] v tt vz set tt [string map [list %l $txt] $tt] set v [string map [list %l $txt %t $tt] $v] if {$tt ne {}} { set tt [my MC $tt] ::baltip tip $lab $tt lappend ::apave::_AP_VARS(TIMW) $lab } if {$inv} { set ft $fg set bt $bg set fg $fg2 set bg $bg2 set fg2 $ft set bg2 $bt } my VisitedLab $lab $v $vz $fg $bg bind $lab <Enter> "::apave::obj EXPORT HoverLab $lab {$v} yes $fg2 $bg2" bind $lab <Leave> "::apave::obj EXPORT HoverLab $lab {$v} no $fg $bg" bind $lab <Button-1> "::apave::obj EXPORT VisitedLab $lab {$v} yes $fg2 $bg2;$v" if {$doadd} {lappend ::apave::_AP_VISITED(ALL) [list $lab $v $inv]} list $fg $bg $fg2 $bg2 }
Makes a popup menu for an editable widget.
| widget's name |
| flag for "is it readonly" optional, default no |
| flag for "is it a text" optional, default no |
| flag for "-tearoff" option; optional, default no |
| additional commands for popup menu; optional, default "" |
| command for "Clear" item; optional, default "" |
method makePopup {w {isRO no} {istext no} {tearoff no} {addpop {}} {clearcom {}}} { # Makes a popup menu for an editable widget. # w - widget's name # isRO - flag for "is it readonly" # istext - flag for "is it a text" # tearoff - flag for "-tearoff" option # addpop - additional commands for popup menu # clearcom - command for "Clear" item set pop $w.popupMenu catch {menu $pop -tearoff $tearoff} $pop delete 0 end if {$isRO || [$w cget -state] eq {disabled}} { $pop add command {*}[my iconA copy] -accelerator Ctrl+C -label Copy -command "event generate $w <<Copy>>" if {$istext} { eval [my popupHighlightCommands $pop $w] after idle [list [self] set_highlight_matches $w] } } else { if {$istext} { ::apave::bindToEvent $w <<Copy>> ::apave::eventOnText $w <<Copy>> ::apave::bindToEvent $w <<Cut>> ::apave::eventOnText $w <<Cut>> $pop add command {*}[my iconA cut] -accelerator Ctrl+X -label Cut -command "event generate $w <<Cut>>" $pop add command {*}[my iconA copy] -accelerator Ctrl+C -label Copy -command "event generate $w <<Copy>>" $pop add command {*}[my iconA paste] -accelerator Ctrl+V -label Paste -command "::apave::eventOnText $w <<Paste>>" $pop add separator $pop add command {*}[my iconA undo] -accelerator Ctrl+Z -label Undo -command "::apave::eventOnText $w <<Undo>>" $pop add command {*}[my iconA redo] -accelerator Ctrl+Shift+Z -label Redo -command "::apave::eventOnText $w <<Redo>>" catch { eval [my popupBlockCommands $pop $w] eval [my popupHighlightCommands $pop $w] if {$addpop ne {}} { lassign $addpop com par1 par2 eval [my $com $pop $w {*}$par1 {*}$par2] } after idle [list [self] set_highlight_matches $w] after idle [my setTextBinds $w] } } else { if {$clearcom ne {}} { $pop add command {*}[my iconA no] -label Clear -command [list [self] clearEntry $w $clearcom] $pop add separator } $pop add command {*}[my iconA cut] -accelerator Ctrl+X -label Cut -command "event generate $w <<Cut>>" $pop add command {*}[my iconA copy] -accelerator Ctrl+C -label Copy -command "event generate $w <<Copy>>" $pop add command {*}[my iconA paste] -accelerator Ctrl+V -label Paste -command "event generate $w <<Paste>>" } } if {$istext} { $pop add separator $pop add command {*}[my iconA none] -accelerator Ctrl+A -label {Select All} -command "$w tag add sel 1.0 end" bind $w <Control-a> "$w tag add sel 1.0 end; break" } bind $w <Button-3> "[self] themePopup $w.popupMenu; tk_popup $w.popupMenu %X %Y" }
Creates a toplevel window that has to be paved.
| window's name |
| window's title |
| options for 'toplevel' command |
If $w
matches "*.fra" then ttk::frame is created with name $w
.
method makeWindow {w ttl args} { # Creates a toplevel window that has to be paved. # w - window's name # ttl - window's title # args - options for 'toplevel' command # If $w matches "*.fra" then ttk::frame is created with name $w. my CleanUps set w [set wtop [string trimright $w .]] set withfr [expr {[set pp [string last . $w]]>0 && [string match *.fra $w]}] if {$withfr} { set wtop [string range $w 0 $pp-1] } catch {destroy $wtop} lassign [::apave::extractOptions args -type {}] type set Modalwin [toplevel $wtop {*}$args] ::apave::withdraw $wtop ;# nice to hide all gui manipulations if {$type ne {} && [tk windowingsystem] eq {x11}} { wm attributes $wtop -type $type } if {$withfr} { pack [frame $w -background [lindex [my csGet] 3]] -expand 1 -fill both } wm title $wtop $ttl return $wtop }
Makes tip(s) for menu and its items.
| menu's path |
| tip's text |
| path to menu's parent (for opc widget); optional, default "" |
The tips for menu items are set by "-indexedtips ?idx tip...?" e.g., a tip can be "parent tip -indexedtips 0 1stItem 9 {10th Item}"
Processes indents and braces at pressing keys.
| text's path |
| key's name |
| key's state; optional, default "" |
method onKeyTextM {w K {s {}}} { # Processes indents and braces at pressing keys. # w - text's path # K - key's name # s - key's state set lindt [string length $::apave::_AP_VARS(INDENT)] switch -exact $K { Return - KP_Enter { # at pressing Enter key, indent (and possibly add the right brace) # but shift/ctrl+Enter acts by default - without indenting if {$s & 1 || $s & 4} return set idx1 [$w index {insert linestart}] set idx2 [$w index {insert lineend}] set line [$w get $idx1 $idx2] set nchars [my leadingSpaces $line] set indent [string range $line 0 $nchars-1] set ch1 [string range $line $nchars $nchars+1] set islist [expr {$ch1 in {{* } {- } {# }}}] set ch2 [string index $line end] set idx1 [$w index insert] set idx2 [$w index "$idx1 +1 line"] set st2 [$w get "$idx2 linestart" "$idx2 lineend"] set ch3 [string index [string trimleft $st2] 0] if {$indent ne {} || $ch2 eq "\{" || $K eq {KP_Enter} || $st2 ne {} || $islist} { set st1 [$w get "$idx1" "$idx1 lineend"] if {[string index $st1 0] in [list \t { }]} { # if space(s) are at the right, remove them at cutting set n1 [my leadingSpaces $st1] $w delete $idx1 [$w index "$idx1 +$n1 char"] } elseif {$ch2 eq "\{" && $st1 eq {}} { # indent + closing brace set nchars2 [my leadingSpaces $st2] if {$st2 eq {} || $nchars>$nchars2 || ($nchars==$nchars2 && $ch3 ne "\}")} { append indent $::apave::_AP_VARS(INDENT) \n $indent "\}" } else { append indent $::apave::_AP_VARS(INDENT) } incr nchars $lindt } elseif {$indent eq {} && $st2 ne {}} { # no indent of previous line, try to get it from the next if {[string trim $st2] eq "\}"} { # add indentation for the next brace set st2 "$::apave::_AP_VARS(INDENT)$st2" } set nchars [my leadingSpaces $st2] set indent [string range $st2 0 [expr {$nchars-1}]] } # a new line supplied with "list-like pattern" if {$islist && ![string match *.0 $idx1] && [string trim [$w get "$idx1 linestart" $idx1]] ne {}} { if {$ch1 eq {# } && int($idx1)>1} { # for comments: if only more than 1 of them, then add another set idx0 [$w index "$idx1 -1 line"] set st0 [string trimleft [$w get "$idx0 linestart" "$idx0 lineend"]] if {[string index $st0 0] ne {#} && $ch3 ne {#}} { set ch1 {} } } set indent "$indent$ch1" incr nchars [string length $ch1] } $w insert $idx1 \n$indent ::tk::TextSetCursor $w [$w index "$idx2 linestart +$nchars char"] return -code break } } braceright { # right brace pressed: shift the brace to left set idx1 [$w index insert] set st [$w get "$idx1 linestart" "$idx1 lineend"] set idx2 [$w index "$idx1 -1 line"] set st2 [$w get "$idx2 linestart" "$idx2 lineend"] set nchars [my leadingSpaces $st] set nchars2 [my leadingSpaces $st2] set st2 [string index $st2 end] if {($st2 ne "\{" && $nchars2<=$nchars || $st2 eq "\{" && $nchars2<$nchars) && [string trimright $st] eq {} && [string length $st]>=$lindt} { if {$nchars>$nchars2} {set lindt [expr {$nchars-$nchars2}]} $w delete "$idx1 lineend -$lindt char" "$idx1 lineend" } } } }
Rids a tk_optionCascade item of braces.
| an item to be trimmed |
Reason: tk_optionCascade items shimmer between 'list' and 'string' so a multiline item is displayed with braces, if not got rid of them.
Returns the item trimmed.
method optionCascadeText {it} { # Rids a tk_optionCascade item of braces. # it - an item to be trimmed # Reason: tk_optionCascade items shimmer between 'list' and 'string' # so a multiline item is displayed with braces, if not got rid of them. # Returns the item trimmed. # See also: tk_optionCascade if {[string match "\{*\}" $it]} { set it [string range $it 1 end-1] } return $it }
Gets a tail (last part) of widget's name
| name (path) of the widget |
method ownWName {name} { # Gets a tail (last part) of widget's name # name - name (path) of the widget lindex [split $name .] end }
Gets parent name of widget.
| name (path) of the widget |
method parentWName {name} { # Gets parent name of widget. # name - name (path) of the widget string range $name 0 [string last . $name]-1 }
Gets the currently paved window's path.
method pavedPath {} { # Gets the currently paved window's path. return $Modalwin }
Gets an option's value.
| option's name |
Returns a value for options like "Moveall".
method paveoptionValue {opt} { # Gets an option's value. # opt - option's name # Returns a value for options like "Moveall". if {$opt in [info object vars [self]]} { variable $opt return [set $opt] } return {} }
Processes "win / list_of_widgets" pairs.
| list of pairs "win / lwidgets" |
The win is a window's path. The lwidgets is a list of widget items. Each widget item contains:
name | widget's name (first 3 characters define its type) |
neighbor | top or left neighbor of the widget |
posofnei | position of neighbor: T (top) or L (left) |
rowspan | row span of the widget |
colspan | column span of the widget |
options | grid/pack options |
attrs | attributes of widget |
First 3 items are mandatory, others are set at need. This method calls paveWindow in a cycle, to process a current "win/lwidgets" pair.
method paveWindow {args} { # Processes "win / list_of_widgets" pairs. # args - list of pairs "win / lwidgets" # The *win* is a window's path. The *lwidgets* is a list of widget items. # Each widget item contains: # name - widget's name (first 3 characters define its type) # neighbor - top or left neighbor of the widget # posofnei - position of neighbor: T (top) or L (left) # rowspan - row span of the widget # colspan - column span of the widget # options - grid/pack options # attrs - attributes of widget # First 3 items are mandatory, others are set at need. # This method calls *paveWindow* in a cycle, to process a current "win/lwidgets" pair. set res [list] set wmain [set wdia {}] foreach {w lwidgets} $args { if {[lindex $lwidgets 0 0] eq {after}} { # if 1st item is "after idle" or like "after 1000", layout the window after... # (fit for "invisible independent" windows/frames/tabs) set what [lindex $lwidgets 0 1] if {$what eq {idle} || [string is integer -strict $what]} { after $what [list [self] paveWindow $w [lrange $lwidgets 1 end]] after $what [list [self] colorWindow $w -doit] } continue } lappend res {*}[my Window $w $lwidgets] if {[set ifnd [regexp -indices -inline {[.]dia\d+} $w]] ne {}} { set wdia [string range $w 0 [lindex $ifnd 0 1]] } else { set wmain .[lindex [split $w .] 1] } } # add a system Menu binding for the created window if {[winfo exists $wdia]} {::apave::initPOP $wdia} elseif { [winfo exists $wmain]} {::apave::initPOP $wmain} return $res }
Switches on/off a widget's readonly state for a text widget.
| text widget's path |
| "on/off" boolean flag; optional, default yes |
| "make popup menu" boolean flag; optional, default yes |
method readonlyWidget {w {on yes} {popup yes}} { # Switches on/off a widget's readonly state for a text widget. # w - text widget's path # on - "on/off" boolean flag # popup - "make popup menu" boolean flag # See also: # [wiki.tcl-lang.org](https://wiki.tcl-lang.org/page/Read-only+text+widget) my TextCommandForChange $w {} $on if {$popup} {my makePopup $w $on yes} }
Gets/sets a variable for vwait command.
| window's path; optional, default "" |
| value of variable; optional, default get |
This method is used when
In the first case, result is set to an integer. In apave dialogs the integer is corresponding a pressed button's index. In the second case, result is omitted or equal to "get".
Returns a value of variable that controls an event cycle.
method res {{win {}} {result get}} { # Gets/sets a variable for *vwait* command. # win - window's path # result - value of variable # This method is used when # - an event cycle should be stopped with changing a variable's value # - a result of event cycle (the variable's value) should be got # In the first case, *result* is set to an integer. In *apave* dialogs # the integer is corresponding a pressed button's index. # In the second case, *result* is omitted or equal to "get". # Returns a value of variable that controls an event cycle. if {$win eq {}} {set win [my dlgPath]} set varname [my WinVarname $win] if {$result eq {get}} { return [set $varname] } my CleanUps $win return [set $varname $result] }
Resets a text widget to edit/view from scratch.
| text widget's name |
| widget's final state (normal/disabled) |
| variable name for contents to be set in the widget; optional, default "" |
method resetText {w state {contsName {}}} { # Resets a text widget to edit/view from scratch. # w - text widget's name # state - widget's final state (normal/disabled) # contsName - variable name for contents to be set in the widget if {$contsName ne {}} { upvar 1 $contsName conts $w replace 1.0 end $conts } $w edit reset $w edit modified no $w configure -state $state }
Retrieves the path where the scrollable contents of frame go.
| frame's path |
| Optional arguments. |
method scrolledFrame {w args} { # Retrieves the path where the scrollable contents of frame go. # w - frame's path lassign [::apave::extractOptions args -toplevel no -anchor center -mode both] tl anc mode ::apave::sframe new $w -toplevel $tl -anchor $anc -mode $mode set path [::apave::sframe content $w] return $path }
Sets / gets a default show option, used in showModal.
| name of option |
| value of option |
method setShowOption {name args} { # Sets / gets a default show option, used in showModal. # name - name of option # args - value of option # See also: showModal ::apave::setProperty [my ShowOption $name] {*}$args }
Returns bindings for a text widget.
| the text's path |
Returns bindings for a text widget.
method setTextBinds {wt} { # Returns bindings for a text widget. # wt - the text's path if {[bind $wt <<Paste>>] eq {}} { set res " ::apave::bindToEvent $wt <<Paste>> [self] pasteText $wt ; ::apave::bindToEvent $wt <KP_Enter> [self] onKeyTextM $wt %K %s ; ::apave::bindToEvent $wt <Return> [self] onKeyTextM $wt %K %s ; catch {::apave::bindToEvent $wt <braceright> [self] onKeyTextM $wt %K}" } foreach k [::apave::getTextHotkeys CtrlD] { append res " ; ::apave::bindToEvent $wt <$k> [self] doubleText $wt" } foreach k [::apave::getTextHotkeys CtrlY] { append res " ; ::apave::bindToEvent $wt <$k> [self] deleteLine $wt" } foreach k [::apave::getTextHotkeys CtrlA] { append res " ; ::apave::bindToEvent $wt <$k> $wt tag add sel 1.0 end {;} break" } foreach k [::apave::getTextHotkeys CtrlT] { append res " ; ::apave::bindToEvent $wt <$k> ::apave::InsertChar $wt {\t} {;} break" } set lstart linestart if {[::isunix]} {append lstart { +1c}} ;# don't use "break" foreach k [::apave::getTextHotkeys CtrlB] { append res " ; ::apave::bindToEvent $wt <$k> ::apave::CursorToBEOL $wt {$lstart}" } foreach k [::apave::getTextHotkeys CtrlE] { append res " ; ::apave::bindToEvent $wt <$k> ::apave::CursorToBEOL $wt lineend" } append res " ; ::apave::bindToEvent $wt <Alt-Up> [self] linesMove $wt -1 ; ::apave::bindToEvent $wt <Alt-Down> [self] linesMove $wt +1" }
Shows a window as modal.
| window's name |
| attributes of window ("-name value" pairs) |
method showModal {win args} { # Shows a window as modal. # win - window's name # args - attributes of window ("-name value" pairs) set ::apave::MODALWINDOW $win ::apave::setAppIcon $win set ontop [my getShowOption -ontop 0] lassign [::apave::extractOptions args -centerme {} -ontop $ontop -modal yes -minsize {} -themed {} -input 0 -variable {} -waitvar {} -transient {-} -root {} -parent {} -waitme {}] centerme ontop modal minsize themed input varname waitvar transient root parent waitme $win configure -bg [lindex [my csGet] 3] ;# removes blinking by default bg if {$themed in {{} {0}} && [my csCurrent] != [apave::cs_Non]} { my colorWindow $win } if {$centerme eq {}} { # obsolete options: -root, -parent if {$root ne {}} {set centerme $root} {set centerme $parent} } set root [winfo parent $win] set rooted 1 if {$centerme ne {}} { ;# forced centering relative to a caller's window lassign [::apave::splitGeometry $centerme] rw rh rx ry set rooted [expr {![regexp {[+|-]+\d+\++} $centerme]}] if {$rooted && [winfo exist $centerme]} { set root $centerme } } set decor [expr {$root in {{} .}}] foreach {o v} [list -decor $decor -focus {} -onclose {} -geometry {} -resizable {} -escape 1 -checkgeometry 1] { set v [my getShowOption $o $v] lappend defargs $o $v set [string range $o 1 end] $v } if {$varname ne {}} { set waitvar 1 } else { set waitvar [string is true $waitvar] ;# default 1: wait for closing the window set varname [my WinVarname $win] } array set opt [list {*}$defargs {*}$args] if {$ontop eq {}} { if {$opt(-ontop)} { set ontop yes } else { set ontop no catch { set ontop [wm attributes [winfo parent $win] -topmost] } if {!$ontop} { # find if a window child of "." is topmost # if so, let this one be topmost too foreach w [winfo children .] { catch {set ontop [wm attributes $w -topmost]} if {$ontop} break } } } } if {$rooted} { lassign [::apave::splitGeometry [wm geometry [winfo toplevel $root]]] rw rh rx ry } if {$transient ne {-}} { wm transient $win $transient } elseif {!$opt(-decor)} { wm transient $win $root } if {[set destroy [expr {$opt(-onclose) eq {destroy}}]]} { set opt(-onclose) {} } if {$opt(-onclose) eq {}} { set opt(-onclose) "set $varname 0" } else { set opt(-onclose) "$opt(-onclose) $varname" ;# $opt(-onclose) is a command set opt(-onclose) [string map [list %w $win] $opt(-onclose)] } if {$destroy} {append opt(-onclose) " ; catch {destroy $win}"} if {$opt(-resizable) ne {}} { if {[string is boolean $opt(-resizable)]} { set opt(-resizable) "$opt(-resizable) $opt(-resizable)" } wm resizable $win {*}$opt(-resizable) } if {!($modal || $waitvar)} { append opt(-onclose) "; ::apave::obj EXPORT CleanUps $win" } foreach ev {KeyRelease ButtonRelease} { after idle [list bind $Modalwin <$ev> "::apave::focusApp $Modalwin"] } if {$modal} {lappend ::apave::FOCUSED $win} wm protocol $win WM_TAKE_FOCUS {after idle ::apave::focusApp} wm protocol $win WM_DELETE_WINDOW $opt(-onclose) # get the window's geometry from its requested sizes set inpgeom $opt(-geometry) if {$inpgeom eq {}} { # this is for less blinking: set opt(-geometry) [my CenteredXY $rw $rh $rx $ry [winfo reqwidth $win] [winfo reqheight $win]] } elseif {[string first pointer $inpgeom]==0} { lassign [split $inpgeom+0+0 +] -> x y set inpgeom +[expr {$x+[winfo pointerx .]}]+[expr {$y+[winfo pointery .]}] set opt(-geometry) $inpgeom } elseif {[string first root $inpgeom]==0} { set root .[string trimleft [string range $inpgeom 5 end] .] set opt(-geometry) [set inpgeom {}] } if {$opt(-geometry) ne {}} { lassign [::apave::splitGeometry $opt(-geometry) {} {}] - - x y if {$x ne {}} {wm geometry $win $x$y} } if {$opt(-focus) eq {}} { set opt(-focus) $win } set $varname {-} if {$opt(-escape)} {bind $win <Escape> $opt(-onclose)} update if {![winfo exists $win]} { return 0 ;# looks idiotic, yet possible at sporadic calls } set w [winfo reqwidth $win] set h [winfo reqheight $win] if {$inpgeom eq {}} { ;# final geometrizing with actual sizes set geo [my CenteredXY $rw $rh $rx $ry $w $h] set y [lindex [split $geo +] end] if {!$rooted || $root ne {.} && (($h/2-$ry-$rh/2)>30 || [::iswindows] && $y>0)} { # ::tk::PlaceWindow needs correcting in rare cases, namely: # when 'root' is of less sizes than 'win' and at screen top wm geometry $win $geo } else { ::tk::PlaceWindow $win widget $root } } else { lassign [::apave::splitGeometry $inpgeom {} {}] - - x y if {$x ne {} && $y ne {} && [string first x $inpgeom]<0 && $opt(-checkgeometry)} { set inpgeom [my checkXY $w $h $x $y] } elseif {$x eq {} && $y eq {} && $centerme ne {} && $opt(-geometry) ne {}} { lassign [split $opt(-geometry) x+] w h lassign [split [my CenteredXY $rw $rh $rx $ry $w $h] +] -> x y set inpgeom ${w}x$h+$x+$y } set inpgeom [::apave::checkGeometry $inpgeom] catch {wm geometry $win $inpgeom} } if {$opt(-focus) eq {Tab}} { after 100 "catch {focus $win; event generate $win <Tab>}" ;# to focus on 1st } else { after 100 "catch {focus -force $opt(-focus); apave::setProperty FOCW_$win $opt(-focus)}" } if {[info exists ::transpops::my::cntwait]} { # this specific bind - for transpops package (to hide a demo message by keys) bind $win <Control-Alt-0> {set ::transpops::my::cntwait 0} } my showWindow $win $modal $ontop $varname $minsize $waitvar $waitme set res 0 catch { if {$modal || $waitvar} {my CleanUps $win} if {[winfo exists $win]} { if {$input} {my GetOutputValues} set res [set [set _ $varname]] } } return $res }
Displays a windows and goes in tkwait cycle to interact with a user.
| the window's path |
| yes at showing the window as modal |
| yes at showing the window as topmost |
| variable's name to receive a result (tkwait's variable); optional, default "" |
| list {minwidth minheight} or {}; optional, default "" |
| if yes, force tkwait variable (mostly for non-modal windows); optional, default 1 |
| if empty, deiconify immediately, otherwise after waiting a variable or "timeout and/or idle" optional, default "" |
method showWindow {win modal ontop {var {}} {minsize {}} {waitvar 1} {waitme {}}} { # Displays a windows and goes in tkwait cycle to interact with a user. # win - the window's path # modal - yes at showing the window as modal # ontop - yes at showing the window as topmost # var - variable's name to receive a result (tkwait's variable) # minsize - list {minwidth minheight} or {} # waitvar - if yes, force tkwait variable (mostly for non-modal windows) # waitme - if empty, deiconify immediately, otherwise after waiting a variable or "timeout and/or idle" ::apave::InfoWindow [expr {[::apave::InfoWindow] + 1}] $win $modal $var yes if {$waitme ne {}} { if {[info exists $waitme]} { vwait $waitme ::apave::deiconify $win catch {incr $waitme} ;# used to trigger chained events } else { after {*}$waitme ::apave::deiconify $win } } else { ::apave::deiconify $win } if {$minsize eq {}} { set minsize [list [winfo width $win] [winfo height $win]] } wm minsize $win {*}$minsize bind $win <Configure> "[namespace current]::WinResize $win" if {$ontop} {wm attributes $win -topmost 1} if {$modal} { # modal window: my waitWinVar $win $var $modal ::apave::InfoWindow [expr {[::apave::InfoWindow] - 1}] $win $modal $var } else { # non-modal window: if {[set wgr [grab current]] ne {}} { # otherwise the non-modal window is irresponsive (in Windows even at WM level): grab release $wgr } if {$waitvar && $var ne {}} { my waitWinVar $win $var $modal ;# show and wait for closing the window } } }
Loads klnd package at need.
| defines which name of package file to be used; optional, default "" |
method sourceKlnd {{num {}}} { # Loads klnd package at need. # num - defines which name of package file to be used if {[info commands ::klnd::calendar$num] eq {}} { # imo, it's more effective to source on request than to require on possibility source [file join $::apave::apaveDir pickers klnd klnd$num.tcl] } }
Gets a label's path of a link in a text widget.
| text's path |
| index of the link |
method textLink {w idx} { # Gets a label's path of a link in a text widget. # w - text's path # idx - index of the link if {[info exists ::apave::__TEXTLINKS__($w)]} { return [lindex $::apave::__TEXTLINKS__($w) $idx] } return {} }
Applies a color scheme to a popup menu.
| name of popup menu |
The method is to be redefined in descendants/mixins.
method themePopup {mnu} { # Applies a color scheme to a popup menu. # mnu - name of popup menu # The method is to be redefined in descendants/mixins. }
Invokes a button's action after a timeout.
| button's path |
| timeout in sec. |
| label widget, where seconds to wait are displayed |
| original text of label; optional, default "" |
method timeoutButton {w tmo lbl {lbltext {}}} { # Invokes a button's action after a timeout. # w - button's path # tmo - timeout in sec. # lbl - label widget, where seconds to wait are displayed # lbltext - original text of label if {$tmo>0} { catch {set lbl [my $lbl]} if {[winfo exist $lbl]} { if {$lbltext eq {}} { set lbltext [$lbl cget -text] lappend ::apave::_AP_VARS(TIMW) $w } $lbl configure -text "$lbltext $tmo sec. " } incr tmo -1 after 1000 [list if "\[info commands [self]\] ne {}" "[self] checkTimeoutButton $w $tmo $lbl {$lbltext}"] return } if {[winfo exist $w]} {$w invoke} }
A bit modified tk_optionCascade widget made by Richard Suchenwirth.
| widget name |
| variable name for current selection |
| list of items |
| ttk::menubutton options (e.g. "-width -4"); optional, default "" |
| command to get entry's options (%a presents its label); optional, default "" |
| additional options of entries |
Returns a path to the widget.
optionCascadeText, wiki.tcl-lang.org
method tk_optionCascade {w vname items {mbopts {}} {precom {}} args} { # A bit modified tk_optionCascade widget made by Richard Suchenwirth. # w - widget name # vname - variable name for current selection # items - list of items # mbopts - ttk::menubutton options (e.g. "-width -4") # precom - command to get entry's options (%a presents its label) # args - additional options of entries # Returns a path to the widget. # See also: # optionCascadeText # [wiki.tcl-lang.org](https://wiki.tcl-lang.org/page/tk_optionCascade) set win $w.m if {![info exists $vname]} { set it [lindex $items 0] while {[llength $it]>1} {set it [lindex $it 0]} set it [my optionCascadeText $it] set $vname $it } lassign [::apave::extractOptions mbopts -tip {} -tooltip {} -com {} -command {}] tip tip2 com com2 if {$tip eq {}} {set tip $tip2} if {$com eq {}} {set com $com2} if {$com ne {}} {lappend args -command $com} ttk::menubutton $w -menu $win -text [set $vname] -style TMenuButtonWest {*}$mbopts menu $win -tearoff 0 my menuTips $win $tip $w my OptionCascade_add $win $vname $items $precom {*}$args trace add variable $vname write "$w config -text \"\[[self] optionCascadeText \${$vname}\]\" ;\#" lappend ::apave::_AP_VARS(_TRACED_$w) $vname ::apave::bindToEvent $w <ButtonPress> focus $w return $win }
Gets default attributes of toolbar button.
| true if textual button |
| image of button |
| bold font |
| foreground |
| background |
| active foreground |
| active background |
method toolbarItem_Attrs {istext img fontB fg bg fga bga} { # Gets default attributes of toolbar button. # istext - true if textual button # img - image of button # fontB - bold font # fg - foreground # bg - background # fga - active foreground # bga - active background if {$istext} { set img "-font {$fontB} -foreground $fg -background $bg -width 2 -pady 0 -padx 2" } else { set img "-image $img -background $bg" } append img " -relief flat -overrelief raised -activeforeground $fga -activebackground $bga -highlightthickness 0 -takefocus 0" }
Displays a current color of color chooser's entry.
| color chooser's label (or apave name's clr1 / Clr1) |
| color chooser's entry; optional, default "" |
Can be called as "validateColorChoice clr1 / Clr1".
method validateColorChoice {lab {ent {}}} { # Displays a current color of color chooser's entry. # lab - color chooser's label (or apave name's clr1 / Clr1) # ent - color chooser's entry # Can be called as "validateColorChoice clr1 / Clr1". if {[string match -nocase clr* $lab]} { set lab [string tolower [string index $lab 0]][string range $lab 1 end] set ent Ent$lab set lab Lab$lab } set ent [my [my ownWName $ent]] set lab [my [my ownWName $lab]] set val [$ent get] catch {$lab configure -background $val} catch {$ent selection clear} return yes }
Tk waiting for variable's change.
| the window's path |
| variable's name to receive a result (tkwait's variable) |
| yes at showing the window as modal |
method waitWinVar {win var modal} { # Tk waiting for variable's change. # win - the window's path # var - variable's name to receive a result (tkwait's variable) # modal - yes at showing the window as modal # first of all, wait till the window be visible after 1 ;# solves an issue with doubleclicking buttons if {![winfo viewable $win]} { tkwait visibility $win } set wmain [::apave::mainWindowOfApp] if {$modal} { ;# for modal, grab the window set wgr [grab current] if {$wmain ne {} && $wmain ne $win} { if {[catch {grab set $win} e]} { catch {tkwait visibility $win} ;# 2nd attempt to get the window visible, by force catch {grab set $win} ;# (not sure, where it can fire, still let it be) puts stderr "\napave::waitWinVar - please send a note to apave developers on this catch. Error: $e" catch {puts stderr "apave::waitWinVar - [info level -1]\n"} } } } # at need, wait till the window associated variable be changed if {$var ne {}} { tkwait variable $var } if {$modal} { ;# for modal, release the grab and restore the old one catch {grab release $win} if {$wgr ne {}} { catch {grab set $wgr} } } }
Gets the widget type based on 3 initial letters of its name. Also fills the grid/pack options and attributes of the widget.
| path to the widget |
| grid/pack options of the widget |
| attribute of the widget |
widget | Tk/Ttk widget name |
options | grid/pack options of the widget |
attrs | attribute of the widget |
nam3 | 3 initial letters of widget's name |
disabled | flag of disabled state |
Returns a list of items:
method widgetType {wnamefull options attrs} { # Gets the widget type based on 3 initial letters of its name. Also # fills the grid/pack options and attributes of the widget. # wnamefull - path to the widget # options - grid/pack options of the widget # attrs - attribute of the widget # Returns a list of items: # widget - Tk/Ttk widget name # options - grid/pack options of the widget # attrs - attribute of the widget # nam3 - 3 initial letters of widget's name # disabled - flag of *disabled* state set disabled [expr {[::apave::getOption -state {*}$attrs] eq {disabled}}] set pack $options set name [my ownWName $wnamefull] if {[info exists ::apave::_AP_VARS(ProSplash,type)] && $::apave::_AP_VARS(ProSplash,type) eq {}} { set val [my progress_Go [incr ::apave::_AP_VARS(ProSplash,curvalue)] {} $name] } set nam3 [string tolower [string index $name 0]][string range $name 1 2] if {[string index $nam3 1] eq "_"} {set k [string range $nam3 0 1]} {set k $nam3} lassign [my defaultATTRS $k] defopts defattrs newtype set options "$defopts $options" set attrs "$defattrs $attrs" switch -glob -- $nam3 { bts { set widget ttk::frame if {![namespace exists ::bartabs]} { source [file join $::apave::SRCDIR bartabs bartabs.tcl] } set attrs "-bartabs {$attrs}" } but { set widget ttk::button my AddButtonIcon $name attrs } buT - btT { set widget button my AddButtonIcon $name attrs } can {set widget canvas} chb {set widget ttk::checkbutton} swi { set widget ttk::checkbutton if {![my apaveTheme]} { set attrs "$attrs -style Switch.TCheckbutton" } } chB {set widget checkbutton} cbx - fco { set widget ttk::combobox if {$nam3 eq {fco}} { ;# file content combobox set attrs [my FCfieldValues $wnamefull $attrs] } set attrs [my FCfieldAttrs $wnamefull $attrs -tvar] } ent {set widget ttk::entry} enT {set widget entry} fil - fiL - fis - fiS - dir - diR - fon - foN - clr - clR - dat - daT - sta - too - fra { # + frame for choosers and bars set widget ttk::frame } frA { set widget frame if {$disabled} {set attrs [::apave::removeOptions $attrs -state]} } ftx {set widget ttk::labelframe} gut {set widget canvas} lab { set widget ttk::label if {$disabled} { set grey [lindex [my csGet] 8] set attrs "-foreground $grey $attrs" } lassign [::apave::parseOptions $attrs -link {} -style {} -font {}] cmd style font if {$cmd ne {}} { set attrs "-linkcom {$cmd} $attrs" set attrs [::apave::removeOptions $attrs -link] } if {$style eq {} && $font eq {}} { set attrs "-font {$::apave::FONTMAIN} $attrs" } elseif {$style ne {}} { # some themes stumble at ttk styles, so bring their attrs directly set attrs [::apave::removeOptions $attrs -style] set attrs "[ttk::style configure $style] $attrs" } } laB {set widget label} lfr {set widget ttk::labelframe} lfR { set widget labelframe if {$disabled} {set attrs [::apave::removeOptions $attrs -state]} } lbx - flb { set widget listbox if {$nam3 eq {flb}} { ;# file content listbox set attrs [my FCfieldValues $wnamefull $attrs] } set attrs "[my FCfieldAttrs $wnamefull $attrs -lvar]" set attrs "[my ListboxesAttrs $wnamefull $attrs]" my AddPopupAttr $wnamefull attrs -entrypop 1 foreach {ev com} {Home {::apave::LbxSelect %w 0} End {::apave::LbxSelect %w end}} { append attrs " -bindEC {<$ev> {$com}} " } } meb {set widget ttk::menubutton} meB {set widget menubutton} nbk { set widget ttk::notebook set attrs "-notebazook {$attrs}" } opc { ;# tk_optionCascade - example of "my method" widget ;# arguments: vname items mbopts precom args set widget {my tk_optionCascade} set imax [expr {min(4,[llength $attrs])}] for {set i 0} {$i<$imax} {incr i} { set atr [lindex $attrs $i] if {$i!=1} { lset attrs $i \{$atr\} } elseif {[llength $atr]==1 && [info exist $atr]} { lset attrs $i [set $atr] ;# items stored in a variable } } } pan {set widget ttk::panedwindow if {[string first -w $attrs]>-1 && [string first -h $attrs]>-1} { # important for panes with fixed (customized) dimensions set attrs "-propagate {$options} $attrs" } } pro {set widget ttk::progressbar} rad {set widget ttk::radiobutton} raD {set widget radiobutton} sca {set widget ttk::scale} scA {set widget scale} sbh {set widget ttk::scrollbar} sbH {set widget scrollbar} sbv {set widget ttk::scrollbar} sbV {set widget scrollbar} scf { if {![namespace exists ::apave::sframe]} { namespace eval ::apave { source [file join $::apave::apaveDir sframe.tcl] } } # scrolledFrame - example of "my method" widget set widget {my scrolledFrame} } seh {set widget ttk::separator} sev {set widget ttk::separator} siz {set widget ttk::sizegrip} spx - spX { if {$nam3 eq {spx}} {set widget ttk::spinbox} {set widget spinbox} lassign [::apave::parseOptions $attrs -command {} -com {} -from {} -to {}] cmd cmd2 from to append cmd $cmd2 lassign [::apave::extractOptions attrs -tip {} -tooltip {}] t1 t2 set t2 "$t1$t2" if {$from ne {} || $to ne {}} { if {$t2 ne {}} {set t2 "\n $t2"} set t2 " $from .. $to $t2" } if {$t2 ne {}} {set t2 "-tip {$t2}"} append attrs " -onReturn {$::apave::UFF{$cmd} {$from} {$to}$::apave::UFF} $t2" } tbl { ;# tablelist if {![namespace exists ::tablelist::]} { namespace eval :: {package require tablelist} } set widget ::tablelist::tablelist set attrs "[my FCfieldAttrs $wnamefull $attrs -lvar]" set attrs "[my ListboxesAttrs $wnamefull $attrs]" } tex {set widget text if {[::apave::getOption -textpop {*}$attrs] eq {}} { my AddPopupAttr $wnamefull attrs -textpop [expr {[::apave::getOption -rotext {*}$attrs] ne {}}] -- disabled } lassign [::apave::parseOptions $attrs -ro {} -readonly {} -rotext {} -gutter {} -gutterwidth 5 -guttershift 6] r1 r2 r3 g1 g2 g3 set b1 [expr [string is boolean -strict $r1]] set b2 [expr [string is boolean -strict $r2]] if {($b1 && $r1) || ($b2 && $r2) || ($r3 ne {} && !($b1 && !$r1) && !($b2 && !$r2))} { set attrs "-takefocus 0 $attrs" } set attrs [::apave::removeOptions $attrs -gutter -gutterwidth -guttershift] if {$g1 ne {}} { set attrs "$attrs -gutter {-canvas $g1 -width $g2 -shift $g3}" } } tre { set widget ttk::treeview set ec [list Home {::apave::TreSelect %w 0} End {::apave::TreSelect %w end}] if {[::isunix]} {lappend ec KP_Enter {event generate %w <Return>}} foreach {ev com} $ec { append attrs " -bindEC {<$ev> {$com}} " } } h_* {set widget ttk::frame} v_* {set widget ttk::frame} default {set widget $newtype} } set attrs [my GetMC $attrs] if {$nam3 in {cbx ent enT fco spx spX}} { # entry-like widgets need their popup menu set clearcom [lindex [::apave::parseOptions $attrs -clearcom -] 0] if {$clearcom eq {-}} { my AddPopupAttr $wnamefull attrs -entrypop 0 readonly disabled } } if {[string first pack [string trimleft $pack]]==0} { catch { # try to expand -after option (if set as WidgetName instead widgetName) if {[set i [lsearch -exact $pack {-after}]]>=0} { set aft [lindex $pack [incr i]] if {[regexp {^[A-Z]} $aft]} { set aft [my $aft] set pack [lreplace $pack $i $i $aft] } } } set options $pack } set options [string trim $options] set attrs [list {*}$attrs] list $widget $options $attrs $nam3 $disabled }
Obsolete version of paveWindow (remains for compatibility).
| Optional arguments. |
method window {args} { # Obsolete version of paveWindow (remains for compatibility). # See also: paveWindow return [uplevel 1 [list [self] paveWindow {*}$args]] }
constructor | Constructor for the class. |
destructor | Destructor for the class. |
abortretrycancel | Shows the ABORTRETRYCANCEL dialog. |
| See ObjectTheming.apaveTheme |
askForSave | For a text, sets/gets "ask for save changes" flag. |
| See ObjectTheming.basicDefFont |
| See ObjectTheming.basicFontSize |
| See ObjectTheming.basicSmallFont |
| See ObjectTheming.basicTextFont |
| See APaveBase.bindGutter |
| See ObjectTheming.boldDefFont |
| See ObjectTheming.boldTextFont |
| See APaveBase.checkTimeoutButton |
| See APaveBase.checkXY |
| See APaveBase.chooser |
| See APaveBase.chooserGeomVars |
| See APaveBase.chooserPath |
| See APaveBase.clearEntry |
| See APaveBase.colorChooser |
| See APaveBase.colorWindow |
| See APaveBase.configure |
| See ObjectTheming.create_Fonts |
| See ObjectTheming.create_FontsType |
| See ObjectTheming.csAdd |
| See ObjectTheming.csCurrent |
| See ObjectTheming.csDark |
| See ObjectTheming.csDeleteExternal |
| See ObjectTheming.csExport |
| See ObjectTheming.csFont |
| See ObjectTheming.csFontDef |
| See ObjectTheming.csFontMono |
| See ObjectTheming.csGet |
| See ObjectTheming.csGetName |
| See ObjectTheming.csMainColors |
| See ObjectTheming.csMapTheme |
| See ObjectTheming.csNewIndex |
| See ObjectTheming.csSet |
| See ObjectTheming.csToned |
| See APaveBase.dateChooser |
| See APaveBase.defaultATTRS |
deleteLine | Deletes a current line of text widget. |
| See APaveBase.displayTaggedText |
| See APaveBase.displayText |
dlgPath | See APaveBase.dlgPath |
doubleText | Doubles a current line or a selection of text widget. |
| See APaveBase.fillGutter |
findInText | Finds a string in text widget. |
| See APaveBase.findWidPath |
| See APaveBase.focusNext |
| See APaveBase.fontChooser |
get_highlighted | Gets a selected word after double-clicking on a text. |
get_HighlightedString | Returns a string got from highlighting by Alt+left/right/q/w. |
| See APaveBase.getShowOption |
| See APaveBase.getTextContent |
| See APaveBase.getWidChildren |
| See APaveBase.gutterContents |
highlight_matches | Highlights matches of selected word in a text. |
highlight_matches_real | Highlights a selected word in a text, esp. fow Windows. Windows thinks a word is edged by spaces only: not in real case. |
| See APaveBase.iconA |
| See APaveBase.initLinkFont |
| See ObjectTheming.initTooltip |
| See APaveBase.labelFlashing |
| See APaveBase.leadingSpaces |
linesMove | Moves a current line or lines of selection up/down. |
| See APaveBase.makeLabelLinked |
| See APaveBase.makePopup |
| See APaveBase.makeWindow |
| See APaveBase.menuTips |
misc | Shows the MISCELLANEOUS dialog. |
ok | Shows the OK dialog. |
okcancel | Shows the OKCANCEL dialog. |
| See APaveBase.onKeyTextM |
| See APaveBase.optionCascadeText |
| See APaveBase.ownWName |
| See APaveBase.parentWName |
pasteText | Removes a selection at pasting. |
| See APaveBase.pavedPath |
| See APaveBase.paveoptionValue |
| See APaveBase.paveWindow |
popupBlockCommands | Returns block commands for a popup menu on a text. |
popupFindCommands | Returns find commands for a popup menu on a text. |
popupHighlightCommands | Returns highlighting commands for a popup menu on a text. |
progress_Begin | Creates and shows a progress window. Fit for splash screens. |
progress_End | Destroys a progress window. |
progress_Go | Updates a progress window. |
| See APaveBase.readonlyWidget |
| See APaveBase.res |
| See APaveBase.resetText |
retrycancel | Shows the RETRYCANCEL dialog. |
| See APaveBase.scrolledFrame |
seek_highlight | Seeks the selected word forward/backward/to first/to last in a text. |
selectedWordText | Returns a word under the cursor or a selected text. |
set_highlight_matches | Creates bindings to highlight matches in a text. |
set_HighlightedString | Saves a string got from highlighting by Alt+left/right/q/w. |
| See APaveBase.setShowOption |
| See APaveBase.setTextBinds |
| See APaveBase.showModal |
| See APaveBase.showWindow |
| See APaveBase.sourceKlnd |
| See APaveBase.textLink |
| See ObjectTheming.thDark |
| See ObjectTheming.themeExternal |
| See ObjectTheming.themeMandatory |
| See ObjectTheming.themeNonThemed |
| See ObjectTheming.themePopup |
| See ObjectTheming.themeWindow |
| See APaveBase.timeoutButton |
| See APaveBase.tk_optionCascade |
| See APaveBase.toolbarItem_Attrs |
| See ObjectTheming.touchWidgets |
unhighlight_matches | Unhighlights matches of selected word in a text. |
| See ObjectTheming.untouchWidgets |
| See APaveBase.validateColorChoice |
varName | Gets a variable name associated with a widget's name of "input" dialogue. |
| See APaveBase.waitWinVar |
| See APaveBase.widgetType |
| See APaveBase.window |
yesno | Shows the YESNO dialog. |
yesnocancel | Shows the YESNOCANCEL dialog. |
Creates APaveDialog object.
| window's name (path); optional, default "" |
| additional arguments |
method constructor {{win {}} args} { # Creates APaveDialog object. # win - window's name (path) # args - additional arguments set Winpath $win ;# dialogs are bound to $win, default "" means . set Dlgpath {} ;# current dialog's path set Foundstr {} ;# current found string set HLstring {} ;# current selected string # Actions on closing the editor ; proc exitEditor {w resExit} { upvar $resExit res set wtxt [my TexM] if {[my askForSave $wtxt] && [$wtxt edit modified]} { set pdlg [::apave::APaveDialog new $w] set r [$pdlg misc warn $::apave::msgarray(savetext) "\n $::apave::msgarray(saveask) \n" [list Save 1 $::apave::msgarray(savenot) Close Cancel 0] 1 -focusback [my TexM] -centerme $w] if {$r==1} { set res 1 } elseif {$r eq "Close"} { set res 0 } $pdlg destroy } else { set res 0 } return } # end of APaveDialog constructor if {[llength [self next]]} { next {*}$args } }
Clears variables used in the object.
method destructor {} { # Clears variables used in the object. if {[llength [self next]]} next }
Shows the ABORTRETRYCANCEL dialog.
| icon |
| title |
| message |
| button to be selected; optional, default RETRY |
| options |
method abortretrycancel {icon ttl msg {defb RETRY} args} { # Shows the *ABORTRETRYCANCEL* dialog. # icon - icon # ttl - title # msg - message # defb - button to be selected # args - options lassign [my PrepArgs {*}$args] args my Query $icon $ttl $msg {ButABORT Abort 1 ButRETRY Retry 2 ButCANCEL Cancel 0} But$defb {} $args }
For a text, sets/gets "ask for save changes" flag.
| text's path |
| flag; optional, default "" |
If the flag argument omitted, returns the flag else sets it.
method askForSave {wtxt {doask {}}} { # For a text, sets/gets "ask for save changes" flag. # wtxt - text's path # doask - flag # If the flag argument omitted, returns the flag else sets it. # See also: constructor set prop _AskForSave_$wtxt if {$doask eq {}} { set res [::apave::getProperty $prop] if {![string is false -strict $res]} {set res 1} } else { set res [::apave::setProperty $prop $doask] } return $res }
Deletes a current line of text widget.
| text's path |
| if true, means "return -code break" optional, default 1 |
The dobreak=true allows to break the Tk processing of keypresses such as Ctrl+Y. If not set, the text widget is identified as my TexM
.
method deleteLine {txt {dobreak 1}} { # Deletes a current line of text widget. # txt - text's path # dobreak - if true, means "return -code break" # The *dobreak=true* allows to break the Tk processing of keypresses # such as Ctrl+Y. # If not set, the text widget is identified as `my TexM`. if {$txt eq {}} {set txt [my TexM]} lassign [my GetLinePosition $txt insert] linestart lineend $txt delete $linestart $lineend if {$dobreak} {return -code break} }
Doubles a current line or a selection of text widget.
| text's path |
| if true, means "return -code break" optional, default 1 |
The dobreak=true allows to break the Tk processing of keypresses such as Ctrl+D. If not set, the text widget is identified as my TexM
.
method doubleText {txt {dobreak 1}} { # Doubles a current line or a selection of text widget. # txt - text's path # dobreak - if true, means "return -code break" # The *dobreak=true* allows to break the Tk processing of keypresses # such as Ctrl+D. # If not set, the text widget is identified as `my TexM`. if {$txt eq {}} {set txt [my TexM]} set err [catch {$txt tag ranges sel} sel] if {!$err && [llength $sel]==2} { lassign $sel pos pos2 set pos3 insert ;# single selection } else { lassign [my GetLinePosition $txt insert] pos pos2 ;# current line set pos3 $pos2 } set duptext [$txt get $pos $pos2] if {$pos3 ne {insert} && $pos2==[$txt index end]} { # current line is the last one: duplicate it properly set duptext \n[string range $duptext 0 end-1] } $txt insert $pos3 $duptext if {$dobreak} {return -code break} }
Finds a string in text widget.
| "1" means 'from a current position'; optional, default 0 |
| path to the text widget; optional, default "" |
| variable; optional, default "" |
| if yes, bells; optional, default yes |
Returns yes, if found (or nothing to find), otherwise returns "no"; also, if there was a real search, the search string is added.
method findInText {{donext 0} {txt {}} {varFind {}} {dobell yes}} { # Finds a string in text widget. # donext - "1" means 'from a current position' # txt - path to the text widget # varFind - variable # dobell - if yes, bells # Returns yes, if found (or nothing to find), otherwise returns "no"; # also, if there was a real search, the search string is added. if {$txt eq {}} { set txt [my TexM] set sel $Foundstr } elseif {$donext && [set sel [my get_HighlightedString]] ne {}} { # find a string got with alt+left/right } elseif {$varFind eq {}} { set sel $Foundstr } else { set sel [set $varFind] } if {$donext} { set pos [$txt index insert] if {{sel} in [$txt tag names $pos]} { set pos [$txt index "$pos + 1 chars"] } set pos [$txt search -- $sel $pos end] } else { set pos {} my set_HighlightedString {} } if {![string length "$pos"]} { set pos [$txt search -- $sel 1.0 end] } if {[string length "$pos"]} { ::tk::TextSetCursor $txt $pos $txt tag add sel $pos [$txt index "$pos + [string length $sel] chars"] focus $txt set res yes } else { if {$dobell} bell set res no } list $res $sel }
Gets a selected word after double-clicking on a text.
| Not documented. |
| path to the text |
method get_highlighted {txt} { # Gets a selected word after double-clicking on a text. # w - path to the text set err [catch {$txt tag ranges sel} sel] lassign $sel pos pos2 if {!$err && [llength $sel]==2} { set sel [$txt get $pos $pos2] ;# single selection } else { if {$err || [string trim $sel] eq {}} { set pos [$txt index "insert wordstart"] set pos2 [$txt index "insert wordend"] set sel [string trim [$txt get $pos $pos2]] if {![string is wordchar -strict $sel]} { # when cursor just at the right of word: take the word at the left # e.g. if "_" stands for cursor then "word_" means selecting "word" set pos [$txt index "insert -1 char wordstart"] set pos2 [$txt index "insert -1 char wordend"] set sel [string trim [$txt get $pos $pos2]] } set slen [string length $sel] if {!$slen} {incr slen; set pos2 [$txt index "$pos2 +1c"]} set pos [$txt index "$pos2 -$slen char"] set sel [string trim [$txt get $pos $pos2]] } } list $sel $pos $pos2 }
Returns a string got from highlighting by Alt+left/right/q/w.
Returns a string got from highlighting by Alt+left/right/q/w.
method get_HighlightedString {} { # Returns a string got from highlighting by Alt+left/right/q/w. if {[info exists HLstring]} { return $HLstring } return {} }
Highlights matches of selected word in a text.
| path to the text |
method highlight_matches {txt} { # Highlights matches of selected word in a text. # txt - path to the text lassign [my get_highlighted $txt] sel pos pos2 if {$sel eq {}} return after idle "[self] highlight_matches_real $txt $pos $pos2" my set_HighlightedString $sel set lenList {} set posList [$txt search -all -count lenList -- "$sel" 1.0 end] foreach pos2 $posList len $lenList { if {$len eq {}} {set len [string length $sel]} set pos3 [$txt index "$pos2 + $len chars"] if {$pos2 == $pos} { lappend matches2 $pos2 $pos3 } else { lappend matches1 $pos2 $pos3 } } catch { $txt tag remove hilited 1.0 end $txt tag remove hilited2 1.0 end $txt tag add hilited {*}$matches1 $txt tag add hilited2 {*}$matches2 } set ::apave::_AP_VARS(HILI,$txt) yes }
Highlights a selected word in a text, esp. fow Windows. Windows thinks a word is edged by spaces only: not in real case.
| path to the text |
| starting position of real selection |
| ending position of real selection |
method highlight_matches_real {txt pos1 pos2} { # Highlights a selected word in a text, esp. fow Windows. # Windows thinks a word is edged by spaces only: not in real case. # txt - path to the text # pos1 - starting position of real selection # pos2 - ending position of real selection $txt tag remove sel 1.0 end if {[$txt get $pos1] eq "\n"} { # if a word at line start, Windows select an empty line above lassign [split $pos1 .] l c set pos1 [incr l].$c } catch {::tk::TextSetCursor $txt $pos1} $txt tag add sel $pos1 $pos2 }
Moves a current line or lines of selection up/down.
| text's path |
| direction (-1 means "up", +1 means "down") |
| if true, means "return -code break" optional, default 1 |
The dobreak=true allows to break the Tk processing of keypresses such as Ctrl+Y. If not set, the text widget is identified as my TexM
.
method linesMove {txt to {dobreak 1}} { # Moves a current line or lines of selection up/down. # txt - text's path # to - direction (-1 means "up", +1 means "down") # dobreak - if true, means "return -code break" # The *dobreak=true* allows to break the Tk processing of keypresses # such as Ctrl+Y. # If not set, the text widget is identified as `my TexM`. ; proc NewRow {ind rn} { set i [string first . $ind] set row [string range $ind 0 $i-1] return [incr row $rn][string range $ind $i end] } if {$txt eq {}} {set txt [my TexM]} set err [catch {$txt tag ranges sel} sel] lassign [$txt index insert] pos ;# position of caret if {[set issel [expr {!$err && [llength $sel]==2}]]} { lassign $sel pos1 pos2 ;# selection's start & end set l1 [expr {int($pos1)}] set l2 [expr {int($pos2)}] set pos21 [$txt index "$pos2 linestart"] if {[$txt get $pos21 $pos2] eq {}} {incr l2 -1} set lfrom [expr {$to>0 ? $l2+1 : $l1-1}] set lto [expr {$to>0 ? $l1-1 : $l2-1}] } else { set lcurr [expr {int($pos)}] set lfrom [expr {$to>0 ? $lcurr+1 : $lcurr-1}] set lto [expr {$to>0 ? $lcurr-1 : $lcurr-1}] } set lend [expr {int([$txt index end])}] if {$lfrom>0 && $lfrom<$lend} { incr lto lassign [my GetLinePosition $txt $lfrom.0] linestart lineend set duptext [$txt get $linestart $lineend] ::apave::undoIn $txt $txt delete $linestart $lineend $txt insert $lto.0 $duptext ::tk::TextSetCursor $txt [NewRow $pos $to] if {$issel} { $txt tag add sel [NewRow $pos1 $to] [NewRow $pos2 $to] } if {[lsearch -glob [$txt tag names] tagCOM*]>-1} { catch {::hl_tcl::my::Modified $txt insert $lto.0 $lto.end} } ::apave::undoOut $txt if {$dobreak} {return -code break} } }
Shows the MISCELLANEOUS dialog.
| icon |
| title |
| message |
| list of buttons |
| button to be selected; optional, default "" |
| options |
The butts is a list of pairs "title of button" "number/ID of button"
method misc {icon ttl msg butts {defb {}} args} { # Shows the *MISCELLANEOUS* dialog. # icon - icon # ttl - title # msg - message # butts - list of buttons # defb - button to be selected # args - options # The *butts* is a list of pairs "title of button" "number/ID of button" foreach {nam num} $butts { set but But[namespace tail $num] ;# for "num" set as a command lappend apave_msc_bttns $but "$nam" $num if {$defb eq {}} { set defb $num } } lassign [my PrepArgs {*}$args] args my Query $icon $ttl $msg $apave_msc_bttns But$defb {} $args }
Shows the OK dialog.
| icon |
| title |
| message |
| options |
method ok {icon ttl msg args} { # Shows the *OK* dialog. # icon - icon # ttl - title # msg - message # args - options lassign [my PrepArgs {*}$args] args comOK my Query $icon $ttl $msg "ButOK OK $comOK" ButOK {} $args }
Shows the OKCANCEL dialog.
| icon |
| title |
| message |
| button to be selected; optional, default OK |
| options |
method okcancel {icon ttl msg {defb OK} args} { # Shows the *OKCANCEL* dialog. # icon - icon # ttl - title # msg - message # defb - button to be selected # args - options lassign [my PrepArgs {*}$args] args my Query $icon $ttl $msg {ButOK OK 1 ButCANCEL Cancel 0} But$defb {} $args }
Removes a selection at pasting.
| text's path |
The absence of this feature is very perpendicular of Tk's paste.
method pasteText {txt} { # Removes a selection at pasting. # txt - text's path # The absence of this feature is very perpendicular of Tk's paste. set err [catch {$txt tag ranges sel} sel] if {!$err && [llength $sel]==2} { lassign $sel pos1 pos2 set pos [$txt index insert] if {[$txt compare $pos >= $pos1] && [$txt compare $pos <= $pos2]} { $txt delete $pos1 $pos2 } } }
Returns block commands for a popup menu on a text.
| path to the menu |
| path to the text; optional, default "" |
Returns block commands for a popup menu on a text.
method popupBlockCommands {pop {txt {}}} { # Returns block commands for a popup menu on a text. # pop - path to the menu # txt - path to the text set accD [::apave::KeyAccelerator [::apave::getTextHotkeys CtrlD]] set accY [::apave::KeyAccelerator [::apave::getTextHotkeys CtrlY]] return "\$pop add separator \$pop add command [my iconA add] -accelerator $accD -label \"Double Selection\" \\ -command \"[self] doubleText {$txt} 0\" \$pop add command [my iconA delete] -accelerator $accY -label \"Delete Line\" \\ -command \"[self] deleteLine {$txt} 0\" \$pop add command [my iconA up] -accelerator Alt+Up -label \"Line(s) Up\" \\ -command \"[self] linesMove {$txt} -1 0\" \$pop add command [my iconA down] -accelerator Alt+Down -label \"Line(s) Down\" \\ -command \"[self] linesMove {$txt} +1 0\"" }
Returns find commands for a popup menu on a text.
| path to the menu |
| path to the text; optional, default "" |
| user's command "find first" optional, default "" |
| user's command "find next" optional, default "" |
Returns find commands for a popup menu on a text.
method popupFindCommands {pop {txt {}} {com1 {}} {com2 {}}} { # Returns find commands for a popup menu on a text. # pop - path to the menu # txt - path to the text # com1 - user's command "find first" # com2 - user's command "find next" set accF3 [::apave::KeyAccelerator [::apave::getTextHotkeys F3]] if {$com1 eq {}} {set com1 "[self] InitFindInText 0 $txt; focus \[[self] Entfind\]"} if {$com2 eq {}} {set com2 "[self] findInText 1 $txt"} return "\$pop add separator \$pop add command [my iconA find] -accelerator Ctrl+F -label \"Find First\" \\ -command {$com1} \$pop add command [my iconA none] -accelerator $accF3 -label \"Find Next\" \\ -command {$com2}" }
Returns highlighting commands for a popup menu on a text.
| path to the menu; optional, default "" |
| path to the text; optional, default "" |
Returns highlighting commands for a popup menu on a text.
method popupHighlightCommands {{pop {}} {txt {}}} { # Returns highlighting commands for a popup menu on a text. # pop - path to the menu # txt - path to the text set accQ [::apave::KeyAccelerator [::apave::getTextHotkeys AltQ]] set accW [::apave::KeyAccelerator [::apave::getTextHotkeys AltW]] set res "\$pop add separator \$pop add command [my iconA upload] -accelerator $accQ \\ -label \"Highlight First\" -command \"[self] seek_highlight %w 2\" \$pop add command [my iconA download] -accelerator $accW \\ -label \"Highlight Last\" -command \"[self] seek_highlight %w 3\" \$pop add command [my iconA previous] -accelerator Alt+Left \\ -label \"Highlight Previous\" -command \"[self] seek_highlight %w 0\" \$pop add command [my iconA next] -accelerator Alt+Right \\ -label \"Highlight Next\" -command \"[self] seek_highlight %w 1\" \$pop add command [my iconA none] -accelerator Dbl.Click \\ -label \"Highlight All\" -command \"[self] highlight_matches %w\"" if {$txt ne {}} {set res [string map [list %w $txt] $res]} return $res }
Creates and shows a progress window. Fit for splash screens.
| any word(s) |
| parent window |
| title message |
| top message |
| bottom message |
| maximum value |
| additional attributes of the progress bar |
If type={}, widgetType method participates too in progress_Go, and also progress_End puts out a little statistics.
APaveBase::widgetType, progress_Go, progress_End
method progress_Begin {type wprn ttl msg1 msg2 maxvalue args} { # Creates and shows a progress window. Fit for splash screens. # type - any word(s) # wprn - parent window # ttl - title message # msg1 - top message # msg2 - bottom message # maxvalue - maximum value # args - additional attributes of the progress bar # If type={}, widgetType method participates too in progress_Go, and also # progress_End puts out a little statistics. # See also: APaveBase::widgetType, progress_Go, progress_End set ::apave::_AP_VARS(win) .proSplashScreen set qdlg $::apave::_AP_VARS(win) set atr1 "-maximum 100 -value 0 -mode determinate -length 300 -orient horizontal" set widlist [list "fra - - - - pack {-h 10}" ".Lab1SplashScreen - - - - pack {-t {$msg1}}" ".ProgSplashScreen - - - - pack {$atr1 $args}" ".Lab2SplashScreen - - - - {pack -anchor w} {-t {$msg2}}" ] set win [my makeWindow $qdlg.fra $ttl] set widlist [my paveWindow $qdlg.fra $widlist] ::tk::PlaceWindow $win widget $wprn my showWindow $win 0 1 update set ::apave::_AP_VARS(ProSplash,type) $type set ::apave::_AP_VARS(ProSplash,win) $win set ::apave::_AP_VARS(ProSplash,wid1) [my Lab1SplashScreen] set ::apave::_AP_VARS(ProSplash,wid2) [my ProgSplashScreen] set ::apave::_AP_VARS(ProSplash,wid3) [my Lab2SplashScreen] set ::apave::_AP_VARS(ProSplash,val1) 0 set ::apave::_AP_VARS(ProSplash,val2) 0 set ::apave::_AP_VARS(ProSplash,value) 0 set ::apave::_AP_VARS(ProSplash,curvalue) 0 set ::apave::_AP_VARS(ProSplash,maxvalue) $maxvalue set ::apave::_AP_VARS(ProSplash,after) [list] # 'after' should be postponed, as 'update' messes it up rename ::after ::ProSplash_after ; proc ::after {args} { lappend ::apave::_AP_VARS(ProSplash,after) $args } }
Destroys a progress window.
method progress_End {} { # Destroys a progress window. # See also: progress_Begin variable ::apave::_AP_VARS catch { destroy $::apave::_AP_VARS(ProSplash,win) rename ::after {} rename ::ProSplash_after ::after foreach aftargs $::apave::_AP_VARS(ProSplash,after) { after {*}$aftargs } if {$::apave::_AP_VARS(ProSplash,type) eq {}} { puts "Splash statistics: \n \"maxvalue\": $::apave::_AP_VARS(ProSplash,maxvalue) \n curr.value: $::apave::_AP_VARS(ProSplash,val1) \n steps made: $::apave::_AP_VARS(ProSplash,val2)" } unset ::apave::_AP_VARS(ProSplash,type) unset ::apave::_AP_VARS(ProSplash,win) unset ::apave::_AP_VARS(ProSplash,wid1) unset ::apave::_AP_VARS(ProSplash,wid2) unset ::apave::_AP_VARS(ProSplash,wid3) unset ::apave::_AP_VARS(ProSplash,val1) unset ::apave::_AP_VARS(ProSplash,val2) unset ::apave::_AP_VARS(ProSplash,value) unset ::apave::_AP_VARS(ProSplash,curvalue) unset ::apave::_AP_VARS(ProSplash,maxvalue) unset ::apave::_AP_VARS(ProSplash,after) } }
Updates a progress window.
| current value of the progress bar |
| top message; optional, default "" |
| bottom message; optional, default "" |
Returns current percents (value) of progress. If it reaches 100, the progress_Go may continue from 0.
method progress_Go {value {msg1 {}} {msg2 {}}} { # Updates a progress window. # value - current value of the progress bar # msg1 - top message # msg2 - bottom message # Returns current percents (value) of progress. # If it reaches 100, the progress_Go may continue from 0. # See also: progress_Begin set ::apave::_AP_VARS(ProSplash,val1) $value incr ::apave::_AP_VARS(ProSplash,val2) set val [expr {min(100,int(100*$value/$::apave::_AP_VARS(ProSplash,maxvalue)))}] if {$val!=$::apave::_AP_VARS(ProSplash,value)} { set ::apave::_AP_VARS(ProSplash,value) $val catch { ;# there might be no splash widgets, then let it run dry $::apave::_AP_VARS(ProSplash,wid2) configure -value $val if {$msg1 ne {}} { $::apave::_AP_VARS(ProSplash,wid1) configure -text $msg1 } if {$msg2 ne {}} { $::apave::_AP_VARS(ProSplash,wid3) configure -text $msg2 } update } } return $val }
Shows the RETRYCANCEL dialog.
| icon |
| title |
| message |
| button to be selected; optional, default RETRY |
| options |
method retrycancel {icon ttl msg {defb RETRY} args} { # Shows the *RETRYCANCEL* dialog. # icon - icon # ttl - title # msg - message # defb - button to be selected # args - options lassign [my PrepArgs {*}$args] args my Query $icon $ttl $msg {ButRETRY Retry 1 ButCANCEL Cancel 0} But$defb {} $args }
Seeks the selected word forward/backward/to first/to last in a text.
| Not documented. |
| 0 (search backward), 1 (forward), 2 (first), 3 (last) |
| path to the text |
method seek_highlight {txt mode} { # Seeks the selected word forward/backward/to first/to last in a text. # w - path to the text # mode - 0 (search backward), 1 (forward), 2 (first), 3 (last) my unhighlight_matches $txt lassign [my get_highlighted $txt] sel pos pos2 if {$sel eq {}} return my set_HighlightedString $sel switch $mode { 0 { ;# backward set nc [expr {[string length $sel] - 1}] set pos [$txt index "$pos - $nc chars"] set pos [$txt search -backwards -- $sel $pos 1.0] } 1 { ;# forward set pos [$txt search -- $sel $pos2 end] } 2 { ;# to first set pos [$txt search -- $sel 1.0 end] } 3 { ;# to last set pos [$txt search -backwards -- $sel end 1.0] } } if {[string length "$pos"]} { ::tk::TextSetCursor $txt $pos $txt tag add sel $pos [$txt index "$pos + [string length $sel] chars"] } }
Returns a word under the cursor or a selected text.
| the text's path |
Returns a word under the cursor or a selected text.
method selectedWordText {txt} { # Returns a word under the cursor or a selected text. # txt - the text's path set seltxt {} if {![catch {$txt tag ranges sel} seltxt]} { if {[set forword [expr {$seltxt eq {}}]]} { set pos [$txt index "insert wordstart"] set pos2 [$txt index "insert wordend"] set seltxt [string trim [$txt get $pos $pos2]] if {![string is wordchar -strict $seltxt]} { # when cursor just at the right of word: take the word at the left set pos [$txt index "insert -1 char wordstart"] set pos2 [$txt index "insert -1 char wordend"] } } else { lassign $seltxt pos pos2 } catch { set seltxt [$txt get $pos $pos2] if {[set sttrim [string trim $seltxt]] ne {}} { if {$forword} {set seltxt $sttrim} } } } return $seltxt }
Creates bindings to highlight matches in a text.
| path to the text |
method set_highlight_matches {w} { # Creates bindings to highlight matches in a text. # w - path to the text if {![winfo exists $w]} return $w tag configure hilited -foreground #1f0000 -background #ffa073 $w tag configure hilited2 -foreground #1f0000 -background #ff6b85 $w tag lower hilited sel bind $w <Double-ButtonPress-1> [list [self] highlight_matches $w] ::apave::bindToEvent $w <KeyRelease> [self] unhighlight_matches $w bind $w <Alt-Left> "[self] seek_highlight $w 0 ; break" bind $w <Alt-Right> "[self] seek_highlight $w 1 ; break" foreach k [::apave::getTextHotkeys AltQ] { bind $w <$k> [list [self] seek_highlight $w 2] } foreach k [::apave::getTextHotkeys AltW] { bind $w <$k> [list [self] seek_highlight $w 3] } }
Saves a string got from highlighting by Alt+left/right/q/w.
| the string to be saved |
method set_HighlightedString {sel} { # Saves a string got from highlighting by Alt+left/right/q/w. # sel - the string to be saved set HLstring $sel if {$sel ne {}} {set Foundstr $sel} }
Unhighlights matches of selected word in a text.
| Not documented. |
| path to the text |
method unhighlight_matches {txt} { # Unhighlights matches of selected word in a text. # w - path to the text if {[info exists ::apave::_AP_VARS(HILI,$txt)] && $::apave::_AP_VARS(HILI,$txt)} { $txt tag remove hilited 1.0 end $txt tag remove hilited2 1.0 end set ::apave::_AP_VARS(HILI,$txt) no } }
Gets a variable name associated with a widget's name of "input" dialogue.
| widget's name |
method varName {wname} { # Gets a variable name associated with a widget's name of "input" dialogue. # wname - widget's name return [namespace current]::var$wname }
Shows the YESNO dialog.
| icon |
| title |
| message |
| button to be selected; optional, default YES |
| options |
method yesno {icon ttl msg {defb YES} args} { # Shows the *YESNO* dialog. # icon - icon # ttl - title # msg - message # defb - button to be selected # args - options lassign [my PrepArgs {*}$args] args my Query $icon $ttl $msg {ButYES Yes 1 ButNO No 0} But$defb {} $args }
Shows the YESNOCANCEL dialog.
| icon |
| title |
| message |
| button to be selected; optional, default YES |
| options |
method yesnocancel {icon ttl msg {defb YES} args} { # Shows the *YESNOCANCEL* dialog. # icon - icon # ttl - title # msg - message # defb - button to be selected # args - options lassign [my PrepArgs {*}$args] args my Query $icon $ttl $msg {ButYES Yes 1 ButNO No 2 ButCANCEL Cancel 0} But$defb {} $args }
constructor | Constructor for the class. |
destructor | Destructor for the class. |
getProperty | Gets an property's value as "object-wide". |
setProperty | Sets a property's value as "object-wide". |
| Optional arguments. |
method constructor {args} { array set _OP_Properties {} # ObjectProperty can play solo or be a mixin if {[llength [self next]]} { next {*}$args } }
method destructor {} { array unset _OP_Properties * if {[llength [self next]]} next }
Gets an property's value as "object-wide".
| name of property |
| default value; optional, default "" |
If the property had been set, the method returns its value. Otherwise, the method returns the default value ($defvalue
).
method getProperty {name {defvalue {}}} { # Gets an property's value as "object-wide". # name - name of property # defvalue - default value # If the property had been set, the method returns its value. # Otherwise, the method returns the default value (`$defvalue`). if {[info exists _OP_Properties($name)]} { return $_OP_Properties($name) } return $defvalue }
Sets a property's value as "object-wide".
| name of property |
| value of property |
If args is omitted, the method returns a property's value. If args is set, the method sets a property's value as $args
.
method setProperty {name args} { # Sets a property's value as "object-wide". # name - name of property # args - value of property # If *args* is omitted, the method returns a property's value. # If *args* is set, the method sets a property's value as $args. switch -exact [llength $args] { 0 {return [my getProperty $name]} 1 {return [set _OP_Properties($name) [lindex $args 0]]} } puts -nonewline stderr "Wrong # args: should be \"[namespace current] setProperty propertyname ?value?\"" return -code error }
constructor | Constructor for the class. |
destructor | Destructor for the class. |
apaveTheme | Checks if apave color scheme is used (always for standard ttk themes). |
basicDefFont | Gets/Sets a basic default font. |
basicFontSize | Gets/Sets a basic size of font used in apave |
basicSmallFont | Gets/Sets a basic small font used in status bar etc. |
basicTextFont | Gets/Sets a basic font used in editing/viewing text widget. |
boldDefFont | Returns a bold default font. |
boldTextFont | Returns a bold fixed font. |
create_Fonts | Creates fonts used in apave. |
create_FontsType | Creates fonts used in apave, with additional options. |
csAdd | Registers new color scheme in the list of CS. |
csCurrent | Gets an index of current color scheme |
csDark | Returns a flag "a color scheme is dark" |
csDeleteExternal | Removes all external CS. |
csExport | TODO |
csFont | Returns attributes of CS font. |
csFontDef | Returns attributes of CS default font. |
csFontMono | Returns attributes of CS monotype font. |
csGet | Gets a color scheme's colors |
csGetName | Gets a color scheme's name |
csMainColors | Returns a list of main colors' indices of CS. |
csMapTheme | Returns a map of CS / themeWindow method colors. The map is a list of indices in CS corresponding to themeWindow's args. |
csNewIndex | Gets a next available CS's index. |
csSet | Sets a color scheme and applies it to Tk/Ttk widgets. |
csToned | Make an external CS that has tones (hues) of colors for a CS. |
initTooltip | Configurates colors and other attributes of tooltip. |
thDark | Checks if a theme is dark, light or neutral. |
themeExternal | Configures an external dialogue so that its colors accord with a current CS. |
themeMandatory | Themes all that must be themed. |
themeNonThemed | Updates the appearances of currently used widgets (non-themed). |
themePopup | Configures a popup menu so that its colors accord with a current CS. |
themeWindow | Changes a Tk style (theming a bit) |
touchWidgets | Makes non-ttk widgets to be touched again. |
untouchWidgets | Makes non-ttk widgets to be untouched by coloring or gets their list. |
| Optional arguments. |
method constructor {args} { my InitCS # ObjectTheming can play solo or be a mixin if {[llength [self next]]} { next {*}$args } }
method destructor {} { if {[llength [self next]]} next }
Checks if apave color scheme is used (always for standard ttk themes).
| a theme to be checked (if omitted, a current ttk theme); optional, default "" |
method apaveTheme {{theme {}}} { # Checks if apave color scheme is used (always for standard ttk themes). # theme - a theme to be checked (if omitted, a current ttk theme) if {$theme eq {}} {set theme [ttk::style theme use]} expr {$theme in {clam alt classic default awdark awlight plastik}} }
Gets/Sets a basic default font.
| font; optional, default "" |
If 'deffont' is omitted or =="", this method gets it. If 'deffont' is set, this method sets it.
method basicDefFont {{deffont {}}} { # Gets/Sets a basic default font. # deffont - font # If 'deffont' is omitted or =="", this method gets it. # If 'deffont' is set, this method sets it. if {$deffont ne ""} { return [set ::apave::_CS_(defFont) $deffont] } else { return $::apave::_CS_(defFont) } }
Gets/Sets a basic size of font used in apave
| font size; optional, default 0 |
| incr/decr of size; optional, default 0 |
If 'fs' is omitted or ==0, this method gets it. If 'fs' >0, this method sets it.
method basicFontSize {{fs 0} {ds 0}} { # Gets/Sets a basic size of font used in apave # fs - font size # ds - incr/decr of size # If 'fs' is omitted or ==0, this method gets it. # If 'fs' >0, this method sets it. if {$fs} { set ::apave::_CS_(fs) [expr {$fs + $ds}] my create_Fonts return $::apave::_CS_(fs) } else { return [expr {$::apave::_CS_(fs) + $ds}] } }
Gets/Sets a basic small font used in status bar etc.
| font; optional, default "" |
If 'smallfont' is omitted or =="", this method gets it. If 'smallfont' is set, this method sets it.
method basicSmallFont {{smallfont {}}} { # Gets/Sets a basic small font used in status bar etc. # smallfont - font # If 'smallfont' is omitted or =="", this method gets it. # If 'smallfont' is set, this method sets it. if {$smallfont ne ""} { return [set ::apave::_CS_(smallFont) $smallfont] } else { return $::apave::_CS_(smallFont) } }
Gets/Sets a basic font used in editing/viewing text widget.
| font; optional, default "" |
If 'textfont' is omitted or =="", this method gets it. If 'textfont' is set, this method sets it.
method basicTextFont {{textfont {}}} { # Gets/Sets a basic font used in editing/viewing text widget. # textfont - font # If 'textfont' is omitted or =="", this method gets it. # If 'textfont' is set, this method sets it. if {$textfont ne ""} { return [set ::apave::_CS_(textFont) $textfont] } else { return $::apave::_CS_(textFont) } }
Returns a bold default font.
| font size; optional, default 0 |
Returns a bold default font.
method boldDefFont {{fs 0}} { # Returns a bold default font. # fs - font size if {$fs == 0} {set fs [my basicFontSize]} set bf [font actual basicDefFont] dict replace $bf -family [my basicDefFont] -weight bold -size $fs }
Returns a bold fixed font.
| font size; optional, default 0 |
Returns a bold fixed font.
method boldTextFont {{fs 0}} { # Returns a bold fixed font. # fs - font size if {$fs == 0} {set fs [expr {2+[my basicFontSize]}]} set bf [font actual TkFixedFont] dict replace $bf -family [my basicTextFont] -weight bold -size $fs }
Creates fonts used in apave.
method create_Fonts {} { # Creates fonts used in apave. catch {font delete apaveFontMono} catch {font delete apaveFontDef} catch {font delete apaveFontMonoBold} catch {font delete apaveFontDefBold} font create apaveFontMono -family $::apave::_CS_(textFont) -size $::apave::_CS_(fs) font create apaveFontDef -family $::apave::_CS_(defFont) -size $::apave::_CS_(fs) font create apaveFontMonoBold {*}[my boldTextFont] font create apaveFontDefBold {*}[my boldDefFont] set ::apave::FONTMAIN "[font actual apaveFontDef]" set ::apave::FONTMAINBOLD "[font actual apaveFontDefBold]" }
Creates fonts used in apave, with additional options.
| type of the created fonts |
| pairs "option value" |
Returns a list of two created font names (default & mono).
method create_FontsType {type args} { # Creates fonts used in apave, with additional options. # type - type of the created fonts # args - pairs "option value" # Returns a list of two created font names (default & mono). set name1 apaveFontDefTyped$type set name2 apaveFontMonoTyped$type catch {font delete $name1} catch {font delete $name2} font create $name1 -family $::apave::_CS_(defFont) -size $::apave::_CS_(fs) {*}$args font create $name2 -family $::apave::_CS_(textFont) -size $::apave::_CS_(fs) {*}$args list $name1 $name2 }
Registers new color scheme in the list of CS.
| CS item |
| if true, sets the CS as current; optional, default true |
Does not register the CS, if it is already registered.
Returns an index of current CS.
method csAdd {newcs {setnew true}} { # Registers new color scheme in the list of CS. # newcs - CS item # setnew - if true, sets the CS as current # Does not register the CS, if it is already registered. # Returns an index of current CS. # See also: themeWindow if {[llength $newcs]<4} { set newcs [my ColorScheme] ;# CS should be defined } lassign $newcs name tfg2 tfg1 tbg2 tbg1 tfhh - - tcur grey bclr set found $::apave::_CS_(NONCS) set maxcs [::apave::cs_Max] for {set i $::apave::_CS_(MINCS)} {$i<=$maxcs} {incr i} { lassign [my csGet $i] cfg2 cfg1 cbg2 cbg1 cfhh - - ccur if {$cfg2 eq $tfg2 && $cfg1 eq $tfg1 && $cbg2 eq $tbg2 && $cbg1 eq $tbg1 && $cfhh eq $tfhh && $ccur eq $tcur} { set found $i break } } if {$found == $::apave::_CS_(MINCS) && [my csCurrent] == $::apave::_CS_(NONCS)} { set setnew false ;# no moves from default CS to 'basic' } elseif {$found == $::apave::_CS_(NONCS)} { lappend ::apave::_CS_(ALL) $newcs set found [expr {$maxcs+1}] } if {$setnew} {set ::apave::_CS_(index) [set ::apave::_CS_(old) $found]} my csCurrent }
Gets an index of current color scheme
method csCurrent {} { # Gets an index of current color scheme return $::apave::_CS_(index) }
Returns a flag "a color scheme is dark"
| the color scheme to be checked (the current one, if not set); optional, default "" |
Returns a flag "a color scheme is dark"
method csDark {{cs {}}} { # Returns a flag "a color scheme is dark" # cs - the color scheme to be checked (the current one, if not set) if {$cs eq {} || $cs==-3} {set cs [my csCurrent]} lassign $::apave::_CS_(TONED) csbasic cstoned if {$cs==$cstoned} {set cs $csbasic} expr {$cs>22} }
Removes all external CS.
method csDeleteExternal {} { # Removes all external CS. set ::apave::_CS_(ALL) [lreplace $::apave::_CS_(ALL) 48 end] }
TODO
method csExport {} { # TODO set theme "" foreach arg {tfg1 tbg1 tfg2 tbg2 tfgS tbgS tfgD tbgD tcur bclr args} { if {[catch {set a "$::apave::_CS_(expo,$arg)"}] || $a==""} { break } append theme " $a" } return $theme }
Returns attributes of CS font.
| Not documented. |
Returns attributes of CS font.
method csFont {fontname} { # Returns attributes of CS font. if {[catch {set font [font configure $fontname]}]} { my create_Fonts set font [font configure $fontname] } return $font }
Returns attributes of CS default font.
Returns attributes of CS default font.
method csFontDef {} { # Returns attributes of CS default font. my csFont apaveFontDef }
Returns attributes of CS monotype font.
Returns attributes of CS monotype font.
method csFontMono {} { # Returns attributes of CS monotype font. my csFont apaveFontMono }
Gets a color scheme's colors
| index of color scheme; optional, default "" |
method csGet {{ncolor {}}} { # Gets a color scheme's colors # ncolor - index of color scheme if {$ncolor eq ""} {set ncolor [my csCurrent]} lrange [my ColorScheme $ncolor] 1 end }
Gets a color scheme's name
| index of color scheme; optional, default 0 |
method csGetName {{ncolor 0}} { # Gets a color scheme's name # ncolor - index of color scheme if {$ncolor < $::apave::_CS_(MINCS)} { return "-2: None" } elseif {$ncolor == $::apave::_CS_(MINCS)} { return "-1: Basic" } lindex [my ColorScheme $ncolor] 0 }
Returns a list of main colors' indices of CS.
Returns a list of main colors' indices of CS.
method csMainColors {} { # Returns a list of main colors' indices of CS. # See also: csMapTheme list 0 1 2 3 5 10 11 13 16 }
Returns a map of CS / themeWindow method colors. The map is a list of indices in CS corresponding to themeWindow's args.
Returns a map of CS / themeWindow method colors. The map is a list of indices in CS corresponding to themeWindow's args.
method csMapTheme {} { # Returns a map of CS / themeWindow method colors. # The map is a list of indices in CS corresponding to themeWindow's args. # See also: themeWindow list 1 3 0 2 6 5 8 3 7 9 4 10 11 1 13 14 15 16 17 18 19 20 21 }
Gets a next available CS's index.
method csNewIndex {} { # Gets a next available CS's index. expr {[::apave::cs_Max]+1} }
Sets a color scheme and applies it to Tk/Ttk widgets.
| index of color scheme; optional, default 0 |
| window's name; optional, default . |
| list of colors if ncolor="" |
The args
can be set as "-doit". In this case the method does set the ncolor
color scheme (otherwise it doesn't set the CS if it's already of the same ncolor
).
method csSet {{ncolor 0} {win .} args} { # Sets a color scheme and applies it to Tk/Ttk widgets. # ncolor - index of color scheme # win - window's name # args - list of colors if ncolor="" # # The `args` can be set as "-doit". In this case the method does set # the `ncolor` color scheme (otherwise it doesn't set the CS if it's # already of the same `ncolor`). # The clrtitf, clrinaf etc. had been designed for e_menu. And as such, # they can be used directly, outside of this "color scheming" UI. # They set pairs of related fb/bg: # clrtitf/clrtitb is item's fg/bg # clrinaf/clrinab is main fg/bg # clractf/clractb is active (selection) fg/bg # and separate colors: # clrhelp is "help" foreground # clrcurs is "caret" background # clrgrey is "shadowing" background # clrhotk is "hotkey/border" foreground # # In color scheming, these colors are transformed to be consistent # with Tk/Ttk's color mechanics. # # Additionally, "grey" color is used as "border color/disabled foreground". # # Returns a list of colors used by the color scheme. if {$ncolor == -2} { ttk::style map Treeview -foreground [list readonly grey disabled grey selected black] return {} } if {$ncolor eq {}} { lassign $args clrtitf clrinaf clrtitb clrinab clrhelp clractb clractf clrcurs clrgrey clrhotk tfgI tbgI fM bM tfgW tbgW tHL2 tbHL chkHL res5 res6 res7 } else { foreach cs [list $ncolor $::apave::_CS_(MINCS)] { lassign [my csGet $cs] clrtitf clrinaf clrtitb clrinab clrhelp clractb clractf clrcurs clrgrey clrhotk tfgI tbgI fM bM tfgW tbgW tHL2 tbHL chkHL res5 res6 res7 if {$clrtitf ne ""} break set ncolor $cs } set ::apave::_CS_(index) $ncolor } # colors can be passed in args as -clrtitf "color" -clrinaf "color" ... if {$ncolor>=0} { foreach nclr {clrtitf clrinaf clrtitb clrinab clrhelp clractb clractf clrcurs clrgrey clrhotk tfgI tbgI fM bM tfgW tbgW tHL2 tbHL chkHL} { incr ic if {[set i [lsearch $args -$nclr]]>-1} { set $nclr [lindex $args $i+1] set chcs [lreplace [lindex $::apave::_CS_(ALL) $ncolor] $ic $ic [set $nclr]] set ::apave::_CS_(ALL) [lreplace $::apave::_CS_(ALL) $ncolor $ncolor $chcs] } } } set fg $clrinaf ;# main foreground set bg $clrinab ;# main background set fE $clrtitf ;# fieldforeground foreground set bE $clrtitb ;# fieldforeground background set fS $clractf ;# active/selection foreground set bS $clractb ;# active/selection background set hh $clrhelp ;# (not used in cs' theming) title color set gr $clrgrey ;# (not used in cs' theming) shadowing color set cc $clrcurs ;# caret's color set ht $clrhotk ;# hotkey color set grey $gr ;# #808080 if {$::apave::_CS_(old) != $ncolor || "-doit" in $args} { set ::apave::_CS_(old) $ncolor my themeWindow $win [list $fg $bg $fE $bE $fS $bS $grey $bg $cc $ht $hh $tfgI $tbgI $fM $bM $tfgW $tbgW $tHL2 $tbHL $chkHL $res5 $res6 $res7] my UpdateColors my initTooltip } set ::apave::FGMAIN $fg set ::apave::BGMAIN $bg set ::apave::FGMAIN2 $fE set ::apave::BGMAIN2 $bE catch { if {[my csDark $ncolor]} {::baltip::configure -relief groove} } list $fg $bg $fE $bE $fS $bS $hh $grey $cc $ht $tfgI $tbgI $fM $bM $tfgW $tbgW $tHL2 $tbHL $chkHL $res5 $res6 $res7 }
Make an external CS that has tones (hues) of colors for a CS.
| internal apave CS to be toned |
| a percent to get light (> 0) or dark (< 0) tones |
| flag "do it anyway" optional, default no |
This method allows only one external CS, eliminating others. Returns: "yes" if the CS was toned
method csToned {cs hue {doit no}} { # Make an external CS that has tones (hues) of colors for a CS. # cs - internal apave CS to be toned # hue - a percent to get light (> 0) or dark (< 0) tones # doit - flag "do it anyway" # This method allows only one external CS, eliminating others. # Returns: "yes" if the CS was toned if {!$doit && [my csCurrent] > $::apave::_CS_(NONCS)} { puts [set msg "\napave method csToned must be run before csSet!\n"] return -code error $msg } if {$cs <= $::apave::_CS_(NONCS) || $cs > $::apave::_CS_(STDCS)} { return no } my csDeleteExternal set CS [my csGet $cs] set mainc [my csMainColors] set ::apave::_CS_(HUE) $hue set hue [expr {(100.0+$hue)/100.0}] foreach i [my csMapTheme] { set color [lindex $CS $i] if {$i in $mainc} { catch { ;# for CS=-1 not working set clr [string map {black #000000 white #ffffff grey #808080 red #ff0000 yellow #ffff00 orange #ffa500 #000 #000000 #fff #ffffff} $color] scan $clr #%2x%2x%2x R G B foreach valname {R G B} { set val [expr {int([set $valname]*$hue)}] set $valname [expr {max(min($val,255),0)}] } set color [format #%02x%02x%02x $R $G $B] } } lappend TWargs $color } set ::apave::_CS_(TONED) [list $cs [my csNewIndex]] my themeWindow . $TWargs no my csSet [my csCurrent] . ;# resets new CS's data return yes }
Configurates colors and other attributes of tooltip.
| options of ::baltip::configure |
method initTooltip {args} { # Configurates colors and other attributes of tooltip. # args - options of ::baltip::configure ::apave::initBaltip lassign [lrange [my csGet] 14 15] fW bW ::baltip config -fg $fW -bg $bW -global yes ::baltip config {*}$args }
Checks if a theme is dark, light or neutral.
| theme's name |
Returns 1 for dark, 0 for light, -1 for neutral.
method thDark {theme} { # Checks if a theme is dark, light or neutral. # theme - theme's name # Returns 1 for dark, 0 for light, -1 for neutral. if {$theme in {alt classic default clam}} { return -1 } string match -nocase *dark* $theme }
Configures an external dialogue so that its colors accord with a current CS.
| list of untouched widgets |
method themeExternal {args} { # Configures an external dialogue so that its colors accord with a current CS. # args - list of untouched widgets if {[set cs [my csCurrent]] != -2} { foreach untw $args {my untouchWidgets $untw} after idle [list [self] csSet $cs . -doit] ;# theme the dialogue to be run } }
Themes all that must be themed.
| window's name |
| options |
method themeMandatory {win args} { # Themes all that must be themed. # win - window's name # args - options # set the new options for nested widgets (menu e.g.) my themeNonThemed $win # other options per widget type foreach {typ v1 v2} $args { if {$typ eq "-"} { # config of non-themed widgets set ind [incr ::apave::_C_($v1,0)] set ::apave::_C_($v1,$ind) "$v2" } else { # style maps of themed widgets my Ttk_style map $typ $v1 [list {*}$v2] } } ::apave::initStyles my ThemeChoosers }
Updates the appearances of currently used widgets (non-themed).
| window path whose children will be touched |
| additional widget(s) to be touched; optional, default "" |
method themeNonThemed {win {addwid {}}} { # Updates the appearances of currently used widgets (non-themed). # win - window path whose children will be touched # addwid - additional widget(s) to be touched # # See also: # untouchWidgets set wtypes [my NonThemedWidgets all] set lwid [winfo children $win] lappend lwid {*}$addwid foreach w1 $lwid { set ts [string tolower [winfo class $w1]] if {$ts ni {tcombobox tlabel tscrollbar tcheckbutton tradiobutton}} { my themeNonThemed $w1 } set tch 1 foreach u $::apave::_CS_(untouch) { lassign $u u addopts if {[string match $u $w1]} {set tch 0; break} } if {[info exist ::apave::_C_($ts,0)] && [lsearch -exact $wtypes $ts]>-1} { set i 0 if {$tch} { set tch $::apave::_C_($ts,0) set addopts {} } else { if {$addopts ne {}} { set tch $::apave::_C_($ts,0) } } while {[incr i] <= $tch} { lassign $::apave::_C_($ts,$i) opt val catch { if {[string first __tooltip__.label $w1]<0} { $w1 configure $opt $val {*}$addopts switch -exact -- [$w1 cget -state] { disabled { $w1 configure {*}[my NonTtkStyle $w1 1] } readonly { $w1 configure {*}[my NonTtkStyle $w1 2] } } } set nam3 [string range [my ownWName $w1] 0 2] if {$nam3 in {lbx tbl flb enT spX}} { my UpdateSelectAttrs $w1 } } } } } }
Configures a popup menu so that its colors accord with a current CS.
| menu's name (path) |
method themePopup {mnu} { # Configures a popup menu so that its colors accord with a current CS. # mnu - menu's name (path) if {[my csCurrent] == $::apave::_CS_(NONCS)} return lassign [my csGet] - fg - bg2 - bgS fgS - tfgD - - - - bg if {$bg eq {}} {set bg $bg2} set opts "-foreground $fg -background $bg -activeforeground $fgS -activebackground $bgS -font {[font actual apaveFontDef]}" if {[catch {my ThemePopup $mnu {*}$opts -disabledforeground $tfgD}]} { my ThemePopup $mnu {*}$opts } my themeNonThemed $mnu $mnu }
Changes a Tk style (theming a bit)
| window's name |
| list of colors; optional, default "" |
| true, if the colors are taken from a CS; optional, default true |
| other options |
The clrs contains:
tfg1 | foreground for themed widgets (main stock) |
tbg1 | background for themed widgets (main stock) |
tfg2 | foreground for themed widgets (enter data stock) |
tbg2 | background for themed widgets (enter data stock) |
tfgS | foreground for selection |
tbgS | background for selection |
tfgD | foreground for disabled themed widgets |
tbgD | background for disabled themed widgets |
tcur | insertion cursor color |
bclr | hotkey/border color |
thlp | help color |
tfgI | foreground for external CS |
tbgI | background for external CS |
tfgM | foreground for menus |
tbgM | background for menus |
The themeWindow can be used outside of "color scheme" UI. E.g., in TKE editor, e_menu and add_shortcuts plugins use it to be consistent with TKE theme.
method themeWindow {win {clrs {}} {isCS true} args} { # Changes a Tk style (theming a bit) # win - window's name # clrs - list of colors # isCS - true, if the colors are taken from a CS # args - other options # # The clrs contains: # tfg1 - foreground for themed widgets (main stock) # tbg1 - background for themed widgets (main stock) # tfg2 - foreground for themed widgets (enter data stock) # tbg2 - background for themed widgets (enter data stock) # tfgS - foreground for selection # tbgS - background for selection # tfgD - foreground for disabled themed widgets # tbgD - background for disabled themed widgets # tcur - insertion cursor color # bclr - hotkey/border color # thlp - help color # tfgI - foreground for external CS # tbgI - background for external CS # tfgM - foreground for menus # tbgM - background for menus # # The themeWindow can be used outside of "color scheme" UI. # E.g., in TKE editor, e_menu and add_shortcuts plugins use it to # be consistent with TKE theme. if {![::apave::cs_Active]} { my themeMandatory $win {*}$args return } lassign $clrs tfg1 tbg1 tfg2 tbg2 tfgS tbgS tfgD tbgD tcur bclr thlp tfgI tbgI tfgM tbgM twfg twbg tHL2 tbHL chkHL res5 res6 res7 if {$tfg1 eq {-}} return if {!$isCS} { # if 'external scheme' is used, register it in _CS_(ALL) # and set it as the current CS # <CS> itemfg mainfg itembg mainbg itemsHL actbg actfg cursor greyed hot emfg embg - menubg winfg winbg itemHL2 #003...reserved... my csAdd [list CS-[my csNewIndex] $tfg2 $tfg1 $tbg2 $tbg1 $thlp $tbgS $tfgS $tcur $tfgD $bclr $tfgI $tbgI $tfgM $tbgM $twfg $twbg $tHL2 $tbHL $chkHL $res5 $res6 $res7] } if {$tfgI eq {}} {set tfgI $tfg2} if {$tbgI eq {}} {set tbgI $tbg2} if {$tfgM in {{} -}} {set tfgM $tfg1} if {$tbgM eq {}} {set tbgM $tbg1} my Main_Style $tfg1 $tbg1 $tfg2 $tbg2 $tfgS $tbgS $tfgD $tbg1 $tfg1 $tbg2 $tbg1 foreach arg {tfg1 tbg1 tfg2 tbg2 tfgS tbgS tfgD tbgD tcur bclr thlp tfgI tbgI tfgM tbgM twfg twbg tHL2 tbHL chkHL res5 res6 res7 args} { if {$win eq {.}} { set ::apave::_C_($win,$arg) [set $arg] } set ::apave::_CS_(expo,$arg) [set $arg] } if {[set darkCS [my csDark]]} {set aclr #ff9dff} {set aclr #890970} set fontdef [font actual apaveFontDef] # configuring themed widgets foreach ts {TLabel TButton TCheckbutton TRadiobutton TMenubutton} { my Ttk_style configure $ts -font $fontdef my Ttk_style configure $ts -foreground $tfg1 my Ttk_style configure $ts -background $tbg1 my Ttk_style map $ts -background [list pressed $tbg2 active $tbg2 focus $tbgS alternate $tbg2] my Ttk_style map $ts -foreground [list disabled $tfgD pressed $tfgS active $aclr focus $tfgS alternate $tfg2 focus $tfg2 selected $tfg1] my Ttk_style map $ts -bordercolor [list focus $bclr pressed $bclr] my Ttk_style map $ts -lightcolor [list focus $bclr] my Ttk_style map $ts -darkcolor [list focus $bclr] } ttk::style configure TLabelframe.Label -foreground $thlp -background $tbg1 -font $fontdef foreach ts {TNotebook TFrame} { my Ttk_style configure $ts -background $tbg1 my Ttk_style map $ts -background [list focus $tbg1 !focus $tbg1] } ttk::style configure TNotebook.Tab -font $fontdef ttk::style map TNotebook.Tab -foreground [list {selected !active} $tfgS {!selected !active} $tfgM active $aclr {selected active} $aclr] -background [list {selected !active} $tbgS {!selected !active} $tbgM {!selected active} $tbg2 {selected active} $tbg2] foreach ts {TEntry Treeview TSpinbox TCombobox TCombobox.Spinbox TMatchbox TNotebook.Tab TScale} { my Ttk_style map $ts -lightcolor [list focus $bclr active $bclr] my Ttk_style map $ts -darkcolor [list focus $bclr active $bclr] } ttk::style configure TScrollbar -arrowcolor $tfg1 ttk::style map TScrollbar -troughcolor [list !active $tbg1 active $tbg2] -background [list !active $tbg1 disabled $tbg1 {!selected !disabled active} $tbgS] ttk::style map TProgressbar -troughcolor [list !active $tbg2 active $tbg1] ttk::style configure TProgressbar -background $tbgS if {[set cs [my csCurrent]]<20} { ttk::style conf TSeparator -background #a2a2a2 } elseif {$cs<23} { ttk::style conf TSeparator -background #656565 } elseif {$cs<28} { ttk::style conf TSeparator -background #3c3c3c } elseif {$cs>35 && $cs<39} { ttk::style conf TSeparator -background #313131 } elseif {$cs==43 || $cs>44} { ttk::style conf TSeparator -background #2e2e2e } foreach ts {TEntry Treeview TSpinbox TCombobox TCombobox.Spinbox TMatchbox} { my Ttk_style configure $ts -font $fontdef my Ttk_style configure $ts -selectforeground $tfgS my Ttk_style configure $ts -selectbackground $tbgS my Ttk_style map $ts -selectforeground [list !focus $::apave::_CS_(!FG)] my Ttk_style map $ts -selectbackground [list !focus $::apave::_CS_(!BG)] my Ttk_style configure $ts -fieldforeground $tfg2 my Ttk_style configure $ts -fieldbackground $tbg2 my Ttk_style configure $ts -insertcolor $tcur my Ttk_style map $ts -bordercolor [list focus $bclr active $bclr] my Ttk_style configure $ts -insertwidth $::apave::_CS_(CURSORWIDTH) if {$ts eq {TCombobox}} { # combobox is sort of individual ttk::style configure $ts -foreground $tfg1 -background $tbg1 -arrowcolor $tfg1 ttk::style map $ts -background [list {readonly focus} $tbg2 {active focus} $tbg2] -foreground [list {readonly focus} $tfg2 {active focus} $tfg2] -fieldforeground [list {active focus} $tfg2 readonly $tfg2 disabled $tfgD] -fieldbackground [list {active focus} $tbg2 {readonly focus} $tbg2 {readonly !focus} $tbg1 disabled $tbgD] -focusfill [list {readonly focus} $tbgS] -arrowcolor [list disabled $tfgD] } else { my Ttk_style configure $ts -foreground $tfg2 my Ttk_style configure $ts -background $tbg2 if {$ts eq {Treeview}} { ttk::style map $ts -foreground [list readonly $tfgD disabled $tfgD {selected focus} $tfgS {selected !focus} $thlp] -background [list readonly $tbgD disabled $tbgD {selected focus} $tbgS {selected !focus} $tbg1] } else { my Ttk_style map $ts -foreground [list readonly $tfgD disabled $tfgD selected $tfgS] my Ttk_style map $ts -background [list readonly $tbgD disabled $tbgD selected $tbgS] my Ttk_style map $ts -fieldforeground [list readonly $tfgD disabled $tfgD] my Ttk_style map $ts -fieldbackground [list readonly $tbgD disabled $tbgD] my Ttk_style map $ts -arrowcolor [list disabled $tfgD] my Ttk_style configure $ts -arrowcolor $tfg1 } } } ttk::style configure Heading -font $fontdef -relief raised -padding 1 -background $tbg1 ttk::style map Heading -foreground [list active $aclr] option add *Listbox.font $fontdef option add *Menu.font $fontdef ttk::style configure TMenubutton -foreground $tfgM -background $tbgM -arrowcolor $tfg1 ttk::style map TMenubutton -arrowcolor [list disabled $tfgD] ttk::style configure TButton -foreground $tfgM -background $tbgM foreach {nam clr} {back tbg2 fore tfg2 selectBack tbgS selectFore tfgS} { option add *Listbox.${nam}ground [set $clr] } foreach {nam clr} {back tbgM fore tfgM selectBack tbgS selectFore tfgS} { option add *Menu.${nam}ground [set $clr] } foreach ts {TRadiobutton TCheckbutton} { ttk::style map $ts -background [list focus $tbg2 !focus $tbg1] } if {$darkCS} { # esp. for default/alt/classic themes and dark CS: # checked buttons to be lighter foreach ts {TCheckbutton TRadiobutton} { ttk::style configure $ts -indicatorcolor $tbgM ttk::style map $ts -indicatorcolor [list pressed $tbg2 selected $chkHL] } } # non-themed widgets of button and entry types foreach ts [my NonThemedWidgets button] { set ::apave::_C_($ts,0) 6 set ::apave::_C_($ts,1) "-background $tbg1" set ::apave::_C_($ts,2) "-foreground $tfg1" set ::apave::_C_($ts,3) "-activeforeground $tfg2" set ::apave::_C_($ts,4) "-activebackground $tbg2" set ::apave::_C_($ts,5) "-font {$fontdef}" set ::apave::_C_($ts,6) "-highlightbackground $tfgD" switch -exact -- $ts { checkbutton - radiobutton { set ::apave::_C_($ts,0) 8 set ::apave::_C_($ts,7) "-selectcolor $tbg1" set ::apave::_C_($ts,8) "-highlightbackground $tbg1" } frame - scrollbar - scale { set ::apave::_C_($ts,0) 8 set ::apave::_C_($ts,4) "-activebackground $tbgS" set ::apave::_C_($ts,7) "-troughcolor $tbg1" set ::apave::_C_($ts,8) "-elementborderwidth 2" } menu { set ::apave::_C_($ts,0) 9 set ::apave::_C_($ts,1) "-background $tbgM" set ::apave::_C_($ts,3) "-activeforeground $tfgS" set ::apave::_C_($ts,4) "-activebackground $tbgS" set ::apave::_C_($ts,5) "-disabledforeground $tfgD" set ::apave::_C_($ts,6) "-font {$fontdef}" if {[::iswindows]} { set ::apave::_C_($ts,0) 6 } elseif {[my apaveTheme]} { set ::apave::_C_($ts,7) {-borderwidth 2} set ::apave::_C_($ts,8) {-relief raised} } else { set ::apave::_C_($ts,7) {-borderwidth 1} set ::apave::_C_($ts,8) {-relief groove} } if {$darkCS} {set c white} {set c black} set ::apave::_C_($ts,9) "-selectcolor $c" } canvas { set ::apave::_C_($ts,1) "-background $tbg2" } } } foreach ts [my NonThemedWidgets entry] { set ::apave::_C_($ts,0) 3 set ::apave::_C_($ts,1) "-foreground $tfg2" set ::apave::_C_($ts,2) "-background $tbg2" set ::apave::_C_($ts,3) "-highlightbackground $tfgD" switch -exact -- $ts { tcombobox - listbox - tmatchbox { set ::apave::_C_($ts,0) 8 set ::apave::_C_($ts,4) "-disabledforeground $tfgD" set ::apave::_C_($ts,5) "-disabledbackground $tbgD" set ::apave::_C_($ts,6) "-highlightcolor $bclr" set ::apave::_C_($ts,7) "-font {$fontdef}" set ::apave::_C_($ts,8) "-insertbackground $tcur" } text - entry - tentry { set ::apave::_C_($ts,0) 11 set ::apave::_C_($ts,4) "-selectforeground $tfgS" set ::apave::_C_($ts,5) "-selectbackground $tbgS" set ::apave::_C_($ts,6) "-disabledforeground $tfgD" set ::apave::_C_($ts,7) "-disabledbackground $tbgD" set ::apave::_C_($ts,8) "-highlightcolor $bclr" if {$ts eq {text}} { set ::apave::_C_($ts,0) 12 set ::apave::_C_($ts,9) "-font {[font actual apaveFontMono]}" set ::apave::_C_($ts,12) "-inactiveselectbackground $tbgS" } else { set ::apave::_C_($ts,9) "-font {$fontdef}" } set ::apave::_C_($ts,10) "-insertwidth $::apave::_CS_(CURSORWIDTH)" set ::apave::_C_($ts,11) "-insertbackground $tcur" } spinbox - tspinbox - tablelist { set ::apave::_C_($ts,0) 12 set ::apave::_C_($ts,4) "-insertbackground $tcur" set ::apave::_C_($ts,5) "-buttonbackground $tbg2" set ::apave::_C_($ts,6) "-selectforeground $::apave::_CS_(!FG)" set ::apave::_C_($ts,7) "-selectbackground $::apave::_CS_(!BG)" set ::apave::_C_($ts,8) "-disabledforeground $tfgD" set ::apave::_C_($ts,9) "-disabledbackground $tbgD" set ::apave::_C_($ts,10) "-font {$fontdef}" set ::apave::_C_($ts,11) "-insertwidth $::apave::_CS_(CURSORWIDTH)" set ::apave::_C_($ts,12) "-highlightcolor $bclr" } } } foreach ts {disabled} { set ::apave::_C_($ts,0) 4 set ::apave::_C_($ts,1) "-foreground $tfgD" set ::apave::_C_($ts,2) "-background $tbgD" set ::apave::_C_($ts,3) "-disabledforeground $tfgD" set ::apave::_C_($ts,4) "-disabledbackground $tbgD" } foreach ts {readonly} { set ::apave::_C_($ts,0) 2 set ::apave::_C_($ts,1) "-foreground $tfg1" set ::apave::_C_($ts,2) "-background $tbg1" } my themeMandatory $win {*}$args }
Makes non-ttk widgets to be touched again.
| list of widget globs (e.g. {.em.fr.win.* .em.fr.h1 .em.fr.h2}) |
If args not set, returns the list of untouched widgets.
untouchWidgets, themeNonThemed
method touchWidgets {args} { # Makes non-ttk widgets to be touched again. # args - list of widget globs (e.g. {.em.fr.win.* .em.fr.h1 .em.fr.h2}) # If args not set, returns the list of untouched widgets. # See also: # untouchWidgets # themeNonThemed if {[llength $args]==0} {return $::apave::_CS_(untouch)} foreach u $args { set u [lindex $u 0] if {[set i [lsearch -index 0 -exact $::apave::_CS_(untouch) $u]]>-1} { set ::apave::_CS_(untouch) [lreplace $::apave::_CS_(untouch) $i $i] } } }
Makes non-ttk widgets to be untouched by coloring or gets their list.
| list of widget globs (e.g. {.em.fr.win.* .em.fr.h1 .em.fr.h2}) |
If args not set, returns the list of untouched widgets. Items of args can have 2 components:
2nd component defines additional attributes that override the defaults. If 1st item of args is "clear", removes all items set with glob patterns (e.g.: my untouchWidgets clear BALTIP - clears all baltip's references).
method untouchWidgets {args} { # Makes non-ttk widgets to be untouched by coloring or gets their list. # args - list of widget globs (e.g. {.em.fr.win.* .em.fr.h1 .em.fr.h2}) # If args not set, returns the list of untouched widgets. # Items of *args* can have 2 components: # - widget glob # - list of option+value pairs, e.g. "*.textWidget {-fg white -bg black}" # 2nd component defines additional attributes that override the defaults. # If 1st item of *args* is "clear", removes all items set with glob patterns # (e.g.: my untouchWidgets clear *BALTIP* - clears all baltip's references). # See also: # touchWidgets # themeNonThemed if {[llength $args]==0} {return $::apave::_CS_(untouch)} if {[lindex $args 0] eq {clear}} { foreach u [lrange $args 1 end] { set ii [lsearch -all -glob $::apave::_CS_(untouch) $u] foreach i [lsort -decreasing -integer $ii] { set ::apave::_CS_(untouch) [lreplace $::apave::_CS_(untouch) $i $i] } } } else { foreach u $args { if {[lsearch -exact $::apave::_CS_(untouch) $u]==-1} { lappend ::apave::_CS_(untouch) $u } } } }