diff --git a/data/tcl/clrpick.tcl b/data/tcl/clrpick.tcl new file mode 100644 index 00000000..5d0b552d --- /dev/null +++ b/data/tcl/clrpick.tcl @@ -0,0 +1,700 @@ +# clrpick.tcl -- +# +# Color selection dialog for platforms that do not support a +# standard color selection dialog. +# +# RCS: @(#) $Id: clrpick.tcl,v 1.20.2.2 2006/03/17 10:50:11 patthoyts Exp $ +# +# Copyright (c) 1996 Sun Microsystems, Inc. +# +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. +# +# ToDo: +# +# (1): Find out how many free colors are left in the colormap and +# don't allocate too many colors. +# (2): Implement HSV color selection. +# + +# Make sure namespaces exist +namespace eval ::tk {} +namespace eval ::tk::dialog {} +namespace eval ::tk::dialog::color { + namespace import ::tk::msgcat::* +} + +# ::tk::dialog::color:: -- +# +# Create a color dialog and let the user choose a color. This function +# should not be called directly. It is called by the tk_chooseColor +# function when a native color selector widget does not exist +# +proc ::tk::dialog::color:: {args} { + variable ::tk::Priv + set dataName __tk__color + upvar ::tk::dialog::color::$dataName data + set w .$dataName + + # The lines variables track the start and end indices of the line + # elements in the colorbar canvases. + set data(lines,red,start) 0 + set data(lines,red,last) -1 + set data(lines,green,start) 0 + set data(lines,green,last) -1 + set data(lines,blue,start) 0 + set data(lines,blue,last) -1 + + # This is the actual number of lines that are drawn in each color strip. + # Note that the bars may be of any width. + # However, NUM_COLORBARS must be a number that evenly divides 256. + # Such as 256, 128, 64, etc. + set data(NUM_COLORBARS) 16 + + # BARS_WIDTH is the number of pixels wide the color bar portion of the + # canvas is. This number must be a multiple of NUM_COLORBARS + set data(BARS_WIDTH) 160 + + # PLGN_WIDTH is the number of pixels wide of the triangular selection + # polygon. This also results in the definition of the padding on the + # left and right sides which is half of PLGN_WIDTH. Make this number even. + set data(PLGN_HEIGHT) 10 + + # PLGN_HEIGHT is the height of the selection polygon and the height of the + # selection rectangle at the bottom of the color bar. No restrictions. + set data(PLGN_WIDTH) 10 + + Config $dataName $args + InitValues $dataName + + set sc [winfo screen $data(-parent)] + set winExists [winfo exists $w] + if {!$winExists || $sc ne [winfo screen $w]} { + if {$winExists} { + destroy $w + } + toplevel $w -class TkColorDialog -screen $sc + BuildDialog $w + } + + # Dialog boxes should be transient with respect to their parent, + # so that they will always stay on top of their parent window. However, + # some window managers will create the window as withdrawn if the parent + # window is withdrawn or iconified. Combined with the grab we put on the + # window, this can hang the entire application. Therefore we only make + # the dialog transient if the parent is viewable. + + if {[winfo viewable [winfo toplevel $data(-parent)]] } { + wm transient $w $data(-parent) + } + + # 5. Withdraw the window, then update all the geometry information + # so we know how big it wants to be, then center the window in the + # display and de-iconify it. + + ::tk::PlaceWindow $w widget $data(-parent) + wm title $w $data(-title) + + # 6. Set a grab and claim the focus too. + + ::tk::SetFocusGrab $w $data(okBtn) + + # 7. Wait for the user to respond, then restore the focus and + # return the index of the selected button. Restore the focus + # before deleting the window, since otherwise the window manager + # may take the focus away so we can't redirect it. Finally, + # restore any grab that was in effect. + + vwait ::tk::Priv(selectColor) + ::tk::RestoreFocusGrab $w $data(okBtn) + unset data + + return $Priv(selectColor) +} + +# ::tk::dialog::color::InitValues -- +# +# Get called during initialization or when user resets NUM_COLORBARS +# +proc ::tk::dialog::color::InitValues {dataName} { + upvar ::tk::dialog::color::$dataName data + + # IntensityIncr is the difference in color intensity between a colorbar + # and its neighbors. + set data(intensityIncr) [expr {256 / $data(NUM_COLORBARS)}] + + # ColorbarWidth is the width of each colorbar + set data(colorbarWidth) \ + [expr {$data(BARS_WIDTH) / $data(NUM_COLORBARS)}] + + # Indent is the width of the space at the left and right side of the + # colorbar. It is always half the selector polygon width, because the + # polygon extends into the space. + set data(indent) [expr {$data(PLGN_WIDTH) / 2}] + + set data(colorPad) 2 + set data(selPad) [expr {$data(PLGN_WIDTH) / 2}] + + # + # minX is the x coordinate of the first colorbar + # + set data(minX) $data(indent) + + # + # maxX is the x coordinate of the last colorbar + # + set data(maxX) [expr {$data(BARS_WIDTH) + $data(indent)-1}] + + # + # canvasWidth is the width of the entire canvas, including the indents + # + set data(canvasWidth) [expr {$data(BARS_WIDTH) + $data(PLGN_WIDTH)}] + + # Set the initial color, specified by -initialcolor, or the + # color chosen by the user the last time. + set data(selection) $data(-initialcolor) + set data(finalColor) $data(-initialcolor) + set rgb [winfo rgb . $data(selection)] + + set data(red,intensity) [expr {[lindex $rgb 0]/0x100}] + set data(green,intensity) [expr {[lindex $rgb 1]/0x100}] + set data(blue,intensity) [expr {[lindex $rgb 2]/0x100}] +} + +# ::tk::dialog::color::Config -- +# +# Parses the command line arguments to tk_chooseColor +# +proc ::tk::dialog::color::Config {dataName argList} { + variable ::tk::Priv + upvar ::tk::dialog::color::$dataName data + + # 1: the configuration specs + # + if {[info exists Priv(selectColor)] && $Priv(selectColor) ne ""} { + set defaultColor $Priv(selectColor) + } else { + set defaultColor [. cget -background] + } + + set specs [list \ + [list -initialcolor "" "" $defaultColor] \ + [list -parent "" "" "."] \ + [list -title "" "" [mc "Color"]] \ + ] + + # 2: parse the arguments + # + tclParseConfigSpec ::tk::dialog::color::$dataName $specs "" $argList + + if {$data(-title) eq ""} { + set data(-title) " " + } + if {[catch {winfo rgb . $data(-initialcolor)} err]} { + error $err + } + + if {![winfo exists $data(-parent)]} { + error "bad window path name \"$data(-parent)\"" + } +} + +# ::tk::dialog::color::BuildDialog -- +# +# Build the dialog. +# +proc ::tk::dialog::color::BuildDialog {w} { + upvar ::tk::dialog::color::[winfo name $w] data + + # TopFrame contains the color strips and the color selection + # + set topFrame [ttk::frame $w.top] + + # StripsFrame contains the colorstrips and the individual RGB entries + set stripsFrame [ttk::frame $topFrame.colorStrip] + + set maxWidth [::tk::mcmaxamp &Red &Green &Blue] + incr maxWidth + set maxWidth [expr {$maxWidth<6?6:$maxWidth}] + set colorList [list \ + red [mc "&Red"] \ + green [mc "&Green"] \ + blue [mc "&Blue"] \ + ] + foreach {color l} $colorList { + # each f frame contains an [R|G|B] entry and the equiv. color strip. + set f [ttk::frame $stripsFrame.$color] + + # The box frame contains the label and entry widget for an [R|G|B] + set box [ttk::frame $f.box] + + bind [::tk::AmpWidget ttk::label $box.label -text $l: -width $maxWidth \ + -anchor ne] <> [list focus $box.entry] + + ttk::entry $box.entry -textvariable \ + ::tk::dialog::color::[winfo name $w]($color,intensity) \ + -width 4 + pack $box.label -side left -fill y -padx 2 -pady 2 + pack $box.entry -side left -anchor n -padx 2 -pady 1 + pack $box -side left -fill both + + set height [expr {[winfo reqheight $box.entry] - 4}] + + canvas $f.color -height $height -width $data(BARS_WIDTH) \ + -relief sunken -bd 2 -highlightthickness 0 + canvas $f.sel -height $data(PLGN_HEIGHT) \ + -width $data(canvasWidth) -highlightthickness 0 \ + -bg [style lookup . -background] + pack $f.color + pack $f.sel -expand yes -fill both + + pack $f -side top -fill x -padx 0 -pady 2 + + set data($color,entry) $box.entry + set data($color,col) $f.color + set data($color,sel) $f.sel + + bind $data($color,col) \ + [list tk::dialog::color::DrawColorScale $w $color 1] + bind $data($color,col) \ + [list tk::dialog::color::EnterColorBar $w $color] + bind $data($color,col) \ + [list tk::dialog::color::LeaveColorBar $w $color] + + bind $data($color,sel) \ + [list tk::dialog::color::EnterColorBar $w $color] + bind $data($color,sel) \ + [list tk::dialog::color::LeaveColorBar $w $color] + + bind $box.entry [list tk::dialog::color::HandleRGBEntry $w] + } + + pack $stripsFrame -side left -fill both -padx 4 -pady 10 + + # The selFrame contains a frame that demonstrates the currently + # selected color + # + set selFrame [ttk::frame $topFrame.sel] + set lab [::tk::AmpWidget ttk::label $selFrame.lab -text [mc "&Selection:"] \ + -anchor sw] + set ent [ttk::entry $selFrame.ent \ + -textvariable ::tk::dialog::color::[winfo name $w](selection) \ + -width 16] + set f1 [frame $selFrame.f1 -relief sunken -bd 2] + set data(finalCanvas) [canvas $f1.demo -relief flat \ + -width 100 -height 70 -highlightthickness 0] + + pack $lab $ent -side top -fill x -padx 4 -pady 2 + pack $f1 -expand yes -anchor nw -fill both -padx 6 -pady 10 + pack $data(finalCanvas) -expand yes -fill both + + bind $ent [list tk::dialog::color::HandleSelEntry $w] + + pack $selFrame -side left -fill none -anchor nw + pack $topFrame -side top -expand yes -fill both -anchor nw + + # the botFrame frame contains the buttons + # + set sep [ttk::separator $w.sep] + set botFrame [ttk::frame $w.bot] + + set maxWidth [::tk::mcmaxamp &OK &Cancel] + set maxWidth [expr {$maxWidth<8?8:$maxWidth}] + + ::tk::AmpWidget ttk::button $botFrame.ok -text [mc "&OK"] \ + -command [list tk::dialog::color::OkCmd $w] -width $maxWidth + ::tk::AmpWidget ttk::button $botFrame.cancel -text [mc "&Cancel"] \ + -command [list tk::dialog::color::CancelCmd $w] -width $maxWidth + + set data(okBtn) $botFrame.ok + set data(cancelBtn) $botFrame.cancel + + grid x $botFrame.ok x $botFrame.cancel x -sticky e + grid configure $botFrame.ok -pady 8 + grid configure $botFrame.cancel -padx 10 -pady 8 + grid columnconfigure $botFrame 0 -weight 1 + pack $botFrame $sep -side bottom -fill x + + + # Accelerator bindings + bind $lab <> [list focus $ent] + bind $w [list tk::ButtonInvoke $data(cancelBtn)] + bind $w [list tk::AltKeyInDialog $w %A] + + wm protocol $w WM_DELETE_WINDOW [list tk::dialog::color::CancelCmd $w] +} + +# ::tk::dialog::color::SetRGBValue -- +# +# Sets the current selection of the dialog box +# +proc ::tk::dialog::color::SetRGBValue {w color} { + upvar ::tk::dialog::color::[winfo name $w] data + + set data(red,intensity) [lindex $color 0] + set data(green,intensity) [lindex $color 1] + set data(blue,intensity) [lindex $color 2] + + RedrawColorBars $w all + + # Now compute the new x value of each colorbars pointer polygon + foreach color [list red green blue ] { + set x [RgbToX $w $data($color,intensity)] + MoveSelector $w $data($color,sel) $color $x 0 + } +} + +# ::tk::dialog::color::XToRgb -- +# +# Converts a screen coordinate to intensity +# +proc ::tk::dialog::color::XToRgb {w x} { + upvar ::tk::dialog::color::[winfo name $w] data + + set x [expr {($x * $data(intensityIncr))/ $data(colorbarWidth)}] + if {$x > 255} { set x 255 } + return $x +} + +# ::tk::dialog::color::RgbToX +# +# Converts an intensity to screen coordinate. +# +proc ::tk::dialog::color::RgbToX {w color} { + upvar ::tk::dialog::color::[winfo name $w] data + + return [expr {($color * $data(colorbarWidth)/ $data(intensityIncr))}] +} + + +# ::tk::dialog::color::DrawColorScale -- +# +# Draw color scale is called whenever the size of one of the color +# scale canvases is changed. +# +proc ::tk::dialog::color::DrawColorScale {w c {create 0}} { + upvar ::tk::dialog::color::[winfo name $w] data + + # col: color bar canvas + # sel: selector canvas + set col $data($c,col) + set sel $data($c,sel) + + # First handle the case that we are creating everything for the first time. + if {$create} { + # First remove all the lines that already exist. + if { $data(lines,$c,last) > $data(lines,$c,start)} { + for {set i $data(lines,$c,start)} \ + {$i <= $data(lines,$c,last)} { incr i} { + $sel delete $i + } + } + # Delete the selector if it exists + if {[info exists data($c,index)]} { + $sel delete $data($c,index) + } + + # Draw the selection polygons + CreateSelector $w $sel $c + $sel bind $data($c,index) \ + [list tk::dialog::color::StartMove $w $sel $c %x $data(selPad) 1] + $sel bind $data($c,index) \ + [list tk::dialog::color::MoveSelector $w $sel $c %x $data(selPad)] + $sel bind $data($c,index) \ + [list tk::dialog::color::ReleaseMouse $w $sel $c %x $data(selPad)] + + set height [winfo height $col] + # Create an invisible region under the colorstrip to catch mouse clicks + # that aren't on the selector. + set data($c,clickRegion) [$sel create rectangle 0 0 \ + $data(canvasWidth) $height -fill {} -outline {}] + + bind $col \ + [list tk::dialog::color::StartMove $w $sel $c %x $data(colorPad)] + bind $col \ + [list tk::dialog::color::MoveSelector $w $sel $c %x $data(colorPad)] + bind $col \ + [list tk::dialog::color::ReleaseMouse $w $sel $c %x $data(colorPad)] + + $sel bind $data($c,clickRegion) \ + [list tk::dialog::color::StartMove $w $sel $c %x $data(selPad)] + $sel bind $data($c,clickRegion) \ + [list tk::dialog::color::MoveSelector $w $sel $c %x $data(selPad)] + $sel bind $data($c,clickRegion) \ + [list tk::dialog::color::ReleaseMouse $w $sel $c %x $data(selPad)] + } else { + # l is the canvas index of the first colorbar. + set l $data(lines,$c,start) + } + + # Draw the color bars. + set highlightW [expr {[$col cget -highlightthickness] + [$col cget -bd]}] + for {set i 0} { $i < $data(NUM_COLORBARS)} { incr i} { + set intensity [expr {$i * $data(intensityIncr)}] + set startx [expr {$i * $data(colorbarWidth) + $highlightW}] + if {$c eq "red"} { + set color [format "#%02x%02x%02x" \ + $intensity \ + $data(green,intensity) \ + $data(blue,intensity)] + } elseif {$c eq "green"} { + set color [format "#%02x%02x%02x" \ + $data(red,intensity) \ + $intensity \ + $data(blue,intensity)] + } else { + set color [format "#%02x%02x%02x" \ + $data(red,intensity) \ + $data(green,intensity) \ + $intensity] + } + + if {$create} { + set index [$col create rect $startx $highlightW \ + [expr {$startx +$data(colorbarWidth)}] \ + [expr {[winfo height $col] + $highlightW}]\ + -fill $color -outline $color] + } else { + $col itemconfigure $l -fill $color -outline $color + incr l + } + } + $sel raise $data($c,index) + + if {$create} { + set data(lines,$c,last) $index + set data(lines,$c,start) [expr {$index - $data(NUM_COLORBARS) + 1}] + } + + RedrawFinalColor $w +} + +# ::tk::dialog::color::CreateSelector -- +# +# Creates and draws the selector polygon at the position +# $data($c,intensity). +# +proc ::tk::dialog::color::CreateSelector {w sel c } { + upvar ::tk::dialog::color::[winfo name $w] data + set data($c,index) [$sel create polygon \ + 0 $data(PLGN_HEIGHT) \ + $data(PLGN_WIDTH) $data(PLGN_HEIGHT) \ + $data(indent) 0] + set data($c,x) [RgbToX $w $data($c,intensity)] + $sel move $data($c,index) $data($c,x) 0 +} + +# ::tk::dialog::color::RedrawFinalColor +# +# Combines the intensities of the three colors into the final color +# +proc ::tk::dialog::color::RedrawFinalColor {w} { + upvar ::tk::dialog::color::[winfo name $w] data + + set color [format "#%02x%02x%02x" $data(red,intensity) \ + $data(green,intensity) $data(blue,intensity)] + + $data(finalCanvas) configure -background $color + set data(finalColor) $color + set data(selection) $color + set data(finalRGB) [list \ + $data(red,intensity) \ + $data(green,intensity) \ + $data(blue,intensity)] +} + +# ::tk::dialog::color::RedrawColorBars -- +# +# Only redraws the colors on the color strips that were not manipulated. +# Params: color of colorstrip that changed. If color is not [red|green|blue] +# Then all colorstrips will be updated +# +proc ::tk::dialog::color::RedrawColorBars {w colorChanged} { + upvar ::tk::dialog::color::[winfo name $w] data + + switch $colorChanged { + red { + DrawColorScale $w green + DrawColorScale $w blue + } + green { + DrawColorScale $w red + DrawColorScale $w blue + } + blue { + DrawColorScale $w red + DrawColorScale $w green + } + default { + DrawColorScale $w red + DrawColorScale $w green + DrawColorScale $w blue + } + } + RedrawFinalColor $w +} + +#---------------------------------------------------------------------- +# Event handlers +#---------------------------------------------------------------------- + +# ::tk::dialog::color::StartMove -- +# +# Handles a mousedown button event over the selector polygon. +# Adds the bindings for moving the mouse while the button is +# pressed. Sets the binding for the button-release event. +# +# Params: sel is the selector canvas window, color is the color of the strip. +# +proc ::tk::dialog::color::StartMove {w sel color x delta {dontMove 0}} { + upvar ::tk::dialog::color::[winfo name $w] data + + if {!$dontMove} { + MoveSelector $w $sel $color $x $delta + } +} + +# ::tk::dialog::color::MoveSelector -- +# +# Moves the polygon selector so that its middle point has the same +# x value as the specified x. If x is outside the bounds [0,255], +# the selector is set to the closest endpoint. +# +# Params: sel is the selector canvas, c is [red|green|blue] +# x is a x-coordinate. +# +proc ::tk::dialog::color::MoveSelector {w sel color x delta} { + upvar ::tk::dialog::color::[winfo name $w] data + + incr x -$delta + + if { $x < 0 } { + set x 0 + } elseif { $x > $data(BARS_WIDTH)} { + set x $data(BARS_WIDTH) + } + set diff [expr {$x - $data($color,x)}] + $sel move $data($color,index) $diff 0 + set data($color,x) [expr {$data($color,x) + $diff}] + + # Return the x value that it was actually set at + return $x +} + +# ::tk::dialog::color::ReleaseMouse +# +# Removes mouse tracking bindings, updates the colorbars. +# +# Params: sel is the selector canvas, color is the color of the strip, +# x is the x-coord of the mouse. +# +proc ::tk::dialog::color::ReleaseMouse {w sel color x delta} { + upvar ::tk::dialog::color::[winfo name $w] data + + set x [MoveSelector $w $sel $color $x $delta] + + # Determine exactly what color we are looking at. + set data($color,intensity) [XToRgb $w $x] + + RedrawColorBars $w $color +} + +# ::tk::dialog::color::ResizeColorbars -- +# +# Completely redraws the colorbars, including resizing the +# colorstrips +# +proc ::tk::dialog::color::ResizeColorBars {w} { + upvar ::tk::dialog::color::[winfo name $w] data + + if { ($data(BARS_WIDTH) < $data(NUM_COLORBARS)) || + (($data(BARS_WIDTH) % $data(NUM_COLORBARS)) != 0)} { + set data(BARS_WIDTH) $data(NUM_COLORBARS) + } + InitValues [winfo name $w] + foreach color [list red green blue ] { + $data($color,col) configure -width $data(canvasWidth) + DrawColorScale $w $color 1 + } +} + +# ::tk::dialog::color::HandleSelEntry -- +# +# Handles the return keypress event in the "Selection:" entry +# +proc ::tk::dialog::color::HandleSelEntry {w} { + upvar ::tk::dialog::color::[winfo name $w] data + + set text [string trim $data(selection)] + # Check to make sure that the color is valid + if {[catch {set color [winfo rgb . $text]} ]} { + set data(selection) $data(finalColor) + return + } + + set R [expr {[lindex $color 0]/0x100}] + set G [expr {[lindex $color 1]/0x100}] + set B [expr {[lindex $color 2]/0x100}] + + SetRGBValue $w "$R $G $B" + set data(selection) $text +} + +# ::tk::dialog::color::HandleRGBEntry -- +# +# Handles the return keypress event in the R, G or B entry +# +proc ::tk::dialog::color::HandleRGBEntry {w} { + upvar ::tk::dialog::color::[winfo name $w] data + + foreach c [list red green blue] { + if {[catch { + set data($c,intensity) [expr {int($data($c,intensity))}] + }]} { + set data($c,intensity) 0 + } + + if {$data($c,intensity) < 0} { + set data($c,intensity) 0 + } + if {$data($c,intensity) > 255} { + set data($c,intensity) 255 + } + } + + SetRGBValue $w "$data(red,intensity) \ + $data(green,intensity) $data(blue,intensity)" +} + +# mouse cursor enters a color bar +# +proc ::tk::dialog::color::EnterColorBar {w color} { + upvar ::tk::dialog::color::[winfo name $w] data + + $data($color,sel) itemconfigure $data($color,index) -fill red +} + +# mouse leaves enters a color bar +# +proc ::tk::dialog::color::LeaveColorBar {w color} { + upvar ::tk::dialog::color::[winfo name $w] data + + $data($color,sel) itemconfigure $data($color,index) -fill black +} + +# user hits OK button +# +proc ::tk::dialog::color::OkCmd {w} { + variable ::tk::Priv + upvar ::tk::dialog::color::[winfo name $w] data + + set Priv(selectColor) $data(finalColor) +} + +# user hits Cancel button +# +proc ::tk::dialog::color::CancelCmd {w} { + variable ::tk::Priv + set Priv(selectColor) "" +} + diff --git a/data/tcl/fsdialog.tcl b/data/tcl/fsdialog.tcl new file mode 100644 index 00000000..fab4f74b --- /dev/null +++ b/data/tcl/fsdialog.tcl @@ -0,0 +1,1766 @@ +# Copyright (C) Schelte Bron. Freely redistributable. +# http://wiki.tcl.tk/15897 + +proc ttk::messageBox {args} { + variable ::ttk::Priv + set dataName __ttk_messagebox + set parent . + foreach {opt val} $args { + switch -- $opt { + -parent { + set parent $val + } + default { + lappend opts $opt $val + } + } + } + lappend opts -command {set ::ttk::Priv(button)} + if {$parent eq "."} { + set win .$dataName + } else { + set win $parent.$dataName + } + eval [linsert $opts 0 ttk::dialog $win] + ::tk::PlaceWindow $win widget $parent + ::tk::SetFocusGrab $win $win + vwait ::ttk::Priv(button) + ::tk::RestoreFocusGrab $win $win + return $Priv(button) +} + +interp alias {} ttk_messageBox {} ::ttk::messageBox + +namespace eval ::ttk::dialog {} +namespace eval ::ttk::dialog::file { + variable sort name hidden 1 sepfolders 1 foldersfirst 1 + variable details 0 reverse 0 filetype none + variable dirlist "" filelist "" +} +namespace eval ::ttk::dialog::image {} + +# Images for the configuration menu + +image create photo ::ttk::dialog::image::blank16 -height 16 -width 16 + +image create photo ::ttk::dialog::image::tick16 -data { +R0lGODlhEAAQAMIAAExOTFRSVPz+/AQCBP///////////////yH5BAEKAAQALAAAAAAQABAA +AAM4CAHcvkEAQqu18uqat+4eFoTEwE3eYFLCWK2lelqyChMtbd84+sqX3IXH8pFwrmNPyRI4 +n9CoIAEAOw==} + +image create photo ::ttk::dialog::image::radio16 -data { +R0lGODlhEAAQAMIAAJyZi////83OxQAAAP///////////////yH5BAEKAAEALAAAAAAQABAA +AAMtGLrc/jCAOaNsAGYn3A5DuHTMFp4KuZjnkGJK6waq8qEvzGlNzQlAn2VILC4SADs=} + +# Images for ttk::getOpenFile, ttk::getSaveFile, ttk::getAppendFile + +image create photo ::ttk::dialog::image::next -data { +R0lGODlhFgAWAMYAADt1BDpzBFiJKb7ZpGaVOTx2A8HcqbfVm3ShSjt0BDp1BDx3Bb/apYe7 +V7DSkIOtWzt0A8Dbpr/apL7ao7zZoXu0RXy0R6bMgo23Zz12CbzZoH+2Sn61SX21R3qzRHiy +QnaxPnOvOnCuNpjFb5e/cUV8ELnXnHiyQXaxP3WwPXCtNm2sMmqqLWaoKIm8WJ3FeEuBGLXV +l2+tNGGlIWanJ2urLWutLmqtK2irJ2SpIl+lHJ/GeFaKIjt1A6jNhU+aB06aBk+cBlKhCFWl +CViqDF6uEmCvFWGtFl2qE3e2Op3HdVWLIjt2BKPLflSjCFipClyvDF6zDWC2Dl+0DYTER5zK +cEqDFjt3A1eoClywDGG3DmW9EGfBEWnCE5XTWZjJZ0R9D6TLfqbPf6nUgazYgq/cg2nDEXPM +GqPfaY7DWj53CTlzBD13Ba7bg3HGH6fecn+0SqbWdmufOjhwBKTPelqNKTNmAk6DHi9dAzdu +A////////////////////////yH5BAEKAH8ALAAAAAAWABYAAAfGgH+Cg4SFhoeIiYgAio0B +Ao2JAQMEBZGGAQYHCAmNCgGgoAsMDQ4PEIoBEasREhMUFRYXGBmSGhsbHB0eHyAhIiMkJYgB +JifHKCkhKissLS4vMIcBMTItMzM0NTY3ODk6Jzs9mD4/QEBBQkNERUZHSElKTJhN50FOT1BR +UlJTVFVXptUDIgRLFi1buHTx8gUMsSZNwogZQ6aMmTNo0qhJtCYUKDZt3LyB0+mSoABk4siZ +Y3JQADp17LR0eQfPzEF5burcKSgQADs=} + +image create photo ::ttk::dialog::image::nextbw -data { +R0lGODlhFgAWAOcAAAAAAAEBAQICAgMDAwQEBAUFBQYGBgcHBwgICAkJCQoKCgsLCwwMDA0N +DQ4ODg8PDxAQEBERERISEhMTExQUFBUVFRYWFhcXFxgYGBkZGRoaGhsbGxwcHB0dHR4eHh8f +HyAgICEhISIiIiMjIyQkJCUlJSYmJicnJygoKCkpKSoqKisrKywsLC0tLS4uLi8vLzAwMDEx +MTIyMjMzMzQ0NDU1NTY2Njc3Nzg4ODk5OTo6Ojs7Ozw8PD09PT4+Pj8/P0BAQEFBQUJCQkND +Q0REREVFRUZGRkdHR0hISElJSUpKSktLS0xMTE1NTU5OTk9PT1BQUFFRUVJSUlNTU1RUVFVV +VVZWVldXV1hYWFlZWVpaWltbW1xcXF1dXV5eXl9fX2BgYGFhYWJiYmNjY2RkZGVlZWZmZmdn +Z2hoaGlpaWpqamtra2xsbG1tbW5ubm9vb3BwcHFxcXJycnNzc3R0dHV1dXZ2dnd3d3h4eHl5 +eXp6ent7e3x8fH19fX5+fn9/f4CAgIGBgYKCgoODg4SEhIWFhYaGhoeHh4iIiImJiYqKiouL +i4yMjI2NjY6Ojo+Pj5CQkJGRkZKSkpOTk5SUlJWVlZaWlpeXl5iYmJmZmZqampubm5ycnJ2d +nZ6enp+fn6CgoKGhoaKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq6ysrK2tra6urq+v +r7CwsLGxsbKysrOzs7S0tLW1tba2tre3t7i4uLm5ubq6uru7u7y8vL29vb6+vr+/v8DAwMHB +wcLCwsPDw8TExMXFxcbGxsfHx8jIyMnJycrKysvLy8zMzM3Nzc7Ozs/Pz9DQ0NHR0dLS0tPT +09TU1NXV1dbW1tfX19jY2NnZ2dra2tvb29zc3N3d3d7e3t/f3+Dg4OHh4eLi4uPj4+Tk5OXl +5ebm5ufn5+jo6Onp6erq6uvr6+zs7O3t7e7u7u/v7/Dw8PHx8fLy8vPz8/T09PX19fb29vf3 +9/j4+Pn5+fr6+vv7+/z8/P39/f7+/v///yH5BAEKAP8ALAAAAAAWABYAAAjUAP8JHEiwoMGD +CBMivKKwYZU3DRNWWcaHYcSCVZwVS2SloZUqIEFiYQYK2KWOEpupbLZsmTJLl3CFwiJRWaZM +mDBVoiQJkiNXqr4grHKMklFJkSA1WpTIUChYZQ5WIdbIkCBBhRItUoSoECBKsSwSrJJrjhw5 +dPDsAUTIUCFBlcIarGLrLB09fwgdSpQI0ShZNOfWlYPHDyFFjyRRkvVKqFRbkHP1CkaMUidg +p7JIDAkyyzBNwTChvPivSrBehKaQHlgFl5wlq1mfKRJ7YJTauHMLDAgAOw==} + +image create photo ::ttk::dialog::image::previous -data { +R0lGODlhFgAWAOcAADp0BFSIJTx1Bzp0A2KSNLrWnz93Czt1BHGeRbXUmL/apTx0BH6qVa/R +joS5UrzZoEF7CzpzBD13CIu2Y6TLf3iyQniyQbnXnbzZob7ao7/apMDbpj92CkR7D5S8bJbD +a22sMW+tNHKvOXaxPnqzRH21R361SX+2SrvYn0mAFprDdIe6VWOmI2aoKGqqLW2sMnCtNnOv +OnWwPXaxP7jWmj52CTt1A1SIIJvEdHWxPlqhF16jHGGlIWSnJWmrK2uvLGqwKGevI2uvKXKy +NrTVlT11CDt3A1SKIJrEcVOdDVWeEFSeD1ekD1enC1mrCluuC1ywDFqqC6rThEmCFZXAbE6a +BlKgB1enCV+0DWK4DmS7D2O7D1+zDajUfkJ5DYy5YYa7U1elDFqsC2jBEWvGEmrFEmfBEWO6 +D6rXfzx1CDx2B4GwU5TGY2GxFGC2Dq7dgLLhhLXmhrTlha/dg63Zgjx2CDpyA3WmRZ3Ob2m5 +HK3bgEF9CTtzBDduA2aYNqHQdazYgTNlAleLJaPOeS1ZA0yBGzx0Bv////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +/////////////////////////////////yH5BAEKAP8ALAAAAAAWABYAAAjgAP8JHEiwoMGD +CBMq/AdgYcIAAhwaHECggAGJBA8gSKDgIsZ/Cxg0cPAAQoSTJw8klDCBQgULFzBk0LChJgeE +HTx8ABFCxIgKJEqYOIHipsEUKlawaOHiBYwYMmZYsECjhkEbOHLo2MGjh48fQIIEETKESBGD +RpDASKJkCZMmTp5AgfIkipSzBgFQIVHFypUnWLJo2ZKFSxe8Br18ARNGDBYtY8iUMXMGTZqE +atawaePmDZw4cuDMoVNHoZ07ePLo2YPyJJ+Fffz8AVT6o8BAggbVtv2PUCFDvAn2CU7cdkAA +Ow==} + +image create photo ::ttk::dialog::image::previousbw -data { +R0lGODlhFgAWAOcAAAAAAAEBAQICAgMDAwQEBAUFBQYGBgcHBwgICAkJCQoKCgsLCwwMDA0N +DQ4ODg8PDxAQEBERERISEhMTExQUFBUVFRYWFhcXFxgYGBkZGRoaGhsbGxwcHB0dHR4eHh8f +HyAgICEhISIiIiMjIyQkJCUlJSYmJicnJygoKCkpKSoqKisrKywsLC0tLS4uLi8vLzAwMDEx +MTIyMjMzMzQ0NDU1NTY2Njc3Nzg4ODk5OTo6Ojs7Ozw8PD09PT4+Pj8/P0BAQEFBQUJCQkND +Q0REREVFRUZGRkdHR0hISElJSUpKSktLS0xMTE1NTU5OTk9PT1BQUFFRUVJSUlNTU1RUVFVV +VVZWVldXV1hYWFlZWVpaWltbW1xcXF1dXV5eXl9fX2BgYGFhYWJiYmNjY2RkZGVlZWZmZmdn +Z2hoaGlpaWpqamtra2xsbG1tbW5ubm9vb3BwcHFxcXJycnNzc3R0dHV1dXZ2dnd3d3h4eHl5 +eXp6ent7e3x8fH19fX5+fn9/f4CAgIGBgYKCgoODg4SEhIWFhYaGhoeHh4iIiImJiYqKiouL +i4yMjI2NjY6Ojo+Pj5CQkJGRkZKSkpOTk5SUlJWVlZaWlpeXl5iYmJmZmZqampubm5ycnJ2d +nZ6enp+fn6CgoKGhoaKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq6ysrK2tra6urq+v +r7CwsLGxsbKysrOzs7S0tLW1tba2tre3t7i4uLm5ubq6uru7u7y8vL29vb6+vr+/v8DAwMHB +wcLCwsPDw8TExMXFxcbGxsfHx8jIyMnJycrKysvLy8zMzM3Nzc7Ozs/Pz9DQ0NHR0dLS0tPT +09TU1NXV1dbW1tfX19jY2NnZ2dra2tvb29zc3N3d3d7e3t/f3+Dg4OHh4eLi4uPj4+Tk5OXl +5ebm5ufn5+jo6Onp6erq6uvr6+zs7O3t7e7u7u/v7/Dw8PHx8fLy8vPz8/T09PX19fb29vf3 +9/j4+Pn5+fr6+vv7+/z8/P39/f7+/v///yH5BAEKAP8ALAAAAAAWABYAAAjXAP8JHEiwoMGD +CBMq/GdlYcI2VxwatJLnmBaJBK8YIsbsIkaGk351UtalikmTERFm+WSLEqVjypYta0YzC0Iv +p1YtavRIEqVKmDBlSmbT4BhXnwYZSrQTUiSflIwVzehKEp8/ggglYsRIkaJFkYhhMYjFVSM7 +ePDw6QNoECFCgwD5GjsxVSU5d/oMQrSz0aJDvega5BLqE59AiBpJsmRJUqNfKQ9iucTqUCJi +yJgtQ1ZMmOCDVBjRejTMy8mTC6P4uRXsM8YlcG65xiikTOSPA6Pg3s1bYEAAOw==} + +image create photo ::ttk::dialog::image::up -data { +R0lGODlhFgAWAOcAADx2Azx2BFWLIlWNIjx1A0uBGJzFdZrFckuDF0V8EJzDdnKvOm+tNZbB +bUR7Dz52CZa/cIW5UlqhGFaeEXmzQ467ZD14CIy2ZZTCaWOmI16jHFmgFlSdDoO4UIKyVTt1 +Azp2BIKsWaLKfWysMWaoKGGlIVyiGlSeD0+bCI2+X3anSDt2BHShSa3RjXexQG+tNGusLWir +J2GoHFOhCVGgB1ahDpXDamiaOWSUN7XVmIS4UXm1QXe1O3O0NG6zLFyqEVeoClenCVamCV6o +F5zIcluOKViKKLvXoL/bpb7bo73coH27QXm8OmWzGVywDFyvDKrVganTgKjRgKDLeU+FHzt1 +BDpzBD14BcDeooLBRXK7KmC2DmG4DmK4DmG3DqzZgj55BcLhpYfHSma6FGW9EGe/EGfAEWa/ +EK/cg8TjpnzDOGnDEWvHEmzIE2vGErDfhMbkqXTBKW/MFHHQFW3KE7HghGy9Hma+EGrEEm3J +E27LFGzHE7HfhMXjqa/aha7bg7Deg6/dg/////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +/////////////////////////////////yH5BAEKAP8ALAAAAAAWABYAAAjWAP8JHEiwoMGD +CBMqXMiw4UEAARwWLGDgAAGJAhMoWMCggQOJDyBEkDCBQgULDQFcwJBBwwYOHTx8WAgihIgR +JEqYOIEihYoVCQGwaOHiBYwYMmbQqGHjxsWDOHLo2MGjh48fQIIIGUKkyEEjR5AkUbKESRMn +Tp5AiSJlCpWCVazIvYIli5YtXLp4+QJGrhUQCK2EETOGTBkzZ9BYYWgljRoya9i0cfNm8UIr +cOKccSNnDp06lhVitnMHTx49e/iETmilj58/gPjU4RNodWC/uOVi3L07IAA7} + +image create photo ::ttk::dialog::image::upbw -data { +R0lGODlhFgAWAOcAAAAAAAEBAQICAgMDAwQEBAUFBQYGBgcHBwgICAkJCQoKCgsLCwwMDA0N +DQ4ODg8PDxAQEBERERISEhMTExQUFBUVFRYWFhcXFxgYGBkZGRoaGhsbGxwcHB0dHR4eHh8f +HyAgICEhISIiIiMjIyQkJCUlJSYmJicnJygoKCkpKSoqKisrKywsLC0tLS4uLi8vLzAwMDEx +MTIyMjMzMzQ0NDU1NTY2Njc3Nzg4ODk5OTo6Ojs7Ozw8PD09PT4+Pj8/P0BAQEFBQUJCQkND +Q0REREVFRUZGRkdHR0hISElJSUpKSktLS0xMTE1NTU5OTk9PT1BQUFFRUVJSUlNTU1RUVFVV +VVZWVldXV1hYWFlZWVpaWltbW1xcXF1dXV5eXl9fX2BgYGFhYWJiYmNjY2RkZGVlZWZmZmdn +Z2hoaGlpaWpqamtra2xsbG1tbW5ubm9vb3BwcHFxcXJycnNzc3R0dHV1dXZ2dnd3d3h4eHl5 +eXp6ent7e3x8fH19fX5+fn9/f4CAgIGBgYKCgoODg4SEhIWFhYaGhoeHh4iIiImJiYqKiouL +i4yMjI2NjY6Ojo+Pj5CQkJGRkZKSkpOTk5SUlJWVlZaWlpeXl5iYmJmZmZqampubm5ycnJ2d +nZ6enp+fn6CgoKGhoaKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq6ysrK2tra6urq+v +r7CwsLGxsbKysrOzs7S0tLW1tba2tre3t7i4uLm5ubq6uru7u7y8vL29vb6+vr+/v8DAwMHB +wcLCwsPDw8TExMXFxcbGxsfHx8jIyMnJycrKysvLy8zMzM3Nzc7Ozs/Pz9DQ0NHR0dLS0tPT +09TU1NXV1dbW1tfX19jY2NnZ2dra2tvb29zc3N3d3d7e3t/f3+Dg4OHh4eLi4uPj4+Tk5OXl +5ebm5ufn5+jo6Onp6erq6uvr6+zs7O3t7e7u7u/v7/Dw8PHx8fLy8vPz8/T09PX19fb29vf3 +9/j4+Pn5+fr6+vv7+/z8/P39/f7+/v///yH5BAEKAP8ALAAAAAAWABYAAAjPAP8JHEiwoMGD +CBMqXMiw4cErWBwWLPPK1RWJAr+4etRIlReJWVR54oOn0qgsDa+AUjXoz547nDJdVHjFUq1F +hgT5wUOHVKOZDxP5mtRIEaJBeO7oWQUIaME9xDpZoiTpUSA/ffgEijXnIBxkzMJqyqSIkFlf +vXbVSlPwSpW3WZyBqpRo0SJFwbS8reKUYJVophw9iiQpErEqDKtI8/SI0iVMlowhXliFWqZI +ljZ5ynRsssLKkyBVyqTpUufE04YNM3asdTHPCffK3ouxdu2AADs=} + +image create photo ::ttk::dialog::image::gohome -data { +R0lGODlhFgAWAMYAAKQAAPR1deU5OeInJ+xGRvFMTPBRUfJVVeAmJvNbW/JeXntMSohaWN4m +JvNkZJldW4SFgpubmsCKitwmJvRsbPRmZp11c4+Qjbi5uMLCwbq6ucShodwlJfNjY6ONi5+g +nr+/vt7e3d3d3dfX18m1tZwICKefnaOjotra2urq6unp6efn59zQ0IQiIaGgnqKjodjY2Obm +5uTk5OPj4+Le3tvc21VXU3d4enZ5fXV1dXV2dvPz8+7u7n6Ae3+BfICCfeXl5XZ5fHmZw3eY +wnV4fPLy8u3t7YSGgYWHguLi4nV4e1+Gt0p2rnJ1evHx8ezs7IaIg4qIZYmIcODg4HF4gTRl +pG52gfDw8Ovr64eJhIiJfvn5+bGztri8wbq7vLm9waSkpO/v74iKhd7e3qKioqOjo2VnY5eZ +lJiZlpmalpmal/j4+P////////////////////////////////////////////////////// +/////////////////////////yH5BAEKAH8ALAAAAAAWABYAAAf+gH+Cg4QAAISIiYUBAYeK +j38AjIyOkIsCjAONloOSBAWZmpWPkgYHjZIIopCSCQqNCwySDauJkg4OjQ8QERKSE7WdARQV +jRYXGBkaG5IcwZEBHY0eHyAhISIjJCUBHJvCjSYnKCnlKiorLNzfgpItLi8wMSv0MTIyMzTc +o5E1Nv//0N3AkQOHjh38/tjgYaOHjx8/YgAJIiTHECJFbCSyYcTGkY9IZCRRsiQHkyZONCKy +8cQGFChRpCSZQqVKjipWrqgkZAOLjSxZtPiYsoVLFy9fwITZOchGChtioooZs4VMmatlRDAV +ZOOKmTNo0qjZwaOs2TVbFQJcyxYgp7cEcDkFAgA7} + +image create photo ::ttk::dialog::image::gohomebw -data { +R0lGODlhFgAWAOcAAAAAAAEBAQICAgMDAwQEBAUFBQYGBgcHBwgICAkJCQoKCgsLCwwMDA0N +DQ4ODg8PDxAQEBERERISEhMTExQUFBUVFRYWFhcXFxgYGBkZGRoaGhsbGxwcHB0dHR4eHh8f +HyAgICEhISIiIiMjIyQkJCUlJSYmJicnJygoKCkpKSoqKisrKywsLC0tLS4uLi8vLzAwMDEx +MTIyMjMzMzQ0NDU1NTY2Njc3Nzg4ODk5OTo6Ojs7Ozw8PD09PT4+Pj8/P0BAQEFBQUJCQkND +Q0REREVFRUZGRkdHR0hISElJSUpKSktLS0xMTE1NTU5OTk9PT1BQUFFRUVJSUlNTU1RUVFVV +VVZWVldXV1hYWFlZWVpaWltbW1xcXF1dXV5eXl9fX2BgYGFhYWJiYmNjY2RkZGVlZWZmZmdn +Z2hoaGlpaWpqamtra2xsbG1tbW5ubm9vb3BwcHFxcXJycnNzc3R0dHV1dXZ2dnd3d3h4eHl5 +eXp6ent7e3x8fH19fX5+fn9/f4CAgIGBgYKCgoODg4SEhIWFhYaGhoeHh4iIiImJiYqKiouL +i4yMjI2NjY6Ojo+Pj5CQkJGRkZKSkpOTk5SUlJWVlZaWlpeXl5iYmJmZmZqampubm5ycnJ2d +nZ6enp+fn6CgoKGhoaKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq6ysrK2tra6urq+v +r7CwsLGxsbKysrOzs7S0tLW1tba2tre3t7i4uLm5ubq6uru7u7y8vL29vb6+vr+/v8DAwMHB +wcLCwsPDw8TExMXFxcbGxsfHx8jIyMnJycrKysvLy8zMzM3Nzc7Ozs/Pz9DQ0NHR0dLS0tPT +09TU1NXV1dbW1tfX19jY2NnZ2dra2tvb29zc3N3d3d7e3t/f3+Dg4OHh4eLi4uPj4+Tk5OXl +5ebm5ufn5+jo6Onp6erq6uvr6+zs7O3t7e7u7u/v7/Dw8PHx8fLy8vPz8/T09PX19fb29vf3 +9/j4+Pn5+fr6+vv7+/z8/P39/f7+/v///yH5BAEKAP8ALAAAAAAWABYAAAj+AP8JHEgwRgyC +CBMW3LTpoMKH/2IwZOgQ4kI2DL80tDhQ4p0+GTVWfCgREKGGEruIhCgRkaKGWc6kXJlQoiNH +Dd0Q0qRJIheaHTdRgtQQ0CNcwXKtkrgFaMRNOGNM+uSrm9Vru2hs2rIxaMNQorSpG5su3blp +WrsKlPgDlChs5s7JNUeO3LhvWkdG3Falb1+zd/DUETxP778q7qr4+QMIkLlyeCjVkXRHXpWE +VdpVIcS5EDlxd/7UcUMn3mWEVdhVMWSIUCFx4Ox0qdOFDrzTBKusq3Ko9x9w+WTt0sWL1Dvc +A6uoq4KoOSJv+USNmj6qG3KBVeCVuYQpU6Z57sIPi8d3/bDf8+j9clzPnmNAADs=} + +image create photo ::ttk::dialog::image::reload -data { +R0lGODlhFgAWAOcAADtqqDtrqDdnpTVmpThopjpqpzdopjpqqHeaxaC726zG4q7I46jC3p25 +2X6hyk16sDZnpTdnpjRlpFqDt7fN5bDI4qC82q3G4bfN5rrP5rvR57vQ57vR6K/H4W+VwThp +pnOYxUZ0rkVyrJ+52Ux4sDlppjdmpU56sYWmzbbN5bXM5abC4LHK5KO/3X+iy8PW6kNxrDtq +p1N+sz5tq0BvqzZnpDpppzprqH+kzLHJ45a325G02bTM5cja7EBuqjtrpzVlpE56tGKNw0x4 +r6fA3a/J43Sfz83d7j1sqD9uq2yWyjpqqT5tqbTJ4pS22nKfz9Xi8DdopabA3cna7M3d7dTi +8Nzn8zZnpjRlpTlppzhopzZmpTVlpdrl8eDp8+Dp9OHq9Nnk8FV+szVmpOLr9aC+3qG+3dvm +8n+gx0FwrOPs9Zu63L3S6Nzm8lB8smWOxEd2sDxsqDRmpOTs9crb7K7I4sHV6oKjyzdopz5u +qz1sqUd0ruXt9sDS5tjj8dHf7qrG4sDU6bjN5YSkzGqQv1B7sj1rqEBuqVeBtZOy1sXV6Dlo +pjtppoelysjY6bDJ5LPK5KrE4Zq42j9vqURxqjxpo2qOvJSx07LJ4rbN5qK+3XKXwy9ZjzNl +pDFbkTZlojZno0FuqDdnpDZmpDRfl/////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +/////////////////////////////////yH5BAEKAP8ALAAAAAAWABYAAAj+AP8JHEiwoMGD +CBMWBBBAwAACBQwYHGCwwAEECRQsYNDAwQMIAyNIKFhgAoUKFi5gyKBhA4cOHj5EABGioIgR +JCKUMAHhBIoUKlawaOHiBQyCMWTEmEGjxkAbN3Dk0LGDRw8fBH8ACSLEhsEPQ4gUMXIECUEb +SZT8W3KQSRMnT6B4HShAYRQpU6hUsXJFIUEsEm5k0WLgChaCA7YoXszF78ABXbx8ARNGjMIx +BIGQKWPmDBqJBW8ITAMAsZo1bNq4yWLQwBs4EuIQlDOHTh07Vu7gASlwQB49MPYUlMOnj58/ +gAIJGkSokKFDiFwkIlAQgqJFjBo5osBDxSMWkBYmRJI0yeAYSgMrWbqEiU2mHJo2leBksJNB +T59AhRI1ipTj/wD6FRAAOw==} + +image create photo ::ttk::dialog::image::folder_new -data { +R0lGODlhEAAQAMYAAG1va2dpZc7OzsrEuW1pXvyxPsDAv5aXlZuYkOOrVb6cZODCkfvSkNyy +bMuYSfywPsnJyaamptm5hv3nw/765/740f3urPzJZvuyQGF6mjRlpDtnoFJwlNvFnv766P77 +5P32u/3xkfzkddSsW2R4jMbY677S6MjMy+64Y/zTk/740/32vP3zo/zue/zoYPq+SNCgVK7H +44yx2I+w05yxwebFif3vrv3xkvzufPzrYfzfUe2+YV9hXdCyfvzLavzld/zoYfzgUfvDRNu6 +gVVXU5OwzeGwYs2yf+a7Zvq9SeW6YNCxeem1ZT5onpWwy5Gw0J2xwOOxX7PF2ERrm4+x0p6x +vomu1qbC4Dlnoq3H44uw14qv14iu1oWr1YCo03qk0nOgz26dzpi53Fh2m5u73XCeznCdz26c +zm2czmybzmubzWqazmmZzWiZzZS226mrqYmv12uazWqazWiYzWaYzGWYzWWXzGSWzGOVzJq6 +3lNxlkVdeT5giT9ghv///////yH5BAEKAH8ALAAAAAAQABAAAAfNgH8Ag4MBAX+IiYgAAo2O +AwSIBYoABgeXlwgJCgsMDQ4PghARpKUSExQVFhcYfwEGGRqyGxwdHh8gISIjJAEQGiUmJico +KSorLC0uLzCvGjEyMjM0NTY3ODk6Oxw8v9DRMj0+P0BBQkMaRAbP4EVGR0hJSktMTUTe4E5P +MlBRNDJSpqhjBy4alSozrFxJBwFLFi0ytGzh0sXLFzBhxKQzMIZMGTNhzqBJo2YNmzZu0r2B +oyaOHDZz6NSxcwdPHj17+MjayZNnH0VAgyIKBAA7} + +image create photo ::ttk::dialog::image::configure -data { +R0lGODlhFgAWAMYAAH9/f+rp6Pn5+NjY1/j39vPy8YKXsjRlpOzq6P///050pHx8fLu7u+3r +6szMzK+vr2WErOjn5Orq6q2trePj4vr6+Xl4dNzc3JmZmejn5vLx7+3r6evp5/r6+oeHh8/N +yvj49/n59/n49/7+/p6enrW1tfb29Z+fnvj4+Ofm5LvByEVxqfT09J2wyt/f31l9q6enpiBK +h1R8rqSttvv7+3WQrqS60JCmvqexvcHBwePi4dPf6qKuvJ22zmN7lYScttfi7Y2YpZ240mB3 +kZmtw9/n8IGTqVhthFtxiYaGhqG0yO7z9mB2j+Tj4V9fXpGmvvD095eltgAAALDG2+3y9oGK +lWyFocDR4v////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +/////////////////////////yH5BAEKAH8ALAAAAAAWABYAAAfygH+CggAAg4eIiX8AAQID +hoqRhAQFj5EGB5EACAKQiAcJCpl/C4WCDA2diaAODxCEERIAExQIFRarFw+jfxgZGhsIHMOq +gwcdB7yCHh8gAiECwyKQByPKhySFACUCwiYnByjXkgACKSorLOOSiy0HLi8w7Icx9QcsMjM0 +npIxNTY3YhzAkUPHCH6J/O3g0cNHDAAjhh2MFOMHkCA+hAyJsWiEsImIYhApYuSIkBpIOHaU +mISekiVGmJxMeQhiEycgYzyBEkUmSpWCpAgdKvRPjClUqswEGpToUKNWhFx5QjORUymDYlix +4lAS0ZD15hUVFAgAOw==} + +image create photo ::ttk::dialog::image::folder -data { +R0lGODlhEAAQAKUAAG1va2dpZc7OzsbGxWNlYcDAv5aXlVVXU8nJyaampqenp6ioqGF6mjRl +pEZtnMbY677S6K7H44yx2F9hXYmu1qbC4Dlnoq3H44uw14qv14iu1oWr1YCo03qk0nOgz26d +zpi53Fh2m5u73XCeznCdz26czm2czmybzmubzWqazmmZzWiZzZS226mrqYmv12uazWqazWiY +zWaYzGWYzWWXzGSWzGOVzJq63lNxlkVdeT5giT9ghv///////////////yH5BAEKAD8ALAAA +AAAQABAAAAaGwB9gOAwEfsgkEiBoOgcEZRJQMFivhoNWu0QkvmCwYnFABgqMhnrNVjsCiMYD +Qq/bH41zIyLp+/8RDRNxfH+GgQcFe4aHDQeEjICOioWRFBWOCBYXGBIYGRobHB0eHyCTISIj +JB8lJicoKSorLI4tLigvMCoxMjM0NTY3ODk6bcdqO1LLy0EAOw==} + +image create photo ::ttk::dialog::image::file -data { +R0lGODlhEAAQAIQAAJmZmYGBgf///+zs7Orq6uvr6+3t7fDw8MTExMXFxcbGxsfHx+7u7u3t +5e3t5u/v78jIyPHx8fLy8pWVlf////////////////////////////////////////////// +/yH5BAEKAB8ALAAAAAAQABAAAAVuIBCMZDl+aCCsbLsGqTAQRGEPg3EI8KcSiERCQVQsdr3f +DWcwMJCxwrBIPPKiBaahMXhefYIClcFweJOynJPxaEPBg+JiAam/VTmyO8L/qgxGdHV8En4C +TWwPBwcREoVoLpE9EyaVARMomZqbmiEAOw==} + +# Images for ttk::chooseDirectory + +image create photo ::ttk::dialog::image::dirclose -data { +R0lGODlhCQAJAKUAAFRWUlVXU1pcWP///1lbV2BiXt/i3Obo5O3u6/P08vj4911fW2NlYeHk +3+bp5Ovt6u/x7vDx72ZoZAAAAGNmYWpsZ93g2t7h2+Di3WdpZG1vatjb1dfb1Njb1Nfb09XZ +0WpsaHBybW1wa3N1cP////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////yH5BAEKAD8ALAAA +AAAJAAkAAAY4QEBgSBwKBsjkgFAYGA6IhGKwYAwajgckMihIBpNweECpDCwXDOYyyGgGG07H +8xmAQsqkaMTv94MAOw==} + +image create photo ::ttk::dialog::image::diropen -data { +R0lGODlhCQAJAKUAAFRWUlVXU1pcWP///1lbV2BiXt/i3Obo5AAAAPP08vj4911fW2NlYeHk +3+bp5O/x7vDx72ZoZGNmYWpsZ93g2t7h2+Di3WdpZG1vatjb1dfb1Nfb09XZ0WpsaHBybW1w +a3N1cP////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////yH5BAEKAD8ALAAA +AAAJAAkAAAY4QEBgSBwKBsjkgFAYGA6IhGKwYAwaDsQDMihEBohweCCZDCgVhKUyuGAGGQ1i +wxl0PMrkB8Tv94MAOw==} + +### ttk::getOpenFile, ttk::getSaveFile, ttk::getAppendFile + +proc ttk::getOpenFile {args} { + return [::ttk::dialog::file::tkFDialog open $args] +} + +proc ttk::getSaveFile {args} { + return [::ttk::dialog::file::tkFDialog save $args] +} + +proc ttk::getAppendFile {args} { + return [::ttk::dialog::file::tkFDialog append $args] +} + +proc ::ttk::dialog::file::Create {win class} { + toplevel $win -class $class + wm withdraw $win + + set dataName [winfo name $win] + upvar ::ttk::dialog::file::$dataName data + + # Additional frame to make sure the toplevel has the correct + # background color for the theme + # + set w [ttk::frame $win.f] + pack $w -fill both -expand 1 + + # f1: the toolbar + # + set f1 [ttk::frame $w.f1 -class Toolbar] + set data(bgLabel) [ttk::label $f1.bg -style Toolbutton] + set data(upBtn) [ttk::button $f1.up -style Toolbutton] + $data(upBtn) configure -image {::ttk::dialog::image::up + disabled ::ttk::dialog::image::upbw} \ + -command [list ::ttk::dialog::file::UpDirCmd $win] + set data(prevBtn) [ttk::button $f1.prev -style Toolbutton] + $data(prevBtn) configure -image {::ttk::dialog::image::previous + disabled ::ttk::dialog::image::previousbw} \ + -command [list ::ttk::dialog::file::PrevDirCmd $win] + set data(nextBtn) [ttk::button $f1.next -style Toolbutton] + $data(nextBtn) configure -image {::ttk::dialog::image::next + disabled ::ttk::dialog::image::nextbw} \ + -command [list ::ttk::dialog::file::NextDirCmd $win] + set data(homeBtn) [ttk::button $f1.home -style Toolbutton] + $data(homeBtn) configure -image {::ttk::dialog::image::gohome \ + disabled ::ttk::dialog::image::gohomebw} \ + -command [list ::ttk::dialog::file::HomeDirCmd $win] + set data(reloadBtn) [ttk::button $f1.reload -style Toolbutton] + $data(reloadBtn) configure -image ::ttk::dialog::image::reload \ + -command [list ::ttk::dialog::file::Update $win] + set data(newBtn) [ttk::button $f1.new -style Toolbutton] + $data(newBtn) configure -image ::ttk::dialog::image::folder_new \ + -command [list ::ttk::dialog::file::NewDirCmd $win] + set data(cfgBtn) [ttk::menubutton $f1.cfg -style Toolbutton] + set data(cfgMenu) [menu $data(cfgBtn).menu -tearoff 0] + $data(cfgBtn) configure -image ::ttk::dialog::image::configure \ + -menu $data(cfgMenu) + set data(dirMenuBtn) [ttk::combobox $f1.menu] + $data(dirMenuBtn) configure \ + -textvariable ::ttk::dialog::file::${dataName}(selectPath) + + set data(sortMenu) [menu $data(cfgMenu).sort -tearoff 0] + + $data(cfgMenu) add cascade -label " Sorting" -menu $data(sortMenu) + $data(cfgMenu) add separator + $data(cfgMenu) add radiobutton -label "Short View" \ + -variable ::ttk::dialog::file::details -value 0 \ + -command [list ::ttk::dialog::file::setopt $win \ + -details ::ttk::dialog::file::details] + $data(cfgMenu) add radiobutton -label "Detailed View" \ + -variable ::ttk::dialog::file::details -value 1 \ + -command [list ::ttk::dialog::file::setopt $win \ + -details ::ttk::dialog::file::details] + $data(cfgMenu) add separator + $data(cfgMenu) add checkbutton -label "Show Hidden Files" \ + -variable ::ttk::dialog::file::hidden \ + -command [list ::ttk::dialog::file::setopt $win \ + -hidden ::ttk::dialog::file::hidden] + $data(cfgMenu) add checkbutton -label "Separate Folders" \ + -variable ::ttk::dialog::file::sepfolders \ + -command [list ::ttk::dialog::file::setopt $win \ + -sepfolders ::ttk::dialog::file::sepfolders] + $data(sortMenu) add radiobutton -label "By Name" \ + -variable ::ttk::dialog::file::sort -value name \ + -command [list ::ttk::dialog::file::setopt $win \ + -sort ::ttk::dialog::file::sort] + $data(sortMenu) add radiobutton -label "By Date" \ + -variable ::ttk::dialog::file::sort -value date \ + -command [list ::ttk::dialog::file::setopt $win \ + -sort ::ttk::dialog::file::sort] + $data(sortMenu) add radiobutton -label "By Size" \ + -variable ::ttk::dialog::file::sort -value size \ + -command [list ::ttk::dialog::file::setopt $win \ + -sort ::ttk::dialog::file::sort] + $data(sortMenu) add separator + $data(sortMenu) add checkbutton -label "Reverse" \ + -variable ::ttk::dialog::file::reverse \ + -command [list ::ttk::dialog::file::setopt $win \ + -reverse ::ttk::dialog::file::reverse] + $data(sortMenu) add checkbutton -label "Folders First" \ + -variable ::ttk::dialog::file::foldersfirst \ + -command [list ::ttk::dialog::file::setopt $win \ + -foldersfirst ::ttk::dialog::file::foldersfirst] + + $data(prevBtn) state disabled + $data(nextBtn) state disabled + if {![info exists ::env(HOME)]} { + $data(homeBtn) state disabled + } + + place $data(bgLabel) -relheight 1 -relwidth 1 + + pack $data(upBtn) -side left -fill y + pack $data(prevBtn) -side left -fill y + pack $data(nextBtn) -side left -fill y + pack $data(homeBtn) -side left -fill y + pack $data(reloadBtn) -side left -fill y + pack $data(newBtn) -side left -fill y + pack $data(cfgBtn) -side left -fill y + pack $data(dirMenuBtn) -side left -fill x -expand 1 -padx 8 + + # f2: the frame with the OK button, cancel button, "file name" field, + # and file types field. + # + set f2 [ttk::frame $w.f2] + ttk::label $f2.lab1 -text "Location:" -anchor w + set data(location) [ttk::combobox $f2.loc] + $data(location) configure \ + -textvariable ::ttk::dialog::file::${dataName}(selectFile) + set data(typeMenuLab) [ttk::label $f2.lab2 -text "Filter:" -anchor w] + set data(typeMenuBtn) [ttk::combobox $f2.filter] + set data(okBtn) [ttk::button $f2.ok -text OK -default active \ + -width 8 -style Slim.TButton \ + -command [list ::ttk::dialog::file::Done $win]] + set data(cancelBtn) [ttk::button $f2.cancel -text Cancel \ + -width 8 -style Slim.TButton \ + -command [list ::ttk::dialog::file::Cancel $win]] + + grid $f2.lab1 $f2.loc $data(okBtn) -padx 4 -pady 5 -sticky ew + grid $f2.lab2 $f2.filter $data(cancelBtn) -padx 4 -pady 5 -sticky ew + grid columnconfigure $f2 1 -weight 1 + + # f3: The file and directory lists + # + set f3 [ttk::paned $w.f3 -orient horizontal] + set font TkDefaultFont + destroy $f3.dummy + $f3 add [ttk::frame $f3.dir] -weight 0 + ttk::label $f3.dir.bg -relief sunken + set data(dirArea) [text $f3.dir.t -bg white -width 20 -height 16 \ + -font $font -bd 0 -highlightthickness 0 -cursor "" \ + -wrap none -spacing1 1 -spacing3 1 -exportselection 0 \ + -state disabled -yscrollcommand [list $f3.dir.y set] \ + -xscrollcommand [list $f3.dir.x set]] + ttk::scrollbar $f3.dir.y -command [list $f3.dir.t yview] + ttk::scrollbar $f3.dir.x -command [list $f3.dir.t xview] \ + -orient horizontal + grid $f3.dir.t $f3.dir.y -sticky ns + grid $f3.dir.x -sticky we + grid $f3.dir.bg -row 0 -column 0 -rowspan 2 -columnspan 2 -sticky news + grid $f3.dir.t -sticky news -padx {2 0} -pady {2 0} + grid columnconfigure $f3.dir 0 -weight 1 + grid rowconfigure $f3.dir 0 -weight 1 + + $f3 add [ttk::frame $f3.file] -weight 1 + + # The short view version + # + set data(short) [ttk::frame $f3.file.short] + ttk::label $data(short).bg -relief sunken + set data(fileArea) [text $data(short).t -width 50 -height 16 \ + -bg white -font $font -bd 0 -highlightthickness 0 \ + -cursor "" -wrap none -spacing1 1 -spacing3 1 \ + -exportselection 0 -state disabled \ + -xscrollcommand [list ::ttk::dialog::file::scrollset $win]] + set data(xScroll) [ttk::scrollbar $data(short).x -orient horizontal \ + -command [list ::ttk::dialog::file::xview $win]] +# set data(xScroll) [ttk::scrollbar $data(short).x -orient horizontal \ +# -command [list $data(short).t xview]] + grid $data(short).t -sticky news -padx 2 -pady {2 0} + grid $data(short).x -sticky ew + grid $data(short).bg -row 0 -column 0 \ + -rowspan 2 -columnspan 2 -sticky news + grid columnconfigure $data(short) 0 -weight 1 + grid rowconfigure $data(short) 0 -weight 1 + + # The detailed view version + # + set data(long) [ttk::frame $f3.file.long] + ttk::label $data(long).bg -relief sunken + ttk::frame $data(long).f + set data(fileHdr) [frame $data(long).f.f] + ttk::label $data(fileHdr).l0 -text Name -style Toolbutton -anchor w + ttk::label $data(fileHdr).l1 -text Size -style Toolbutton -anchor w + ttk::label $data(fileHdr).l2 -text Date -style Toolbutton -anchor w + ttk::label $data(fileHdr).l3 -text Permissions -style Toolbutton -anchor w + ttk::label $data(fileHdr).l4 -text Owner -style Toolbutton -anchor w + ttk::label $data(fileHdr).l5 -text Group -style Toolbutton -anchor w + ttk::separator $data(fileHdr).s1 -orient vertical + ttk::separator $data(fileHdr).s2 -orient vertical + ttk::separator $data(fileHdr).s3 -orient vertical + ttk::separator $data(fileHdr).s4 -orient vertical + ttk::separator $data(fileHdr).s5 -orient vertical + set height [winfo reqheight $data(fileHdr).l1] + $data(long).f configure -height [expr {$height + 1}] + $data(fileHdr) configure -height $height + place $data(fileHdr) -x 1 -relwidth 1 + place $data(fileHdr).l0 -x -1 -relwidth 1 -relheight 1 + place $data(fileHdr).s1 -rely .1 -relheight .8 -anchor n + place $data(fileHdr).s2 -rely .1 -relheight .8 -anchor n + place $data(fileHdr).s3 -rely .1 -relheight .8 -anchor n + place $data(fileHdr).s4 -rely .1 -relheight .8 -anchor n + place $data(fileHdr).s5 -rely .1 -relheight .8 -anchor n + set data(fileList) [text $data(long).t -width 42 -height 12 \ + -bg white -font $font -bd 0 -highlightthickness 0 \ + -cursor "" -wrap none -spacing1 1 -spacing3 1 \ + -exportselection 0 -state disabled \ + -yscrollcommand [list $data(long).y set] \ + -xscrollcommand [list ::ttk::dialog::file::scrollhdr $win]] + ttk::scrollbar $data(long).y -command [list $data(long).t yview] + ttk::scrollbar $data(long).x -orient horizontal \ + -command [list $data(long).t xview] + grid $data(long).f $data(long).y -sticky ew -padx {2 0} -pady {2 0} + grid $data(long).t ^ -sticky news -padx {2 0} + grid $data(long).x -sticky ew + grid $data(long).y -sticky ns -padx 0 -pady 0 + grid $data(long).bg -row 0 -column 0 \ + -rowspan 3 -columnspan 2 -sticky news + grid columnconfigure $data(long) 0 -weight 1 + grid rowconfigure $data(long) 1 -weight 1 + + grid $data(long) $data(short) -row 0 -column 0 -sticky news + grid columnconfigure $f3.file 0 -weight 1 + grid rowconfigure $f3.file 0 -weight 1 + + # Get rid of the default Text bindings + bindtags $data(dirArea) [list $data(dirArea) FileDialogDir $win all] + bindtags $data(fileArea) [list $data(fileArea) FileDialogFile $win all] + bindtags $data(fileList) [list $data(fileList) FileDialogList $win all] + + $data(fileArea) tag bind file <1> \ + {set ::ttk::dialog::file::filetype file} + $data(fileArea) tag bind characterSpecial <1> \ + {set ::ttk::dialog::file::filetype file} + $data(fileArea) tag bind blockSpecial <1> \ + {set ::ttk::dialog::file::filetype file} + $data(fileArea) tag bind fifo <1> \ + {set ::ttk::dialog::file::filetype file} + $data(fileArea) tag bind link <1> \ + {set ::ttk::dialog::file::filetype link} + $data(fileArea) tag bind directory <1> \ + {set ::ttk::dialog::file::filetype directory} + $data(fileList) tag bind file <1> \ + {set ::ttk::dialog::file::filetype file} + $data(fileList) tag bind characterSpecial <1> \ + {set ::ttk::dialog::file::filetype file} + $data(fileList) tag bind blockSpecial <1> \ + {set ::ttk::dialog::file::filetype file} + $data(fileList) tag bind fifo <1> \ + {set ::ttk::dialog::file::filetype file} + $data(fileList) tag bind link <1> \ + {set ::ttk::dialog::file::filetype link} + $data(fileList) tag bind directory <1> \ + {set ::ttk::dialog::file::filetype directory} + + set data(paneWin) $f3 + + pack $f1 -side top -fill x + pack $f2 -side bottom -fill x -padx 8 -pady {0 5} + pack $f3 -side bottom -fill both -expand 1 -padx 8 -pady {6 0} + + set data(columns) 0 + set data(history) "" + set data(histpos) -1 + + update idletasks + pack propagate $w 0 + + wm protocol $win WM_DELETE_WINDOW [list $data(cancelBtn) invoke] + + bind $data(fileArea) \ + [list ::ttk::dialog::file::configure $win] + bind $data(dirMenuBtn) [list ::ttk::dialog::file::chdir $win] + bind $data(dirMenuBtn) <> \ + [list ::ttk::dialog::file::chdir $win] + bind $data(location) [list ::ttk::dialog::file::Done $win] + bind $data(typeMenuBtn) \ + [list ::ttk::dialog::file::SetFilter $win] + bind $data(typeMenuBtn) <> \ + [list ::ttk::dialog::file::SelectFilter $win] +} + +proc ::ttk::dialog::file::ChangeDir {w dir} { + set dataName [winfo name $w] + upvar ::ttk::dialog::file::$dataName data + + set data(history) [lrange $data(history) 0 $data(histpos)] + set cwd [lindex $data(history) $data(histpos)] + set data(selectPath) [file normalize [file join $cwd $dir]] + lappend data(history) $data(selectPath) + if {[incr data(histpos)]} { + $data(prevBtn) state !disabled + set data(selectFile) "" + } + $data(nextBtn) state disabled + + UpdateWhenIdle $w +} + +proc ::ttk::dialog::file::UpdateWhenIdle {w} { + upvar ::ttk::dialog::file::[winfo name $w] data + + if {[info exists data(updateId)]} { + return + } elseif {[winfo ismapped $w]} { + set after idle + } else { + set after 1 + } + set data(updateId) [after $after [list ::ttk::dialog::file::Update $w]] +} + +proc ::ttk::dialog::file::Update {w} { + # This proc may be called within an idle handler. Make sure that the + # window has not been destroyed before this proc is called + if {![winfo exists $w]} { + return + } + + set dataName [winfo name $w] + upvar ::ttk::dialog::file::$dataName data + unset -nocomplain data(updateId) + + if {$data(-details)} { + grid $data(long) + grid remove $data(short) + } else { + grid $data(short) + grid remove $data(long) + } + if {$data(-sepfolders)} { + if {![llength [winfo manager $data(paneWin).dir]]} { + $data(paneWin) insert 0 $data(paneWin).dir + } + } else { + if {[llength [winfo manager $data(paneWin).dir]]} { + $data(paneWin) forget 0 + } + } + + $w configure -cursor watch + update + + set dir ::ttk::dialog::image::folder + set file ::ttk::dialog::image::file + + set cwd [lindex $data(history) $data(histpos)] + + if {$data(-hidden)} { + set pattern "* .*" + } else { + set pattern "*" + } + + # Make the directory list + set dlist "" + foreach f [eval glob -nocomplain -tails \ + -directory $cwd -type d $pattern] { + if {[string equal $f .]} continue + if {[string equal $f ..]} continue + lappend dlist [list $f dir] + } + + # Make the file list + set flist "" + set filter $data(filter) + if {[string equal $filter *]} { + set filter $pattern + } + foreach f [eval [linsert $filter 0 glob -nocomplain -tails \ + -directory $cwd -type {f l c b p}]] { + # Links can still be directories. Skip those. + if {[file isdirectory [file join $cwd $f]]} continue + lappend flist [list $f file] + } + + # Combine the two lists, if necessary + if {$data(-sepfolders)} { + set dlist [sort $w $dlist] + set flist [sort $w $flist] + } elseif {$data(-foldersfirst)} { + set flist [concat [sort $w $dlist] [sort $w $flist]] + set dlist "" + } else { + set flist [sort $w [concat $flist $dlist]] + set dlist "" + } + + set t $data(dirArea) + $t configure -state normal + $t delete 1.0 end + foreach f $dlist { + $t image create end -image $dir + $t insert end " [lindex $f 0]\n" + } + $t delete end-1c end + $t configure -state disabled + + if {$data(-details)} { + set t $data(fileList) + $t configure -state normal + $t delete 1.0 end + set size "" + set date "" + set mode "" + set uid "" + set gid "" + set maxsize 50 + set font [$t cget -font] + foreach f $flist { + lassign $f name type size date mode uid gid + if {![info exists users($uid)] || \ + ![info exists groups($gid)]} { + set fname [file join $cwd $name] + # May fail for dead links + if {![catch {array set attr \ + [file attributes $fname]}]} { + if {[info exists attr(-owner)]} { + set users($uid) $attr(-owner) + } else { + set users($uid) "" + } + if {[info exists attr(-group)]} { + set groups($gid) $attr(-group) + } else { + set groups($gid) "" + } + } + } + catch {set uid $users($uid)} + catch {set gid $groups($gid)} + set image [expr {$type eq "directory" ? $dir : $file}] + set img [$t image create end -image $image] + $t tag add name $img + $t tag add $type $img + $t insert end " $name" [list name $type] + $t insert end "\t$size\t" $type + $t insert end "[datefmt $date]\t" $type + $t insert end "[modefmt $type $mode]\t" $type + $t insert end "$uid\t$gid\t\n" $type + set size [font measure $font " $name"] + if {$size > $maxsize} { + set maxsize $size + } + } + $t delete end-1c end + $t configure -state disabled + set today [datefmt [clock seconds]] + set maxp [winfo reqwidth $data(fileHdr).l3] + set maxu [winfo reqwidth $data(fileHdr).l4] + foreach n [array names users] { + set size [font measure $font $users($n)] + if {$size > $maxu} {set maxu $size} + } + set maxg [winfo reqwidth $data(fileHdr).l5] + foreach n [array names groups] { + set size [font measure $font $groups($n)] + if {$size > $maxg} {set maxg $size} + } + set tabs [list [set x [incr maxsize 22]]] + lappend tabs [incr x [font measure $font 1000000000]] \ + [incr x [font measure $font " $today "]] \ + [incr x [incr maxp 8]] \ + [incr x [incr maxu 8]] [incr x [incr maxg 8]] + $t configure -tabs $tabs + set i 1 + foreach n $tabs { + place $data(fileHdr).l$i -x $n + place $data(fileHdr).s$i -x $n + if {[incr i] > 5} break + } + } else { + set t $data(fileArea) + $t configure -state normal + $t delete 1.0 end + set lines [expr {[winfo height $t] / 18}] + set row 1 + set col 0 + set maxsize 50 + set list "" + set font [$t cget -font] + foreach f $flist { + set idx "$row.end" + lassign $f name type + set image [expr {$type eq "directory" ? $dir : $file}] + set img [$t image create $idx -image $image] + $t tag add $type $img + $t tag add name $img + $t insert $idx " $name" [list name $type] "\t" $type + lappend list $name $type + set size [font measure $font " $name"] + if {$size > $maxsize} { + set maxsize $size + } + if {[incr row] > $lines} { + incr col + set row 1 + } elseif {$col == 0} { + $t insert $idx "\n" + } + } + # Make sure maxsize is a multiple of an average size character + set dx [font measure $font 0] + set maxsize [expr {($maxsize + 20 + $dx) / $dx * $dx}] + $t insert 1.end "\t" + $t configure -state disabled + $t configure -tabs $maxsize + set data(columns) [expr {$row > 1 ? $col + 1 : $col}] + set data(rows) $lines + set data(colwidth) $maxsize + set data(list) $list + } + + if {[string equal $cwd "/"]} { + $data(upBtn) state disabled + } else { + $data(upBtn) state !disabled + } + $w configure -cursor "" +} + +proc ::ttk::dialog::file::sort {w list} { + set dataName [winfo name $w] + upvar ::ttk::dialog::file::$dataName data + + set cwd [lindex $data(history) $data(histpos)] + set order [expr {$data(-reverse) ? "-decreasing" : "-increasing"}] + set newlist "" + foreach f $list { + set file [lindex $f 0] + # Use lstat in case the destination doesn't exists + file lstat [file join $cwd $file] stat + if {[string equal $stat(type) link]} { + # This may fail if the link points to nothing + if {![catch {file stat [file join $cwd $file] dest}]} { + array set stat [array get dest] + if {[string equal $stat(type) file]} { + set stat(type) link + } + } + } + lappend newlist [list $file $stat(type) $stat(size) \ + $stat(mtime) $stat(mode) $stat(uid) $stat(gid)] + } + switch -- $data(-sort) { + size { + set mode -integer + set idx 2 + } + date { + set mode -integer + set idx 3 + } + default { + set mode -dictionary + set idx 0 + } + } + lsort $order $mode -index $idx $newlist +} + +proc ::ttk::dialog::file::datefmt {str} { + clock format $str -format {%d-%m-%Y %H:%M} +} + +proc ::ttk::dialog::file::modefmt {type mode} { + switch $type { + file {set rc -} + default {set rc [string index $type 0]} + } + binary scan [binary format I $mode] B* bits + foreach b [split [string range $bits end-8 end] ""] \ + c {r w x r w x r w x} { + if {$b} {append rc $c} else {append rc -} + } + set rc +} + +proc ::ttk::dialog::file::xview {w cmd number {units ""}} { + set dataName [winfo name $w] + upvar ::ttk::dialog::file::$dataName data + + set width [winfo width $data(fileArea)] + lassign [$data(fileArea) xview] pos1 pos2 + set cols $data(columns) + set page [expr {int($width / $data(colwidth))}] + if {!$page} {set page 1} + + switch $cmd { + scroll { + set col [expr {round($pos1 * ($cols + 1))}] + if {[string match p* $units]} { + incr col [expr {$number * $page}] + } else { + incr col $number + } + } + moveto { + set col [expr {round($number * $cols)}] + } + } + set max [expr {$cols - $page}] + if {$col > $max} {set col $max} + if {$col < 0} {set col 0} + set pos [expr {double($col) / ($cols + 1)}] + $data(fileArea) xview moveto $pos +} + +proc ::ttk::dialog::file::scrollset {w first last} { + set dataName [winfo name $w] + upvar ::ttk::dialog::file::$dataName data + + if {$data(columns)} { + if {$last >= 0.999} { + xview $w scroll -1 units + return + } + set w $data(colwidth) + set cols $data(columns) + set width [winfo width $data(fileArea)] + set vwidth [expr {$width % $w + $cols * $w}] + set total [expr {$width / ($last - $first)}] + set first [expr {$first * $total / $vwidth}] + set last [expr {$last * $total / $vwidth}] + } + + $data(xScroll) set $first $last +} + +proc ::ttk::dialog::file::scrollhdr {w first last} { + set dataName [winfo name $w] + upvar ::ttk::dialog::file::$dataName data + + lassign [$data(fileList) dlineinfo @0,0] x y width height base + place $data(fileHdr) -x $x -width $width + $data(long).x set $first $last +} + +proc ::ttk::dialog::file::configure {w} { + set dataName [winfo name $w] + upvar ::ttk::dialog::file::$dataName data + + if {$data(columns) == 0} return + + set dir ::ttk::dialog::image::folder + set file ::ttk::dialog::image::file + + set h [winfo height $data(fileArea)] + set rows [expr {$h / 18}] + if {$rows == $data(rows)} return + set t $data(fileArea) + set lines $rows + set row 1 + set col 0 + $t configure -state normal + $t delete 1.0 end + foreach {name type} $data(list) { + set idx $row.end + set image [expr {$type eq "directory" ? $dir : $file}] + $t tag add file [$t image create $idx -image $image] + $t insert $idx " $name" file "\t" + if {[incr row] > $lines} { + incr col + set row 1 + } elseif {$col == 0} { + $t insert $idx "\n" + } + } + $t insert 1.end "\t" + $t configure -state disabled + set data(columns) [expr {$row > 1 ? $col + 1 : $col}] + set data(rows) $lines +} + +proc ::ttk::dialog::file::setopt {w option var} { + set dataName [winfo name $w] + upvar ::ttk::dialog::file::$dataName data + upvar #0 $var value + + + set data($option) $value + UpdateWhenIdle $w +} + +proc ::ttk::dialog::file::UpDirCmd {w} { + set dataName [winfo name $w] + upvar ::ttk::dialog::file::$dataName data + + ChangeDir $w [file dirname [lindex $data(history) $data(histpos)]] +} + +proc ::ttk::dialog::file::PrevDirCmd {w} { + set dataName [winfo name $w] + upvar ::ttk::dialog::file::$dataName data + + set data(selectFile) "" + incr data(histpos) -1 + set data(selectPath) [lindex $data(history) $data(histpos)] + $data(nextBtn) state !disabled + if {!$data(histpos)} { + $data(prevBtn) state disabled + } + Update $w +} + +proc ::ttk::dialog::file::NextDirCmd {w} { + set dataName [winfo name $w] + upvar ::ttk::dialog::file::$dataName data + + set data(selectFile) "" + incr data(histpos) + set data(selectPath) [lindex $data(history) $data(histpos)] + $data(prevBtn) state !disabled + if {$data(histpos) >= [llength $data(history)] - 1} { + $data(nextBtn) state disabled + } + Update $w +} + +proc ::ttk::dialog::file::HomeDirCmd {w} { + ChangeDir $w ~ +} + +proc ::ttk::dialog::file::NewDirCmd {win} { + set dataName [winfo name $win] + upvar ::ttk::dialog::file::$dataName data + + set dir [lindex $data(history) $data(histpos)] + + toplevel $win.new + wm title $win.new "New Folder" + set w [ttk::frame $win.new.f] + pack $w -expand 1 -fill both + + ttk::label $w.prompt -anchor w -justify left \ + -text "Create new folder in:\n$dir" + ttk::entry $w.box -width 36 -validate all \ + -validatecommand [list ::ttk::dialog::file::NewDirVCmd $w %P] + ttk::separator $w.sep + set f [ttk::frame $w.buttons] + ttk::button $f.clear -text Clear -takefocus 0 \ + -command [list $w.box delete 0 end] + ttk::button $f.ok -text OK -default active \ + -command [list ::ttk::dialog::file::NewDirExit $win 1] + ttk::button $f.cancel -text Cancel \ + -command [list ::ttk::dialog::file::NewDirExit $win] + grid $f.clear $f.ok $f.cancel -padx 4 -pady {0 10} -sticky we + grid columnconfigure $f {0 1 2} -uniform 1 + pack $w.prompt $w.box $w.sep $f \ + -side top -padx 12 -pady 3 -anchor w -fill x + pack $w.prompt -pady {12 0} + pack $f -anchor e -fill none -padx 8 + wm transient $win.new $win + wm resizable $win.new 0 0 + wm protocol $win.new WM_DELETE_WINDOW [list $f.cancel invoke] + + bind $w.box [list $f.ok invoke] + + ::tk::PlaceWindow $win.new widget $win + ::tk::SetFocusGrab $win.new $w.box +} + +proc ::ttk::dialog::file::NewDirVCmd {w str} { + if {[string length $str]} { + $w.buttons.ok state !disabled + $w.buttons.clear state !disabled + } else { + $w.buttons.ok state disabled + $w.buttons.clear state disabled + } + return 1 +} + +proc ::ttk::dialog::file::NewDirExit {w {save 0}} { + upvar ::ttk::dialog::file::[winfo name $w] data + + if {$save} { + set dir [lindex $data(history) $data(histpos)] + set newdir [file join $dir [$w.new.f.box get]] + if {[catch {file mkdir $newdir} err]} { + ttk::messageBox -type ok -parent $w.new -icon error \ + -message "$err" + return + } else { + ChangeDir $w $newdir + } + } + destroy $w.new + ::tk::RestoreFocusGrab $w.new $w.new.f.box +} + +proc ::ttk::dialog::file::Cancel {w} { + variable selectFilePath "" +} + +proc ::ttk::dialog::file::Done {w} { + variable selectFilePath + variable filelist + set dataName [winfo name $w] + upvar ::ttk::dialog::file::$dataName data + + if {![string length $data(selectFile)] || \ + [string equal $data(selectFile) .]} { + return -code break + } + + set cwd [lindex $data(history) $data(histpos)] + set path [file join $cwd $data(selectFile)] + + if {[file isdirectory $path]} { + ChangeDir $w $path + return -code break + } + + if {![string length [file extension $path]]} { + append path $data(-defaultextension) + } + + if {[file exists $path]} { + if {[string equal $data(type) save]} { + set reply [ttk::messageBox -icon warning -type yesno \ + -parent $w -message "File\ + \"$path\" already exists.\nDo\ + you want to overwrite it?"] + if {[string equal $reply "no"]} {return} + } + } else { + if {[string equal $data(type) open]} { + ttk::messageBox -icon warning -type ok -parent $w \ + -message "File \"$path\" does not exist." + return + } + } + + set idx [lsearch -exact $filelist $path] + set filelist [linsert [lreplace $filelist $idx $idx] 0 $path] + + set selectFilePath $path + return -code break +} + +proc ::ttk::dialog::file::chdir {w} { + upvar ::ttk::dialog::file::[winfo name $w] data + + set dir $data(selectPath) + if {[file isdirectory $dir]} { + ChangeDir $w $dir + } else { + ttk::messageBox -type ok -parent $w \ + -message "Cannot change to the directory\ + \"$data(selectPath)\".\nPermission denied." \ + -icon warning + } + return -code break +} + +proc ::ttk::dialog::file::SelectFilter {w} { + upvar ::ttk::dialog::file::[winfo name $w] data + + set data(filter) [lindex $data(-filetypes) \ + [$data(typeMenuBtn) current] 1] + ::ttk::dialog::file::UpdateWhenIdle $w +} + +proc ::ttk::dialog::file::SetFilter {w} { + upvar ::ttk::dialog::file::[winfo name $w] data + + set data(filter) [$data(typeMenuBtn) get] + ::ttk::dialog::file::UpdateWhenIdle $w + return -code break +} + +proc ::ttk::dialog::file::DirButton1 {w x y} { + scan [$w index @$x,$y] %d.%d line char + $w tag remove sel 1.0 end + $w tag add sel $line.2 $line.end +} + +proc ::ttk::dialog::file::DirRelease1 {w x y} { + set top [winfo toplevel $w] + $top configure -cursor "" +} + +proc ::ttk::dialog::file::DirDouble1 {w x y} { + set dir [$w get sel.first sel.last] + ChangeDir [winfo toplevel $w] $dir +} + +proc ::ttk::dialog::file::DirMotion1 {w x y} { + [winfo toplevel $w] configure -cursor "X_cursor #C00 #000" +} + +proc ::ttk::dialog::file::FileButton1 {w x y} { + set dataName [winfo name [winfo toplevel $w]] + upvar ::ttk::dialog::file::$dataName data + variable filetype + + if {[string equal $filetype none]} return + + set range [$w tag prevrange name @$x,$y+1c "@$x,$y linestart"] + if {[llength $range]} { + lassign $range index1 index2 + $w tag remove sel 1.0 end + $w tag add sel $index1+2c $index2 + if {$filetype eq "file" || $filetype eq "link"} { + set data(selectFile) [$w get sel.first sel.last] + } + } +} + +proc ::ttk::dialog::file::FileRelease1 {w x y} { + set dataName [winfo name [winfo toplevel $w]] + upvar ::ttk::dialog::file::$dataName data + variable filetype + + set top [winfo toplevel $w] + if {[llength [$top cget -cursor]]} { + # The mouse has been moved, don't perform the action + $top configure -cursor "" + } elseif {![string equal $filetype directory]} { + # A file was selected + } elseif {[llength [$w tag ranges sel]]} { + set dir [$w get sel.first sel.last] + ChangeDir [winfo toplevel $w] $dir + } + [winfo toplevel $w] configure -cursor "" + set filetype none +} + +proc ::ttk::dialog::file::FileMotion1 {w x y} { + [winfo toplevel $w] configure -cursor "X_cursor #C00 #000" +} + +proc ::ttk::dialog::file::tkFDialog {type arglist} { + global env + variable selectFilePath + variable filelist + set dataName __ttk_filedialog + upvar ::ttk::dialog::file::$dataName data + + ::ttk::dialog::file::Config $dataName $type $arglist + + if {[string equal $data(-parent) .]} { + set w .$dataName + } else { + set w $data(-parent).$dataName + } + + if {![winfo exists $w]} { + ::ttk::dialog::file::Create $w TkFDialog + } elseif {![string equal [winfo class $w] TkFDialog]} { + destroy $w + ::ttk::dialog::file::Create $w TkFDialog + } else { + $data(fileArea) configure -state normal + $data(fileArea) delete 1.0 end + $data(fileArea) configure -state disabled + $data(dirArea) configure -state normal + $data(dirArea) delete 1.0 end + $data(dirArea) configure -state disabled + $data(prevBtn) state disabled + $data(nextBtn) state disabled + $data(upBtn) state disabled + set data(history) "" + set data(histpos) -1 + } + + wm transient $w $data(-parent) + + if {[llength $data(-filetypes)]} { + set titles "" + foreach type $data(-filetypes) { + lassign $type title filter + lappend titles $title + } + $data(typeMenuBtn) configure -values $titles + $data(typeMenuLab) state !disabled + $data(typeMenuBtn) state !disabled + $data(typeMenuBtn) current 0 + ::ttk::dialog::file::SelectFilter $w + } else { + set data(filter) "*" + $data(typeMenuBtn) configure -takefocus 0 + $data(typeMenuBtn) state disabled + $data(typeMenuLab) state disabled + } + + set dirlist "/" + if {[info exists env(HOME)] && ![string equal $env(HOME) /]} { + lappend dirlist $env(HOME) + } + if {[lsearch -exact $dirlist $data(selectPath)] < 0} { + lappend dirlist $data(selectPath) + } + foreach n $filelist { + set dir [file dirname $n] + if {[lsearch -exact $dirlist $dir] < 0} { + lappend dirlist $dir + } + } + $data(dirMenuBtn) configure -values $dirlist + $data(location) configure -values $filelist + + ::ttk::dialog::file::ChangeDir $w $data(selectPath) + + ::tk::PlaceWindow $w widget $data(-parent) + wm title $w $data(-title) + + ::tk::SetFocusGrab $w $data(location) + + tkwait variable ::ttk::dialog::file::selectFilePath + + ::tk::RestoreFocusGrab $w $data(location) withdraw + + return $selectFilePath +} + +proc ::ttk::dialog::file::Config {dataName type argList} { + upvar ::ttk::dialog::file::$dataName data + + set data(type) $type + + # 1: the configuration specs + # + set specs { + {-defaultextension "" "" ""} + {-filetypes "" "" ""} + {-initialdir "" "" ""} + {-initialfile "" "" ""} + {-parent "" "" "."} + {-title "" "" ""} + {-sepfolders "" "" 1} + {-foldersfirst "" "" 1} + {-sort "" "" "name"} + {-reverse "" "" 0} + {-details "" "" 0} + {-hidden "" "" 0} + } + + # 2: default values depending on the type of the dialog + # + if {![info exists data(selectPath)]} { + # first time the dialog has been popped up + set data(selectPath) [pwd] + set data(selectFile) "" + } + + # 3: parse the arguments + # + tclParseConfigSpec ::ttk::dialog::file::$dataName $specs "" $argList + + if {$data(-title) == ""} { + if {[string equal $type "save"]} { + set data(-title) "Save As" + } else { + set data(-title) "Open" + } + } + + # 4: set the default directory and selection according to the -initial + # settings + # + + # Ensure that initialdir is an absolute path name. + if {[string length $data(-initialdir)]} { + set dir [file normalize [file join [pwd] $data(-initialdir)]] + if {[string equal [file type $dir] "link"]} { + set dir [file normalize [file join $dir [file link $dir]]] + } + if {[file isdirectory $dir]} { + set data(selectPath) $dir + } else { + set data(selectPath) [pwd] + } + } + set data(selectFile) $data(-initialfile) + + # 5. Parse the -filetypes option + # + set data(-filetypes) [::tk::FDGetFileTypes $data(-filetypes)] + + if {![winfo exists $data(-parent)]} { + error "bad window path name \"$data(-parent)\"" + } + + variable sepfolders $data(-sepfolders) + variable foldersfirst $data(-foldersfirst) + variable sort $data(-sort) + variable reverse $data(-reverse) + variable details $data(-details) + variable hidden $data(-hidden) +} + +### ttk::chooseDirectory + +proc ::ttk::dialog::file::treeCreate {w} { + destroy $w + toplevel $w -class TkChooseDir + wm iconname $w Dialog + + set dataName [winfo name $w] + upvar ::ttk::dialog::file::$dataName data + + if {[winfo viewable [winfo toplevel $data(-parent)]] } { + wm transient $w $data(-parent) + } + + set f1 [ttk::frame $w.f1] + set data(dirMenuBtn) [ttk::combobox $f1.dir \ + -textvariable ::ttk::dialog::file::${dataName}(selectPath)] + pack $f1.dir -fill x -expand 1 -padx 8 -pady 5 + + set f2 [ttk::frame $w.f2] + ttk::frame $f2.f + ttk::label $f2.f.bg -relief sunken + set font TkDefaultFont + destroy $f2.f.dummy + ttk::label $f2.f.title -text Folder -anchor w -style Toolbutton + set data(text) [text $f2.f.text -width 48 -height 16 -font $font \ + -tabs 20 -wrap none -highlightthickness 0 -bd 0 -cursor "" \ + -spacing1 1 -spacing3 1 -exportselection 0 \ + -yscrollcommand [list $f2.f.scroll set]] + $data(text) mark set subdir end + $data(text) mark gravity subdir left + ttk::scrollbar $f2.f.scroll -command [list $data(text) yview] + grid $f2.f.title $f2.f.scroll -sticky ns + grid $f2.f.text ^ -sticky news -padx {2 0} -pady {0 2} + grid $f2.f.title -padx {2 0} -pady {2 1} -sticky ew + grid $f2.f.bg -column 0 -row 0 -columnspan 2 -rowspan 2 -sticky news + grid columnconfigure $f2.f 0 -weight 1 + grid rowconfigure $f2.f 1 -weight 1 + pack $f2.f -fill both -expand 1 -padx 8 -pady 4 + + set f3 [ttk::frame $w.f3] + ttk::button $f3.ok -text OK -default active \ + -command [list ::ttk::dialog::file::TreeDone $w] + ttk::button $f3.cancel -text Cancel \ + -command [list ::ttk::dialog::file::Cancel $w] + grid x $f3.ok $f3.cancel -sticky ew -padx {4 8} -pady 8 + grid columnconfigure $f3 {1 2} -uniform buttons -minsize 80 + grid columnconfigure $f3 0 -weight 1 + + pack $f1 -side top -fill x + pack $f3 -side bottom -fill x + pack $f2 -side top -fill both -expand 1 + + $data(text) image create end -padx 1 \ + -image ::ttk::dialog::image::folder + $data(text) insert end " /" name + $data(text) configure -state disabled + + # Get rid of the default Text bindings + bindtags $data(text) [list $data(text) DirDialog $w all] + + bind $data(dirMenuBtn) \ + [list ::ttk::dialog::file::TreeReturn $w] + + wm protocol $w WM_DELETE_WINDOW [list $f3.cancel invoke] +} + +proc ::ttk::dialog::file::treeUpdate {w dir} { + upvar ::ttk::dialog::file::[winfo name $w](text) txt + + set dir [file normalize [file join [pwd] $dir]] + set list [lassign [file split $dir] parent] + lappend list . + $txt configure -state normal + $txt delete 1.end end + $txt mark set subdir end + + foreach d $list { + treeOpen $w $parent subdir $d + set parent [file join $parent $d] + } + $txt yview subdir-5l + TreeSelect $w subdir +} + +proc ::ttk::dialog::file::treeOpen {w path {index insert} {subdir .}} { + upvar ::ttk::dialog::file::[winfo name $w](text) txt + + set level [llength [file split $path]] + set tabs [string repeat "\t" [expr {$level - 1}]] + set img [lindex [$txt dump -image \ + "$index linestart" "$index lineend"] 1] + if {[string length $img] && \ + [string equal [$txt image cget $img -name] diropen]} { + $txt image configure $img -image ::ttk::dialog::image::dirclose + } else { + set img "" + } + + # Do we already have this data available, but perhaps elided? + if {[llength [$txt tag ranges $path]]} { + # Also show all subdirectories that were expanded before + set list [lsearch -all -inline [$txt tag names] $path/*] + foreach n [lappend list $path] { + $txt tag configure $n -elide 0 + } + return + } + + # This may take a little longer so give some indication to the user + $w configure -cursor watch + update + + $txt configure -state normal + $txt mark set insert $index + set list [glob -nocomplain -tails -dir $path -type d * .*] + foreach d [lsort -dictionary $list] { + # Skip . and .. + if {[string equal $d .] || [string equal $d ..]} continue + # Specify no tags so the tags at the current position are used + $txt insert insert "\n" + # Insert the line with the appropriate tags + $txt insert insert $tabs [list $path] + file stat [file join $path $d] stat + if {$stat(nlink) != 2} { + set img [$txt image create insert -name diropen \ + -image ::ttk::dialog::image::diropen -padx 3] + $txt tag add $path $img + } + $txt insert insert "\t" [list $path] + set img [$txt image create insert -padx 1 \ + -image ::ttk::dialog::image::folder] + $txt tag add $path $img + $txt insert insert " $d" [list name $path] + # Remove tags from the lineend + foreach n [$txt tag names insert] { + $txt tag remove $n insert + } + # Add the correct tag to the lineend + $txt tag add $path insert + # Put a mark if this is the specified subdirectory + if {[string equal $d $subdir]} { + $txt mark set subdir insert + } + } + # Directory is considered empty if it only contains . and .. + if {[llength $list] <= 2 && [string length $img]} { + $txt delete $img + } + $txt configure -state disabled + $w configure -cursor "" +} + +proc ::ttk::dialog::file::treeClose {w path} { + upvar ::ttk::dialog::file::[winfo name $w](text) txt + + set img root + set pathindex [lindex [$txt tag ranges $path] 0] + lassign [$txt dump -image "$pathindex-1l" $pathindex] - img pos + if {[string match diropen* $img]} { + $txt image configure $img -image ::ttk::dialog::image::diropen + } + + set list [lsearch -all -inline [$txt tag names] $path/*] + lappend list $path + $txt configure -state normal + foreach n $list { + # Eliding sounds promising, but doesn't work correctly + # $txt tag configure $n -elide 1 + eval [list $txt delete] [$txt tag ranges $n] + $txt tag delete $n + } + $txt configure -state disabled +} + +proc ::ttk::dialog::file::TreeDone {w} { + upvar ::ttk::dialog::file::[winfo name $w] data + + if {[file exists $data(selectPath)]} { + if {![file isdirectory $data(selectPath)]} { + return + } + } elseif {[string is true $data(-mustexists)]} { + return + } + variable selectFilePath $data(selectPath) +} + +proc ::ttk::dialog::file::cdTree {w dir {subdir .}} { + upvar ::ttk::dialog::file::[winfo name $w](text) txt + + set parent [file dirname $dir] + + set ranges [$txt tag ranges $parent] + if {[llength $ranges]} { + set pat [format {^\t* %s$} [file tail $dir]] + foreach {index1 index2} $ranges { + set idx [$txt search -regexp $pat $index1 $index2] + if {[string length $idx]} { + $txt mark set subdir "$idx lineend" + break + } + } + } else { + cdTree $w $parent [file tail $dir] + } + ::ttk::dialog::file::treeOpen $w $dir subdir $subdir +} + +proc ::ttk::dialog::file::TreeSelect {w index} { + upvar ::ttk::dialog::file::[winfo name [winfo toplevel $w]] data + + set idx [$data(text) index "$index lineend"] + set range [$data(text) tag prevrange name $idx "$idx linestart"] + if {[llength $range]} { + lassign $range index1 index2 + $data(text) tag remove sel 1.0 end + $data(text) tag add sel $index1-1c $index2+1c + set path [lsearch -inline [$data(text) tag names $index1] /*] + set dir [$data(text) get $index1+1c $index2] + set data(selectPath) [file join $path $dir] + } +} + +proc ::ttk::dialog::file::TreeRelease1 {w} { + set w [winfo toplevel $w] + upvar ::ttk::dialog::file::[winfo name $w](text) txt + + if {[string length [$w cget -cursor]]} { + $w configure -cursor "" + return + } + + set dir [string range [$txt get sel.first sel.last] 1 end-1] + set path [lsearch -inline [$txt tag names sel.first] /*] + if {![catch {$txt image cget sel.first-2c -image} name]} { + set index [$txt index sel.last-1c] + $txt mark set selmark sel.first + switch -glob $name { + *::diropen { + treeOpen $w [file join $path $dir] $index + } + *::dirclose { + treeClose $w [file join $path $dir] + } + } + $txt tag remove sel 1.0 end + $txt tag add sel selmark "selmark lineend+1c" + } +} + +proc ::ttk::dialog::file::TreeMotion1 {w} { + [winfo toplevel $w] configure -cursor "X_cursor #C00 #000" +} + +proc ::ttk::dialog::file::TreeReturn {w} { + upvar ::ttk::dialog::file::[winfo name $w] data + + if {[file isdirectory $data(selectPath)]} { + ::ttk::dialog::file::cdTree $w $data(selectPath) + $data(text) yview subdir-5l + TreeSelect $w subdir + } + + return -code break +} + +proc ttk::chooseDirectory {args} { + set dataName __ttk_dirdialog + upvar ::ttk::dialog::file::$dataName data + + set specs { + {-initialdir "" "" .} + {-mustexists "" "" 0} + {-parent "" "" .} + {-title "" "" ""} + } + tclParseConfigSpec ::ttk::dialog::file::$dataName $specs "" $args + + if {$data(-title) == ""} { + set data(-title) "[::tk::mc "Choose Directory"]" + } + + if {![winfo exists $data(-parent)]} { + error "bad window path name \"$data(-parent)\"" + } + + if {[string equal $data(-parent) .]} { + set w .$dataName + } else { + set w $data(-parent).$dataName + } + + if {![winfo exists $w]} { + ::ttk::dialog::file::treeCreate $w + } + + ::tk::PlaceWindow $w widget $data(-parent) + wm title $w $data(-title) + ::tk::SetFocusGrab $w $data(text) + + ::ttk::dialog::file::treeUpdate $w $data(-initialdir) + + tkwait variable ::ttk::dialog::file::selectFilePath + + ::tk::RestoreFocusGrab $w $data(text) withdraw + + return $::ttk::dialog::file::selectFilePath +} + +# Alternative procedure names +interp alias {} ttk_getOpenFile {} ::ttk::dialog::file::tkFDialog open +interp alias {} ttk_getSaveFile {} ::ttk::dialog::file::tkFDialog save +interp alias {} ttk_getAppendFile {} ::ttk::dialog::file::tkFDialog append + + +# Need to have a lassign procedure +if {![llength [info procs lassign]]} { + proc lassign {list args} { + uplevel 1 [list foreach $args $list break] + lrange $list [llength $args] end + } +} + +style default Slim.TButton -padding 0 +option add *TkFDialog*selectBackground #0a5f89 +option add *TkFDialog*selectForeground #ffffff +option add *TkFDialog*Toolbar*takeFocus 0 +option add *TkFDialog*Text.background white +# option add *TkFDialog*Menu.activeBackground #0a5f89 +# option add *TkFDialog*Menu.activeForeground #ffffff +# option add *TkFDialog*Menu.activeBorderWidth 1 +# option add *TkFDialog*Menu.borderWidth 1 +# option add *TkFDialog*Menu.relief solid +# option add *TkFDialog*Menu.Image ::ttk::dialog::image::blank16 +# option add *TkFDialog*Menu*selectImage ::ttk::dialog::image::tick16 + +# Bindings +bind FileDialogDir {::ttk::dialog::file::DirButton1 %W %x %y} +bind FileDialogDir {::ttk::dialog::file::DirRelease1 %W %x %y} +bind FileDialogDir {::ttk::dialog::file::DirDouble1 %W %x %y} +bind FileDialogDir {::ttk::dialog::file::DirMotion1 %W %x %y} +bind FileDialogDir <4> {%W yview scroll -5 units} +bind FileDialogDir <5> {%W yview scroll 5 units} +bind FileDialogFile {::ttk::dialog::file::FileButton1 %W %x %y} +bind FileDialogFile {::ttk::dialog::file::FileRelease1 %W %x %y} +bind FileDialogFile {::ttk::dialog::file::FileMotion1 %W %x %y} +bind FileDialogFile {::ttk::dialog::file::Done [winfo toplevel %W]} +bind FileDialogFile <4> \ + {::ttk::dialog::file::xview [winfo toplevel %W] scroll -1 units} +bind FileDialogFile <5> \ + {::ttk::dialog::file::xview [winfo toplevel %W] scroll 1 units} +bind FileDialogList {::ttk::dialog::file::FileButton1 %W %x %y} +bind FileDialogList {::ttk::dialog::file::FileRelease1 %W %x %y} +bind FileDialogList {::ttk::dialog::file::FileMotion1 %W %x %y} +bind FileDialogList {::ttk::dialog::file::Done [winfo toplevel %W]} +bind FileDialogList <4> {%W yview scroll -5 units} +bind FileDialogList <5> {%W yview scroll 5 units} + +bind DirDialog <4> {%W yview scroll -5 units} +bind DirDialog <5> {%W yview scroll 5 units} +bind DirDialog {::ttk::dialog::file::TreeSelect %W @%x,%y} +bind DirDialog {::ttk::dialog::file::TreeRelease1 %W} +bind DirDialog {::ttk::dialog::file::TreeMotion1 %W} diff --git a/data/themes/clearlooks/clearlooks.tcl b/data/themes/clearlooks/clearlooks.tcl new file mode 100644 index 00000000..f130682e --- /dev/null +++ b/data/themes/clearlooks/clearlooks.tcl @@ -0,0 +1,322 @@ +# clearlooks.tcl + +namespace eval tile::theme::clearlooks { + + package provide tile::theme::clearlooks 0.1 + + variable I + array set I [tile::LoadImages \ + [file join [file dirname [info script]] clearlooks] *.gif] + + variable colors + + array set colors { + -frame "#efebe7" + -lighter "#f5f3f0" + -dark "#cfcdc8" + -darker "#9e9a9e" + -darkest "#d4cfca" + -selectbg "#7c99ad" + -selectfg "#ffffff" + -disabledfg "#b5b3ac" + -entryfocus "#6f9dc6" + -tabbg "#c9c1bc" + -tabborder "#b5aca7" + -troughcolor "#d7cbbe" + -troughborder "#ae9e8e" + -checklight "#f5f3f0" + } + + + style theme create clearlooks -parent clam -settings { + + style configure . \ + -borderwidth 1 \ + -background $colors(-frame) \ + -foreground black \ + -bordercolor $colors(-darkest) \ + -darkcolor $colors(-dark) \ + -lightcolor $colors(-lighter) \ + -troughcolor $colors(-troughcolor) \ + -selectforeground $colors(-selectfg) \ + -selectbackground $colors(-selectbg) \ + -font TkDefaultFont \ + ; + + style map . \ + -background [list disabled $colors(-frame) \ + active $colors(-lighter)] \ + -foreground [list disabled $colors(-disabledfg)] \ + -selectbackground [list !focus $colors(-darker)] \ + -selectforeground [list !focus white] \ + ; + + +# style configure Frame.border -relief groove + + ## Treeview. + # + style element create Treeheading.cell image $I(tree-n) \ + -map [list \ + selected $I(tree-p) \ + disabled $I(tree-d) \ + pressed $I(tree-p) \ + active $I(tree-h) \ + ] \ + -border 4 -sticky ew + + #style configure Treeview -fieldbackground white + style configure Row -background "#efefef" + style map Row -background [list \ + {focus selected} "#71869e" \ + selected "#969286" \ + alternate white] + style map Item -foreground [list selected white] + style map Cell -foreground [list selected white] + + + ## Buttons. + # + style configure TButton -padding {10 0} + style layout TButton { + Button.button -children { + Button.focus -children { + Button.padding -children { + Button.label + } + } + } + } + + style element create button image $I(button-n) \ + -map [list \ + pressed $I(button-p) \ + {selected active} $I(button-pa) \ + selected $I(button-p) \ + active $I(button-a) \ + disabled $I(button-d) \ + ] \ + -border 4 -sticky ew + + + ## Checkbuttons. + # + style element create Checkbutton.indicator image $I(check-nu) \ + -width 24 -sticky w -map [list \ + {disabled selected} $I(check-dc) \ + disabled $I(check-du) \ + {pressed selected} $I(check-pc) \ + pressed $I(check-pu) \ + {active selected} $I(check-ac) \ + active $I(check-au) \ + selected $I(check-nc) ] + + style map TCheckbutton -background [list active $colors(-checklight)] + style configure TCheckbutton -padding 1 + + + ## Radiobuttons. + # + style element create Radiobutton.indicator image $I(radio-nu) \ + -width 24 -sticky w \ + -map [list \ + {disabled selected} $I(radio-dc) \ + disabled $I(radio-du) \ + {pressed selected} $I(radio-pc) \ + pressed $I(radio-pu) \ + {active selected} $I(radio-ac) \ + active $I(radio-au) \ + selected $I(radio-nc) ] + + style map TRadiobutton -background [list active $colors(-checklight)] + style configure TRadiobutton -padding 1 + + + ## Menubuttons. + # + #style configure TMenubutton -relief raised -padding {10 2} +# style element create Menubutton.border image $I(toolbutton-n) \ +# -map [list \ +# pressed $I(toolbutton-p) \ +# selected $I(toolbutton-p) \ +# active $I(toolbutton-a) \ +# disabled $I(toolbutton-n)] \ +# -border {4 7 4 7} -sticky nsew + + style element create Menubutton.border image $I(button-n) \ + -map [list \ + selected $I(button-p) \ + disabled $I(button-d) \ + active $I(button-a) \ + ] \ + -border 4 -sticky ew + + + ## Toolbar buttons. + # + style configure Toolbutton -padding -5 -relief flat + style configure Toolbutton.label -padding 0 -relief flat + + style element create Toolbutton.border image $I(blank) \ + -map [list \ + pressed $I(toolbutton-p) \ + {selected active} $I(toolbutton-pa) \ + selected $I(toolbutton-p) \ + active $I(toolbutton-a) \ + disabled $I(blank)] \ + -border 11 -sticky nsew + + + ## Entry widgets. + # + style configure TEntry -padding 1 -insertwidth 1 \ + -fieldbackground white + + style map TEntry \ + -fieldbackground [list readonly $colors(-frame)] \ + -bordercolor [list focus $colors(-selectbg)] \ + -lightcolor [list focus $colors(-entryfocus)] \ + -darkcolor [list focus $colors(-entryfocus)] \ + ; + + + ## Combobox. + # + style configure TCombobox -selectbackground + + style element create Combobox.downarrow image $I(comboarrow-n) \ + -map [list \ + disabled $I(comboarrow-d) \ + pressed $I(comboarrow-p) \ + active $I(comboarrow-a) \ + ] \ + -border 1 -sticky {} + + style element create Combobox.field image $I(combo-n) \ + -map [list \ + {readonly disabled} $I(combo-rd) \ + {readonly pressed} $I(combo-rp) \ + {readonly focus} $I(combo-rf) \ + readonly $I(combo-rn) + ] \ + -border 4 -sticky ew + + + ## Notebooks. + # +# style element create tab image $I(tab-a) -border {2 2 2 0} \ +# -map [list selected $I(tab-n)] + + style configure TNotebook.Tab -padding {6 2 6 2} + style map TNotebook.Tab \ + -padding [list selected {6 4 6 2}] \ + -background [list selected $colors(-frame) {} $colors(-tabbg)] \ + -lightcolor [list selected $colors(-lighter) {} $colors(-dark)] \ + -bordercolor [list selected $colors(-darkest) {} $colors(-tabborder)] \ + ; + + ## Labelframes. + # + style configure TLabelframe -borderwidth 2 -relief groove + + + ## Scrollbars. + # + style layout Vertical.TScrollbar { + Scrollbar.trough -sticky ns -children { + Scrollbar.uparrow -side top + Scrollbar.downarrow -side bottom + Vertical.Scrollbar.thumb -side top -expand true -sticky ns + } + } + + style layout Horizontal.TScrollbar { + Scrollbar.trough -sticky we -children { + Scrollbar.leftarrow -side left + Scrollbar.rightarrow -side right + Horizontal.Scrollbar.thumb -side left -expand true -sticky we + } + } + + style element create Horizontal.Scrollbar.thumb image $I(sbthumb-hn) \ + -map [list \ + disabled $I(sbthumb-hd) \ + pressed $I(sbthumb-ha) \ + active $I(sbthumb-ha)] \ + -border 3 + + style element create Vertical.Scrollbar.thumb image $I(sbthumb-vn) \ + -map [list \ + disabled $I(sbthumb-vd) \ + pressed $I(sbthumb-va) \ + active $I(sbthumb-va)] \ + -border 3 + + foreach dir {up down left right} { + style element create ${dir}arrow image $I(arrow${dir}-n) \ + -map [list \ + disabled $I(arrow${dir}-d) \ + pressed $I(arrow${dir}-p) \ + active $I(arrow${dir}-a)] \ + -border 1 -sticky {} + } + + style configure TScrollbar -bordercolor $colors(-troughborder) + + + ## Scales. + # + style element create Scale.slider image $I(scale-hn) \ + -map [list \ + disabled $I(scale-hd) \ + active $I(scale-ha) \ + ] + + style element create Scale.trough image $I(scaletrough-h) \ + -border 2 -sticky ew -padding 0 + + style element create Vertical.Scale.slider image $I(scale-vn) \ + -map [list \ + disabled $I(scale-vd) \ + active $I(scale-va) \ + ] + style element create Vertical.Scale.trough image $I(scaletrough-v) \ + -border 2 -sticky ns -padding 0 + + style configure TScale -bordercolor $colors(-troughborder) + + + ## Progressbar. + # + style element create Horizontal.Progressbar.pbar image $I(progress-h) \ + -border {2 2 1 1} + style element create Vertical.Progressbar.pbar image $I(progress-v) \ + -border {2 2 1 1} + + style configure TProgressbar -bordercolor $colors(-troughborder) + + + ## Statusbar parts. + # + style element create sizegrip image $I(sizegrip) + + + ## Paned window parts. + # +# style element create hsash image $I(hseparator-n) -border {2 0} \ +# -map [list {active !disabled} $I(hseparator-a)] +# style element create vsash image $I(vseparator-n) -border {0 2} \ +# -map [list {active !disabled} $I(vseparator-a)] + + style configure Sash -sashthickness 6 -gripcount 16 + + + ## Separator. + # + #style element create separator image $I(sep-h) + #style element create hseparator image $I(sep-h) + #style element create vseparator image $I(sep-v) + + } +} + diff --git a/data/themes/clearlooks/clearlooks/arrowdown-a.gif b/data/themes/clearlooks/clearlooks/arrowdown-a.gif new file mode 100644 index 00000000..c5f8761f Binary files /dev/null and b/data/themes/clearlooks/clearlooks/arrowdown-a.gif differ diff --git a/data/themes/clearlooks/clearlooks/arrowdown-d.gif b/data/themes/clearlooks/clearlooks/arrowdown-d.gif new file mode 100644 index 00000000..061990e2 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/arrowdown-d.gif differ diff --git a/data/themes/clearlooks/clearlooks/arrowdown-n.gif b/data/themes/clearlooks/clearlooks/arrowdown-n.gif new file mode 100644 index 00000000..b72fe3e1 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/arrowdown-n.gif differ diff --git a/data/themes/clearlooks/clearlooks/arrowdown-p.gif b/data/themes/clearlooks/clearlooks/arrowdown-p.gif new file mode 100644 index 00000000..99626890 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/arrowdown-p.gif differ diff --git a/data/themes/clearlooks/clearlooks/arrowleft-a.gif b/data/themes/clearlooks/clearlooks/arrowleft-a.gif new file mode 100644 index 00000000..bb919459 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/arrowleft-a.gif differ diff --git a/data/themes/clearlooks/clearlooks/arrowleft-d.gif b/data/themes/clearlooks/clearlooks/arrowleft-d.gif new file mode 100644 index 00000000..8800f1ae Binary files /dev/null and b/data/themes/clearlooks/clearlooks/arrowleft-d.gif differ diff --git a/data/themes/clearlooks/clearlooks/arrowleft-n.gif b/data/themes/clearlooks/clearlooks/arrowleft-n.gif new file mode 100644 index 00000000..143739f0 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/arrowleft-n.gif differ diff --git a/data/themes/clearlooks/clearlooks/arrowleft-p.gif b/data/themes/clearlooks/clearlooks/arrowleft-p.gif new file mode 100644 index 00000000..dca719a8 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/arrowleft-p.gif differ diff --git a/data/themes/clearlooks/clearlooks/arrowright-a.gif b/data/themes/clearlooks/clearlooks/arrowright-a.gif new file mode 100644 index 00000000..c139129e Binary files /dev/null and b/data/themes/clearlooks/clearlooks/arrowright-a.gif differ diff --git a/data/themes/clearlooks/clearlooks/arrowright-d.gif b/data/themes/clearlooks/clearlooks/arrowright-d.gif new file mode 100644 index 00000000..1b5afb0e Binary files /dev/null and b/data/themes/clearlooks/clearlooks/arrowright-d.gif differ diff --git a/data/themes/clearlooks/clearlooks/arrowright-n.gif b/data/themes/clearlooks/clearlooks/arrowright-n.gif new file mode 100644 index 00000000..57f0f802 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/arrowright-n.gif differ diff --git a/data/themes/clearlooks/clearlooks/arrowright-p.gif b/data/themes/clearlooks/clearlooks/arrowright-p.gif new file mode 100644 index 00000000..7706aa6c Binary files /dev/null and b/data/themes/clearlooks/clearlooks/arrowright-p.gif differ diff --git a/data/themes/clearlooks/clearlooks/arrowup-a.gif b/data/themes/clearlooks/clearlooks/arrowup-a.gif new file mode 100644 index 00000000..b3307676 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/arrowup-a.gif differ diff --git a/data/themes/clearlooks/clearlooks/arrowup-d.gif b/data/themes/clearlooks/clearlooks/arrowup-d.gif new file mode 100644 index 00000000..95bb2b62 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/arrowup-d.gif differ diff --git a/data/themes/clearlooks/clearlooks/arrowup-n.gif b/data/themes/clearlooks/clearlooks/arrowup-n.gif new file mode 100644 index 00000000..8628d612 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/arrowup-n.gif differ diff --git a/data/themes/clearlooks/clearlooks/arrowup-p.gif b/data/themes/clearlooks/clearlooks/arrowup-p.gif new file mode 100644 index 00000000..bcedfb38 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/arrowup-p.gif differ diff --git a/data/themes/clearlooks/clearlooks/blank.gif b/data/themes/clearlooks/clearlooks/blank.gif new file mode 100644 index 00000000..be618398 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/blank.gif differ diff --git a/data/themes/clearlooks/clearlooks/button-a.gif b/data/themes/clearlooks/clearlooks/button-a.gif new file mode 100644 index 00000000..2cc46a46 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/button-a.gif differ diff --git a/data/themes/clearlooks/clearlooks/button-d.gif b/data/themes/clearlooks/clearlooks/button-d.gif new file mode 100644 index 00000000..4d32129f Binary files /dev/null and b/data/themes/clearlooks/clearlooks/button-d.gif differ diff --git a/data/themes/clearlooks/clearlooks/button-n.gif b/data/themes/clearlooks/clearlooks/button-n.gif new file mode 100644 index 00000000..b6cdc4ae Binary files /dev/null and b/data/themes/clearlooks/clearlooks/button-n.gif differ diff --git a/data/themes/clearlooks/clearlooks/button-p.gif b/data/themes/clearlooks/clearlooks/button-p.gif new file mode 100644 index 00000000..495fc308 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/button-p.gif differ diff --git a/data/themes/clearlooks/clearlooks/button-pa.gif b/data/themes/clearlooks/clearlooks/button-pa.gif new file mode 100644 index 00000000..7f1d2464 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/button-pa.gif differ diff --git a/data/themes/clearlooks/clearlooks/check-ac.gif b/data/themes/clearlooks/clearlooks/check-ac.gif new file mode 100644 index 00000000..a1c3a17f Binary files /dev/null and b/data/themes/clearlooks/clearlooks/check-ac.gif differ diff --git a/data/themes/clearlooks/clearlooks/check-au.gif b/data/themes/clearlooks/clearlooks/check-au.gif new file mode 100644 index 00000000..e2e1bfdf Binary files /dev/null and b/data/themes/clearlooks/clearlooks/check-au.gif differ diff --git a/data/themes/clearlooks/clearlooks/check-dc.gif b/data/themes/clearlooks/clearlooks/check-dc.gif new file mode 100644 index 00000000..2991c7fa Binary files /dev/null and b/data/themes/clearlooks/clearlooks/check-dc.gif differ diff --git a/data/themes/clearlooks/clearlooks/check-du.gif b/data/themes/clearlooks/clearlooks/check-du.gif new file mode 100644 index 00000000..e2e1bfdf Binary files /dev/null and b/data/themes/clearlooks/clearlooks/check-du.gif differ diff --git a/data/themes/clearlooks/clearlooks/check-nc.gif b/data/themes/clearlooks/clearlooks/check-nc.gif new file mode 100644 index 00000000..a1c3a17f Binary files /dev/null and b/data/themes/clearlooks/clearlooks/check-nc.gif differ diff --git a/data/themes/clearlooks/clearlooks/check-nu.gif b/data/themes/clearlooks/clearlooks/check-nu.gif new file mode 100644 index 00000000..e2e1bfdf Binary files /dev/null and b/data/themes/clearlooks/clearlooks/check-nu.gif differ diff --git a/data/themes/clearlooks/clearlooks/check-pc.gif b/data/themes/clearlooks/clearlooks/check-pc.gif new file mode 100644 index 00000000..6364fd21 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/check-pc.gif differ diff --git a/data/themes/clearlooks/clearlooks/check-pu.gif b/data/themes/clearlooks/clearlooks/check-pu.gif new file mode 100644 index 00000000..af240b92 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/check-pu.gif differ diff --git a/data/themes/clearlooks/clearlooks/combo-n.gif b/data/themes/clearlooks/clearlooks/combo-n.gif new file mode 100644 index 00000000..027de9cf Binary files /dev/null and b/data/themes/clearlooks/clearlooks/combo-n.gif differ diff --git a/data/themes/clearlooks/clearlooks/combo-ra.gif b/data/themes/clearlooks/clearlooks/combo-ra.gif new file mode 100644 index 00000000..982372fe Binary files /dev/null and b/data/themes/clearlooks/clearlooks/combo-ra.gif differ diff --git a/data/themes/clearlooks/clearlooks/combo-rd.gif b/data/themes/clearlooks/clearlooks/combo-rd.gif new file mode 100644 index 00000000..ded0fc55 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/combo-rd.gif differ diff --git a/data/themes/clearlooks/clearlooks/combo-rf.gif b/data/themes/clearlooks/clearlooks/combo-rf.gif new file mode 100644 index 00000000..bc722bdb Binary files /dev/null and b/data/themes/clearlooks/clearlooks/combo-rf.gif differ diff --git a/data/themes/clearlooks/clearlooks/combo-rn.gif b/data/themes/clearlooks/clearlooks/combo-rn.gif new file mode 100644 index 00000000..1d9cb50c Binary files /dev/null and b/data/themes/clearlooks/clearlooks/combo-rn.gif differ diff --git a/data/themes/clearlooks/clearlooks/combo-rp.gif b/data/themes/clearlooks/clearlooks/combo-rp.gif new file mode 100644 index 00000000..fe32cd9a Binary files /dev/null and b/data/themes/clearlooks/clearlooks/combo-rp.gif differ diff --git a/data/themes/clearlooks/clearlooks/comboarrow-a.gif b/data/themes/clearlooks/clearlooks/comboarrow-a.gif new file mode 100644 index 00000000..b4a2cd6e Binary files /dev/null and b/data/themes/clearlooks/clearlooks/comboarrow-a.gif differ diff --git a/data/themes/clearlooks/clearlooks/comboarrow-d.gif b/data/themes/clearlooks/clearlooks/comboarrow-d.gif new file mode 100644 index 00000000..8d50d86a Binary files /dev/null and b/data/themes/clearlooks/clearlooks/comboarrow-d.gif differ diff --git a/data/themes/clearlooks/clearlooks/comboarrow-n.gif b/data/themes/clearlooks/clearlooks/comboarrow-n.gif new file mode 100644 index 00000000..59077528 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/comboarrow-n.gif differ diff --git a/data/themes/clearlooks/clearlooks/comboarrow-p.gif b/data/themes/clearlooks/clearlooks/comboarrow-p.gif new file mode 100644 index 00000000..e370d0ec Binary files /dev/null and b/data/themes/clearlooks/clearlooks/comboarrow-p.gif differ diff --git a/data/themes/clearlooks/clearlooks/progress-h.gif b/data/themes/clearlooks/clearlooks/progress-h.gif new file mode 100644 index 00000000..01c24a1b Binary files /dev/null and b/data/themes/clearlooks/clearlooks/progress-h.gif differ diff --git a/data/themes/clearlooks/clearlooks/progress-v.gif b/data/themes/clearlooks/clearlooks/progress-v.gif new file mode 100644 index 00000000..a5e201f7 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/progress-v.gif differ diff --git a/data/themes/clearlooks/clearlooks/radio-ac.gif b/data/themes/clearlooks/clearlooks/radio-ac.gif new file mode 100644 index 00000000..42c6ccae Binary files /dev/null and b/data/themes/clearlooks/clearlooks/radio-ac.gif differ diff --git a/data/themes/clearlooks/clearlooks/radio-au.gif b/data/themes/clearlooks/clearlooks/radio-au.gif new file mode 100644 index 00000000..f8488509 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/radio-au.gif differ diff --git a/data/themes/clearlooks/clearlooks/radio-dc.gif b/data/themes/clearlooks/clearlooks/radio-dc.gif new file mode 100644 index 00000000..2103534d Binary files /dev/null and b/data/themes/clearlooks/clearlooks/radio-dc.gif differ diff --git a/data/themes/clearlooks/clearlooks/radio-du.gif b/data/themes/clearlooks/clearlooks/radio-du.gif new file mode 100644 index 00000000..498ab275 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/radio-du.gif differ diff --git a/data/themes/clearlooks/clearlooks/radio-nc.gif b/data/themes/clearlooks/clearlooks/radio-nc.gif new file mode 100644 index 00000000..ea734bad Binary files /dev/null and b/data/themes/clearlooks/clearlooks/radio-nc.gif differ diff --git a/data/themes/clearlooks/clearlooks/radio-nu.gif b/data/themes/clearlooks/clearlooks/radio-nu.gif new file mode 100644 index 00000000..498ab275 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/radio-nu.gif differ diff --git a/data/themes/clearlooks/clearlooks/radio-pc.gif b/data/themes/clearlooks/clearlooks/radio-pc.gif new file mode 100644 index 00000000..c1b6e50c Binary files /dev/null and b/data/themes/clearlooks/clearlooks/radio-pc.gif differ diff --git a/data/themes/clearlooks/clearlooks/radio-pu.gif b/data/themes/clearlooks/clearlooks/radio-pu.gif new file mode 100644 index 00000000..01ae60c8 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/radio-pu.gif differ diff --git a/data/themes/clearlooks/clearlooks/sbthumb-ha.gif b/data/themes/clearlooks/clearlooks/sbthumb-ha.gif new file mode 100644 index 00000000..d0b03ccd Binary files /dev/null and b/data/themes/clearlooks/clearlooks/sbthumb-ha.gif differ diff --git a/data/themes/clearlooks/clearlooks/sbthumb-hd.gif b/data/themes/clearlooks/clearlooks/sbthumb-hd.gif new file mode 100644 index 00000000..d4bdecfe Binary files /dev/null and b/data/themes/clearlooks/clearlooks/sbthumb-hd.gif differ diff --git a/data/themes/clearlooks/clearlooks/sbthumb-hn.gif b/data/themes/clearlooks/clearlooks/sbthumb-hn.gif new file mode 100644 index 00000000..3bdb0945 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/sbthumb-hn.gif differ diff --git a/data/themes/clearlooks/clearlooks/sbthumb-hp.gif b/data/themes/clearlooks/clearlooks/sbthumb-hp.gif new file mode 100644 index 00000000..3bdb0945 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/sbthumb-hp.gif differ diff --git a/data/themes/clearlooks/clearlooks/sbthumb-va.gif b/data/themes/clearlooks/clearlooks/sbthumb-va.gif new file mode 100644 index 00000000..5edabba8 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/sbthumb-va.gif differ diff --git a/data/themes/clearlooks/clearlooks/sbthumb-vd.gif b/data/themes/clearlooks/clearlooks/sbthumb-vd.gif new file mode 100644 index 00000000..7f6a0258 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/sbthumb-vd.gif differ diff --git a/data/themes/clearlooks/clearlooks/sbthumb-vn.gif b/data/themes/clearlooks/clearlooks/sbthumb-vn.gif new file mode 100644 index 00000000..64309622 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/sbthumb-vn.gif differ diff --git a/data/themes/clearlooks/clearlooks/sbthumb-vp.gif b/data/themes/clearlooks/clearlooks/sbthumb-vp.gif new file mode 100644 index 00000000..64309622 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/sbthumb-vp.gif differ diff --git a/data/themes/clearlooks/clearlooks/scale-ha.gif b/data/themes/clearlooks/clearlooks/scale-ha.gif new file mode 100644 index 00000000..68b27d53 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/scale-ha.gif differ diff --git a/data/themes/clearlooks/clearlooks/scale-hd.gif b/data/themes/clearlooks/clearlooks/scale-hd.gif new file mode 100644 index 00000000..628c5d7b Binary files /dev/null and b/data/themes/clearlooks/clearlooks/scale-hd.gif differ diff --git a/data/themes/clearlooks/clearlooks/scale-hn.gif b/data/themes/clearlooks/clearlooks/scale-hn.gif new file mode 100644 index 00000000..5e1c0e90 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/scale-hn.gif differ diff --git a/data/themes/clearlooks/clearlooks/scale-va.gif b/data/themes/clearlooks/clearlooks/scale-va.gif new file mode 100644 index 00000000..b5208935 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/scale-va.gif differ diff --git a/data/themes/clearlooks/clearlooks/scale-vd.gif b/data/themes/clearlooks/clearlooks/scale-vd.gif new file mode 100644 index 00000000..da58a5d4 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/scale-vd.gif differ diff --git a/data/themes/clearlooks/clearlooks/scale-vn.gif b/data/themes/clearlooks/clearlooks/scale-vn.gif new file mode 100644 index 00000000..8068c596 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/scale-vn.gif differ diff --git a/data/themes/clearlooks/clearlooks/scaletrough-h.gif b/data/themes/clearlooks/clearlooks/scaletrough-h.gif new file mode 100644 index 00000000..46f1a922 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/scaletrough-h.gif differ diff --git a/data/themes/clearlooks/clearlooks/scaletrough-v.gif b/data/themes/clearlooks/clearlooks/scaletrough-v.gif new file mode 100644 index 00000000..2558fd9c Binary files /dev/null and b/data/themes/clearlooks/clearlooks/scaletrough-v.gif differ diff --git a/data/themes/clearlooks/clearlooks/sep-h.gif b/data/themes/clearlooks/clearlooks/sep-h.gif new file mode 100644 index 00000000..26acc534 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/sep-h.gif differ diff --git a/data/themes/clearlooks/clearlooks/sep-v.gif b/data/themes/clearlooks/clearlooks/sep-v.gif new file mode 100644 index 00000000..52391a83 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/sep-v.gif differ diff --git a/data/themes/clearlooks/clearlooks/sizegrip.gif b/data/themes/clearlooks/clearlooks/sizegrip.gif new file mode 100644 index 00000000..7e30f930 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/sizegrip.gif differ diff --git a/data/themes/clearlooks/clearlooks/tab-a.gif b/data/themes/clearlooks/clearlooks/tab-a.gif new file mode 100644 index 00000000..a4f0ef68 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/tab-a.gif differ diff --git a/data/themes/clearlooks/clearlooks/tab-n.gif b/data/themes/clearlooks/clearlooks/tab-n.gif new file mode 100644 index 00000000..f8cef6ec Binary files /dev/null and b/data/themes/clearlooks/clearlooks/tab-n.gif differ diff --git a/data/themes/clearlooks/clearlooks/toolbutton-a.gif b/data/themes/clearlooks/clearlooks/toolbutton-a.gif new file mode 100644 index 00000000..a6ec6f40 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/toolbutton-a.gif differ diff --git a/data/themes/clearlooks/clearlooks/toolbutton-d.gif b/data/themes/clearlooks/clearlooks/toolbutton-d.gif new file mode 100644 index 00000000..3f10fef9 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/toolbutton-d.gif differ diff --git a/data/themes/clearlooks/clearlooks/toolbutton-n.gif b/data/themes/clearlooks/clearlooks/toolbutton-n.gif new file mode 100644 index 00000000..b3a1949f Binary files /dev/null and b/data/themes/clearlooks/clearlooks/toolbutton-n.gif differ diff --git a/data/themes/clearlooks/clearlooks/toolbutton-p.gif b/data/themes/clearlooks/clearlooks/toolbutton-p.gif new file mode 100644 index 00000000..bed50998 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/toolbutton-p.gif differ diff --git a/data/themes/clearlooks/clearlooks/toolbutton-pa.gif b/data/themes/clearlooks/clearlooks/toolbutton-pa.gif new file mode 100644 index 00000000..e81d1d3d Binary files /dev/null and b/data/themes/clearlooks/clearlooks/toolbutton-pa.gif differ diff --git a/data/themes/clearlooks/clearlooks/tree-d.gif b/data/themes/clearlooks/clearlooks/tree-d.gif new file mode 100644 index 00000000..d353aacd Binary files /dev/null and b/data/themes/clearlooks/clearlooks/tree-d.gif differ diff --git a/data/themes/clearlooks/clearlooks/tree-h.gif b/data/themes/clearlooks/clearlooks/tree-h.gif new file mode 100644 index 00000000..5797b9cf Binary files /dev/null and b/data/themes/clearlooks/clearlooks/tree-h.gif differ diff --git a/data/themes/clearlooks/clearlooks/tree-n.gif b/data/themes/clearlooks/clearlooks/tree-n.gif new file mode 100644 index 00000000..d9503266 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/tree-n.gif differ diff --git a/data/themes/clearlooks/clearlooks/tree-p.gif b/data/themes/clearlooks/clearlooks/tree-p.gif new file mode 100644 index 00000000..05aa8c28 Binary files /dev/null and b/data/themes/clearlooks/clearlooks/tree-p.gif differ diff --git a/data/themes/clearlooks/convert_imgs.sh b/data/themes/clearlooks/convert_imgs.sh new file mode 100755 index 00000000..ae8ed9ea --- /dev/null +++ b/data/themes/clearlooks/convert_imgs.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +from_dir=images +to_dir=clearlooks + + +# transpose +for t in $from_dir/sbthumb-v*.png; do + echo transpose $t + mv -f $t tmp.png + convert tmp.png -transpose $t + rm -f tmp.png +done +for t in progress scaletrough; do + echo transpose $t + convert $from_dir/$t-h.png -transpose $from_dir/$t-v.png +done + + +# convert to gif +for f in $from_dir/*.png; do + t=`basename $f .png` + echo convert $t + pngtopnm images/$t.png | ppmtogif -transparent==red > $to_dir/$t.gif +done + + + diff --git a/data/themes/clearlooks/create_imgs.py b/data/themes/clearlooks/create_imgs.py new file mode 100755 index 00000000..a01f36af --- /dev/null +++ b/data/themes/clearlooks/create_imgs.py @@ -0,0 +1,442 @@ +#!/usr/bin/env python +# -*- mode: python; coding: koi8-r; -*- + +import os +import gtk, gobject + +imdir = 'images' +imtype = 'png' +background = '#efebe7' + +#fill_color = 0xff000000 # red +fill_color = int('ff000000', 16) + +if not os.path.exists(imdir): + os.mkdir(imdir) + +gc = None +def draw_rect(): + global gc + if gc is None: + gc = drawing_area.window.new_gc() + colormap = gtk.gdk.colormap_get_system() + gc.set_colormap(colormap) + color = gtk.gdk.color_parse('red') + colormap.alloc_color(color) + gc.set_rgb_fg_color(color) + drawing_area.window.draw_rectangle(gc, True, 0,0, 800,800) + + +def save_image(fn, w, h, x=0, y=0): + pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, w, h) + pixbuf.fill(fill_color) + pb = pixbuf.get_from_drawable(drawing_area.window, + drawing_area.get_colormap(), + x,y, 0,0, w,h) + pb.save(os.path.join(imdir, fn+"."+imtype), imtype) + drawing_area.window.clear() + draw_rect() + + +done = False +def save_callback(*args): + global done + + + + if done: return + done = True + print 'create images' + + style = drawing_area.get_style() + draw_rect() + + # separator + w = 20 + style.paint_vline(drawing_area.window, gtk.STATE_NORMAL, None, + drawing_area, "frame", 0, w, 0) + save_image('sep-v', 2, w) + style.paint_hline(drawing_area.window, gtk.STATE_NORMAL, None, + drawing_area, "frame", 0, w, 0) + save_image('sep-h', w, 2) + + + # tree + w, h = 32, 32 + w, h = 24, 24 + for fn, state, shadow in ( + ("tree-n", gtk.STATE_NORMAL, gtk.SHADOW_OUT), + ("tree-h", gtk.STATE_PRELIGHT, gtk.SHADOW_OUT), + ("tree-p", gtk.STATE_ACTIVE, gtk.SHADOW_IN), + ("tree-d", gtk.STATE_INSENSITIVE, gtk.SHADOW_IN), + ): + style.paint_box(drawing_area.window, state, shadow, + None, drawing_area, "stepper", 0,0, w,h) + save_image(fn, w, h) + + + # sizegrip + w, h = 16, 16 + fn = 'sizegrip' + style.paint_resize_grip(drawing_area.window, gtk.STATE_NORMAL, None, + drawing_area, "statusbar", + gtk.gdk.WINDOW_EDGE_SOUTH_EAST, 0,0, w,h) + save_image(fn, w, h) + + + # progress + w, h = 37+3, 16+3 + progress_style = progress.get_style() + fn = 'progress-h' + progress_style.paint_box(drawing_area.window, + gtk.STATE_PRELIGHT, gtk.SHADOW_NONE, + None, progress, "bar", 0,0, w,h) + save_image(fn, w, h) + + + # button + w, h = 32, 32 + w, h = 28, 28 + for fn, state, shadow in ( + ("button-n", gtk.STATE_NORMAL, gtk.SHADOW_OUT), + ("button-a", gtk.STATE_PRELIGHT, gtk.SHADOW_OUT), + ("button-p", gtk.STATE_ACTIVE, gtk.SHADOW_IN), + ("button-d", gtk.STATE_INSENSITIVE, gtk.SHADOW_OUT), + ): + style.paint_box(drawing_area.window, state, shadow, + None, drawing_area, "buttondefault", 0,0, w,h) + save_image(fn, w, h) + + style.paint_box(drawing_area.window, gtk.STATE_PRELIGHT, gtk.SHADOW_IN, + None, togglebutton, "buttondefault", 0,0, w,h) + save_image("button-pa", w, h) + + + # toolbar + w, h = 16, 16 + w, h = 24, 24 + + fn = "blank" + pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, w, h) + pixbuf.fill(fill_color) + pixbuf.save(os.path.join(imdir, fn+"."+imtype), imtype) + + for fn, state, shadow in ( + ("toolbutton-n", gtk.STATE_NORMAL, gtk.SHADOW_OUT), + ("toolbutton-a", gtk.STATE_PRELIGHT, gtk.SHADOW_OUT), + ("toolbutton-p", gtk.STATE_ACTIVE, gtk.SHADOW_IN), + ("toolbutton-d", gtk.STATE_INSENSITIVE, gtk.SHADOW_IN), + ): + style.paint_box(drawing_area.window, state, shadow, + None, drawing_area, "buttondefault", 0,0, w,h) + save_image(fn, w, h) + + style.paint_box(drawing_area.window, gtk.STATE_PRELIGHT, gtk.SHADOW_IN, + None, togglebutton, "buttondefault", 0,0, w,h) + save_image("toolbutton-pa", w, h) + + + # slider + msl = hscroll.style_get_property("min_slider_length") + msl = 20 + sw = hscroll.style_get_property("slider_width") + print '>>', msl, sw + for t, w, h, state, orient in ( + ('hn', msl,sw, gtk.STATE_NORMAL, gtk.ORIENTATION_HORIZONTAL), + ('ha', msl,sw, gtk.STATE_PRELIGHT, gtk.ORIENTATION_HORIZONTAL), + ('hp', msl,sw, gtk.STATE_NORMAL, gtk.ORIENTATION_HORIZONTAL), + ('hd', msl,sw, gtk.STATE_INSENSITIVE, gtk.ORIENTATION_HORIZONTAL), + + ('vn', sw,msl, gtk.STATE_NORMAL, gtk.ORIENTATION_VERTICAL), + ('va', sw,msl, gtk.STATE_PRELIGHT, gtk.ORIENTATION_VERTICAL), + ('vp', sw,msl, gtk.STATE_NORMAL, gtk.ORIENTATION_VERTICAL), + ('vd', sw,msl, gtk.STATE_INSENSITIVE, gtk.ORIENTATION_VERTICAL), + ): + fn = 'sbthumb-'+t + if 0: + style.paint_slider(drawing_area.window, state, gtk.SHADOW_OUT, + None, drawing_area, "slider", 0,0, w,h, orient) + else: + if orient == gtk.ORIENTATION_VERTICAL: + w, h = h, w + style.paint_box(drawing_area.window, state, shadow, + None, drawing_area, "stepper", 0,0, w,h) + save_image(fn, w, h) + + + msl = hscroll.style_get_property("min_slider_length") + sw = hscroll.style_get_property("slider_width") + # scale + for t, w, h, state, orient in ( + ('hn', msl,sw, gtk.STATE_NORMAL, gtk.ORIENTATION_HORIZONTAL), + ('ha', msl,sw, gtk.STATE_PRELIGHT, gtk.ORIENTATION_HORIZONTAL), + ('hd', msl,sw, gtk.STATE_INSENSITIVE, gtk.ORIENTATION_HORIZONTAL), + ('vn', sw,msl, gtk.STATE_NORMAL, gtk.ORIENTATION_VERTICAL), + ('va', sw,msl, gtk.STATE_PRELIGHT, gtk.ORIENTATION_VERTICAL), + ('vd', sw,msl, gtk.STATE_INSENSITIVE, gtk.ORIENTATION_VERTICAL), + ): + fn = 'scale-'+t + if orient == gtk.ORIENTATION_HORIZONTAL: + detail = "hscale" + else: + detail = "vscale" + style.paint_slider(drawing_area.window, state, gtk.SHADOW_OUT, + None, drawing_area, detail, 0,0, w+2,h+2, orient) + save_image(fn, w, h, 1, 1) + + w, h = msl, sw + fn = 'scaletrough-h' + style.paint_box(drawing_area.window, gtk.STATE_ACTIVE, gtk.SHADOW_IN, + None, scale, "trough", 0,0, w,h) + save_image(fn, w, h) + + + # arrow + w = h = hscroll.style_get_property("stepper_size") + #w = h = 15 + arrow_width = w / 2 + arrow_height = h / 2 + arrow_x = (w - arrow_width) / 2 + arrow_y = (h - arrow_height) / 2 + + alloc = hscroll.get_allocation() + x0 = alloc.x + x1 = alloc.x+alloc.width-w + alloc = vscroll.get_allocation() + y0 = alloc.y + y1 = alloc.y+alloc.height-h + + sn = gtk.STATE_NORMAL + sp = gtk.STATE_PRELIGHT + sa = gtk.STATE_ACTIVE + si = gtk.STATE_INSENSITIVE + + for fn, x, y, state, shadow, arrow_type, widget in ( + ("arrowleft-n", x0, 0, sn, gtk.SHADOW_OUT, gtk.ARROW_LEFT, hscroll), + ("arrowleft-a", x0, 0, sp, gtk.SHADOW_OUT, gtk.ARROW_LEFT, hscroll), + ("arrowleft-p", x0, 0, sa, gtk.SHADOW_IN, gtk.ARROW_LEFT, hscroll), + ("arrowleft-d", x0, 0, si, gtk.SHADOW_OUT, gtk.ARROW_LEFT, hscroll), + + ("arrowright-n", x1, 0, sn, gtk.SHADOW_OUT, gtk.ARROW_RIGHT, hscroll), + ("arrowright-a", x1, 0, sp, gtk.SHADOW_OUT, gtk.ARROW_RIGHT, hscroll), + ("arrowright-p", x1, 0, sa, gtk.SHADOW_IN, gtk.ARROW_RIGHT, hscroll), + ("arrowright-d", x1, 0, si, gtk.SHADOW_OUT, gtk.ARROW_RIGHT, hscroll), + + ("arrowup-n", 0, y0, sn, gtk.SHADOW_OUT, gtk.ARROW_UP, vscroll), + ("arrowup-a", 0, y0, sp, gtk.SHADOW_OUT, gtk.ARROW_UP, vscroll), + ("arrowup-p", 0, y0, sa, gtk.SHADOW_IN, gtk.ARROW_UP, vscroll), + ("arrowup-d", 0, y0, si, gtk.SHADOW_OUT, gtk.ARROW_UP, vscroll), + + ("arrowdown-n", 0, y1, sn, gtk.SHADOW_OUT, gtk.ARROW_DOWN, vscroll), + ("arrowdown-a", 0, y1, sp, gtk.SHADOW_OUT, gtk.ARROW_DOWN, vscroll), + ("arrowdown-p", 0, y1, sa, gtk.SHADOW_IN, gtk.ARROW_DOWN, vscroll), + ("arrowdown-d", 0, y1, si, gtk.SHADOW_OUT, gtk.ARROW_DOWN, vscroll), + ): + if 0: + detail = 'hscrollbar' + if widget is vscroll: + detail = 'vscrollbar' + else: + x, y = 0, 0 + detail = 'stepper' + widget = drawing_area + style.paint_box(drawing_area.window, state, shadow, + None, widget, detail, x,y, w,h) + style.paint_arrow(drawing_area.window, state, shadow, + None, widget, detail, arrow_type, True, + x+arrow_x, y+arrow_y, arrow_width, arrow_height) + save_image(fn, w, h, x, y) + + + # combobox + w, h = w, 24 + w, h = 16, 24 + alloc = hscroll.get_allocation() + x1 = alloc.x+alloc.width-w + arrow_width = w / 2 + arrow_height = h / 2 + arrow_x = (w - arrow_width) / 2 + arrow_y = (h - arrow_height) / 2 + detail = 'hscrollbar' + widget = hscroll + for fn, state, shadow, arrow_type in ( + ("comboarrow-n", gtk.STATE_NORMAL, gtk.SHADOW_OUT, gtk.ARROW_DOWN), + ("comboarrow-a", gtk.STATE_PRELIGHT, gtk.SHADOW_OUT, gtk.ARROW_DOWN), + ("comboarrow-p", gtk.STATE_ACTIVE, gtk.SHADOW_IN, gtk.ARROW_DOWN), + ("comboarrow-d", gtk.STATE_INSENSITIVE, gtk.SHADOW_IN, gtk.ARROW_DOWN), + ): + style.paint_box(drawing_area.window, state, shadow, + None, widget, detail, x1,0, w,h) + style.paint_arrow(drawing_area.window, state, shadow, + None, drawing_area, "stepper", arrow_type, True, + x1+arrow_x, arrow_y, arrow_width, arrow_height) + save_image(fn, w, h, x1, 0) + + w = 24 + for fn, state, shadow in ( + ("combo-rn", gtk.STATE_NORMAL, gtk.SHADOW_OUT), + ("combo-ra", gtk.STATE_PRELIGHT, gtk.SHADOW_OUT), + ("combo-rp", gtk.STATE_ACTIVE, gtk.SHADOW_IN), + ("combo-rd", gtk.STATE_INSENSITIVE, gtk.SHADOW_OUT), + ): + style.paint_box(drawing_area.window, state, shadow, + None, drawing_area, "button", 0,0, w+2,h) + save_image(fn, w, h) + + style.paint_box(drawing_area.window, gtk.STATE_NORMAL, gtk.SHADOW_OUT, + None, drawing_area, "button", 0,0, w+2,h) + d = 3 + style.paint_focus(drawing_area.window, gtk.STATE_NORMAL, + None, drawing_area, "button", d,d, w-2*d,h-2*d) + save_image('combo-rf', w, h) + + style.paint_shadow(drawing_area.window, gtk.STATE_NORMAL, gtk.SHADOW_IN, + None, drawing_area, "entry", 0,0, w+2,h) + save_image('combo-n', w, h) + + + # checkbutton + #define INDICATOR_SIZE 13 + #define INDICATOR_SPACING 2 + x, y = 2, 2 + w, h = 13, 13 + #w = h = checkbutton.style_get_property("indicator_size") + for fn, state, shadow in ( + ("check-nc", gtk.STATE_NORMAL, gtk.SHADOW_IN), + ("check-nu", gtk.STATE_NORMAL, gtk.SHADOW_OUT), + ("check-ac", gtk.STATE_PRELIGHT, gtk.SHADOW_IN), + ("check-au", gtk.STATE_PRELIGHT, gtk.SHADOW_OUT), + ("check-pc", gtk.STATE_ACTIVE, gtk.SHADOW_IN), + ("check-pu", gtk.STATE_ACTIVE, gtk.SHADOW_OUT), + ("check-dc", gtk.STATE_INSENSITIVE, gtk.SHADOW_IN), + ("check-du", gtk.STATE_INSENSITIVE, gtk.SHADOW_OUT), + ): +## style.paint_flat_box(drawing_area.window, +## gtk.STATE_PRELIGHT, +## gtk.SHADOW_ETCHED_OUT, +## gtk.gdk.Rectangle(0,0,w,h), drawing_area, +## "checkbutton", 0,0, w,h) + + style.paint_check(drawing_area.window, state, shadow, + None, drawing_area, "checkbutton", x,y, w,h) + save_image(fn, w+2*x, h+2*y) + + + # radiobutton + for fn, state, shadow in ( + ("radio-nc", gtk.STATE_NORMAL, gtk.SHADOW_IN), + ("radio-nu", gtk.STATE_NORMAL, gtk.SHADOW_OUT), + ("radio-ac", gtk.STATE_PRELIGHT, gtk.SHADOW_IN), + ("radio-au", gtk.STATE_PRELIGHT, gtk.SHADOW_OUT), + ("radio-pc", gtk.STATE_ACTIVE, gtk.SHADOW_IN), + ("radio-pu", gtk.STATE_ACTIVE, gtk.SHADOW_OUT), + ("radio-dc", gtk.STATE_INSENSITIVE, gtk.SHADOW_IN), + ("radio-du", gtk.STATE_INSENSITIVE, gtk.SHADOW_OUT), + ): +## style.paint_flat_box(drawing_area.window, +## gtk.STATE_PRELIGHT, +## gtk.SHADOW_ETCHED_OUT, +## gtk.gdk.Rectangle(0,0,w,h), drawing_area, +## "checkbutton", 0,0, w,h) + style.paint_option(drawing_area.window, state, shadow, + None, drawing_area, "radiobutton", x,y, w,h) + save_image(fn, w+2*x, h+2*y) + + + # notebook + w, h = 28, 22 + state = gtk.STATE_NORMAL + shadow = gtk.SHADOW_OUT + + for fn, gap_h, state in ( + ("tab-n", 0, gtk.STATE_NORMAL), + ("tab-a", 2, gtk.STATE_ACTIVE), + ): +## style.paint_box_gap(drawing_area.window, state, shadow, +## gtk.gdk.Rectangle(0,0,w,gap_h), drawing_area, +## "notebook", 0,0, w,gap_h, gtk.POS_TOP, 0, w) + y = gap_h + hh = h - y + style.paint_extension(drawing_area.window, state, gtk.SHADOW_OUT, + None, drawing_area, "tab", + 0,y, w,hh, gtk.POS_BOTTOM) + save_image(fn, w, h+2) + + + + print 'done' + + gtk.main_quit() + + +def pack(w, row, col): + table.attach(w, + col, col+1, row, row+1, + gtk.EXPAND | gtk.FILL, gtk.EXPAND | gtk.FILL, + 0, 0) + +win = gtk.Window() +win.connect("destroy", gtk.main_quit) + +table = gtk.Table() +win.add(table) + +row, col = 0, 0 + +drawing_area = gtk.DrawingArea() +#drawing_area.set_size_request(100, 100) +pack(drawing_area, row, col) +row += 1 + +vscroll = gtk.VScrollbar() +pack(vscroll, 0, 1) + +hscroll = gtk.HScrollbar() +pack(hscroll, row, col) +row += 1 + + +notebook = gtk.Notebook() +label = gtk.Label("Label") +notebook.append_page(label) +label = gtk.Label("Label") +notebook.append_page(label) +pack(notebook, row, col) +row += 1 + +button = gtk.Button("Button") +pack(button, row, col) +row += 1 + +checkbutton = gtk.CheckButton("CheckButton") +pack(checkbutton, row, col) +row += 1 + +progress = gtk.ProgressBar() +pack(progress, row, col) +row += 1 + +scale = gtk.HScale() +pack(scale, row, col) +row += 1 + +entry = gtk.Entry() +pack(entry, row, col) +row += 1 + +togglebutton = gtk.ToggleButton() +pack(togglebutton, row, col) +togglebutton.set_active(True) +row += 1 + + +drawing_area.connect("expose-event", save_callback) +#gobject.timeout_add(2000, save_callback) + +win.show_all() +#drawing_area.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse('red')) + +gtk.main() + + + diff --git a/data/themes/clearlooks/pkgIndex.tcl b/data/themes/clearlooks/pkgIndex.tcl new file mode 100644 index 00000000..288fdae3 --- /dev/null +++ b/data/themes/clearlooks/pkgIndex.tcl @@ -0,0 +1,7 @@ +# Package index for tile demo pixmap themes. + +if {[file isdirectory [file join $dir clearlooks]]} { + package ifneeded tile::theme::clearlooks 0.1 \ + [list source [file join $dir clearlooks.tcl]] +} + diff --git a/pysollib/app.py b/pysollib/app.py index b3c40982..77db88ee 100644 --- a/pysollib/app.py +++ b/pysollib/app.py @@ -281,8 +281,8 @@ class Options: def setDefaults(self, top=None): # toolbar - if WIN_SYSTEM == 'win32': - self.toolbar_style = 'crystal' + #if WIN_SYSTEM == 'win32': + # self.toolbar_style = 'crystal' # fonts if WIN_SYSTEM == 'win32': self.fonts["sans"] = ("times new roman", 12) diff --git a/pysollib/customgame.py b/pysollib/customgame.py index d50b8131..7b1a870a 100644 --- a/pysollib/customgame.py +++ b/pysollib/customgame.py @@ -120,10 +120,13 @@ class CustomGame(Game): 'waste' : False, 'texts' : True, } + playcards = 0 if s['talon'] is InitialDealTalonStack: layout_kw['texts'] = False - layout_kw['playcards'] = max( - 16, 12+s['deal_face_down']+s['deal_face_up']) + playcards = 12 + 52 * s['decks'] / s['rows_num'] + else: + playcards = 12 + s['deal_face_down'] + s['deal_face_up'] + layout_kw['playcards'] = max(16, playcards) if s['talon'] in (DealRowRedealTalonStack, SpiderTalonStack, GroundForADivorceTalonStack): diff --git a/pysollib/game.py b/pysollib/game.py index ffb15a40..10749ee1 100644 --- a/pysollib/game.py +++ b/pysollib/game.py @@ -193,14 +193,16 @@ class Game: ##self.top.bind('', self.top._sleepEvent) ##self.top.bind('<3>', self.top._sleepEvent) # update display properties - self.top.wm_geometry("") # cancel user-specified geometry + self.canvas.busy = True self.canvas.setInitialSize(self.width, self.height) if self.app.opt.save_games_geometry and \ self.id in self.app.opt.games_geometry: # restore game geometry w, h = self.app.opt.games_geometry[self.id] self.canvas.config(width=w, height=h) - self.top.update_idletasks() # apply geometry now + self.top.wm_geometry("") # cancel user-specified geometry + self.top.update_idletasks() + self.canvas.busy = False if DEBUG >= 4: MfxCanvasRectangle(self.canvas, 0, 0, self.width, self.height, width=2, fill=None, outline='green') @@ -2665,7 +2667,6 @@ for %d moves. self.updatePlayTime(do_after=0) reset_solver_dialog() - return 1 @@ -2694,6 +2695,7 @@ for %d moves. self.updateText() self.updateStatus(moves=(self.moves.index, self.stats.total_moves)) self.updateMenus() + reset_solver_dialog() def redo(self): assert self.canRedo() @@ -2718,6 +2720,7 @@ for %d moves. self.updateText() self.updateStatus(moves=(self.moves.index, self.stats.total_moves)) self.updateMenus() + reset_solver_dialog() # diff --git a/pysollib/init.py b/pysollib/init.py index b5e2a9c9..a0d9cbff 100644 --- a/pysollib/init.py +++ b/pysollib/init.py @@ -110,8 +110,8 @@ def init(): sys.argv.remove('--tile') if settings.TOOLKIT == 'tk': import Tkinter - from Tkinter import TclError root = Tkinter.Tk(className='PySol') + root.withdraw() settings.WIN_SYSTEM = root.tk.call('tk', 'windowingsystem') if settings.WIN_SYSTEM == 'aqua': # TkAqua displays the console automatically in application @@ -119,13 +119,12 @@ def init(): from macosx.appSupport import hideTkConsole hideTkConsole(root) # - root.withdraw() if settings.USE_TILE == 'auto': - # check tile + # check Tile settings.USE_TILE = False try: root.tk.call('package', 'require', 'tile', '0.7.8') - except TclError: + except Tkinter.TclError: pass else: settings.USE_TILE = True diff --git a/pysollib/tile/Tile.py b/pysollib/tile/Tile.py index 38bffeba..ce882dac 100644 --- a/pysollib/tile/Tile.py +++ b/pysollib/tile/Tile.py @@ -1,28 +1,25 @@ - -from pysollib.settings import WIN_SYSTEM +# http://tkinter.unpythonic.net/wiki/TileWrapper import Tkinter -from Tkconstants import * -BooleanVar = Tkinter.BooleanVar -IntVar = Tkinter.IntVar -DoubleVar = Tkinter.DoubleVar -StringVar = Tkinter.StringVar +def initialize(root=None): + if root is None: + root = Tkinter._default_root + root.tk.call("package", "require", "tile", "0.7.8") + # This forces an update of the available packages list. + # It's required for package names to find the themes in data/themes/ + root.tk.call('eval', '[package unknown]', 'Tcl', '[package provide Tcl]') -Tk = Tkinter.Tk -Toplevel = Tkinter.Toplevel -Menu = Tkinter.Menu -Message = Tkinter.Message -Listbox = Tkinter.Listbox -Text = Tkinter.Text -Canvas = Tkinter.Canvas -Spinbox = Tkinter.Spinbox +def availableThemes(root=None): + if root is None: + root = Tkinter._default_root + return root.tk.call("tile::availableThemes") -PhotoImage = Tkinter.PhotoImage -Event = Tkinter.Event -TkVersion = Tkinter.TkVersion -TclError = Tkinter.TclError +def setTheme(root=None, theme=None): + if root is None: + root = Tkinter._default_root + return root.tk.call("tile::setTheme", theme) class Style(Tkinter.Misc): @@ -33,18 +30,21 @@ class Style(Tkinter.Misc): def default(self, style, **kw): """Sets the default value of the specified option(s) in style""" - pass + opts = self._options(kw) + return self.tk.call("style", "default", style, *opts) def map_style(self, **kw): """Sets dynamic values of the specified option(s) in style. See - "STATE MAPS", below.""" - pass + "STATE MAPS", below. + """ + raise NotImplementedError() def layout(self, style, layoutSpec): """Define the widget layout for style style. See "LAYOUTS" below for the format of layoutSpec. If layoutSpec is omitted, return the - layout specification for style style. """ - pass + layout specification for style style. + """ + raise NotImplementedError() def element_create(self, name, type, *args): """Creates a new element in the current theme of type type. The @@ -52,11 +52,11 @@ class Style(Tkinter.Misc): themes may define other element types (see Ttk_RegisterElementFactory). """ - pass + raise NotImplementedError() def element_names(self): - """Returns a list of all elements defined in the current theme. """ - pass + """Returns a list of all elements defined in the current theme.""" + return self.tk.call("style", "elements", "names") def theme_create(self, name, parent=None, basedon=None): """Creates a new theme. It is an error if themeName already exists. @@ -65,17 +65,17 @@ class Style(Tkinter.Misc): script is evaluated in the context of the new theme as per style theme settings. """ - pass + raise NotImplementedError() def theme_settings(self, name, script): - """Temporarily sets the current theme to themeName, evaluate script, - then restore the previous theme. Typically script simply defines styles - and elements, though arbitrary Tcl code may appear. + """Temporarily sets the current theme to themeName, evaluate script, + then restore the previous theme. Typically script simply defines + styles and elements, though arbitrary Tcl code may appear. """ - pass + raise NotImplementedError() def theme_names(self): - """Returns a list of the available themes. """ + """Returns a list of the available themes.""" return self.tk.call("style", "theme", "names") def theme_use(self, theme): @@ -263,6 +263,7 @@ class Notebook(Widget): properly if all panes are direct children of the notebook.""" return self.tk.call("ttk::notebook::enableTraversal", self._w) + class Paned(Widget): """ WIDGET OPTIONS @@ -300,10 +301,11 @@ class Paned(Widget): self.tk.call(self._w, "forget", pane) def insert(self, pos, subwindow, **kw): - """Inserts a pane at the specified position. pos is either the string - end, an integer index, or the name of a managed subwindow. If subwindow - is already managed by the paned window, moves it to the specified - position. See PANE OPTIONS for the list of available options. + """Inserts a pane at the specified position. pos is either the string + end, an integer index, or the name of a managed subwindow. If + subwindow is already managed by the paned window, moves it to the + specified position. See PANE OPTIONS for the list of available + options. """ return self.tk.call((self._w, "insert", pos, subwindow) + self._options(kw)) @@ -325,13 +327,21 @@ class Progressbar(Widget): def step(self, amount=1.0): """Increments the -value by amount. amount defaults to 1.0 - if omitted. """ + if omitted. + """ return self.tk.call(self._w, "step", amount) - def start(self): - self.tk.call("ttk::progressbar::start", self._w) + def start(self, interval=None): + """Begin autoincrement mode: schedules a recurring timer event that + calls step every interval milliseconds. If omitted, interval defaults + to 50 milliseconds (20 steps/second). + """ + self.tk.call("ttk::progressbar::start", self._w, interval) def stop(self): + """Stop autoincrement mode: cancels any recurring timer event + initiated by pathName start. + """ self.tk.call("ttk::progressbar::stop", self._w) @@ -344,11 +354,6 @@ class Scrollbar(Widget, Tkinter.Scrollbar): def __init__(self, master=None, cnf={}, **kw): Widget.__init__(self, master, "ttk::scrollbar", cnf, kw) -# from http://tkinter.unpythonic.net/wiki/PyLocateTile : -# standard Tk scrollbars work on OS X, but Tile ones look weird -if WIN_SYSTEM == "aqua": - Scrollbar = Tkinter.Scrollbar - class Separator(Widget): def __init__(self, master=None, cnf={}, **kw): @@ -369,6 +374,9 @@ class Treeview(Widget, Tkinter.Listbox): the items in newchildren may be an ancestor of item. """ return self.tk.call(self._w, "children", item, newchildren) + # Workaround: `children' overwrite in Tkinter.BaseWidget.__init__ + child = children + tree_children = children def column(self, column, **kw): """Query or modify the options for the specified column. @@ -433,35 +441,35 @@ class Treeview(Widget, Tkinter.Listbox): """ return self.tk.call((self._w, 'heading', column) + self._options(kw)) - def identify(self, x, y): - """Returns a description of the widget component under the point given - by x and y. The return value is a list with one of the following forms: + def identify(self, component, x, y): + """Returns a description of the specified component under the point + given by x and y, or the empty string if no such component is + present at that position. The following subcommands are + supported: - heading #n - The column heading for display column #n. - separator #n - The border to the right of display column #n. - cell itemid #n - The data value for item itemid in display column #n. - item itemid element - The tree label for item itemid; element is one of text, image, or - indicator, or another element name depending on the style. - row itemid - The y position is over the item but x does not identify any element - or displayed data value. - nothing - The coordinates are not over any identifiable object. + pathname identify row x y + Returns the item ID of the item at position y. - See COLUMN IDENTIFIERS for a discussion of display columns and data + pathname identify column x y + Returns the data column identifier of the cell at position x. + The tree column has ID #0. + + See COLUMN IDENTIFIERS for a discussion of display columns and data columns. """ - pass + return self.tk.call(self._w, "identify", component, x, y) + + def identify_row(self, x, y): + return self.identify('row', x, y) + + def identify_column(self, x, y): + return self.identify('column', x, y) def index(self, item): """Returns the integer index of item within its parent's list of children. """ - pass + return self.tk.call(self._w, "index", item) def insert(self, parent, index, id=None, **kw): """Creates a new item. parent is the item ID of the parent item, or @@ -488,7 +496,7 @@ class Treeview(Widget, Tkinter.Listbox): item's options are updated with the specified values. See ITEM OPTIONS for the list of available options. """ - pass + return self.tk.call((self._w, 'item') + self._options(kw)) def move(self, item, parent, index): """Moves item to position index in parent's list of children. It is @@ -498,148 +506,105 @@ class Treeview(Widget, Tkinter.Listbox): beginning; if greater than or equal to the number of children, it's moved to the end. """ - pass + return self.tk.call(self._w, 'move', item, parent, index) def next(self, item): """Returns the identifier of item's next sibling, or {} if item is the last child of its parent. """ - pass + return self.tk.call(self._w, 'next', item) def parent(self, item): """Returns the ID of the parent of item, or {} if item is at the top level of the hierarchy. """ - pass + return self.tk.call(self._w, 'parent', item) def prev(self, item): """Returns the identifier of item's previous sibling, or {} if item is the first child of its parent. """ - pass + return self.tk.call(self._w, 'prev', item) def selection(self): - """Returns the list of selected items""" + """Returns the list of selected items.""" return self.tk.call(self._w, "selection") def selection_set(self, items): - """items becomes the new selection. """ - pass + """items becomes the new selection.""" + return self.tk.call(self._w, "selection", "set", items) def selection_add(self, items): - """Add items to the selection """ - pass + """Add items to the selection.""" + return self.tk.call(self._w, "selection", "add", items) def selection_remove(self, items): - """Remove items from the selection """ - pass + """Remove items from the selection.""" + return self.tk.call(self._w, "selection", "remove", items) def selection_toggle(self, items): - """Toggle the selection state of each item in items. """ - pass + """Toggle the selection state of each item in items.""" + return self.tk.call(self._w, "selection", "toggle", items) def set(self, item, column, value=None): - """If value is specified, sets the value of column column in item item, - otherwise returns the current value. See COLUMN IDENTIFIERS. + """If value is specified, sets the value of column column in item + item, otherwise returns the current value. See COLUMN IDENTIFIERS. """ - pass + raise NotImplementedError() - -if __name__=="__main__": - def callback(): - print "Hello" - +def test(): + import sys root = Tkinter.Tk() - root.tk.call("package", "require", "tile") - - b = Button(root, text="Tile Button", command=callback) - b.pack() - - #~ c = Checkbutton(root) - #~ c.pack() - #~ print b.theme_names() - - #~ cb = Combobox(root) - #~ cb.pack() - - #~ e = Entry(root) - #~ e.validate() - #~ e.pack() - - #~ l = Label(root, text="Tile Label") - #~ l.pack() - - - #~ mb = Menubutton(root) - #~ mb.pack() - - - #~ nb = Notebook(root) - - #~ f1 = Label(nb, text="page1") - #~ nb.add(f1, text="Page1") - #~ f1.pack() - - #~ f2 = Label(nb, text="page2") - #~ nb.add(f2, text="Page 2") - #~ f2.pack() - - #~ nb.pack() - - - pb = Progressbar(root, mode="indeterminate") - pb.pack() - - - pb.start() - b = Button(root, text="Start", command=pb.start) - b.pack() - b = Button(root, text="Stop", command=pb.stop) - b.pack() - - #~ rb = Radiobutton(root) - #~ rb.pack() - - #~ text = Tkinter.Text(root) - #~ scrol = Scrollbar(root) - #~ text.pack(side="left", fill="both", expand="yes") - #~ scrol.pack(side="left", fill="y") - #~ text['yscrollcommand'] = scrol.set - #~ scrol['command'] = text.yview - - - #~ l = Label(root, text="Label1") - #~ l.pack() - #~ s = Separator(root) - #~ s.pack(fill="x") - #~ l = Label(root, text="Label2") - #~ l.pack() - - - b.theme_use("default") - - #~ b1 = Tkinter.Button(root, text="Tk Button", command=callback) - #~ b1.pack() - - - panes = Paned(root) - panes.pack(fill="both", expand="yes") - - label1 = Label(panes, text="pane1") - label2 = Label(panes, text="Pane2") - - - panes.add(label1) - panes.add(label2) - - - - - #~ tree = Treeview(root, columns=("One", "Two", "Three")) - - #~ tree.insert(None, "end", text="Hello") - - #~ tree.pack() - + initialize() + root.option_add('*Toolbar.relief', 'groove') + root.option_add('*Toolbar.borderWidth', 2) + root.option_add('*Toolbar.Button.Pad', 2) + base = Frame(root) + base.pack(expand=True, fill='both') + tb_frame = Frame(base, class_='Toolbar') + tb_frame.pack(side='top', expand=False, fill='x') + b = Button(tb_frame, text='Open', style='Toolbutton') + b.grid(row=0, column=0, sticky='news') + b = Button(tb_frame, text='Save', style='Toolbutton') + b.grid(row=0, column=1, sticky='news') + b = Checkbutton(tb_frame, text='Bold', style='Toolbutton') + b.grid(row=0, column=2, sticky='news') + b = Checkbutton(tb_frame, text='Italic', style='Toolbutton') + b.grid(row=0, column=3, sticky='news') + tb_frame.grid_columnconfigure(4, weight=1) + theme_frame = LabelFrame(base, text='Theme') + theme_frame.pack(side='left', expand=False, fill='y', padx=4, pady=4) + theme_var = Tkinter.StringVar() + theme_var.set('default') + for theme in availableThemes(): + command = lambda theme=theme: setTheme(theme=theme) + b = Radiobutton(theme_frame, text=theme, variable=theme_var, + value=theme, command=command) + b.pack(side='top', expand=False, fill='x', padx=4) + right_frame = Frame(base) + right_frame.pack(side='right', expand=True, fill='both') + b = Checkbutton(right_frame, text='Checkbutton') + b.pack(expand=False, fill='x') + b = Button(right_frame, text='Button') + b.pack(expand=False, fill='x') + text_frame = Frame(right_frame) + text_frame.pack(expand=True, fill='both') + text = Tkinter.Text(text_frame, width=40, height=20, + fg='black', bg='white', wrap='none') + hsb = Scrollbar(text_frame, orient='horizontal', command=text.xview) + vsb = Scrollbar(text_frame, orient='vertical', command=text.yview) + text.grid(row=0, column=0, sticky='nwse') + hsb.grid(row=1, column=0, sticky='we') + vsb.grid(row=0, column=1, sticky='ns') + text.configure(xscrollcommand=hsb.set) + text.configure(yscrollcommand=vsb.set) + text.insert('end', open(sys.argv[0]).read()) + grip = Sizegrip(text_frame) + grip.grid(row=1, column=1, sticky='se') + text_frame.grid_columnconfigure(0, weight=1) + text_frame.grid_rowconfigure(0, weight=1) root.mainloop() + +if __name__ == '__main__': + test() diff --git a/pysollib/tile/colorsdialog.py b/pysollib/tile/colorsdialog.py index 1298c26c..0a4be322 100644 --- a/pysollib/tile/colorsdialog.py +++ b/pysollib/tile/colorsdialog.py @@ -22,16 +22,14 @@ __all__ = ['ColorsDialog'] # imports -import os, sys -import Tkinter as Tk -import Tile as Tkinter +import Tkinter +import Tile from tkColorChooser import askcolor # PySol imports -from pysollib.mfxutil import destruct, kwdefault, KwStruct, Struct +from pysollib.mfxutil import KwStruct # Toolkit imports -from tkconst import EVENT_HANDLED, EVENT_PROPAGATE from tkwidget import MfxDialog # /*********************************************************************** @@ -45,7 +43,7 @@ class ColorsDialog(MfxDialog): top_frame, bottom_frame = self.createFrames(kw) self.createBitmaps(top_frame, kw) - frame = Tkinter.Frame(top_frame) + frame = Tile.Frame(top_frame) frame.pack(expand=True, fill='both', padx=5, pady=10) frame.columnconfigure(0, weight=1) @@ -77,13 +75,13 @@ class ColorsDialog(MfxDialog): (_('Hint arrow:'), self.hintarrow_var), (_('Highlight not matching:'), self.not_matching_var), ): - Tkinter.Label(frame, text=title, anchor='w', - ).grid(row=row, column=0, sticky='we') - l = Tk.Label(frame, width=10, height=2, + Tile.Label(frame, text=title, anchor='w', + ).grid(row=row, column=0, sticky='we') + l = Tkinter.Label(frame, width=10, height=2, bg=var.get(), textvariable=var) l.grid(row=row, column=1, padx=5) - b = Tkinter.Button(frame, text=_('Change...'), width=10, - command=lambda l=l: self.selectColor(l)) + b = Tile.Button(frame, text=_('Change...'), width=10, + command=lambda l=l: self.selectColor(l)) b.grid(row=row, column=2) row += 1 # @@ -100,7 +98,7 @@ class ColorsDialog(MfxDialog): self.not_matching_color = self.not_matching_var.get() def selectColor(self, label): - c = askcolor(master=self.top, initialcolor=label.cget('bg'), + c = askcolor(parent=self.top, initialcolor=label.cget('bg'), title=_("Select color")) if c and c[1]: label.configure(bg=c[1]) diff --git a/pysollib/tile/edittextdialog.py b/pysollib/tile/edittextdialog.py index ec64fb6d..b7086f90 100644 --- a/pysollib/tile/edittextdialog.py +++ b/pysollib/tile/edittextdialog.py @@ -36,11 +36,11 @@ __all__ = ['EditTextDialog'] # imports -import os, sys -import Tile as Tkinter +import Tkinter +import Tile # PySol imports -from pysollib.mfxutil import destruct, kwdefault, KwStruct, Struct +from pysollib.mfxutil import KwStruct # Toolkit imports from tkwidget import MfxDialog @@ -61,7 +61,7 @@ class EditTextDialog(MfxDialog): wrap="word", width=64, height=16) self.text_w.pack(side='left', fill="both", expand=True) ###self.text_w.pack(side='top', padx=kw.padx, pady=kw.pady) - vbar = Tkinter.Scrollbar(top_frame) + vbar = Tile.Scrollbar(top_frame) vbar.pack(side='right', fill='y') self.text_w["yscrollcommand"] = vbar.set vbar["command"] = self.text_w.yview diff --git a/pysollib/tile/findcarddialog.py b/pysollib/tile/findcarddialog.py index 6cb931fa..93afbd78 100644 --- a/pysollib/tile/findcarddialog.py +++ b/pysollib/tile/findcarddialog.py @@ -27,9 +27,6 @@ __all__ = ['create_find_card_dialog', # imports import os import Tkinter -import traceback - -# PySol imports # Toolkit imports from tkutil import after, after_cancel diff --git a/pysollib/tile/fontsdialog.py b/pysollib/tile/fontsdialog.py index 673b4752..1c1e96fb 100644 --- a/pysollib/tile/fontsdialog.py +++ b/pysollib/tile/fontsdialog.py @@ -22,16 +22,14 @@ __all__ = ['FontsDialog'] # imports -import os, sys -import types -import Tile as Tkinter +import Tkinter +import Tile import tkFont # PySol imports -from pysollib.mfxutil import destruct, kwdefault, KwStruct, Struct +from pysollib.mfxutil import KwStruct # Toolkit imports -from tkconst import EVENT_HANDLED, EVENT_PROPAGATE from tkwidget import MfxDialog from tkutil import bind from tkwidget import PysolScale @@ -81,28 +79,28 @@ class FontChooserDialog(MfxDialog): self.size_var = Tkinter.IntVar() self.size_var.set(self.font_size) # - frame = Tkinter.Frame(top_frame) + frame = Tile.Frame(top_frame) frame.pack(expand=True, fill='both', padx=5, pady=10) frame.columnconfigure(0, weight=1) #frame.rowconfigure(1, weight=1) - self.entry = Tkinter.Entry(frame) + self.entry = Tile.Entry(frame) self.entry.grid(row=0, column=0, columnspan=2, sticky='news') self.entry.insert('end', _('abcdefghABCDEFGH')) self.list_box = Tkinter.Listbox(frame, width=36, exportselection=False) - sb = Tkinter.Scrollbar(frame) + sb = Tile.Scrollbar(frame) self.list_box.configure(yscrollcommand=sb.set) sb.configure(command=self.list_box.yview) self.list_box.grid(row=1, column=0, sticky='news') # rowspan=4 sb.grid(row=1, column=1, sticky='ns') bind(self.list_box, '<>', self.fontupdate) ##self.list_box.focus() - cb1 = Tkinter.Checkbutton(frame, text=_('Bold'), - command=self.fontupdate, - variable=self.weight_var) + cb1 = Tile.Checkbutton(frame, text=_('Bold'), + command=self.fontupdate, + variable=self.weight_var) cb1.grid(row=2, column=0, columnspan=2, sticky='we') - cb2 = Tkinter.Checkbutton(frame, text=_('Italic'), - command=self.fontupdate, - variable=self.slant_var) + cb2 = Tile.Checkbutton(frame, text=_('Italic'), + command=self.fontupdate, + variable=self.slant_var) cb2.grid(row=3, column=0, columnspan=2, sticky='we') sc = PysolScale(frame, from_=6, to=40, resolution=1, @@ -157,7 +155,7 @@ class FontsDialog(MfxDialog): top_frame, bottom_frame = self.createFrames(kw) self.createBitmaps(top_frame, kw) - frame = Tkinter.Frame(top_frame) + frame = Tile.Frame(top_frame) frame.pack(expand=True, fill='both', padx=5, pady=10) frame.columnconfigure(0, weight=1) @@ -174,16 +172,16 @@ class FontsDialog(MfxDialog): ): font = app.opt.fonts[fn] self.fonts[fn] = font - Tkinter.Label(frame, text=title, anchor='w' - ).grid(row=row, column=0, sticky='we') + Tile.Label(frame, text=title, anchor='w' + ).grid(row=row, column=0, sticky='we') if font: title = ' '.join([str(i) for i in font if i not in ('roman', 'normal')]) elif font is None: title = 'Default' - l = Tkinter.Label(frame, font=font, text=title) + l = Tile.Label(frame, font=font, text=title) l.grid(row=row, column=1, padx=8) - b = Tkinter.Button(frame, text=_('Change...'), width=10, - command=lambda l=l, fn=fn: self.selectFont(l, fn)) + b = Tile.Button(frame, text=_('Change...'), width=10, + command=lambda l=l, fn=fn: self.selectFont(l, fn)) b.grid(row=row, column=2) row += 1 # diff --git a/pysollib/tile/gameinfodialog.py b/pysollib/tile/gameinfodialog.py index 49bea456..ccb1d7a4 100644 --- a/pysollib/tile/gameinfodialog.py +++ b/pysollib/tile/gameinfodialog.py @@ -23,8 +23,7 @@ __all__ = ['GameInfoDialog'] # imports -import os, sys -import Tile as Tkinter +import Tile # PySol imports from pysollib.mfxutil import KwStruct @@ -44,7 +43,7 @@ class GameInfoDialog(MfxDialog): top_frame, bottom_frame = self.createFrames(kw) self.createBitmaps(top_frame, kw) - frame = Tkinter.Frame(top_frame) + frame = Tile.Frame(top_frame) frame.pack(expand=True, fill='both', padx=5, pady=10) frame.columnconfigure(0, weight=1) @@ -108,10 +107,10 @@ class GameInfoDialog(MfxDialog): ('Hint:', hint), ): if t: - Tkinter.Label(frame, text=n, anchor='w' - ).grid(row=row, column=0, sticky='nw') - Tkinter.Label(frame, text=t, anchor='w', justify='left' - ).grid(row=row, column=1, sticky='nw') + Tile.Label(frame, text=n, anchor='w' + ).grid(row=row, column=0, sticky='nw') + Tile.Label(frame, text=t, anchor='w', justify='left' + ).grid(row=row, column=1, sticky='nw') row += 1 if game.s.talon: @@ -134,8 +133,8 @@ class GameInfoDialog(MfxDialog): self.mainloop(focus, kw.timeout) def showStacks(self, frame, row, title, stacks): - Tkinter.Label(frame, text=title, anchor='w' - ).grid(row=row, column=0, sticky='nw') + Tile.Label(frame, text=title, anchor='w' + ).grid(row=row, column=0, sticky='nw') if isinstance(stacks, (list, tuple)): fs = {} for f in stacks: @@ -147,8 +146,8 @@ class GameInfoDialog(MfxDialog): t = '\n'.join(['%s (%d)' % (i[0], i[1]) for i in fs.items()]) else: t = stacks.__class__.__name__ - Tkinter.Label(frame, text=t, anchor='w', justify='left' - ).grid(row=row, column=1, sticky='nw') + Tile.Label(frame, text=t, anchor='w', justify='left' + ).grid(row=row, column=1, sticky='nw') def initKw(self, kw): kw = KwStruct(kw, diff --git a/pysollib/tile/menubar.py b/pysollib/tile/menubar.py index b00cd125..c3e994c6 100644 --- a/pysollib/tile/menubar.py +++ b/pysollib/tile/menubar.py @@ -38,15 +38,15 @@ __all__ = ['PysolMenubar'] # imports import math, os, sys, re, traceback -import Tile as Tkinter +import Tile +import Tkinter import tkFileDialog # PySol imports -from pysollib.mfxutil import destruct, Struct, kwdefault +from pysollib.mfxutil import Struct, kwdefault from pysollib.mfxutil import Image from pysollib.util import CARDSET from pysollib.settings import PACKAGE, WIN_SYSTEM -from pysollib.settings import TOP_TITLE from pysollib.settings import SELECT_GAME_MENU from pysollib.settings import USE_FREECELL_SOLVER from pysollib.settings import DEBUG @@ -1035,6 +1035,8 @@ class PysolMenubar(PysolMenubarActions): self.updateMenus() def mPause(self, *args): + if not self.game: + return if not self.game.pause: if self._cancelDrag(): return self.game.doPause() @@ -1350,8 +1352,7 @@ the next time you restart """)+PACKAGE, def createThemesMenu(self, menu): submenu = MfxMenu(menu, label=n_("Set t&heme")) - style = Tkinter.Style(self.top) - all_themes = list(style.theme_names()) + all_themes = list(Tile.availableThemes()) all_themes.sort() # tn = { diff --git a/pysollib/tile/playeroptionsdialog.py b/pysollib/tile/playeroptionsdialog.py index 553f23da..e34dc106 100644 --- a/pysollib/tile/playeroptionsdialog.py +++ b/pysollib/tile/playeroptionsdialog.py @@ -36,16 +36,14 @@ __all__ = ['PlayerOptionsDialog'] # imports -import os, sys -import Tile as Tkinter +import Tkinter +import Tile # PySol imports -from pysollib.mfxutil import destruct, kwdefault, KwStruct, Struct +from pysollib.mfxutil import KwStruct # Toolkit imports -from tkconst import EVENT_HANDLED, EVENT_PROPAGATE from tkwidget import MfxDialog -from tkutil import bind # /*********************************************************************** @@ -67,25 +65,25 @@ class PlayerOptionsDialog(MfxDialog): self.win_animation_var = Tkinter.BooleanVar() self.win_animation_var.set(app.opt.win_animation != 0) # - frame = Tkinter.Frame(top_frame) + frame = Tile.Frame(top_frame) frame.pack(expand=True, fill='both', padx=5, pady=10) - widget = Tkinter.Label(frame, text=_("\nPlease enter your name"), - takefocus=0) + widget = Tile.Label(frame, text=_("\nPlease enter your name"), + takefocus=0) widget.grid(row=0, column=0, columnspan=2, sticky='ew', padx=0, pady=5) # w = kw.get("e_width", 30) # width in characters names = self.app.getAllUserNames() - self.player_var = Tkinter.Combobox(frame, width=w, values=tuple(names)) + self.player_var = Tile.Combobox(frame, width=w, values=tuple(names)) self.player_var.current(names.index(app.opt.player)) self.player_var.grid(row=1, column=0, sticky='ew', padx=0, pady=5) # - widget = Tkinter.Checkbutton(frame, variable=self.confirm_var, - text=_("Confirm quit")) + widget = Tile.Checkbutton(frame, variable=self.confirm_var, + text=_("Confirm quit")) widget.grid(row=2, column=0, columnspan=2, sticky='ew', padx=0, pady=5) - widget = Tkinter.Checkbutton(frame, variable=self.update_stats_var, - text=_("Update statistics and logs")) + widget = Tile.Checkbutton(frame, variable=self.update_stats_var, + text=_("Update statistics and logs")) widget.grid(row=3, column=0, columnspan=2, sticky='ew', padx=0, pady=5) -### widget = Tkinter.Checkbutton(frame, variable=self.win_animation_var, +### widget = Tile.Checkbutton(frame, variable=self.win_animation_var, ### text="Win animation") ### widget.pack(side='top', padx=kw.padx, pady=kw.pady) frame.columnconfigure(0, weight=1) diff --git a/pysollib/tile/progressbar.py b/pysollib/tile/progressbar.py index 2da923c8..4d4cf2de 100644 --- a/pysollib/tile/progressbar.py +++ b/pysollib/tile/progressbar.py @@ -36,11 +36,11 @@ __all__ = ['PysolProgressBar'] # imports -import os, sys -import Tile as Tkinter +import Tkinter +import Tile # Toolkit imports -from tkconst import EVENT_HANDLED, EVENT_PROPAGATE +from tkconst import EVENT_HANDLED from tkutil import makeToplevel, setTransient @@ -59,15 +59,15 @@ class PysolProgressBar: self.top.wm_resizable(0, 0) self.top.config(cursor="watch") # - self.frame = Tkinter.Frame(self.top, relief='flat', borderwidth=0) - self.progress = Tkinter.Progressbar(self.frame, maximum=100, length=250) - ##style = Tkinter.Style(self.progress) + self.frame = Tile.Frame(self.top, relief='flat', borderwidth=0) + self.progress = Tile.Progressbar(self.frame, maximum=100, length=250) + ##style = Tile.Style(self.progress) ##style.configure('TProgressbar', background=color) if images: - self.f1 = Tkinter.Label(self.frame, image=images[0]) + self.f1 = Tile.Label(self.frame, image=images[0]) self.f1.pack(side='left', ipadx=8, ipady=4) self.progress.pack(side='left', expand=True, fill='x') - self.f2 = Tkinter.Label(self.frame, image=images[1]) + self.f2 = Tile.Label(self.frame, image=images[1]) self.f2.pack(side='left', ipadx=8, ipady=4) else: self.progress.pack(expand=True, fill='x') diff --git a/pysollib/tile/selectcardset.py b/pysollib/tile/selectcardset.py index 4a5b5e5f..9009dbc3 100644 --- a/pysollib/tile/selectcardset.py +++ b/pysollib/tile/selectcardset.py @@ -36,11 +36,12 @@ __all__ = ['SelectCardsetDialogWithPreview'] # imports -import os, re, sys, types -import Tile as Tkinter +import os +import Tkinter +import Tile # PySol imports -from pysollib.mfxutil import destruct, Struct, KwStruct +from pysollib.mfxutil import KwStruct from pysollib.util import CARDSET from pysollib.resource import CSI @@ -200,10 +201,10 @@ class SelectCardsetDialogWithPreview(MfxDialog): w1, w2 = 216, 400 else: w1, w2 = 200, 300 - paned_window = Tkinter.PanedWindow(top_frame) + paned_window = Tile.PanedWindow(top_frame) paned_window.pack(expand=True, fill='both') - left_frame = Tkinter.Frame(paned_window) - right_frame = Tkinter.Frame(paned_window) + left_frame = Tile.Frame(paned_window) + right_frame = Tile.Frame(paned_window) paned_window.add(left_frame) paned_window.add(right_frame) font = app.getFont("default") @@ -307,11 +308,11 @@ class CardsetInfoDialog(MfxDialog): MfxDialog.__init__(self, parent, title, kw.resizable, kw.default) top_frame, bottom_frame = self.createFrames(kw) self.createBitmaps(top_frame, kw) - frame = Tkinter.Frame(top_frame) + frame = Tile.Frame(top_frame) frame.pack(fill="both", expand=True, padx=5, pady=10) # # - info_frame = Tkinter.LabelFrame(frame, text=_('About cardset')) + info_frame = Tile.LabelFrame(frame, text=_('About cardset')) info_frame.grid(row=0, column=0, columnspan=2, sticky='ew', padx=0, pady=5, ipadx=5, ipady=5) styles = nationalities = year = None @@ -333,11 +334,11 @@ class CardsetInfoDialog(MfxDialog): (_('Size:'), '%d x %d' % (cardset.CARDW, cardset.CARDH)), ): if t is not None: - l = Tkinter.Label(info_frame, text=n, - anchor='w', justify='left') + l = Tile.Label(info_frame, text=n, + anchor='w', justify='left') l.grid(row=row, column=0, sticky='nw', padx=4) - l = Tkinter.Label(info_frame, text=t, - anchor='w', justify='left') + l = Tile.Label(info_frame, text=t, + anchor='w', justify='left') l.grid(row=row, column=1, sticky='nw', padx=4) row += 1 if images: @@ -346,10 +347,10 @@ class CardsetInfoDialog(MfxDialog): im = choice(images) f = os.path.join(cardset.dir, cardset.backname) self.back_image = loadImage(file=f) # store the image - l = Tkinter.Label(info_frame, image=im, padding=5) + l = Tile.Label(info_frame, image=im, padding=5) l.grid(row=0, column=2, rowspan=row+1, sticky='ne') - l = Tkinter.Label(info_frame, image=self.back_image, - padding=(0,5,5,5)) # left margin = 0 + l = Tile.Label(info_frame, image=self.back_image, + padding=(0,5,5,5)) # left margin = 0 l.grid(row=0, column=3, rowspan=row+1, sticky='ne') info_frame.columnconfigure(2, weight=1) @@ -361,7 +362,7 @@ class CardsetInfoDialog(MfxDialog): text_w = Tkinter.Text(frame, bd=1, relief="sunken", wrap="word", padx=4, width=64, height=16, bg=bg) text_w.grid(row=1, column=0, sticky='nsew') - sb = Tkinter.Scrollbar(frame) + sb = Tile.Scrollbar(frame) sb.grid(row=1, column=1, sticky='ns') text_w.configure(yscrollcommand=sb.set) sb.configure(command=text_w.yview) diff --git a/pysollib/tile/selectgame.py b/pysollib/tile/selectgame.py index cb76ca83..f8c42ac5 100644 --- a/pysollib/tile/selectgame.py +++ b/pysollib/tile/selectgame.py @@ -35,8 +35,8 @@ # imports -import os, re, sys, types -import Tile as Tkinter +import os +import Tile from UserList import UserList # PySol imports @@ -49,7 +49,6 @@ from pysollib.resource import CSI # Toolkit imports from tkutil import unbind_destroy from tkwidget import MfxDialog, MfxScrolledCanvas -from tkcanvas import MfxCanvasText from selecttree import SelectDialogTreeLeaf, SelectDialogTreeNode from selecttree import SelectDialogTreeData, SelectDialogTreeCanvas @@ -361,10 +360,10 @@ class SelectGameDialogWithPreview(SelectGameDialog): #padx, pady = kw.padx/2, kw.pady/2 padx, pady = 4, 4 # PanedWindow - paned_window = Tkinter.PanedWindow(top_frame) + paned_window = Tile.PanedWindow(top_frame) paned_window.pack(expand=True, fill='both', padx=8, pady=8) - left_frame = Tkinter.Frame(paned_window) - right_frame = Tkinter.Frame(paned_window) + left_frame = Tile.Frame(paned_window) + right_frame = Tile.Frame(paned_window) paned_window.add(left_frame) paned_window.add(right_frame) # Tree @@ -373,10 +372,10 @@ class SelectGameDialogWithPreview(SelectGameDialog): default=kw.default, font=font, width=w1) self.tree.frame.pack(padx=padx, pady=pady, expand=True, fill='both') # LabelFrame - info_frame = Tkinter.LabelFrame(right_frame, text=_('About game')) + info_frame = Tile.LabelFrame(right_frame, text=_('About game')) info_frame.grid(row=0, column=0, padx=padx, pady=pady, ipadx=4, ipady=4, sticky='nws') - stats_frame = Tkinter.LabelFrame(right_frame, text=_('Statistics')) + stats_frame = Tile.LabelFrame(right_frame, text=_('Statistics')) stats_frame.grid(row=0, column=1, padx=padx, pady=pady, ipadx=4, ipady=4, sticky='nws') # Info @@ -398,9 +397,9 @@ class SelectGameDialogWithPreview(SelectGameDialog): ('moves', _('Moves:'), stats_frame, 4), ('percent', _('% won:'), stats_frame, 5), ): - title_label = Tkinter.Label(f, text=t, justify='left', anchor='w') + title_label = Tile.Label(f, text=t, justify='left', anchor='w') title_label.grid(row=row, column=0, sticky='nw', padx=4) - text_label = Tkinter.Label(f, justify='left', anchor='w') + text_label = Tile.Label(f, justify='left', anchor='w') text_label.grid(row=row, column=1, sticky='nw', padx=4) self.info_labels[n] = (title_label, text_label) ##info_frame.columnconfigure(1, weight=1) @@ -512,11 +511,6 @@ class SelectGameDialogWithPreview(SelectGameDialog): # self.preview_game = gi.gameclass(gi) self.preview_game.createPreview(self.preview_app) - tx, ty = 0, 0 - gw, gh = self.preview_game.width, self.preview_game.height - canvas.config(scrollregion=(-tx, -ty, -tx, -ty)) - canvas.xview_moveto(0) - canvas.yview_moveto(0) # random = None if gameid == self.gameid: @@ -525,7 +519,10 @@ class SelectGameDialogWithPreview(SelectGameDialog): self.preview_game.restoreGameFromBookmark(self.bookmark) else: self.preview_game.newGame(random=random, autoplay=1) - canvas.config(scrollregion=(-tx, -ty, gw, gh)) + gw, gh = self.preview_game.width, self.preview_game.height + canvas.config(scrollregion=(0, 0, gw, gh)) + canvas.xview_moveto(0) + canvas.yview_moveto(0) # self.preview_app.audio = self.app.audio if self.app.opt.animations: @@ -595,4 +592,3 @@ class SelectGameDialogWithPreview(SelectGameDialog): text_label.grid() text_label.config(text=t) - diff --git a/pysollib/tile/selecttile.py b/pysollib/tile/selecttile.py index 4d5639d0..924883f7 100644 --- a/pysollib/tile/selecttile.py +++ b/pysollib/tile/selecttile.py @@ -35,16 +35,13 @@ # imports -import os, string, sys, types -import Tile as Tkinter +import Tkinter import tkColorChooser # PySol imports -from pysollib.mfxutil import destruct, Struct, KwStruct -from pysollib.resource import CSI +from pysollib.mfxutil import KwStruct # Toolkit imports -from tkutil import loadImage from tkwidget import MfxDialog, MfxScrolledCanvas from selecttree import SelectDialogTreeLeaf, SelectDialogTreeNode from selecttree import SelectDialogTreeData, SelectDialogTreeCanvas diff --git a/pysollib/tile/selecttree.py b/pysollib/tile/selecttree.py index 19bf2474..31aafc5d 100644 --- a/pysollib/tile/selecttree.py +++ b/pysollib/tile/selecttree.py @@ -36,16 +36,9 @@ __all__ = ['SelectDialogTreeData'] # imports -import os, re, sys, types -import Tile as Tkinter import tkFont -# PySol imports -from pysollib.mfxutil import destruct, Struct, KwStruct, kwdefault - # Toolkit imports -from tkutil import makeImage -from tkcanvas import MfxCanvas from tktree import MfxTreeLeaf, MfxTreeNode, MfxTreeInCanvas diff --git a/pysollib/tile/solverdialog.py b/pysollib/tile/solverdialog.py index dc32fa43..3c78d6ab 100644 --- a/pysollib/tile/solverdialog.py +++ b/pysollib/tile/solverdialog.py @@ -28,19 +28,17 @@ __all__ = [ ] # imports -import os, sys -import Tile as Tkinter -import traceback +import Tkinter +import Tile # PySol imports -from pysollib.mfxutil import destruct, kwdefault, KwStruct, Struct from pysollib.settings import PACKAGE +from pysollib.mfxutil import KwStruct # Toolkit imports -from tkconst import EVENT_HANDLED, EVENT_PROPAGATE +from tkconst import EVENT_HANDLED from tkwidget import MfxDialog -from tkwidget import PysolScale, PysolCombo -from tkutil import bind, unbind_destroy +from tkwidget import PysolCombo # /*********************************************************************** @@ -68,14 +66,14 @@ class SolverDialog(MfxDialog): self.games = {} # key: gamename; value: gameid # - frame = Tkinter.Frame(top_frame) + frame = Tile.Frame(top_frame) frame.pack(expand=True, fill='both', padx=4, pady=4) frame.columnconfigure(1, weight=1) # row = 0 - Tkinter.Label(frame, text=_('Game:'), anchor='w' - ).grid(row=row, column=0, sticky='ew', padx=2, pady=2) + Tile.Label(frame, text=_('Game:'), anchor='w' + ).grid(row=row, column=0, sticky='ew', padx=2, pady=2) games = app.getGamesForSolver() gamenames = [''] for id in games: @@ -93,8 +91,8 @@ class SolverDialog(MfxDialog): # row += 1 - Tkinter.Label(frame, text=_('Solving method:'), anchor='w' - ).grid(row=row, column=0, sticky='ew', padx=2, pady=2) + Tile.Label(frame, text=_('Solving method:'), anchor='w' + ).grid(row=row, column=0, sticky='ew', padx=2, pady=2) ##sm = self.solving_methods.values() ##sm.sort() sm = ['A*', @@ -110,8 +108,8 @@ class SolverDialog(MfxDialog): # row += 1 - Tkinter.Label(frame, text=_('Preset:'), anchor='w' - ).grid(row=row, column=0, sticky='ew', padx=2, pady=2) + Tile.Label(frame, text=_('Preset:'), anchor='w' + ).grid(row=row, column=0, sticky='ew', padx=2, pady=2) presets = [ 'none', 'abra-kadabra', @@ -134,8 +132,8 @@ class SolverDialog(MfxDialog): row += 1 self.max_iters_var = Tkinter.IntVar() self.max_iters_var.set(10e4) - Tkinter.Label(frame, text=_('Max iterations:'), anchor='w' - ).grid(row=row, column=0, sticky='ew', padx=2, pady=2) + Tile.Label(frame, text=_('Max iterations:'), anchor='w' + ).grid(row=row, column=0, sticky='ew', padx=2, pady=2) spin = Tkinter.Spinbox(frame, bg='white', from_=1000, to=10e6, increment=1000, textvariable=self.max_iters_var) spin.grid(row=row, column=1, sticky='w', padx=2, pady=2) @@ -144,8 +142,8 @@ class SolverDialog(MfxDialog): row += 1 self.max_depth_var = Tkinter.IntVar() self.max_depth_var.set(1000) - Tkinter.Label(frame, text=_('Max depth:'), anchor='w' - ).grid(row=row, column=0, sticky='ew', padx=2, pady=2) + Tile.Label(frame, text=_('Max depth:'), anchor='w' + ).grid(row=row, column=0, sticky='ew', padx=2, pady=2) spin = Tkinter.Spinbox(frame, bg='white', from_=100, to=10000, increment=100, textvariable=self.max_depth_var) spin.grid(row=row, column=1, sticky='w', padx=2, pady=2) @@ -154,38 +152,38 @@ class SolverDialog(MfxDialog): row += 1 self.progress_var = Tkinter.BooleanVar() self.progress_var.set(True) - w = Tkinter.Checkbutton(frame, variable=self.progress_var, - text=_('Show progress')) + w = Tile.Checkbutton(frame, variable=self.progress_var, + text=_('Show progress')) w.grid(row=row, column=0, columnspan=2, sticky='ew', padx=2, pady=2) # - label_frame = Tkinter.LabelFrame(top_frame, text=_('Progress')) + label_frame = Tile.LabelFrame(top_frame, text=_('Progress')) label_frame.pack(expand=True, fill='both', padx=6, pady=2) #label_frame.columnconfigure(0, weight=1) label_frame.columnconfigure(1, weight=1) # frow = 0 - Tkinter.Label(label_frame, text=_('Iteration:'), anchor='w' - ).grid(row=frow, column=0, sticky='ew', padx=4, pady=2) - lb = Tkinter.Label(label_frame, anchor='w') + Tile.Label(label_frame, text=_('Iteration:'), anchor='w' + ).grid(row=frow, column=0, sticky='ew', padx=4, pady=2) + lb = Tile.Label(label_frame, anchor='w') lb.grid(row=frow, column=1, sticky='ew', padx=4, pady=2) self.iter_label = lb frow += 1 - Tkinter.Label(label_frame, text=_('Depth:'), anchor='w' - ).grid(row=frow, column=0, sticky='ew', padx=4, pady=2) - lb = Tkinter.Label(label_frame, anchor='w') + Tile.Label(label_frame, text=_('Depth:'), anchor='w' + ).grid(row=frow, column=0, sticky='ew', padx=4, pady=2) + lb = Tile.Label(label_frame, anchor='w') lb.grid(row=frow, column=1, sticky='ew', padx=4, pady=2) self.depth_label = lb frow += 1 - Tkinter.Label(label_frame, text=_('Stored-States:'), anchor='w' - ).grid(row=frow, column=0, sticky='ew', padx=4, pady=2) - lb = Tkinter.Label(label_frame, anchor='w') + Tile.Label(label_frame, text=_('Stored-States:'), anchor='w' + ).grid(row=frow, column=0, sticky='ew', padx=4, pady=2) + lb = Tile.Label(label_frame, anchor='w') lb.grid(row=frow, column=1, sticky='ew', padx=4, pady=2) self.states_label = lb # - lb = Tkinter.Label(top_frame, anchor='w') + lb = Tile.Label(top_frame, anchor='w') lb.pack(expand=True, fill='x', padx=6, pady=4) self.result_label = lb diff --git a/pysollib/tile/soundoptionsdialog.py b/pysollib/tile/soundoptionsdialog.py index 9f8628ce..ba836d16 100644 --- a/pysollib/tile/soundoptionsdialog.py +++ b/pysollib/tile/soundoptionsdialog.py @@ -36,17 +36,17 @@ __all__ = ['SoundOptionsDialog'] # imports -import os, sys, string -import Tile as Tkinter -import traceback +import os +import Tkinter +import Tile # PySol imports -from pysollib.mfxutil import destruct, kwdefault, KwStruct, Struct +from pysollib.mfxutil import KwStruct from pysollib.settings import PACKAGE from pysollib.pysolaudio import pysolsoundserver # Toolkit imports -from tkconst import EVENT_HANDLED, EVENT_PROPAGATE +from tkconst import EVENT_HANDLED from tkwidget import MfxDialog, MfxMessageDialog from tkwidget import PysolScale @@ -104,45 +104,45 @@ class SoundOptionsDialog(MfxDialog): ] # - frame = Tkinter.Frame(top_frame) + frame = Tile.Frame(top_frame) frame.pack(expand=True, fill='both', padx=5, pady=5) frame.columnconfigure(1, weight=1) # row = 0 - w = Tkinter.Checkbutton(frame, variable=self.sound, - text=_("Sound enabled")) + w = Tile.Checkbutton(frame, variable=self.sound, + text=_("Sound enabled")) w.grid(row=row, column=0, columnspan=2, sticky='ew') # if os.name == "nt" and pysolsoundserver: row += 1 - w = Tkinter.Checkbutton(frame, variable=self.sound_mode, - text=_("Use DirectX for sound playing"), - command=self.mOptSoundDirectX) + w = Tile.Checkbutton(frame, variable=self.sound_mode, + text=_("Use DirectX for sound playing"), + command=self.mOptSoundDirectX) w.grid(row=row, column=0, columnspan=2, sticky='ew') # if app.audio.CAN_PLAY_MUSIC: # and app.startup_opt.sound_mode > 0: row += 1 - Tkinter.Label(frame, text=_('Sample volume:'), anchor='w' - ).grid(row=row, column=0, sticky='ew') + Tile.Label(frame, text=_('Sample volume:'), anchor='w' + ).grid(row=row, column=0, sticky='ew') w = PysolScale(frame, from_=0, to=128, resolution=1, - orient='horizontal', takefocus=0, - length="3i", #label=_('Sample volume'), - variable=self.sample_volume) + orient='horizontal', takefocus=0, + length="3i", #label=_('Sample volume'), + variable=self.sample_volume) w.grid(row=row, column=1, sticky='w', padx=5) row += 1 - Tkinter.Label(frame, text=_('Music volume:'), anchor='w' - ).grid(row=row, column=0, sticky='ew') + Tile.Label(frame, text=_('Music volume:'), anchor='w' + ).grid(row=row, column=0, sticky='ew') w = PysolScale(frame, from_=0, to=128, resolution=1, - orient='horizontal', takefocus=0, - length="3i", #label=_('Music volume'), - variable=self.music_volume) + orient='horizontal', takefocus=0, + length="3i", #label=_('Music volume'), + variable=self.music_volume) w.grid(row=row, column=1, sticky='w', padx=5) else: # remove "Apply" button kw.strings[1] = None # - frame = Tkinter.LabelFrame(top_frame, text=_('Enable samples')) + frame = Tile.LabelFrame(top_frame, text=_('Enable samples')) frame.pack(expand=True, fill='both', padx=5, pady=5) frame.columnconfigure(0, weight=1) frame.columnconfigure(1, weight=1) @@ -151,7 +151,7 @@ class SoundOptionsDialog(MfxDialog): col = 0 for n, t, v in self.samples: v.set(app.opt.sound_samples[n]) - w = Tkinter.Checkbutton(frame, text=t, variable=v) + w = Tile.Checkbutton(frame, text=t, variable=v) w.grid(row=row, column=col, sticky='ew', padx=3, pady=1) if col == 1: col = 0 diff --git a/pysollib/tile/statusbar.py b/pysollib/tile/statusbar.py index 770c82f8..7afbe557 100644 --- a/pysollib/tile/statusbar.py +++ b/pysollib/tile/statusbar.py @@ -38,7 +38,8 @@ __all__ = ['PysolStatusbar', # imports import os, sys -import Tile as Tkinter +import Tkinter +import Tile if __name__ == '__main__': d = os.path.abspath(os.path.join(sys.path[0], os.pardir, os.pardir)) @@ -68,18 +69,18 @@ class MfxStatusbar: # self.padx = 1 self.label_relief = 'sunken' - self.top_frame = Tkinter.Frame(self.top) + self.top_frame = Tile.Frame(self.top) self.top_frame.grid(row=self._row, column=self._column, columnspan=self._columnspan, sticky='ew') - self.frame = Tkinter.Frame(self.top_frame) + self.frame = Tile.Frame(self.top_frame) self.frame.pack(side='left', expand=True, fill='both', padx=0, pady=1) # util def _createLabel(self, name, side='left', fill='none', expand=False, width=0, tooltip=None): - frame = Tkinter.Frame(self.frame, borderwidth=1, relief=self.label_relief) + frame = Tile.Frame(self.frame, borderwidth=1, relief=self.label_relief) frame.pack(side=side, fill=fill, padx=self.padx, expand=expand) - label = Tkinter.Label(frame, width=width) + label = Tile.Label(frame, width=width) label.pack(expand=True, fill='both') setattr(self, name + "_label", label) self._widgets.append(label) @@ -90,7 +91,7 @@ class MfxStatusbar: return label def _createSizegrip(self): - sg = Tkinter.Sizegrip(self.top_frame) + sg = Tile.Sizegrip(self.top_frame) sg.pack(side='right', anchor='se') diff --git a/pysollib/tile/timeoutsdialog.py b/pysollib/tile/timeoutsdialog.py index 8aa8aa59..8d2faf76 100644 --- a/pysollib/tile/timeoutsdialog.py +++ b/pysollib/tile/timeoutsdialog.py @@ -22,16 +22,14 @@ __all__ = ['TimeoutsDialog'] # imports -import os, sys -import Tile as Tkinter +import Tkinter +import Tile # PySol imports -from pysollib.mfxutil import destruct, kwdefault, KwStruct, Struct +from pysollib.mfxutil import KwStruct # Toolkit imports -from tkconst import EVENT_HANDLED, EVENT_PROPAGATE -from tkwidget import MfxDialog -from tkwidget import PysolScale +from tkwidget import MfxDialog, PysolScale # /*********************************************************************** @@ -45,7 +43,7 @@ class TimeoutsDialog(MfxDialog): top_frame, bottom_frame = self.createFrames(kw) #self.createBitmaps(top_frame, kw) - frame = Tkinter.Frame(top_frame) + frame = Tile.Frame(top_frame) frame.pack(expand=True, fill='both', padx=5, pady=10) frame.columnconfigure(0, weight=1) @@ -62,20 +60,23 @@ class TimeoutsDialog(MfxDialog): self.highlight_samerank_sleep_var = Tkinter.DoubleVar() self.highlight_samerank_sleep_var.set(app.opt.timeouts['highlight_samerank']) # - #Tkinter.Label(frame, text='Set delays in seconds').grid(row=0, column=0, columnspan=2) + lframe = Tile.LabelFrame(frame, text=_('Set delays in seconds'), + padding=(10, 5)) + lframe.pack(expand=True, fill='both', padx=4) row = 0 - for title, var in ((_('Demo:'), self.demo_sleep_var), - (_('Hint:'), self.hint_sleep_var), - (_('Raise card:'), self.raise_card_sleep_var), - (_('Highlight piles:'), self.highlight_piles_sleep_var), - (_('Highlight cards:'), self.highlight_cards_sleep_var), - (_('Highlight same rank:'), self.highlight_samerank_sleep_var), - ): - Tkinter.Label(frame, text=title, anchor='w' - ).grid(row=row, column=0, sticky='we') - widget = PysolScale(frame, from_=0.2, to=9.9, value=var.get(), - resolution=0.1, orient='horizontal', - length="3i", variable=var, takefocus=0) + for title, var in ( + (_('Demo:'), self.demo_sleep_var), + (_('Hint:'), self.hint_sleep_var), + (_('Raise card:'), self.raise_card_sleep_var), + (_('Highlight piles:'), self.highlight_piles_sleep_var), + (_('Highlight cards:'), self.highlight_cards_sleep_var), + (_('Highlight same rank:'), self.highlight_samerank_sleep_var), + ): + Tile.Label(lframe, text=title, anchor='w' + ).grid(row=row, column=0, sticky='we') + widget = PysolScale(lframe, from_=0.2, to=9.9, value=var.get(), + resolution=0.1, orient='horizontal', + length="3i", variable=var, takefocus=0) widget.grid(row=row, column=1) row += 1 # diff --git a/pysollib/tile/tkcanvas.py b/pysollib/tile/tkcanvas.py index 3da04cee..fb3be6e9 100644 --- a/pysollib/tile/tkcanvas.py +++ b/pysollib/tile/tkcanvas.py @@ -41,12 +41,11 @@ __all__ = ['MfxCanvasGroup', 'MfxCanvas'] # imports -import os, sys, types -import Tile as Tkinter +import Tkinter import Canvas # PySol imports -from pysollib.mfxutil import Image, ImageTk, ImageOps +from pysollib.mfxutil import Image, ImageTk # Toolkit imports from tkutil import bind, unbind_destroy, loadImage @@ -128,6 +127,7 @@ class MfxCanvas(Tkinter.Canvas): def __init__(self, *args, **kw): Tkinter.Canvas.__init__(self, *args, **kw) self.preview = 0 + self.busy = False # this is also used by lib-tk/Canvas.py self.items = {} # private @@ -227,14 +227,14 @@ class MfxCanvas(Tkinter.Canvas): def setInitialSize(self, width, height): ##print 'setInitialSize:', width, height if self.preview: - self.config(width=width, height=height) - self.config(scrollregion=(0, 0, width, height)) + self.config(width=width, height=height, + scrollregion=(0, 0, width, height)) else: # add margins ##dx, dy = 40, 40 dx, dy = self.xmargin, self.ymargin - self.config(width=dx+width+dx, height=dy+height+dy) - self.config(scrollregion=(-dx, -dy, width+dx, height+dy)) + self.config(width=dx+width+dx, height=dy+height+dy, + scrollregion=(-dx, -dy, width+dx, height+dy)) # diff --git a/pysollib/tile/tkconst.py b/pysollib/tile/tkconst.py index 7699127c..7e215a65 100644 --- a/pysollib/tile/tkconst.py +++ b/pysollib/tile/tkconst.py @@ -51,8 +51,6 @@ __all__ = ['EVENT_HANDLED', ] # imports -import sys, os -import traceback import Tkinter diff --git a/pysollib/tile/tkhtml.py b/pysollib/tile/tkhtml.py index 7438eb80..961e912f 100644 --- a/pysollib/tile/tkhtml.py +++ b/pysollib/tile/tkhtml.py @@ -36,9 +36,10 @@ __all__ = ['HTMLViewer'] # imports -import os, sys, re, types +import os, sys import htmllib, formatter -import Tile as Tkinter +import Tkinter +import Tile if __name__ == '__main__': d = os.path.abspath(os.path.join(sys.path[0], '..', '..')) @@ -51,7 +52,7 @@ from pysollib.mfxutil import Struct, openURL from pysollib.settings import PACKAGE # Toolkit imports -from tkutil import bind, unbind_destroy, loadImage +from tkutil import bind, unbind_destroy from tkwidget import MfxMessageDialog from statusbar import HtmlStatusbar @@ -247,34 +248,34 @@ class HTMLViewer: ##self.defcursor = 'xterm' self.handcursor = "hand2" - frame = Tkinter.Frame(parent, width=640, height=440) + frame = Tile.Frame(parent, width=640, height=440) frame.pack(expand=True, fill='both') frame.grid_propagate(False) # create buttons button_width = 8 - self.homeButton = Tkinter.Button(frame, text=_("Index"), - width=button_width, - command=self.goHome) + self.homeButton = Tile.Button(frame, text=_("Index"), + width=button_width, + command=self.goHome) self.homeButton.grid(row=0, column=0, sticky='w') - self.backButton = Tkinter.Button(frame, text=_("Back"), - width=button_width, - command=self.goBack) + self.backButton = Tile.Button(frame, text=_("Back"), + width=button_width, + command=self.goBack) self.backButton.grid(row=0, column=1, sticky='w') - self.forwardButton = Tkinter.Button(frame, text=_("Forward"), - width=button_width, - command=self.goForward) + self.forwardButton = Tile.Button(frame, text=_("Forward"), + width=button_width, + command=self.goForward) self.forwardButton.grid(row=0, column=2, sticky='w') - self.closeButton = Tkinter.Button(frame, text=_("Close"), - width=button_width, - command=self.destroy) + self.closeButton = Tile.Button(frame, text=_("Close"), + width=button_width, + command=self.destroy) self.closeButton.grid(row=0, column=3, sticky='e') # create text widget - text_frame = Tkinter.Frame(frame) + text_frame = Tile.Frame(frame) text_frame.grid(row=1, column=0, columnspan=4, sticky='nsew', padx=1, pady=1) - vbar = Tkinter.Scrollbar(text_frame) + vbar = Tile.Scrollbar(text_frame) vbar.pack(side='right', fill='y') self.text = Tkinter.Text(text_frame, fg='black', bg='white', diff --git a/pysollib/tile/tkstats.py b/pysollib/tile/tkstats.py index 48c32ebc..84c52c37 100644 --- a/pysollib/tile/tkstats.py +++ b/pysollib/tile/tkstats.py @@ -45,11 +45,12 @@ __all__ = ['SingleGame_StatsDialog', # imports import os import time -import Tile as Tkinter +import Tkinter +import Tile import tkFont # PySol imports -from pysollib.mfxutil import destruct, Struct, kwdefault, KwStruct +from pysollib.mfxutil import KwStruct from pysollib.mfxutil import format_time ##from pysollib.util import * from pysollib.stats import PysolStatsFormatter, ProgressionFormatter @@ -58,7 +59,6 @@ from pysollib.settings import TOP_TITLE # Toolkit imports from tkutil import bind, unbind_destroy, loadImage from tkwidget import MfxDialog, MfxMessageDialog -from tkwidget import MfxScrolledCanvas # /*********************************************************************** @@ -77,14 +77,14 @@ class StatsDialog(MfxDialog): self.font = app.getFont('default') self.tkfont = tkFont.Font(parent, self.font) self.font_metrics = self.tkfont.metrics() - style = Tkinter.Style() + style = Tile.Style() heading_font = style.lookup('Heading', 'font') # treeview heading self.heading_tkfont = tkFont.Font(parent, heading_font) self.selected_game = None top_frame, bottom_frame = self.createFrames(kw) - notebook = Tkinter.Notebook(top_frame) + notebook = Tile.Notebook(top_frame) notebook.pack(expand=True, fill='both', padx=10, pady=10) self.notebook_tabs = [] @@ -167,16 +167,16 @@ SingleGame_StatsDialog = AllGames_StatsDialog = Top_StatsDialog = ProgressionDia # // # ************************************************************************/ -class SingleGameFrame(Tkinter.Frame): +class SingleGameFrame(Tile.Frame): def __init__(self, dialog, parent, app, player, gameid, **kw): - Tkinter.Frame.__init__(self, parent) + Tile.Frame.__init__(self, parent) self.oval_width = 120 self.oval_height = 60 - left_label = Tkinter.Label(self, image=app.gimages.logos[5]) + left_label = Tile.Label(self, image=app.gimages.logos[5]) left_label.pack(side='left', expand=True, fill='both') - self.right_frame = Tkinter.Frame(self) + self.right_frame = Tile.Frame(self) self.right_frame.pack(side='right', expand=True) self.dialog = dialog @@ -232,9 +232,9 @@ class SingleGameFrame(Tkinter.Frame): return pwon, plost def _createChartInit(self, text): - frame = Tkinter.LabelFrame(self.right_frame, text=text) + frame = Tile.LabelFrame(self.right_frame, text=text) frame.pack(side='top', fill='both', expand=False, padx=20, pady=10) - style = Tkinter.Style(self.right_frame) + style = Tile.Style(self.right_frame) fg = style.lookup('.', 'foreground') or None # use default if fg == '' bg = style.lookup('.', 'background') or None self.fg = fg @@ -379,10 +379,10 @@ class TreeFormatter(PysolStatsFormatter): self.parent_window.tree_items.append(id) self.parent_window.games[id] = t8 - total, played, won, lost, time, moves, perc = self.getStatSummary() + total, played, won, lost, time_, moves, perc = self.getStatSummary() text = _("Total (%d out of %d games)") % (played, total) id = self.tree.insert(None, "end", text=text, - values=(won+lost, won, lost, time, moves, perc)) + values=(won+lost, won, lost, time_, moves, perc)) self.parent_window.tree_items.append(id) return 1 @@ -413,12 +413,12 @@ class TreeFormatter(PysolStatsFormatter): # // # ************************************************************************/ -class AllGamesFrame(Tkinter.Frame): +class AllGamesFrame(Tile.Frame): COLUMNS = ('played', 'won', 'lost', 'time', 'moves', 'percent') def __init__(self, dialog, parent, app, player, **kw): - Tkinter.Frame.__init__(self, parent) + Tile.Frame.__init__(self, parent) # self.dialog = dialog self.app = app @@ -431,12 +431,12 @@ class AllGamesFrame(Tkinter.Frame): self.tree_tabs = None self.games = {} # tree_itemid: gameid # - frame = Tkinter.Frame(self) + frame = Tile.Frame(self) frame.pack(fill='both', expand=True, padx=10, pady=10) - sb = Tkinter.Scrollbar(frame) + sb = Tile.Scrollbar(frame) sb.pack(side='right', fill='y') - self.tree = Tkinter.Treeview(frame, columns=self.COLUMNS, - selectmode='browse') + self.tree = Tile.Treeview(frame, columns=self.COLUMNS, + selectmode='browse') self.tree.pack(side='left', fill='both', expand=True) self.tree.config(yscrollcommand=sb.set) sb.config(command=self.tree.yview) @@ -504,7 +504,7 @@ class LogDialog(MfxDialog): self.font = app.getFont('default') self.tkfont = tkFont.Font(parent, self.font) - style = Tkinter.Style() + style = Tile.Style() heading_font = style.lookup('Heading', 'font') # treeview heading self.heading_tkfont = tkFont.Font(parent, heading_font) self.font_metrics = self.tkfont.metrics() @@ -519,7 +519,7 @@ class LogDialog(MfxDialog): ##self.selected_game = None top_frame, bottom_frame = self.createFrames(kw) - notebook = Tkinter.Notebook(top_frame) + notebook = Tile.Notebook(top_frame) notebook.pack(expand=True, fill='both', padx=10, pady=10) self.notebook_tabs = [] @@ -664,48 +664,48 @@ class _TopDialog(MfxDialog): cnf = {'master': top_frame, 'padding': (4, 1), } - frame = Tkinter.Frame(**cnf) + frame = Tile.Frame(**cnf) frame.pack(expand=True, fill='both', padx=10, pady=10) frame.columnconfigure(0, weight=1) cnf['master'] = frame cnf['text'] = _('N') - l = Tkinter.Label(**cnf) + l = Tile.Label(**cnf) l.grid(row=0, column=0, sticky='ew') if gameid == 'all': cnf['text'] = _('Game') - l = Tkinter.Label(**cnf) + l = Tile.Label(**cnf) l.grid(row=0, column=1, sticky='ew') cnf['text'] = _('Game number') - l = Tkinter.Label(**cnf) + l = Tile.Label(**cnf) l.grid(row=0, column=2, sticky='ew') cnf['text'] = _('Started at') - l = Tkinter.Label(**cnf) + l = Tile.Label(**cnf) l.grid(row=0, column=3, sticky='ew') cnf['text'] = _('Result') - l = Tkinter.Label(**cnf) + l = Tile.Label(**cnf) l.grid(row=0, column=4, sticky='ew') row = 1 for i in top: # N cnf['text'] = str(row) - l = Tkinter.Label(**cnf) + l = Tile.Label(**cnf) l.grid(row=row, column=0, sticky='ew') if gameid == 'all': name = app.getGameTitleName(i.gameid) if name is None: name = _("** UNKNOWN %d **") % i.gameid cnf['text'] = name - l = Tkinter.Label(**cnf) + l = Tile.Label(**cnf) l.grid(row=row, column=1, sticky='ew') # Game number cnf['text'] = '#'+str(i.game_number) - l = Tkinter.Label(**cnf) + l = Tile.Label(**cnf) l.grid(row=row, column=2, sticky='ew') # Start time t = time.strftime('%Y-%m-%d %H:%M', time.localtime(i.game_start_time)) cnf['text'] = t - l = Tkinter.Label(**cnf) + l = Tile.Label(**cnf) l.grid(row=row, column=3, sticky='ew') # Result if isinstance(i.value, float): @@ -715,7 +715,7 @@ class _TopDialog(MfxDialog): # moves s = str(i.value) cnf['text'] = s - l = Tkinter.Label(**cnf) + l = Tile.Label(**cnf) l.grid(row=row, column=4, sticky='ew') row += 1 @@ -728,31 +728,31 @@ class _TopDialog(MfxDialog): return MfxDialog.initKw(self, kw) -class TopFrame(Tkinter.Frame): +class TopFrame(Tile.Frame): def __init__(self, dialog, parent, app, player, gameid): - Tkinter.Frame.__init__(self, parent) + Tile.Frame.__init__(self, parent) self.app = app self.dialog = dialog - left_label = Tkinter.Label(self, image=app.gimages.logos[5]) + left_label = Tile.Label(self, image=app.gimages.logos[5]) left_label.pack(side='left', expand=True, fill='both') - frame = Tkinter.LabelFrame(self, text=_('Current game'), + frame = Tile.LabelFrame(self, text=_('Current game'), padding=(10,5,10,10)) frame.pack(side='top', expand=True, fill='x', padx=10, pady=10) ##frame.columnconfigure(0, weight=1) if not self.createTopFrame(frame, player, gameid): - Tkinter.Label(frame, text=_('No TOP for this game') - ).pack(padx=10, pady=10) + Tile.Label(frame, text=_('No TOP for this game') + ).pack(padx=10, pady=10) - frame = Tkinter.LabelFrame(self, text=_('All games'), - padding=(10,5,10,10)) + frame = Tile.LabelFrame(self, text=_('All games'), + padding=(10,5,10,10)) frame.pack(side='top', expand=True, fill='x', padx=10, pady=10) ##frame.columnconfigure(0, weight=1) if not self.createTopFrame(frame, player, 'all'): - Tkinter.Label(frame, text=_('No TOP for all games') - ).pack(padx=10, pady=10) + Tile.Label(frame, text=_('No TOP for all games') + ).pack(padx=10, pady=10) def createTopFrame(self, frame, player, gameid): app = self.app @@ -762,13 +762,13 @@ class TopFrame(Tkinter.Frame): not app.stats.games_stats[player][gameid].time_result.top): return False - Tkinter.Label(frame, text=_('Minimum') - ).grid(row=0, column=1, padx=5, pady=5) - Tkinter.Label(frame, text=_('Maximum') - ).grid(row=0, column=2, padx=5, pady=5) - Tkinter.Label(frame, text=_('Average') - ).grid(row=0, column=3, padx=5, pady=5) - ##Tkinter.Label(frame, text=_('Total')).grid(row=0, column=4) + Tile.Label(frame, text=_('Minimum') + ).grid(row=0, column=1, padx=5, pady=5) + Tile.Label(frame, text=_('Maximum') + ).grid(row=0, column=2, padx=5, pady=5) + Tile.Label(frame, text=_('Average') + ).grid(row=0, column=3, padx=5, pady=5) + ##Tile.Label(frame, text=_('Total')).grid(row=0, column=4) s = app.stats.games_stats[player][gameid] @@ -809,19 +809,19 @@ class TopFrame(Tkinter.Frame): ## s.score_casino_result.max, ## round(s.score_casino_result.average, 2), )) for l, min, max, avr, tot, top in ll: - Tkinter.Label(frame, text=l - ).grid(row=row, column=0, padx=5, pady=5) - Tkinter.Label(frame, text=str(min) - ).grid(row=row, column=1, padx=5, pady=5) - Tkinter.Label(frame, text=str(max) - ).grid(row=row, column=2, padx=5, pady=5) - Tkinter.Label(frame, text=str(avr) - ).grid(row=row, column=3, padx=5, pady=5) - ##Tkinter.Label(frame, text=str(tot)).grid(row=row, column=4) + Tile.Label(frame, text=l + ).grid(row=row, column=0, padx=5, pady=5) + Tile.Label(frame, text=str(min) + ).grid(row=row, column=1, padx=5, pady=5) + Tile.Label(frame, text=str(max) + ).grid(row=row, column=2, padx=5, pady=5) + Tile.Label(frame, text=str(avr) + ).grid(row=row, column=3, padx=5, pady=5) + ##Tile.Label(frame, text=str(tot)).grid(row=row, column=4) def command(gameid=gameid, top=top): self.showTop(gameid, top) - b = Tkinter.Button(frame, text=TOP_TITLE+' ...', width=10, - command=command) + b = Tile.Button(frame, text=TOP_TITLE+' ...', + width=10, command=command) b.grid(row=row, column=5) row += 1 return True @@ -834,10 +834,10 @@ class TopFrame(Tkinter.Frame): # // # ************************************************************************/ -class ProgressionFrame(Tkinter.Frame): +class ProgressionFrame(Tile.Frame): def __init__(self, dialog, parent, app, player, gameid, **kw): - Tkinter.Frame.__init__(self, parent) + Tile.Frame.__init__(self, parent) self.mapped = False @@ -848,7 +848,7 @@ class ProgressionFrame(Tkinter.Frame): self.items = [] self.formatter = ProgressionFormatter(app, player, gameid) - frame = Tkinter.Frame(self) + frame = Tile.Frame(self) frame.pack(expand=True, fill='both', padx=5, pady=10) frame.columnconfigure(0, weight=1) @@ -871,21 +871,19 @@ class ProgressionFrame(Tkinter.Frame): canvas.pack(side='left', padx=5) # right frame - right_frame = Tkinter.Frame(frame) + right_frame = Tile.Frame(frame) right_frame.pack(side='left', fill='x', padx=5) self.all_games_variable = var = Tkinter.StringVar() var.set('all') - b = Tkinter.Radiobutton(right_frame, text=_('All games'), - variable=var, value='all', - command=self.updateGraph, - ) + b = Tile.Radiobutton(right_frame, text=_('All games'), + variable=var, value='all', + command=self.updateGraph) b.pack(fill='x', expand=True, padx=3, pady=1) - b = Tkinter.Radiobutton(right_frame, text=_('Current game'), - variable=var, value='current', - command=self.updateGraph, - ) + b = Tile.Radiobutton(right_frame, text=_('Current game'), + variable=var, value='current', + command=self.updateGraph) b.pack(fill='x', expand=True, padx=3, pady=1) - label_frame = Tkinter.LabelFrame(right_frame, text=_('Statistics for')) + label_frame = Tile.LabelFrame(right_frame, text=_('Statistics for')) label_frame.pack(side='top', fill='x', pady=10) self.variable = var = Tkinter.StringVar() var.set('week') @@ -895,32 +893,28 @@ class ProgressionFrame(Tkinter.Frame): ('year', _('Last year')), ('all', _('All time')), ): - b = Tkinter.Radiobutton(label_frame, text=t, variable=var, value=v, - command=self.updateGraph, - ) + b = Tile.Radiobutton(label_frame, text=t, variable=var, + value=v, command=self.updateGraph) b.pack(fill='x', expand=True, padx=3, pady=1) - label_frame = Tkinter.LabelFrame(right_frame, text=_('Show graphs')) + label_frame = Tile.LabelFrame(right_frame, text=_('Show graphs')) label_frame.pack(side='top', fill='x') self.played_graph_var = Tkinter.BooleanVar() self.played_graph_var.set(True) - b = Tkinter.Checkbutton(label_frame, text=_('Played'), - command=self.updateGraph, - variable=self.played_graph_var, - ) + b = Tile.Checkbutton(label_frame, text=_('Played'), + command=self.updateGraph, + variable=self.played_graph_var) b.pack(fill='x', expand=True, padx=3, pady=1) self.won_graph_var = Tkinter.BooleanVar() self.won_graph_var.set(True) - b = Tkinter.Checkbutton(label_frame, text=_('Won'), - command=self.updateGraph, - variable=self.won_graph_var, - ) + b = Tile.Checkbutton(label_frame, text=_('Won'), + command=self.updateGraph, + variable=self.won_graph_var) b.pack(fill='x', expand=True, padx=3, pady=1) self.percent_graph_var = Tkinter.BooleanVar() self.percent_graph_var.set(True) - b = Tkinter.Checkbutton(label_frame, text=_('% won'), - command=self.updateGraph, - variable=self.percent_graph_var, - ) + b = Tile.Checkbutton(label_frame, text=_('% won'), + command=self.updateGraph, + variable=self.percent_graph_var) b.pack(fill='x', expand=True, padx=3, pady=1) #self.createGraph() diff --git a/pysollib/tile/tktree.py b/pysollib/tile/tktree.py index 01862b01..d7071483 100644 --- a/pysollib/tile/tktree.py +++ b/pysollib/tile/tktree.py @@ -35,7 +35,7 @@ # imports import os -import Tile as Tkinter +import Tkinter # Toolkit imports from tkutil import bind diff --git a/pysollib/tile/tkutil.py b/pysollib/tile/tkutil.py index 7e1b8e96..e54b163a 100644 --- a/pysollib/tile/tkutil.py +++ b/pysollib/tile/tkutil.py @@ -56,9 +56,8 @@ __all__ = ['wm_withdraw', ] # imports -import sys, os, re -import traceback -import Tile as Tkinter +import re +import Tkinter from tkFont import Font # PySol imports diff --git a/pysollib/tile/tkwidget.py b/pysollib/tile/tkwidget.py index 62f6bda1..73074d70 100644 --- a/pysollib/tile/tkwidget.py +++ b/pysollib/tile/tkwidget.py @@ -44,9 +44,9 @@ __all__ = ['MfxDialog', ] # imports -import os, sys, time, locale -import Tkinter as Tk -import Tile as Tkinter +import os, time, locale +import Tkinter +import Tile import tkFont import traceback @@ -55,8 +55,7 @@ from pysollib.mfxutil import destruct, kwdefault, KwStruct, openURL from pysollib.settings import WIN_SYSTEM # Toolkit imports -from tkconst import EVENT_HANDLED, EVENT_PROPAGATE -from tkutil import after, after_idle, after_cancel +from tkutil import after, after_cancel from tkutil import bind, unbind_destroy from tkutil import makeToplevel, setTransient from tkcanvas import MfxCanvas @@ -78,7 +77,7 @@ class MfxDialog: # ex. _ToplevelDialog self.buttons = [] self.accel_keys = {} self.top = makeToplevel(parent, title=title) - #self._frame = Tkinter.Frame(self.top) + #self._frame = Tile.Frame(self.top) #self._frame.pack(expand=True, fill='both') self._frame = self.top self.top.wm_resizable(resizable, resizable) @@ -168,23 +167,23 @@ class MfxDialog: # ex. _ToplevelDialog return kw def createFrames(self, kw): - bottom_frame = Tkinter.Frame(self._frame, relief='flat', borderwidth=4) + bottom_frame = Tile.Frame(self._frame, relief='flat', borderwidth=4) bottom_frame.pack(side='bottom', fill='both', expand=False) if kw.separatorwidth > 0: - separator = Tkinter.Separator(self._frame) + separator = Tile.Separator(self._frame) separator.pack(side='bottom', fill='x') - top_frame = Tkinter.Frame(self._frame) + top_frame = Tile.Frame(self._frame) top_frame.pack(side='top', fill='both', expand=1) return top_frame, bottom_frame def createBitmaps(self, frame, kw): if kw.bitmap: ## in ("error", "info", "question", "warning") img = self.img.get(kw.bitmap) - b = Tkinter.Label(frame, image=img) + b = Tile.Label(frame, image=img) b.pack(side=kw.bitmap_side, padx=kw.bitmap_padx, pady=kw.bitmap_pady) elif kw.image: - b = Tkinter.Label(frame, image=kw.image) + b = Tile.Label(frame, image=kw.image) b.pack(side=kw.image_side, padx=kw.image_padx, pady=kw.image_pady) def createButtons(self, frame, kw): @@ -230,9 +229,9 @@ class MfxDialog: # ex. _ToplevelDialog button_img = MfxDialog.button_img.get(s) s = s.replace('&', '') if button < 0: - widget = Tkinter.Button(frame, text=s, state="disabled") + widget = Tile.Button(frame, text=s, state="disabled") else: - widget = Tkinter.Button(frame, text=s, default="normal", + widget = Tile.Button(frame, text=s, default="normal", command = lambda self=self, button=button: \ self.mDone(button)) if button == kw.default: @@ -275,7 +274,7 @@ class MfxMessageDialog(MfxDialog): self.createBitmaps(top_frame, kw) # self.button = kw.default - msg = Tkinter.Label(top_frame, text=kw.text, justify=kw.justify, + msg = Tile.Label(top_frame, text=kw.text, justify=kw.justify, width=kw.width) msg.pack(fill='both', expand=True, padx=kw.padx, pady=kw.pady) # @@ -315,16 +314,16 @@ class PysolAboutDialog(MfxMessageDialog): self.createBitmaps(top_frame, kw) # self.button = kw.default - frame = Tkinter.Frame(top_frame) + frame = Tile.Frame(top_frame) frame.pack(fill='both', expand=True, padx=kw.padx, pady=kw.pady) - msg = Tkinter.Label(frame, text=kw.text, justify=kw.justify, - width=kw.width) + msg = Tile.Label(frame, text=kw.text, justify=kw.justify, + width=kw.width) msg.pack(fill='both', expand=True) font = tkFont.Font(parent, app.getFont('default')) font.configure(underline=True) - url_label = Tkinter.Label(frame, text=kw.url, font=font, - foreground='blue', cursor='hand2') + url_label = Tile.Label(frame, text=kw.url, font=font, + foreground='blue', cursor='hand2') url_label.pack() url_label.bind('<1>', self._urlClicked) # @@ -348,10 +347,10 @@ class MfxSimpleEntry(MfxDialog): # self.value = value if label: - label = Tkinter.Label(top_frame, text=label, takefocus=0) + label = Tile.Label(top_frame, text=label, takefocus=0) label.pack(pady=5) w = kw.get("e_width", 0) # width in characters - self.var = Tkinter.Entry(top_frame, exportselection=1, width=w) + self.var = Tile.Entry(top_frame, exportselection=1, width=w) self.var.insert(0, value) self.var.pack(side='top', padx=kw.padx, pady=kw.pady) # @@ -442,10 +441,9 @@ class MfxTooltip: self.timer = None if self.tooltip or not self.text: return -## if isinstance(self.widget, (Tkinter.Button, Tkinter.Checkbutton)): +## if isinstance(self.widget, (Tile.Button, Tile.Checkbutton)): ## if self.widget["state"] == 'disabled': ## return - import Tkinter # not Tile ##x = self.widget.winfo_rootx() x = self.widget.winfo_pointerx() y = self.widget.winfo_rooty() + self.widget.winfo_height() @@ -555,20 +553,20 @@ class MfxScrolledCanvas: def createFrame(self, kw): width = kw.get("width") height = kw.get("height") - self.frame = Tkinter.Frame(self.parent, width=width, height=height) + self.frame = Tile.Frame(self.parent, width=width, height=height) def createCanvas(self, kw): self.canvas = MfxCanvas(self.frame, **kw) self.canvas.grid(row=0, column=0, sticky="news") def createHbar(self): - self.hbar = Tkinter.Scrollbar(self.frame, takefocus=0, - orient="horizontal") + self.hbar = Tile.Scrollbar(self.frame, takefocus=0, + orient="horizontal") self.canvas["xscrollcommand"] = self._setHbar self.hbar["command"] = self.canvas.xview self.hbar.grid(row=1, column=0, sticky="we") self.hbar.grid_remove() def createVbar(self): - self.vbar = Tkinter.Scrollbar(self.frame, takefocus=0) + self.vbar = Tile.Scrollbar(self.frame, takefocus=0) self.canvas["yscrollcommand"] = self._setVbar self.vbar["command"] = self.canvas.yview self.vbar.grid(row=0, column=1, sticky="ns") @@ -599,28 +597,28 @@ class MfxScrolledCanvas: print 'MfxScrolledCanvas.mouse_wheel', args def _setHbar(self, first, last): - sb = self.hbar - if not self.canvas.winfo_ismapped(): - sb.set(first, last) + if self.canvas.busy: return + sb = self.hbar if float(first) <= 0 and float(last) >= 1: sb.grid_remove() self.hbar_show = False else: - sb.grid() - self.hbar_show = True + if self.canvas.winfo_ismapped(): + sb.grid() + self.hbar_show = True sb.set(first, last) def _setVbar(self, first, last): - sb = self.vbar - if not self.canvas.winfo_ismapped(): - sb.set(first, last) + if self.canvas.busy: return - if float(first) <= 0and float(last) >= 1: + sb = self.vbar + if float(first) <= 0 and float(last) >= 1: sb.grid_remove() self.vbar_show = False else: - sb.grid() - self.vbar_show = True + if self.canvas.winfo_ismapped(): + sb.grid() + self.vbar_show = True sb.set(first, last) def _xview(self, *args): @@ -668,8 +666,6 @@ class StackDesc: self.canvas = game.canvas self.bindings = [] - import Tkinter # not Tile - font = game.app.getFont('canvas_small') ##print self.app.cardset.CARDW, self.app.images.CARDW cardw = game.app.images.CARDW @@ -684,7 +680,8 @@ class StackDesc: label.pack() self.label = label self.id = self.canvas.create_window(x, y, window=frame, anchor='n') - self.bindings.append(label.bind('', self._buttonPressEvent)) + self.bindings.append(label.bind('', + self._buttonPressEvent)) ##self.bindings.append(label.bind('', self._enterEvent)) else: self.id = None @@ -749,11 +746,11 @@ class MyPysolScale: # create widgets side = 'left' # 'top' - self.frame = Tkinter.Frame(parent) - self.label = Tkinter.Label(self.frame, anchor='w', - width=width, padding=(5,0)) + self.frame = Tile.Frame(parent) + self.label = Tile.Label(self.frame, anchor='w', + width=width, padding=(5,0)) self.label.pack(side=side, expand=False, fill='x') - self.scale = Tkinter.Scale(self.frame, **kw) + self.scale = Tile.Scale(self.frame, **kw) self.scale.pack(side=side, expand=True, fill='both', pady=4) if value is not None: @@ -791,11 +788,11 @@ class MyPysolScale: config = configure -class TkinterScale(Tk.Scale): +class TkinterScale(Tkinter.Scale): def __init__(self, parent, **kw): if 'value' in kw: del kw['value'] - Tk.Scale.__init__(self, parent, **kw) + Tkinter.Scale.__init__(self, parent, **kw) PysolScale = MyPysolScale @@ -806,13 +803,13 @@ PysolScale = MyPysolScale # // Tile.Combobox workaround (clear selection) # ************************************************************************/ -class PysolCombo(Tkinter.Combobox): +class PysolCombo(Tile.Combobox): def __init__(self, master=None, **kw): self._command = None if 'selectcommand' in kw: self._command = kw['selectcommand'] del kw['selectcommand'] - Tkinter.Combobox.__init__(self, master, **kw) + Tile.Combobox.__init__(self, master, **kw) self.bind('<>', self._callback) def _callback(self, *args): diff --git a/pysollib/tile/tkwrap.py b/pysollib/tile/tkwrap.py index a92860be..a71b462d 100644 --- a/pysollib/tile/tkwrap.py +++ b/pysollib/tile/tkwrap.py @@ -37,17 +37,11 @@ __all__ = ['TclError', 'MfxRoot'] # imports -import os, sys, time, types -from Tkinter import TclError -import Tile as Tkinter -from tkFont import Font +import Tkinter +TclError = Tkinter.TclError # PySol imports -from pysollib.mfxutil import destruct, Struct -from pysollib.settings import PACKAGE, VERSION -from pysollib.macosx.appSupport import setupApp -from tkutil import after_idle -from tkconst import EVENT_HANDLED, EVENT_PROPAGATE +from tkconst import EVENT_PROPAGATE # /*********************************************************************** diff --git a/pysollib/tile/toolbar.py b/pysollib/tile/toolbar.py index 4677edfb..ec4c40cb 100644 --- a/pysollib/tile/toolbar.py +++ b/pysollib/tile/toolbar.py @@ -37,18 +37,19 @@ __all__ = ['PysolToolbar'] # imports import os -import Tile as Tkinter +import Tkinter +import Tile # PySol imports from pysollib.mfxutil import destruct -from pysollib.mfxutil import Image, ImageTk, ImageOps +from pysollib.mfxutil import Image, ImageTk from pysollib.util import IMAGE_EXTENSIONS from pysollib.settings import PACKAGE from pysollib.actions import PysolToolbarActions from pysollib.winsystems import TkSettings # Toolkit imports -from tkconst import EVENT_HANDLED, EVENT_PROPAGATE +from tkconst import EVENT_HANDLED from tkwidget import MfxTooltip from menubar import createToolbarMenu, MfxMenu @@ -87,23 +88,25 @@ class AbstractToolbarButton: self.grid_forget() -class ToolbarCheckbutton(AbstractToolbarButton, Tkinter.Checkbutton): +class ToolbarCheckbutton(AbstractToolbarButton, Tile.Checkbutton): def __init__(self, parent, toolbar, toolbar_name, position, **kwargs): kwargs['style'] = 'Toolbutton' - Tkinter.Checkbutton.__init__(self, parent, **kwargs) - AbstractToolbarButton.__init__(self, parent, toolbar, toolbar_name, position) + Tile.Checkbutton.__init__(self, parent, **kwargs) + AbstractToolbarButton.__init__(self, parent, toolbar, + toolbar_name, position) -class ToolbarButton(AbstractToolbarButton, Tkinter.Button): +class ToolbarButton(AbstractToolbarButton, Tile.Button): def __init__(self, parent, toolbar, toolbar_name, position, **kwargs): kwargs['style'] = 'Toolbutton' - Tkinter.Button.__init__(self, parent, **kwargs) - AbstractToolbarButton.__init__(self, parent, toolbar, toolbar_name, position) + Tile.Button.__init__(self, parent, **kwargs) + AbstractToolbarButton.__init__(self, parent, toolbar, + toolbar_name, position) -class ToolbarSeparator(Tkinter.Separator): +class ToolbarSeparator(Tile.Separator): def __init__(self, parent, toolbar, position, **kwargs): kwargs['orient'] = 'vertical' - Tkinter.Separator.__init__(self, parent, **kwargs) + Tile.Separator.__init__(self, parent, **kwargs) self.toolbar = toolbar self.position = position self.visible = False @@ -177,9 +180,9 @@ class PysolToolbar(PysolToolbarActions): self.compound = compound self.orient='horizontal' # - self.frame = Tkinter.Frame(top, class_='Toolbar', - relief=TkSettings.toolbar_relief, - borderwidth=TkSettings.toolbar_borderwidth) + self.frame = Tile.Frame(top, class_='Toolbar', + relief=TkSettings.toolbar_relief, + borderwidth=TkSettings.toolbar_borderwidth) # for l, f, t in ( (n_("New"), self.mNewGame, _("New game")), diff --git a/pysollib/tile/wizarddialog.py b/pysollib/tile/wizarddialog.py index 3e174fe0..3a93e070 100644 --- a/pysollib/tile/wizarddialog.py +++ b/pysollib/tile/wizarddialog.py @@ -23,10 +23,11 @@ __all__ = ['WizardDialog'] # imports -from Tile import * +import Tkinter +import Tile # PySol imports -from pysollib.mfxutil import destruct, kwdefault, KwStruct, Struct +from pysollib.mfxutil import KwStruct from pysollib.wizardutil import WizardWidgets from pysollib.wizardpresets import presets @@ -46,26 +47,26 @@ class WizardDialog(MfxDialog): top_frame, bottom_frame = self.createFrames(kw) self.createBitmaps(top_frame, kw) - frame = Frame(top_frame) + frame = Tile.Frame(top_frame) frame.pack(expand=True, fill='both', padx=10, pady=10) frame.columnconfigure(0, weight=1) - notebook = Notebook(frame) + notebook = Tile.Notebook(frame) notebook.pack(expand=True, fill='both') for w in WizardWidgets: if isinstance(w, basestring): - frame = Frame(notebook) + frame = Tile.Frame(notebook) notebook.add(frame, text=w, sticky='nsew', padding=5) frame.columnconfigure(1, weight=1) row = 0 continue - Label(frame, text=w.label).grid(row=row, column=0) + Tile.Label(frame, text=w.label).grid(row=row, column=0) if w.widget == 'preset': if w.variable is None: - w.variable = StringVar() + w.variable = Tkinter.StringVar() values = [_(v) for v in w.values] default = _(w.default) values.remove(default) @@ -80,12 +81,12 @@ class WizardDialog(MfxDialog): cb.grid(row=row, column=1, sticky='ew', padx=2, pady=2) elif w.widget == 'entry': if w.variable is None: - w.variable = StringVar() - en = Entry(frame, textvariable=w.variable) + w.variable = Tkinter.StringVar() + en = Tile.Entry(frame, textvariable=w.variable) en.grid(row=row, column=1, sticky='ew', padx=2, pady=2) elif w.widget == 'menu': if w.variable is None: - w.variable = StringVar() + w.variable = Tkinter.StringVar() values = [_(v) for v in w.values] cb = PysolCombo(frame, values=tuple(values), textvariable=w.variable, @@ -94,7 +95,7 @@ class WizardDialog(MfxDialog): cb.grid(row=row, column=1, sticky='ew', padx=2, pady=2) elif w.widget == 'spin': if w.variable is None: - w.variable = IntVar() + w.variable = Tkinter.IntVar() else: # delete all trace callbacks for mod, cbname in w.variable.trace_vinfo(): @@ -107,8 +108,9 @@ class WizardDialog(MfxDialog): s.grid(row=row, column=1, sticky='ew', padx=2, pady=2) elif w.widget == 'check': if w.variable is None: - w.variable = BooleanVar() - ch = Checkbutton(frame, variable=w.variable, takefocus=False) + w.variable = Tkinter.BooleanVar() + ch = Tile.Checkbutton(frame, variable=w.variable, + takefocus=False) ch.grid(row=row, column=1, sticky='ew', padx=2, pady=2) if w.current_value is None: diff --git a/pysollib/tk/colorsdialog.py b/pysollib/tk/colorsdialog.py index b9b20719..30a9e8e0 100644 --- a/pysollib/tk/colorsdialog.py +++ b/pysollib/tk/colorsdialog.py @@ -99,7 +99,7 @@ class ColorsDialog(MfxDialog): self.not_matching_color = self.not_matching_var.get() def selectColor(self, label): - c = askcolor(master=self.top, initialcolor=label.cget('bg'), + c = askcolor(parent=self.top, initialcolor=label.cget('bg'), title=_("Select color")) if c and c[1]: label.configure(bg=c[1]) diff --git a/pysollib/tk/menubar.py b/pysollib/tk/menubar.py index 30db3dee..7ac73bcc 100644 --- a/pysollib/tk/menubar.py +++ b/pysollib/tk/menubar.py @@ -1038,6 +1038,8 @@ class PysolMenubar(PysolMenubarActions): self.updateMenus() def mPause(self, *args): + if not self.game: + return if not self.game.pause: if self._cancelDrag(): return self.game.doPause() diff --git a/pysollib/tk/selectgame.py b/pysollib/tk/selectgame.py index bd01708b..977a6a1f 100644 --- a/pysollib/tk/selectgame.py +++ b/pysollib/tk/selectgame.py @@ -523,11 +523,6 @@ class SelectGameDialogWithPreview(SelectGameDialog): # self.preview_game = gi.gameclass(gi) self.preview_game.createPreview(self.preview_app) - tx, ty = 0, 0 - gw, gh = self.preview_game.width, self.preview_game.height - canvas.config(scrollregion=(-tx, -ty, -tx, -ty)) - canvas.xview_moveto(0) - canvas.yview_moveto(0) # random = None if gameid == self.gameid: @@ -536,7 +531,10 @@ class SelectGameDialogWithPreview(SelectGameDialog): self.preview_game.restoreGameFromBookmark(self.bookmark) else: self.preview_game.newGame(random=random, autoplay=1) - canvas.config(scrollregion=(-tx, -ty, gw, gh)) + gw, gh = self.preview_game.width, self.preview_game.height + canvas.config(scrollregion=(0, 0, gw, gh)) + canvas.xview_moveto(0) + canvas.yview_moveto(0) # self.preview_app.audio = self.app.audio if self.app.opt.animations: @@ -606,4 +604,3 @@ class SelectGameDialogWithPreview(SelectGameDialog): text_label.grid() text_label.config(text=t) - diff --git a/pysollib/tk/tkcanvas.py b/pysollib/tk/tkcanvas.py index a7449836..71d9467d 100644 --- a/pysollib/tk/tkcanvas.py +++ b/pysollib/tk/tkcanvas.py @@ -127,6 +127,7 @@ class MfxCanvas(Tkinter.Canvas): def __init__(self, *args, **kw): Tkinter.Canvas.__init__(self, *args, **kw) self.preview = 0 + self.busy = False # this is also used by lib-tk/Canvas.py self.items = {} # private @@ -226,14 +227,14 @@ class MfxCanvas(Tkinter.Canvas): def setInitialSize(self, width, height): ##print 'setInitialSize:', width, height if self.preview: - self.config(width=width, height=height) - self.config(scrollregion=(0, 0, width, height)) + self.config(width=width, height=height, + scrollregion=(0, 0, width, height)) else: # add margins ##dx, dy = 40, 40 dx, dy = self.xmargin, self.ymargin - self.config(width=dx+width+dx, height=dy+height+dy) - self.config(scrollregion=(-dx, -dy, width+dx, height+dy)) + self.config(width=dx+width+dx, height=dy+height+dy, + scrollregion=(-dx, -dy, width+dx, height+dy)) # diff --git a/pysollib/tk/tkwidget.py b/pysollib/tk/tkwidget.py index 9f696daa..524dcfbd 100644 --- a/pysollib/tk/tkwidget.py +++ b/pysollib/tk/tkwidget.py @@ -594,28 +594,28 @@ class MfxScrolledCanvas: print 'MfxScrolledCanvas.mouse_wheel', args def _setHbar(self, first, last): - sb = self.hbar - if not self.canvas.winfo_ismapped(): - sb.set(first, last) + if self.canvas.busy: return + sb = self.hbar if float(first) <= 0 and float(last) >= 1: sb.grid_remove() self.hbar_show = False else: - sb.grid() - self.hbar_show = True + if self.canvas.winfo_ismapped(): + sb.grid() + self.hbar_show = True sb.set(first, last) def _setVbar(self, first, last): - sb = self.vbar - if not self.canvas.winfo_ismapped(): - sb.set(first, last) + if self.canvas.busy: return + sb = self.vbar if float(first) <= 0 and float(last) >= 1: sb.grid_remove() self.vbar_show = False else: - sb.grid() - self.vbar_show = True + if self.canvas.winfo_ismapped(): + sb.grid() + self.vbar_show = True sb.set(first, last) def _xview(self, *args): diff --git a/pysollib/winsystems/aqua.py b/pysollib/winsystems/aqua.py index fbd628c7..7a16d598 100644 --- a/pysollib/winsystems/aqua.py +++ b/pysollib/winsystems/aqua.py @@ -20,6 +20,7 @@ ##---------------------------------------------------------------------------## import sys, os +import Tkinter from pysollib.settings import TOOLKIT, USE_TILE from pysollib.tile import Tile @@ -40,7 +41,10 @@ class initRootWindow(baseInitRootWindow): color = style.lookup('.', 'background') if color: root.tk_setPalette(color) # for non-Tile widgets - pass + + # standard Tk scrollbars work on OS X, but Tile ones look weird + Tile.Scrollbar = Tkinter.Scrollbar + else: # pure Tk #root.option_add(...) pass diff --git a/pysollib/winsystems/common.py b/pysollib/winsystems/common.py index 37416bbb..cf632b72 100644 --- a/pysollib/winsystems/common.py +++ b/pysollib/winsystems/common.py @@ -29,29 +29,26 @@ from pysollib.mfxutil import print_err from pysollib.tile import Tile -def init_tile(app, top, theme): - top.tk.call("package", "require", "tile") - # load available themes +def init_tile(app, top): d = os.path.join(app.dataloader.dir, 'themes') if os.path.isdir(d): top.tk.call('lappend', 'auto_path', d) - for t in os.listdir(d): - if os.path.exists(os.path.join(d, t, 'pkgIndex.tcl')): - try: - top.tk.call('package', 'require', 'tile::theme::'+t) - #print 'load theme:', t - except: - traceback.print_exc() - pass + Tile.initialize(top) + def set_theme(app, top, theme): # set theme - style = Tile.Style(top) - all_themes = style.theme_names() - if theme not in all_themes: + try: + Tile.setTheme(top, theme) + except: print_err(_('invalid theme name: ') + theme) - theme = app.opt.default_tile_theme - style.theme_use(theme) + Tile.setTheme(top, app.opt.default_tile_theme) +## style = Tile.Style(top) +## #all_themes = style.theme_names() +## if theme not in all_themes: +## print_err(_('invalid theme name: ') + theme) +## theme = app.opt.default_tile_theme +## style.theme_use(theme) def get_font_name(font): @@ -92,7 +89,7 @@ class baseInitRootWindow: pass elif USE_TILE: theme = app.opt.tile_theme - init_tile(app, root, theme) + init_tile(app, root) set_theme(app, root, theme) else: pass diff --git a/pysollib/winsystems/x11.py b/pysollib/winsystems/x11.py index 9952f07d..aea0817a 100644 --- a/pysollib/winsystems/x11.py +++ b/pysollib/winsystems/x11.py @@ -19,8 +19,9 @@ ## ##---------------------------------------------------------------------------## -import sys, os +import sys, os, traceback +import Tkinter import tkFont from pysollib.settings import PACKAGE @@ -48,7 +49,28 @@ class initRootWindow(baseInitRootWindow): elif USE_TILE: f = os.path.join(app.dataloader.dir, 'tcl', 'menu8.4.tcl') if os.path.exists(f): - root.tk.call('source', f) + try: + root.tk.call('source', f) + except: + traceback.print_exc() + f = os.path.join(app.dataloader.dir, 'tcl', 'clrpick.tcl') + if os.path.exists(f): + try: + root.tk.call('source', f) + except: + traceback.print_exc() + f = os.path.join(app.dataloader.dir, 'tcl', 'fsdialog.tcl') + if os.path.exists(f): + try: + root.tk.call('source', f) + except: + traceback.print_exc() + else: + import tkFileDialog + tkFileDialog.Open.command = 'ttk::getOpenFile' + tkFileDialog.SaveAs.command = 'ttk::getSaveFile' + tkFileDialog.Directory.command = 'ttk::chooseDirectory' + style = Tile.Style(root) color = style.lookup('.', 'background') if color: @@ -62,6 +84,8 @@ class initRootWindow(baseInitRootWindow): root.option_add('*Listbox.background', 'white', 60) root.option_add('*Listbox.foreground', 'black', 60) + root.option_add('*Listbox*selectBackground', '#0a5f89', 60) + root.option_add('*Listbox*selectForeground', 'white', 60) font = root.option_get('font', PACKAGE) if font: @@ -86,12 +110,15 @@ class initRootWindow(baseInitRootWindow): root.wm_minsize(550, 360) style.configure('TLabelframe', labeloutside=False, labelmargins=(8, 0, 8, 0)) + # else: root.option_add('*Entry.background', 'white', 60) root.option_add('*Entry.foreground', 'black', 60) root.option_add('*Listbox.background', 'white', 60) root.option_add('*Listbox.foreground', 'black', 60) + root.option_add('*Listbox*selectBackground', '#0a5f89', 60) + root.option_add('*Listbox*selectForeground', 'white', 60) ##root.option_add('*borderWidth', '1', 50) ##root.option_add('*Button.borderWidth', '1', 50) root.option_add('*Scrollbar.elementBorderWidth', 1, 60)