From c32521e8418bd49e9dcce570d02a0687e6248cf4 Mon Sep 17 00:00:00 2001 From: skomoroh Date: Fri, 15 Jun 2007 22:01:18 +0000 Subject: [PATCH] * improved Tile.py * added `clearlooks' theme for tile-binding * added dialogs for tile-binding: File Selecton and Color Chooser (for x11) * refactoring: tile: replaced Tkinter to Tile * refactoring: tile: removed non-used imports git-svn-id: https://pysolfc.svn.sourceforge.net/svnroot/pysolfc/PySolFC/trunk@174 39dd0a4e-7c14-0410-91b3-c4f2d318f732 --- data/tcl/clrpick.tcl | 700 +++++++ data/tcl/fsdialog.tcl | 1766 +++++++++++++++++ data/themes/clearlooks/clearlooks.tcl | 322 +++ .../clearlooks/clearlooks/arrowdown-a.gif | Bin 0 -> 245 bytes .../clearlooks/clearlooks/arrowdown-d.gif | Bin 0 -> 230 bytes .../clearlooks/clearlooks/arrowdown-n.gif | Bin 0 -> 246 bytes .../clearlooks/clearlooks/arrowdown-p.gif | Bin 0 -> 248 bytes .../clearlooks/clearlooks/arrowleft-a.gif | Bin 0 -> 248 bytes .../clearlooks/clearlooks/arrowleft-d.gif | Bin 0 -> 234 bytes .../clearlooks/clearlooks/arrowleft-n.gif | Bin 0 -> 252 bytes .../clearlooks/clearlooks/arrowleft-p.gif | Bin 0 -> 251 bytes .../clearlooks/clearlooks/arrowright-a.gif | Bin 0 -> 250 bytes .../clearlooks/clearlooks/arrowright-d.gif | Bin 0 -> 235 bytes .../clearlooks/clearlooks/arrowright-n.gif | Bin 0 -> 252 bytes .../clearlooks/clearlooks/arrowright-p.gif | Bin 0 -> 251 bytes .../clearlooks/clearlooks/arrowup-a.gif | Bin 0 -> 244 bytes .../clearlooks/clearlooks/arrowup-d.gif | Bin 0 -> 228 bytes .../clearlooks/clearlooks/arrowup-n.gif | Bin 0 -> 248 bytes .../clearlooks/clearlooks/arrowup-p.gif | Bin 0 -> 247 bytes data/themes/clearlooks/clearlooks/blank.gif | Bin 0 -> 63 bytes .../themes/clearlooks/clearlooks/button-a.gif | Bin 0 -> 661 bytes .../themes/clearlooks/clearlooks/button-d.gif | Bin 0 -> 590 bytes .../themes/clearlooks/clearlooks/button-n.gif | Bin 0 -> 656 bytes .../themes/clearlooks/clearlooks/button-p.gif | Bin 0 -> 519 bytes .../clearlooks/clearlooks/button-pa.gif | Bin 0 -> 394 bytes .../themes/clearlooks/clearlooks/check-ac.gif | Bin 0 -> 331 bytes .../themes/clearlooks/clearlooks/check-au.gif | Bin 0 -> 96 bytes .../themes/clearlooks/clearlooks/check-dc.gif | Bin 0 -> 223 bytes .../themes/clearlooks/clearlooks/check-du.gif | Bin 0 -> 96 bytes .../themes/clearlooks/clearlooks/check-nc.gif | Bin 0 -> 331 bytes .../themes/clearlooks/clearlooks/check-nu.gif | Bin 0 -> 96 bytes .../themes/clearlooks/clearlooks/check-pc.gif | Bin 0 -> 332 bytes .../themes/clearlooks/clearlooks/check-pu.gif | Bin 0 -> 96 bytes data/themes/clearlooks/clearlooks/combo-n.gif | Bin 0 -> 100 bytes .../themes/clearlooks/clearlooks/combo-ra.gif | Bin 0 -> 527 bytes .../themes/clearlooks/clearlooks/combo-rd.gif | Bin 0 -> 512 bytes .../themes/clearlooks/clearlooks/combo-rf.gif | Bin 0 -> 550 bytes .../themes/clearlooks/clearlooks/combo-rn.gif | Bin 0 -> 533 bytes .../themes/clearlooks/clearlooks/combo-rp.gif | Bin 0 -> 402 bytes .../clearlooks/clearlooks/comboarrow-a.gif | Bin 0 -> 441 bytes .../clearlooks/clearlooks/comboarrow-d.gif | Bin 0 -> 432 bytes .../clearlooks/clearlooks/comboarrow-n.gif | Bin 0 -> 451 bytes .../clearlooks/clearlooks/comboarrow-p.gif | Bin 0 -> 450 bytes .../clearlooks/clearlooks/progress-h.gif | Bin 0 -> 281 bytes .../clearlooks/clearlooks/progress-v.gif | Bin 0 -> 304 bytes .../themes/clearlooks/clearlooks/radio-ac.gif | Bin 0 -> 356 bytes .../themes/clearlooks/clearlooks/radio-au.gif | Bin 0 -> 223 bytes .../themes/clearlooks/clearlooks/radio-dc.gif | Bin 0 -> 362 bytes .../themes/clearlooks/clearlooks/radio-du.gif | Bin 0 -> 226 bytes .../themes/clearlooks/clearlooks/radio-nc.gif | Bin 0 -> 359 bytes .../themes/clearlooks/clearlooks/radio-nu.gif | Bin 0 -> 226 bytes .../themes/clearlooks/clearlooks/radio-pc.gif | Bin 0 -> 359 bytes .../themes/clearlooks/clearlooks/radio-pu.gif | Bin 0 -> 225 bytes .../clearlooks/clearlooks/sbthumb-ha.gif | Bin 0 -> 276 bytes .../clearlooks/clearlooks/sbthumb-hd.gif | Bin 0 -> 263 bytes .../clearlooks/clearlooks/sbthumb-hn.gif | Bin 0 -> 278 bytes .../clearlooks/clearlooks/sbthumb-hp.gif | Bin 0 -> 278 bytes .../clearlooks/clearlooks/sbthumb-va.gif | Bin 0 -> 266 bytes .../clearlooks/clearlooks/sbthumb-vd.gif | Bin 0 -> 262 bytes .../clearlooks/clearlooks/sbthumb-vn.gif | Bin 0 -> 271 bytes .../clearlooks/clearlooks/sbthumb-vp.gif | Bin 0 -> 271 bytes .../themes/clearlooks/clearlooks/scale-ha.gif | Bin 0 -> 474 bytes .../themes/clearlooks/clearlooks/scale-hd.gif | Bin 0 -> 336 bytes .../themes/clearlooks/clearlooks/scale-hn.gif | Bin 0 -> 477 bytes .../themes/clearlooks/clearlooks/scale-va.gif | Bin 0 -> 526 bytes .../themes/clearlooks/clearlooks/scale-vd.gif | Bin 0 -> 342 bytes .../themes/clearlooks/clearlooks/scale-vn.gif | Bin 0 -> 511 bytes .../clearlooks/clearlooks/scaletrough-h.gif | Bin 0 -> 87 bytes .../clearlooks/clearlooks/scaletrough-v.gif | Bin 0 -> 111 bytes data/themes/clearlooks/clearlooks/sep-h.gif | Bin 0 -> 40 bytes data/themes/clearlooks/clearlooks/sep-v.gif | Bin 0 -> 40 bytes .../themes/clearlooks/clearlooks/sizegrip.gif | Bin 0 -> 77 bytes data/themes/clearlooks/clearlooks/tab-a.gif | Bin 0 -> 536 bytes data/themes/clearlooks/clearlooks/tab-n.gif | Bin 0 -> 549 bytes .../clearlooks/clearlooks/toolbutton-a.gif | Bin 0 -> 554 bytes .../clearlooks/clearlooks/toolbutton-d.gif | Bin 0 -> 499 bytes .../clearlooks/clearlooks/toolbutton-n.gif | Bin 0 -> 557 bytes .../clearlooks/clearlooks/toolbutton-p.gif | Bin 0 -> 527 bytes .../clearlooks/clearlooks/toolbutton-pa.gif | Bin 0 -> 333 bytes data/themes/clearlooks/clearlooks/tree-d.gif | Bin 0 -> 509 bytes data/themes/clearlooks/clearlooks/tree-h.gif | Bin 0 -> 519 bytes data/themes/clearlooks/clearlooks/tree-n.gif | Bin 0 -> 528 bytes data/themes/clearlooks/clearlooks/tree-p.gif | Bin 0 -> 420 bytes data/themes/clearlooks/convert_imgs.sh | 28 + data/themes/clearlooks/create_imgs.py | 442 +++++ data/themes/clearlooks/pkgIndex.tcl | 7 + pysollib/app.py | 4 +- pysollib/customgame.py | 7 +- pysollib/game.py | 9 +- pysollib/init.py | 7 +- pysollib/tile/Tile.py | 321 ++- pysollib/tile/colorsdialog.py | 22 +- pysollib/tile/edittextdialog.py | 8 +- pysollib/tile/findcarddialog.py | 3 - pysollib/tile/fontsdialog.py | 38 +- pysollib/tile/gameinfodialog.py | 21 +- pysollib/tile/menubar.py | 11 +- pysollib/tile/playeroptionsdialog.py | 26 +- pysollib/tile/progressbar.py | 16 +- pysollib/tile/selectcardset.py | 33 +- pysollib/tile/selectgame.py | 30 +- pysollib/tile/selecttile.py | 7 +- pysollib/tile/selecttree.py | 7 - pysollib/tile/solverdialog.py | 60 +- pysollib/tile/soundoptionsdialog.py | 46 +- pysollib/tile/statusbar.py | 13 +- pysollib/tile/timeoutsdialog.py | 41 +- pysollib/tile/tkcanvas.py | 14 +- pysollib/tile/tkconst.py | 2 - pysollib/tile/tkhtml.py | 37 +- pysollib/tile/tkstats.py | 172 +- pysollib/tile/tktree.py | 2 +- pysollib/tile/tkutil.py | 5 +- pysollib/tile/tkwidget.py | 95 +- pysollib/tile/tkwrap.py | 12 +- pysollib/tile/toolbar.py | 31 +- pysollib/tile/wizarddialog.py | 28 +- pysollib/tk/colorsdialog.py | 2 +- pysollib/tk/menubar.py | 2 + pysollib/tk/selectgame.py | 11 +- pysollib/tk/tkcanvas.py | 9 +- pysollib/tk/tkwidget.py | 20 +- pysollib/winsystems/aqua.py | 6 +- pysollib/winsystems/common.py | 31 +- pysollib/winsystems/x11.py | 31 +- 125 files changed, 3867 insertions(+), 638 deletions(-) create mode 100644 data/tcl/clrpick.tcl create mode 100644 data/tcl/fsdialog.tcl create mode 100644 data/themes/clearlooks/clearlooks.tcl create mode 100644 data/themes/clearlooks/clearlooks/arrowdown-a.gif create mode 100644 data/themes/clearlooks/clearlooks/arrowdown-d.gif create mode 100644 data/themes/clearlooks/clearlooks/arrowdown-n.gif create mode 100644 data/themes/clearlooks/clearlooks/arrowdown-p.gif create mode 100644 data/themes/clearlooks/clearlooks/arrowleft-a.gif create mode 100644 data/themes/clearlooks/clearlooks/arrowleft-d.gif create mode 100644 data/themes/clearlooks/clearlooks/arrowleft-n.gif create mode 100644 data/themes/clearlooks/clearlooks/arrowleft-p.gif create mode 100644 data/themes/clearlooks/clearlooks/arrowright-a.gif create mode 100644 data/themes/clearlooks/clearlooks/arrowright-d.gif create mode 100644 data/themes/clearlooks/clearlooks/arrowright-n.gif create mode 100644 data/themes/clearlooks/clearlooks/arrowright-p.gif create mode 100644 data/themes/clearlooks/clearlooks/arrowup-a.gif create mode 100644 data/themes/clearlooks/clearlooks/arrowup-d.gif create mode 100644 data/themes/clearlooks/clearlooks/arrowup-n.gif create mode 100644 data/themes/clearlooks/clearlooks/arrowup-p.gif create mode 100644 data/themes/clearlooks/clearlooks/blank.gif create mode 100644 data/themes/clearlooks/clearlooks/button-a.gif create mode 100644 data/themes/clearlooks/clearlooks/button-d.gif create mode 100644 data/themes/clearlooks/clearlooks/button-n.gif create mode 100644 data/themes/clearlooks/clearlooks/button-p.gif create mode 100644 data/themes/clearlooks/clearlooks/button-pa.gif create mode 100644 data/themes/clearlooks/clearlooks/check-ac.gif create mode 100644 data/themes/clearlooks/clearlooks/check-au.gif create mode 100644 data/themes/clearlooks/clearlooks/check-dc.gif create mode 100644 data/themes/clearlooks/clearlooks/check-du.gif create mode 100644 data/themes/clearlooks/clearlooks/check-nc.gif create mode 100644 data/themes/clearlooks/clearlooks/check-nu.gif create mode 100644 data/themes/clearlooks/clearlooks/check-pc.gif create mode 100644 data/themes/clearlooks/clearlooks/check-pu.gif create mode 100644 data/themes/clearlooks/clearlooks/combo-n.gif create mode 100644 data/themes/clearlooks/clearlooks/combo-ra.gif create mode 100644 data/themes/clearlooks/clearlooks/combo-rd.gif create mode 100644 data/themes/clearlooks/clearlooks/combo-rf.gif create mode 100644 data/themes/clearlooks/clearlooks/combo-rn.gif create mode 100644 data/themes/clearlooks/clearlooks/combo-rp.gif create mode 100644 data/themes/clearlooks/clearlooks/comboarrow-a.gif create mode 100644 data/themes/clearlooks/clearlooks/comboarrow-d.gif create mode 100644 data/themes/clearlooks/clearlooks/comboarrow-n.gif create mode 100644 data/themes/clearlooks/clearlooks/comboarrow-p.gif create mode 100644 data/themes/clearlooks/clearlooks/progress-h.gif create mode 100644 data/themes/clearlooks/clearlooks/progress-v.gif create mode 100644 data/themes/clearlooks/clearlooks/radio-ac.gif create mode 100644 data/themes/clearlooks/clearlooks/radio-au.gif create mode 100644 data/themes/clearlooks/clearlooks/radio-dc.gif create mode 100644 data/themes/clearlooks/clearlooks/radio-du.gif create mode 100644 data/themes/clearlooks/clearlooks/radio-nc.gif create mode 100644 data/themes/clearlooks/clearlooks/radio-nu.gif create mode 100644 data/themes/clearlooks/clearlooks/radio-pc.gif create mode 100644 data/themes/clearlooks/clearlooks/radio-pu.gif create mode 100644 data/themes/clearlooks/clearlooks/sbthumb-ha.gif create mode 100644 data/themes/clearlooks/clearlooks/sbthumb-hd.gif create mode 100644 data/themes/clearlooks/clearlooks/sbthumb-hn.gif create mode 100644 data/themes/clearlooks/clearlooks/sbthumb-hp.gif create mode 100644 data/themes/clearlooks/clearlooks/sbthumb-va.gif create mode 100644 data/themes/clearlooks/clearlooks/sbthumb-vd.gif create mode 100644 data/themes/clearlooks/clearlooks/sbthumb-vn.gif create mode 100644 data/themes/clearlooks/clearlooks/sbthumb-vp.gif create mode 100644 data/themes/clearlooks/clearlooks/scale-ha.gif create mode 100644 data/themes/clearlooks/clearlooks/scale-hd.gif create mode 100644 data/themes/clearlooks/clearlooks/scale-hn.gif create mode 100644 data/themes/clearlooks/clearlooks/scale-va.gif create mode 100644 data/themes/clearlooks/clearlooks/scale-vd.gif create mode 100644 data/themes/clearlooks/clearlooks/scale-vn.gif create mode 100644 data/themes/clearlooks/clearlooks/scaletrough-h.gif create mode 100644 data/themes/clearlooks/clearlooks/scaletrough-v.gif create mode 100644 data/themes/clearlooks/clearlooks/sep-h.gif create mode 100644 data/themes/clearlooks/clearlooks/sep-v.gif create mode 100644 data/themes/clearlooks/clearlooks/sizegrip.gif create mode 100644 data/themes/clearlooks/clearlooks/tab-a.gif create mode 100644 data/themes/clearlooks/clearlooks/tab-n.gif create mode 100644 data/themes/clearlooks/clearlooks/toolbutton-a.gif create mode 100644 data/themes/clearlooks/clearlooks/toolbutton-d.gif create mode 100644 data/themes/clearlooks/clearlooks/toolbutton-n.gif create mode 100644 data/themes/clearlooks/clearlooks/toolbutton-p.gif create mode 100644 data/themes/clearlooks/clearlooks/toolbutton-pa.gif create mode 100644 data/themes/clearlooks/clearlooks/tree-d.gif create mode 100644 data/themes/clearlooks/clearlooks/tree-h.gif create mode 100644 data/themes/clearlooks/clearlooks/tree-n.gif create mode 100644 data/themes/clearlooks/clearlooks/tree-p.gif create mode 100755 data/themes/clearlooks/convert_imgs.sh create mode 100755 data/themes/clearlooks/create_imgs.py create mode 100644 data/themes/clearlooks/pkgIndex.tcl 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 0000000000000000000000000000000000000000..c5f8761f244338ffb3d7e72edecd0dfec094bae5 GIT binary patch literal 245 zcmZ?wbh9u|C(LEtk`8&C^S+xz#g-#@>7O+Y~4|8I~y0}{{yu|ak* zuvR5B_oR5LaV%cgh#TTwb@0Jjf<_bt1G{Xi@m?U foqa;SCO0?xj9Ig0rt(NET(o$hlG<_=MFwjCE0KE+ literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/arrowdown-d.gif b/data/themes/clearlooks/clearlooks/arrowdown-d.gif new file mode 100644 index 0000000000000000000000000000000000000000..061990e25c2a26f4dbfcee48c4c66b4ca7b217d1 GIT binary patch literal 230 zcmZ?wbh9u|G!zjtig+W-Im1ND6W{Qdps_aN~6-g}_b<7?0FUweN08UrfO z0dYZgF|cMUsPv_9x@N3emL%fSD8is`;2Wj==JLDXraLPQ76h;zNeYyZ4AEkC7U4>j zg=4cQh+3}XCG@(gQOqZ)MAxf&#P3r0jV|_mMdx94q&y?Wj<8Q3wZ}E}j;^&g= T>FM*4nmlFdWVIQ}iVW5OIlXY3 literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/arrowdown-n.gif b/data/themes/clearlooks/clearlooks/arrowdown-n.gif new file mode 100644 index 0000000000000000000000000000000000000000..b72fe3e12814296924ef767a1111557bfb13bffd GIT binary patch literal 246 zcmZ?wbh9u|wC|i-+TV}-t+tS{{R19U78Hk_Wkqs_n+T`!1H_Wfl`mJJ->hL`R!{0 z0s;&$paWun>|$W8Ua+Mn#nZ@p$+|bY3<4ckgBeaRxaKCQ{FyR;gVK#XO0AAdjXbob zN{6H*Y~ literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/arrowdown-p.gif b/data/themes/clearlooks/clearlooks/arrowdown-p.gif new file mode 100644 index 0000000000000000000000000000000000000000..99626890c4f4e19837933a861097416608723a18 GIT binary patch literal 248 zcmVI=#Nmdo6uIzfHfj|V05DU2GT$oVc5TCCA z(V#GeK_OX)D3wND#6UGns|H=lAOU#4fJ4HVIw%g{uwoL$C@2cW7xAWOE)L9MLD>WL y8+#ff7z`T>3=4;chDLcA3>*xQ9FiOvZ5bIIo16`r9d{`jq@|{$J0_|mApkpB<#VC(LEtk`8&C^S+xz#g-#@>7O+Y~4|8I~y0}{{yu|ak* zu+}Ct_oR5LaV%cUdPJnqRGa^*4@;@R#?Nu iK50@X`{Y7RZf^G3bLY-UG!zjtig+W-Im1ND6W{Qdps_aFe&_59v@pzPyo&+lJ*e)}2& z63_v$L3S~)<}0Z5rEt1ttXh^N;?pR?pl{$Ct^MZmyWplfD-9L|u(i5w)ac>Sn%bDS zvA}IMdvmH+uM7v94zuH1xpQX?9|iR(+&k;7d@&(h`iI)Fhc~QONmTnv^7HYx@Cov_ b`$}=~b4g8@Fv(YX`iz;=)#fNGGFSrulaP51 literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/arrowleft-n.gif b/data/themes/clearlooks/clearlooks/arrowleft-n.gif new file mode 100644 index 0000000000000000000000000000000000000000..143739f062c9cf10e62cd2884f2bc4716957fa8f GIT binary patch literal 252 zcmZ?wbh9u|wC|i-+TV}-t+tS{{R19U78Hk_Wkqs_n+T`08r!ed+&j=kFPzyf9?70 zYXSlS3}B!GB0+XBur@B((v#w8x_+tU?PDSn zMlxtjb&EUVV9LM{+N_s4K}IP2z`+lu%lNvSB_@RVERtY#UC5#QMC9zz#z-BFx^Qmk zIw@rd9%&w)W`?d#w;D+v8J@{9Q)MIzBqe3%&F7sfTcs(re8tM;)@o~26d9}m{~2;8 literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/arrowright-a.gif b/data/themes/clearlooks/clearlooks/arrowright-a.gif new file mode 100644 index 0000000000000000000000000000000000000000..c139129e0a1ac3564aff98b07aba66a51312df76 GIT binary patch literal 250 zcmZ?wbh9u|C(LEtk`8&C^S+xz#g-#@>7O+Y~4|8I~y0}{{yu|ak* zu+}Fu_oR5LaV%ctt*l;63f=j$ylC_?d)kTwyi;YdPr=Kmb kmWzGLlrHwEMLgWx>~rVOpO?-fv26K@WlCymR1_Jk0q;h7ApigX literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/arrowright-d.gif b/data/themes/clearlooks/clearlooks/arrowright-d.gif new file mode 100644 index 0000000000000000000000000000000000000000..1b5afb0e17193e442b9d9b4df0f985bbb00db1cd GIT binary patch literal 235 zcmZ?wbh9u|G!zjtig+W-Im1ND6W{Qdps_aFe&_59v@pzPyo&+lJ*e)}2& z63_v$L3S~)7AUCnrEt1ttXh^N;?pR?pl{$Ct^MZmyWplfD-9L|h#g4^l#mS3YCd|1 zq1A|=t=nwC|i-+TV}-t+tS{{R19U78Hk_Wkqs_n+T`08r!ed+&j=kFPzyf9?70 zYXSlS3}B!GB0+XBur@B((v#w8FElrl@j0=n9?mUy;xA1OMpvy!GcAZf-);su3Dj_woXNn!5RQRk$w{Z literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/arrowright-p.gif b/data/themes/clearlooks/clearlooks/arrowright-p.gif new file mode 100644 index 0000000000000000000000000000000000000000..7706aa6cec9314cecf36f017fdbf362bcc9adb13 GIT binary patch literal 251 zcmVNk%v~VGjTg0K@I=#Nmdo6uIzfHfj|V05DU2GT$oVc5TCCA z(V#GeL7@OBM3hP+FJhaSHQvWHKq=V!z3(LOr#hEMWF~Iyp#0E&uC(LEtk`8&J#p_pjeSzkN+WK;ZvxkR$^t&;fBlb}_J4 zCN%e?c&c$MUiYR;#pjvBW@YOis>cGqeL3LqP8pm9mcoUdHR_UoO z@X?s@!R3SMA(j@$3f&bUdKa6j_R8^e@U|^X(3JR9&C2Sc$;QRj(b-v0$;IB+*T&vo cpvle6K7HoQ8EHJ?3l=U~prp1;MUlZ809c23&;S4c literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/arrowup-d.gif b/data/themes/clearlooks/clearlooks/arrowup-d.gif new file mode 100644 index 0000000000000000000000000000000000000000..95bb2b62fdc8ba8e1fcc55e4e009c60e363613fb GIT binary patch literal 228 zcmZ?wbh9u|G!zjtig+W-Im1ND6W{Qdps_aFe&_59v@pzPyo&+lJ*e)}2& z63_v$L3S~)W-6%krEt1ttXh^N;?pR?pl{$Ct^MZmyWplfD-9L|upLPXl#mS3Vm^F` zq1A|=t-EC71{sbvZRUfz^5@PJR`xm===UDsx|)zA(^qX*pPnYi$6sH;-{d33#m^wC|i-+TV}-t+tS{{R19U78Hk_Wkqs_n+T`08r!ed+&j=kFPzyf9?70 zYXSlS3}B!GB0+XBu+}cv(v#w8@OSBc8Lo*iwMU?Z(1JiQW7kGP>TbQx3+1VagB_+TwFrhwQxI literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/arrowup-p.gif b/data/themes/clearlooks/clearlooks/arrowup-p.gif new file mode 100644 index 0000000000000000000000000000000000000000..bcedfb38a5089b729e96007f8608a50b05a204ea GIT binary patch literal 247 zcmZ?wbh9u|`q;VS z$Icx-mYo@O@AkQS*U#Mp%3eNp?fkK8r-6dW*{R9JsmaH-tvz;p@AKQ&&Yj+S?)ctw zhxdXF1`#?S0%R8hYfVCMZ;EHom8I+6WG!uUVCfU!uDBL4J>UWV{PiDBEYNFpRE%uU znCd2X#KDwdRY>e90ZRpj2h9hwePo5$H~iA+j1v;xT4QuFLQ1?fY0-0SlPXDNac(JY s?)uhtDYps50-3c@h#bvu5+mlqu7cT)brIVr#XPDvAu&0AF5kGXMYp literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/blank.gif b/data/themes/clearlooks/clearlooks/blank.gif new file mode 100644 index 0000000000000000000000000000000000000000..be6183986384fdf9381ad4f3580dbba31e011838 GIT binary patch literal 63 zcmZ?wbhEHblwgoxXkcLY&j137KUo+-v<`>>$uKa9we+t%{g!|6oGrJyH{aXyo4@Um K$FyKZ25SJZj}h_! literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/button-a.gif b/data/themes/clearlooks/clearlooks/button-a.gif new file mode 100644 index 0000000000000000000000000000000000000000..2cc46a4666eb9976b48c1e0c8bcc6f78eb8ea615 GIT binary patch literal 661 zcmZ?wbh9u|lwpuzxXQrr{rmgxpWlCf|Ni~w=kMP?fB*XV`{&Q+OsbyKS3RezdQMyQ zwae$uojx{aQp=pamX_M$IbAI+mBlTk#Zzjlduoe&fb81rmdfmw((LNe?B}oVJ%4`h z`Qv-f@8A0m1i%0P{|pXl5@vLi}@E;eCbR~ zS$1Phy4#l;r}_QjZ#XND$8QY(^Dyp|yr9IKdB-y||J0OCtZ+~=F;Qx0YHU_$Xl+qy ztjX^+RZ^a)G-*=rlxb6@8w-lbDKnTVn=&j~p}cCzs>N%SjYUP}mNRTsR$0Dt=OTuk zTU9pjFWAk%xLb7_BjdK6$M@|w77>wCQ9aJ6dQIi_t?S3{-(tL^FQ;~z@%f9FFH~N= zeSYc6n^$V@UcEd0^Xp^br%b0=W>lyf%stSgCcri0V^ix+24*G(kr@Vxww=#?co;02 zTb;X@h4Zdd6g=@@6iMF^@i1{Q!*o%98570JOAkym4%_m<;lYvJ#~AHW+3tEUyy#rS zl=Uoy(`4m^1)lNqR%mX1eryhx4Tpk5LiY9b?)!`8p1S&)M^vjK&sJ(%)}{4vbHCZl zKH$vA#QI6hVWRl@xIJ}$pUs`f&=kweW|E$-!6g;DBP=i)%7wN7`f;Z%wCHec6c9FBtx8e}7-5>GTKN j#|N6&j2C&&_uISc3mZ3=P5yzsyT8AGurr;XiNP8GTW&^A literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/button-d.gif b/data/themes/clearlooks/clearlooks/button-d.gif new file mode 100644 index 0000000000000000000000000000000000000000..4d32129fd3cdef7efbd84260a9811b53442fbdea GIT binary patch literal 590 zcmZ?wbh9u|lwpuzxXQrr|MU0n-`{`#{Qmp<_upT?fB*UU`}fb^zkdGy`SW}Cuid*1 zMCYErz6azze|+!x{d>=E-#fN#?f?J(zyAhm{Qmv(_xGRQgTU+e&w;vL-+TZ3-uuV* z-UC%WzV`h7wdc35J->eK|M%|{E_?>m{Ol7gC Nnx|8HoDd6xH2`#D2-E-o literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/button-n.gif b/data/themes/clearlooks/clearlooks/button-n.gif new file mode 100644 index 0000000000000000000000000000000000000000..b6cdc4ae47c67fdb1945905e222d2ae228e6f90a GIT binary patch literal 656 zcmV;B0&o3CNk%v~VH^M)0M!5h|MU0v_wV=f@AvQT_v`QP^XKpH=kM$1@8{>7l6#zv zdz^}UoQ8Ye-`3vS*4ER`&dbJ}l7yU&goJ%_oQi~md2@tybKcv|lzn@QeRGU?bA)|s zgn4U(b!&TdYv=3U=jYz%*W{o0^=T znw^`V1348NBm)HlDXOX|1+A^Dtg9)or5YL}1}O%;y#&Dq!oI}6z62>b6Q~CUDh3D9 z&%X!N!q>#rIT;xw)GE*6(&g9B+SlDOB22M1IUkBV@Ku1T=oW{7@66%A7z~=2RIlCkT->8IV8#;%QZ?RB2q*`V^>D8aZ0D zAo0|xSF>21mesnj#R3u`K!gZUgKk~9b>r5+i+6601r*@g5OL#12*V*n9JY}-gbl=x z9p|9Hf&`8RI7Dc^EFv?G%bY!b#+*Yz0uniLjJVt&bq*XkT90tOy0z-m5+sng;DEP| q9KCh;?#;Wm10BR2T*t2Wj&K-O8AOJg54OMLb literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/button-p.gif b/data/themes/clearlooks/clearlooks/button-p.gif new file mode 100644 index 0000000000000000000000000000000000000000..495fc308a5c8a625c57cfbab2fdf1afb60eeeff5 GIT binary patch literal 519 zcmV+i0{Hz$Nk%v~VH^M)0K@2Jm>*vU^b7f=3wynm?y~fAA z#>2hN%e~IWz0SkEEC2ui02}}u000I4VBke$X`X25iBaaha4f%(2W3Q(69XX(iJmXl zEAn^{Oh!Ra0GZ63B6yrOp#;qBST**d%EgnuLO0UDW6A zYE5Vb7dLH#YI=x=gL{M*8H#!xjS3x!1(%YE5D$?B3woiMlA@BMpcjw}l%XB02Cy9l zlm)bt2AQ21v$nmqw7Hk8r#|6 z#oF5F9_8Q-4b~p>^c&#z+V~su;QSBO_6}?~aKJ-Bg9r@{JaDhz0SndU?VE^jV!?e9 z5AL%NZ^MUzA3c2V=+NWGeFBX~3T!|j!^nXfJj#6e!9&asHDQWuP$7dy4kJHsAURMa z(4jbkZm1A%Bv7F^haOdmbHh=fEHgaiz;!BDs8^##rO>l$(yv#|ru|xhfmRL@H~`=p zm+RcPc;(XNI$=VFxqIbGxZAaGUAh$vOaLGO0fM=Y5pa-<051T?moZN;5I}L?&!9t# J{>(W906Pdg`Y`|i literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/button-pa.gif b/data/themes/clearlooks/clearlooks/button-pa.gif new file mode 100644 index 0000000000000000000000000000000000000000..7f1d2464f0960108bc48d214e33a888805afa7fa GIT binary patch literal 394 zcmV;50d@XINk%v~VH^M)0K@iKzT0jeUWlvF4M2>3_5qVEWX@`$>5gmhGmxN?$9+WtHnT~poR1ls&k)m8= zm>n88Xt7Vben1+xLvmVNL5MsY8G~tOj;tD{ROoL}YXb~8KOS70*C^mK1{dxFb@I(BvFSC%0g)0 o6ez&L2b#4xm&^n(kl>lglPC~TCNKbiWP+D4W6GTQl4S@0J7(Fg(f|Me literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/check-ac.gif b/data/themes/clearlooks/clearlooks/check-ac.gif new file mode 100644 index 0000000000000000000000000000000000000000..a1c3a17f271fe5c1e1bbbda13f17a51c62fae2de GIT binary patch literal 331 zcmZ?wbhEHb6l4%&xXJ(mYv=V8mlkJdW=F+F1qB9qd3tT#wsq^Kt!vk4gnEKmgLODh)52pITPm3X;1WBS?jT8t*ax0H2{xtS`h#M literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/check-au.gif b/data/themes/clearlooks/clearlooks/check-au.gif new file mode 100644 index 0000000000000000000000000000000000000000..e2e1bfdfbae7cac19b6a47add3d5ad907823c582 GIT binary patch literal 96 zcmZ?wbhEHb6l4%&n8?7ec3#ha28RDY@cp~uPZmZ721W)Q1|R^*GcXzU^shYqfM1?z y@h$5EGK+q%m%ZZ7wa{?dJ;^1jcJ7sZy~;%WzLCzO_48)CwCS{coT0(MU=09$JtZ9g literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/check-dc.gif b/data/themes/clearlooks/clearlooks/check-dc.gif new file mode 100644 index 0000000000000000000000000000000000000000..2991c7fa1ea008c4e7f433f29926e436ecac284b GIT binary patch literal 223 zcmZ?wbhEHb6l4%&IKsfNc3#i>*U#TSe}3=wwQHBpT|0m7-05Tg85s8N+PZh!)~(yt zZr!x@`Qv;4f#CQ5@87>4JG}S(d!X{?_wL`@yKU{Y>(|bmKL?axzyTD0vM@3*urug@ z`Td4gnEKmgLODh)52pITPm3X;1WBS?jT8t*ax0H2{xtS`h#M literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/check-nu.gif b/data/themes/clearlooks/clearlooks/check-nu.gif new file mode 100644 index 0000000000000000000000000000000000000000..e2e1bfdfbae7cac19b6a47add3d5ad907823c582 GIT binary patch literal 96 zcmZ?wbhEHb6l4%&n8?7ec3#ha28RDY@cp~uPZmZ721W)Q1|R^*GcXzU^shYqfM1?z y@h$5EGK+q%m%ZZ7wa{?dJ;^1jcJ7sZy~;%WzLCzO_48)CwCS{coT0(MU=09$JtZ9g literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/check-pc.gif b/data/themes/clearlooks/clearlooks/check-pc.gif new file mode 100644 index 0000000000000000000000000000000000000000..6364fd21476723c39669ca30442d7089bfdbdd44 GIT binary patch literal 332 zcmZ?wbhEHb6l4%&xXJ(mYv=VO$3|(YC|)~%?%e5P=Z+ua;9v*}4f68!^78a@a&)?O z{@AtC$Equft4oWQ&YP2+nf#xDp{J{7@2;&=CiP6|>p6CKZ%v{7{$ycfU=U)^0SSWq#K4y6&{^Q2Bh`PRq3C3c5OeQ}l3N@$ z(k*MQDL4qMab97TeL{!p{_2O5QdKOb=tOW_EwN+ad9ZM<_X1&d1yN?{jG}NBJ_b1k q!Q{Fm7OtMc+D;a6X|CkV#E3{Sfw>bG%$=U-yQJYB@Fc#a5%!KQnA z`d_!oX-t#M?8>l8%Gt3mT4#Qq?fo5lpYL^B&6;{Rd}67Os_*Hb;F2GyJiS?q85pbq D;{z#R literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/combo-ra.gif b/data/themes/clearlooks/clearlooks/combo-ra.gif new file mode 100644 index 0000000000000000000000000000000000000000..982372fe109e6e0770da73feeb1ee78793e75396 GIT binary patch literal 527 zcmZ?wbh9u|lwgoxxXQrr{rCIt-`{`#{Qmp<_wPSHfB*jZ``6FkKY#xI@$)&8s^@f7 zU%Pzn-05R;Cbi7zYnjv4(o$L6Q(N3po83~G-BOxeU7Fp}RQ&w)z30#GJ%4=fKM?%> z|NlD(e*gU)1U>^z2bv5t9cc9PDP7f5+N!5CRrjS{h_B`&?S{)ooTc@}}Lse8+_DIw2`}Mg@6=8I03A=gyot zM_y2B&J0DS*$N7Zs~OiZ&JmMhTD4MP+sbWw*6w9ms-U!rN$Jq4!zcHgRMM0>b@=GE zQ>?iKhDk?jgjvNZEH)?~?2=V2(=jM)Vd7QcSrL=DfZ_BM zt=M%n3mzV5 b7aCfxuTMDKm73U)-Ml&D@~T*A76xkoS7Z6_ literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/combo-rd.gif b/data/themes/clearlooks/clearlooks/combo-rd.gif new file mode 100644 index 0000000000000000000000000000000000000000..ded0fc5595f74b80ac48fe672a7def07bfc588fe GIT binary patch literal 512 zcmZ?wbh9u|lwgoxxXQrr|MU0n-`{`#{Qmp<_upT?fB*UU`}fb^zkdGy`SW}Cuid*1 zMCYErz6azze|+!x{d>=E-#fN#?f?J(zyAhm{Qe!N9jFzk`SW`a0Gjan-uvhG-UAgs zzV`h7wdc35{r~=*fttV(*)Sat2jmw9wtokhHJo&$`cIq)IFw^GKfu$)X`#;=MK6un zb5pk7`!Gdl0mG`N4m-IxLax1jxm2m({QVyd3H{?@ z%#$T0nWs;kG-L7<=80@93l~eWu`QKc#IkgeWH1~1vW@JE*rgV4T)crTn0?=deVY&N z+kQ}reedB@r%#{U$8+k!nS*U;OE z-MfA5+U0ZSP9K{ysbx-I%bc#3mdfILx6dWV2KCeyx7230RA#r7W>=SHw=@+$e|_)y z^Lx)9-+O-l-t*h{{{R2~{r7he_zbcKWXMOUc zWftBqDbFUnlkMcTlV|pxW!rM*(&a11PwE`KCUyDtl}lPjb=h^<*rlF5efs2;@Lg?r z_Tw+upT2nh{mV0UP5DR9*%`J!m3B9fv*rEsD7RoE<9xPu_Lv9O4UZ19HHh=a#H=t} z)ZHhnl(%9>;vu&-`M|uG6CW0Jvxr&ld7v=)S=%iAyi+=slbL;5_+`}&ykJOP5xB_N zQsnIg$4qt>d69}40?n^jScRAQ9gW($s$IfRt|r2vtdVDP`pIRctHYWi+4xdU%=O;B UE>@E5fz^%E+t=UU4-8>z0A8U8hyVZp literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/combo-rn.gif b/data/themes/clearlooks/clearlooks/combo-rn.gif new file mode 100644 index 0000000000000000000000000000000000000000..1d9cb50c97bc0f594b4f1ab8013c9c8e928e2a7e GIT binary patch literal 533 zcmZ?wbh9u|lwgoxxXQrr|MU0n-`{`#{Qmp<_upT?fB*UU`}fb^zkdGy`SUrGs^@f7 z-@AY9-tBAGE}uJh`q-RFEpz%>=5)2RR2JX6eXggrxTQ9`r82vvG`qSqyQQi4`RjYn zpWl1__}=sT_nzOr_y7O@@4tcOfBz1&1!x1%j?eEw;Pv|{UDZ?Cs;4wn_p}xFG!?&p zeeeDAd+&i7A76WZ|Jw80*ZzP1&VU^_A`9z)I3T|;u>CvG{MboHs{h344~KKC=3n4{ zCd}2iX7dG|*{rEs?|o>M;$U3$)L|zVN5{47)9orkJ6^u8aX4_E+eJl4Ub&`5S+%uB zm6=(!g{hCJNR5?ws+t<}%;{5RO`XOpDzC=IvUK?pwk2xISe7hP6Om_QXWO!68N2%O zt;@Gd%CjHZa%k((qq|SAZ#sVV+e#ovZ&%tr; z%IjBG9(;WFKvVwqgI5pV-TCu}UFxgAjvEF6^Vpi1o+>(gOl-Dl=a3QV(YV0sTFNXb zG{xdVl6xl$yH&};1&ZzBGJebMEcnEFda_PnQOAdc%sdiig|E)sY&>jzme00O?Z<`# z&OH*`eQI9=L{2Jm>*vU^b7f=3wynm?y~fAA z#>2hN%e~IWz0SkEEC2ui02lxm000I4VBke$X`W~_W^C)ea0X>WQWFCq3`wrnxgY_P zQ4kb4qmgjLIhP8>%-M`So7E<9P$(!0Ij{I=_LI&?7Fq|k+B8Q6l wEKYdG5aYy;7Xe%}Fad!C1OONSphUm{0ZNH1C5SW$AOOh;ICJXU$uk51JJ+4Q5&!@I literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/comboarrow-a.gif b/data/themes/clearlooks/clearlooks/comboarrow-a.gif new file mode 100644 index 0000000000000000000000000000000000000000..b4a2cd6ef32f0d6b51e0cd4698d48dd1240a9626 GIT binary patch literal 441 zcmZ?wbhEHb6kw2GxXQrr{rmgxpWlCf|Ni~w=kMP?fB*XV`{&Qkoj%r5n*E=Fp}I8t z`RjYnpWl1__}>5j|Eo)r|Ns8~{r~sxzrTaPXP{=FMxf^R?_a-v4%GYl-uvhG-ao$g z{Pr~g0fGO&L24PO3>=ZoQ~b%o$iTqKpaT*F`H6w;nnO#0hl-pKS9{UP7$rVWjw6hn zKC5r=DQQlOP>ehAocW!NK*&lKow)T|GXl12Pxn_@(8pBE?)#@!xV(U`fuX6RAuXd_ zgrQHkeNq%ZAESt9|8&Ob42)G7bL18;krNY{@5Co2#J! zw@#d8|KXOyhYyKMu$-)#%EEeq<@DuCEv%9^Sa09C9p%Y(`ym_m6V`_d_?|xDmU{Z` z?R~x{JZ#^dNPpw$=Hrp!VPO2n?QznvnN3DODW%}T{5^aE%3du$mUJ9dbZ=r{um%9l Co2sDz literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/comboarrow-d.gif b/data/themes/clearlooks/clearlooks/comboarrow-d.gif new file mode 100644 index 0000000000000000000000000000000000000000..8d50d86a37b29184e9d590c351e319ea281e445f GIT binary patch literal 432 zcmZ?wbhEHb6kw2GxXQrr|MU0n-`{`#{Qmp<_upT?fB*UU`}fb^zkdGy`SbUWpWl0Y z?cV)s{}~vzZd&{N^}XlM?>&Ef@A>_E&u`y5wr%bI|NnuSzkdem2Wor|0zea<-+TY~ z-g}^$$Jd_UzxMq0H3ljJM`ZI9f3h$#Fz_(wfCNE)VqiOaptHb3rAb1#tLS8mpTo(n zr9qrNjMp4kXYo|%PFp|2o3UM&Y0K9nMQ($p@6`fY#X32);awics zNfx#qX14zRlwLMAsVP&~Q`p&g=gsHsoz*diV*#(%oD>cY_GR$_yLDF}MNUvqPEO#-%NHqv vT=Gw!a($Ffkr$HZ{>lC07k7$+g9nGk2Dy%E22QPzA4@t8E4nu^FjxZs{^6%~ literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/comboarrow-n.gif b/data/themes/clearlooks/clearlooks/comboarrow-n.gif new file mode 100644 index 0000000000000000000000000000000000000000..5907752879c10bdba976b3375b34bf11ccf27090 GIT binary patch literal 451 zcmZ?wbhEHb6kw2GxXQrr|MU0n-`{`#{Qmp<_upT?fB*UU`}fb^zkdGy`SbUWpWl0Y z?cV)s=T0AMDb4=Rz))S9{rvU4=g;pwe|+!x{d>=E-~0dne|2dx(1`D!fu;bpzXt)J zInVFCe|+yfP|f3O&+lJ*e*2n$fB*w^fFrUoia%Kx85sB&bU=b2KQXX9IM7z$p<*P{ z-&J%n#!TWQ_p>5SAI573T(5Yr?UUfC(Ai|7m1yX;VOyHPoy`u)GtRS@9CY|HA)BqC zs=m2Uv_YDcS-QQeI!%;KnuTpLGuyOjF=7)Yv&l?hTfknE&d#p9Vx{tw#ZIEjI94ey zTh_|K!M<_Dc7g3Ro*aAkDj$?RDA+0}D=5fumh72p=ovzSrPxQt85C7?s2 XZ~;g2FNL5xJ3e|&?04=1`qvr&2e-AK literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/comboarrow-p.gif b/data/themes/clearlooks/clearlooks/comboarrow-p.gif new file mode 100644 index 0000000000000000000000000000000000000000..e370d0ecfa78eebb8a143b0741c3e02d77261605 GIT binary patch literal 450 zcmZ?wbhEHb6kw2GxXJ(m_ikUicm3ME%h#^mK6mZ`q;VS z$Icx-mYo@O@A|oWm(Se;N?ks7?fkK8r;lAb4irz$PEG#Lz)+l;d~Dm=W2g5XJHGeW z;l0mqUpset@44f9&mGC zk*@qw2LSM@*8L zt-YPUy^TM)rJbEkpkqo7uOu70py0%bGv}12va>TRUB)nnJ;zIkbIEcc_KoE&8#gXv z=in6LDEAWP+$GGw#mTjct67rk%vmnsbLG>|a&w8C5s~ATTPS(^{;m65cSOCo<>k3w zN!@>SSDHs&TKdJuPx7lJ6~6E&{FVMEks}e@#>~MdEx_cmBmeZ$W&z%!2^@#Q+xR4m RvyN~a?KrM1-o(IQ4FKC-n==3a literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/progress-h.gif b/data/themes/clearlooks/clearlooks/progress-h.gif new file mode 100644 index 0000000000000000000000000000000000000000..01c24a1bf7135c921bb6fdadf92e2eb6cf37c69b GIT binary patch literal 281 zcmV+!0p|WkNk%v~VJH9-0J8u9t-j8Co~?VDt$UWOdy=hlnx%7=rE`*{dzz(tmZf`= zrG%ojgr2p8nze+Utx{oYEC2ui04M+x000Ee@X1N5y|{wSyZ>OgNr1xyCu1^8>$)b2 zu5ay-X%n-x+vK~Rk3kAF0!E{-g-j+J%SDrP6da*TqcyO_3bhTAASsA)$K$G5fEHWJ z%eTA%7tRIldT+oM@cU7JerzOsfqw%CgNJO1euYtki35BCk(CIPj}HKW1(cKspPrzJ zqa;fP37`g`QL3!23#dJ-1gZwN1W~rQx-PUYx4F3rxlzNq#=F3rH3kR7#LPm_(!Vdk f3j_oQ-QM2F-QVLq!3XH+=~3$KLK*P!@eu$!^VNgA literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/progress-v.gif b/data/themes/clearlooks/clearlooks/progress-v.gif new file mode 100644 index 0000000000000000000000000000000000000000..a5e201f7087bce8321daee9838d2cf0c24173794 GIT binary patch literal 304 zcmV-00nh$NNk%v~VG{r-0J8u9t-j8CnyrMQwR@JWgr2o~lC6ZAwNhbgdzz(tmZfu= zrG%cXdy=JdmZfu&rF)*OEC2ui022Tx000E#@W@GP1vu-CC0N8`1mrLXXexN2@jPUp zs@@X@#yHalK)5d14&|sVf+qy zhbN>>A}=vXH8(jzLo7frP+AX1wn=qcR%5+Y23J{OVnbeFEKp=-j5}#-ZD&JqbIOH% zczSNxDSm*0iq8V4QiFs5Dw~jHnCU5$f0hI9@B*9ko;>QIBPFRmn5s0(f*w#EKfibT+P&-7_O4r6U0GdRSR54@<>l#h z@A|o8`?mgPV3;#&&Xj3Wdir|K?c4hN@xABw?;YEshI9M2 zK7V}g`TcvxcCFpIYR-Qk`2GJo5Pbgr{PFX>+tzMfGzG{%cX%%Y4xspxg^_`QlR*b0 z53-YiH6}r+FC}x{3l9^~08^J$7S}iGv@V>(b(CWo`;(6jZ#-CzD>>u{@oo%!Y$R#b zsU5UbVW*k0s8E8y7a_)5jWapa4qoeDbBdvTnh3|{iR`^LN-S2I+PeCInjM|$iVW5O Ds1jjy literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/radio-dc.gif b/data/themes/clearlooks/clearlooks/radio-dc.gif new file mode 100644 index 0000000000000000000000000000000000000000..2103534d376fb867575332c4502502c9ffef177c GIT binary patch literal 362 zcmZ?wbhEHb6l4%&xXQq=c3#i-_wV1oe*XUX^Lw|i-MfBm@4BVuP9M8>{akfv@zQy7 zTAHel?b~{6*Vg|G3_X24TQ{wJ{`lVW`}dA*TRUggl&!1g{0D;H|JN>>a_sot@87>4 zJG}S%=kGmTEzci6zjy!M-fe5IUB7ni^0jm4&mB8{?Em-g=ML{>pa?i3>sI{9!pOkD z$Djie1o?@9t=*x$z(Yr>|Ab;v6Jvr}N6O+PCl@7F=f^h~JXusvA5BWk>Fn@Q5oiif zP~47@C;H3M8dvIlFsZ xgjvLD`MEi{>Knb-QgZVP#fn{dc~W+#q{XnYNcFHpd3yW$mw28&y7O-?La%JL}Zi6n;*zYvR+rnatrpk{ZE Ix*~%$0PCk>*w#EKfibT+P&-7_O4r6U0GdRSR54@<>l#h z@A|o8`?en2we>#(!<<=jrc9gC)7SI-@xABw?;YE=cFwdZTUX8b4+OveuU$0dI}m*S zZfRp_X<_;N@pDZb&Ar>!Dk>=c|Ni~l;k{rBDI^?`^(+2lVPs(7XV3u&g8an5)^eb| zz(Yr>|AgY=MVuL0Jxd-tCHbheH9vmA5y+<jfWUvMRaesJ! literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/radio-nu.gif b/data/themes/clearlooks/clearlooks/radio-nu.gif new file mode 100644 index 0000000000000000000000000000000000000000..498ab275cd8005debe4307784b63f74d1020e386 GIT binary patch literal 226 zcmZ?wbhEHb6l4%&IKsfNc3#i-_wV1oe*XUX^Lw|i-MfBm@4BV;uAe)$Z|kvLTmLgK zJb!%e`TcvxwyoW|YR-Qk`2BzFqAA~j;PdzAkDu?|w)X$`@8=HhWxxRxf3h$#FmN&G zfaF1TGO)%kQ0hy`ocE%_L{PxgeU`=bjXJFp=Xf6Fn8yC(qr)2y_Tx$pIYPV}10Op{ zT6MOtX$H-RnLUYv(}1I{v*GOnAD+olEZ>y7O-?La%JL}Zi6n;*zYvR+rnatrpk{ZE Ix*~%$0PCk>Txx;(GR#Am;L^eh7CkrD3gD8UzND$;F2DX+1T?HOGQvD|s z8JW2n3|gL~CNHp%5jp#`;-rt$MCK<2205KAyy_bz7}&TrsaYKnahb$^_>jO6O$iqT z5e{Y^ZeH1Zb`Av>MkPT8u}(P#h7`soCH6MiY2Cdp5+dweOw$?U>l?kKQn>O8ib|Zt c*;00DPTDo`L(rf3>ojZN(-0@?__U*lP{@AtCK*rW% zySDykU^oY2tlhe5&emmf)-IZI?C{>Li>91AzW3bWy$pDP;!hSv1_mAm9gr%JoeZpT z3d(&cne$#qSO^niXG88&AD+oF+-8d1EhiQ(J@z2yiQ_I7R!etvZC(99&8}{BMFwjCB0W~z literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/sbthumb-ha.gif b/data/themes/clearlooks/clearlooks/sbthumb-ha.gif new file mode 100644 index 0000000000000000000000000000000000000000..d0b03ccdfb3ad847d1fc1efd74f8cf71ce81e268 GIT binary patch literal 276 zcmZ?wbh9u|6k*_JIKsg2{rCIt-`{`#{Qmp<_upT?fB*UU`}fb^zkdGy`SX_2?CR3& z=dbTQe}3=(|Nqsc$^U=<|Nk8XzyJOY0-u38fm+^!08sDqd(UrQ`~Mpx&j15DAO^@T z2G*GiCikRd&hlNgZp|!>v)^1kE8G8YJ3ULnTbiRlLy}8zRygy4nI0AmoXg5M+2U?$JBGb@TaT6i?3 zG&;_Ho4569^TH&H8QSbkjR|_~;vLR5dFxK|hguwJx}f~8pg=5CjE9p)ti6?|qnk5S zoR@dv$@iErMVxe}q0Tzp)TD_5>wy+SfnYV($@+cvB1+@;814FDj9 BgXaJM literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/sbthumb-hn.gif b/data/themes/clearlooks/clearlooks/sbthumb-hn.gif new file mode 100644 index 0000000000000000000000000000000000000000..3bdb094572036fb5c69764705fddad4b359c117d GIT binary patch literal 278 zcmZ?wbh9u|6k*_JIKsg2|MU0n-`{`#{Qmp<_upT?fB*UU`}fb^zkdGy`SbUWpWnNG zt)(=(x-|Rw>wC|i-+TV}-t+tS{{R19U78Hk_Wkqs_n+T`08r!ed+&j=kFPzyf9?70 zYYZ@;17d*eVql%UU`tO*=B&U~>(=Zt2y|c#W;nrMdfG_ctw}-EV~v2ODA#jQO&+bO zjh{Vxr7U|~QxZ1v@Wii|_;WOizpeY>fqgO@Y)sW}n`NasobArPd(H11Rly;_(ah0N zQ6b?iBq+hh$tN*s0^j6moQ;B#{QPt0&!4+^Uaz2(0KdSBc>=3fu98XwC|i-+TV}-t+tS{{R19U78Hk_Wkqs_n+T`08r!ed+&j=kFPzyf9?70 zYYZ@;17d*eVql%UU`tO*=B&U~>(=Zt2y|c#W;nrMdfG_ctw}-EV~v2ODA#jQO&+bO zjh{Vxr7U|~QxZ1v@Wii|_;WOizpeY>fqgO@Y)sW}n`NasobArPd(H11Rly;_(ah0N zQ6b?iBq+hh$tN*s0^j6moQ;B#{QPt0&!4+^Uaz2(0KdSBc>=3fu98X{ZJUl`smv^eoMzEt!4oWno*8Csaceft@X_jQPf7o< z)}rM^z`~QNYiGD^DDY4zu`y^*d+f)1^@fvo-!qm|ubmUj56nstCVo4scUPD z;^=NDs`j_AiuZ0xsmmw~XPIJA-d^m_k><`OnKgfw6pwYg*rv@}HmQkdGAM0l&{AZu F1^|ypi7fyC literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/sbthumb-vd.gif b/data/themes/clearlooks/clearlooks/sbthumb-vd.gif new file mode 100644 index 0000000000000000000000000000000000000000..7f6a02586f5abe7937341b698432c8de65550bf3 GIT binary patch literal 262 zcmZ?wbh9u|izrI@1H-u_W$$uW82n#|Ni~?{cGPpe}8`a+WXJX|NsC0{`ozS=GXTaP=OAJ z3$lxWwL3wjFGVsoW7V=pt}@eJ+JA z#B@d>V9LIAO=`y)COah<-7=o|;oF9@YY*;tt$X-!#_OE9oI6X@L+yAHqd6^0!wQ`F zb9Li+TTNp+J=nP;DgyeOM7T1giW>E}y9-_Bii_CHlJHN}72UjL>t?kb%8Cru0R7g6 A761SM literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/sbthumb-vn.gif b/data/themes/clearlooks/clearlooks/sbthumb-vn.gif new file mode 100644 index 0000000000000000000000000000000000000000..643096224bc6f5c1cac4deab56a673660a8a017f GIT binary patch literal 271 zcmZ?wbh9u|nqR_t)>MOOt`j_pjeSe|+u#=kGx9{Qk9;((Lb_zdyfy?fvKH|NsAg|NI_E|Lc1U zFrWisfb3#mow6X9GdZ+NDKa(Z^|rJyg&RgZbHrS(h(>oDO+IWWz{k~)Z<=hQz~=m@ zAtp^t>{ycV1py|{*E!Z5S$sCDThb2uigFcBkp3$-W&eZCHS3ODi!yghsL+md;!Ta` zvaO6NaThE!Oy=*jOz8FD;EAaTncODEohwt;YQ)oD>akE#%we8XaHgU7_8mL7tBGnd MDeYm>Qe?0O0A%-t6951J literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/sbthumb-vp.gif b/data/themes/clearlooks/clearlooks/sbthumb-vp.gif new file mode 100644 index 0000000000000000000000000000000000000000..643096224bc6f5c1cac4deab56a673660a8a017f GIT binary patch literal 271 zcmZ?wbh9u|nqR_t)>MOOt`j_pjeSe|+u#=kGx9{Qk9;((Lb_zdyfy?fvKH|NsAg|NI_E|Lc1U zFrWisfb3#mow6X9GdZ+NDKa(Z^|rJyg&RgZbHrS(h(>oDO+IWWz{k~)Z<=hQz~=m@ zAtp^t>{ycV1py|{*E!Z5S$sCDThb2uigFcBkp3$-W&eZCHS3ODi!yghsL+md;!Ta` zvaO6NaThE!Oy=*jOz8FD;EAaTncODEohwt;YQ)oD>akE#%we8XaHgU7_8mL7tBGnd MDeYm>Qe?0O0A%-t6951J literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/scale-ha.gif b/data/themes/clearlooks/clearlooks/scale-ha.gif new file mode 100644 index 0000000000000000000000000000000000000000..68b27d531c75267cd090688d09843779c0d13e7b GIT binary patch literal 474 zcmZ?wbhEHblw;s$xXQrr{r&szuiwA_{QUj<=kH%XfB*dX`^V4cOsbyKRekUNwR^X( z-MfD6+U0ZSP9K{ysbx-A%e~v@?p;53@AA2x+Txzd;+ER%mdfmw((L~X49{QRd;a|1 z^T+p|-@kWk+uHv?@caM!_wT24RZnTF?rAITX)1pI`riBJ_ud25Jihk){j;S^HhkkjJQ;{5pO^Vjd+ zK7IKnr1)MS%ppJ_Ai<%DS&%DaK|+E9hmf4i2LZ)HO)bL@7T7r|AFB5|M#!&y?=i1Jy87dwdeP*J->bJ`SoiI zs6g>23nK#qH-ipH7-S~{>)8jBTvIaVy_nfK@yWgdo#PiZ3>_I*ERMdhmf>?aDcZ_4 zN##O@LGihar9XSZv`>Z|PR!)k7Tdiz@nzjv-;L(lg*)!&6{b9zasA~7^WUEeY<@J9 z^A|S@*VcFN=kQBN@H6xGOe|)eGNpeavjlSvv*fJ#vu8~co+>OM(90|!DUrj@BFQpu z-uz-^VU}VR7WPdW=6FeQupBwM=g5)6$E8>fpWTzg!OFpT<;t~dmv7zRyu*=mkL})* g$M?86Up#v9ipx{^-N#R#zkD&((fs-AyCQ=%0EnHaQ2+n{ literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/scale-hn.gif b/data/themes/clearlooks/clearlooks/scale-hn.gif new file mode 100644 index 0000000000000000000000000000000000000000..5e1c0e909e46672bfba8c3b5b55b67a7eddf0d58 GIT binary patch literal 477 zcmZ?wbhEHblw;s$xXQrr{`K?s&!4}4{Cv)&>N#E2_wHZ2cl+AC>(}mGzIN^MxpSwF z&6(6Pr>o`O{d4zjpSySc+`Y@^dTNV%DvMicvs)^&TS~M4GcY`Veee16d(R)=dw&1k z^V|21ZCm>v2!8*c(p5dBt-7bJxTmT3{p)-0pWk~ARP*@S^ZVDH-@f+z`ZWe}fFrUd z#h)yU3=ConIv_!ipBUJFIdm^_(vj*vvDhi%rN#UUD@>v!%k&x<6dGh>w?*rS8JwDS zbOP5>;R6Y`Zf>9Rr0w+EC10c_YbLVP)Tv5JsMa;K=QY<0hzQF{PMkEcSw>EB+KlOw zCkY4%%Bo38N-bJ8OKRFmxy4J@NeKul$x5lKOR-9A-8GGM@7^7|Sk+ktloVxIH4dLX za(KVoJ~?&iZLHE7>H>-ivb<~>Y^P40o~AL4?FAd}!}~`SSY$Q%*uH#a`~KzgcTKj> ze}5>{bUc61(9F)ptK&u=kMP?fB*XV`{&Q!KYl)EQuV$2*Y4fE zcJKPNYuC?RyL|54>0@&ywan>jnbXzMQdxZO{<(X%&)vIz?%w5dJ+;L>mBlT!*)5gX zEv4E285nw+s-M5U_x$<2=a26_zkl!f?R&?zt^E%KzyH7g{2l~ezn{`qJ*BI9N?Y}m zrs|%y;-04B_s{RW2daO3?fLy{&u?FQe*GE)7T}01rudVEk%2*mK?fuV@)HBwKZm|# zXB{bXzK3l`a;!X0EY%cXU|F`T@v4&wt6#H2gwHcQ|K$vhbMuN#Rhk+crr%~2<5jbp zznFuygjGyPNQJedkyWFUMNCq%y|YuUvtL|Aj*X3V)-1MJViGghhn#xi;R zrAwFTi|Og9=*zP!@7cpHFTZ-bg1mz2@#6-&wjNeEcl5$hFNy{c%a zc;dLiLopp~6-7m(*KZ%b5z~EX#Hn~o+32g7_DiK-kG(oP6b?0UiK+;x%rHz&bZ#}~ zQA)8;Y;0=fN{gA|(d2ZjUnH$1Btg-YMTk2iAY$hN)mBy!9hU}&MNF++y19prL{3W6 zImczu$hDQB@!16~v4*IGgo8{>vwSC;rFu=xXl4)GoK}0G;qX=Vgu`8LrC1oO0cF(c ASO5S3 literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/scale-vd.gif b/data/themes/clearlooks/clearlooks/scale-vd.gif new file mode 100644 index 0000000000000000000000000000000000000000..da58a5d46850fd2c2e564bf749758d0421f82dda GIT binary patch literal 342 zcmZ?wbhEHbw)Q^|{Qm#``Mvi*!N=F0-@o?!_O<8NuQ8wk z#h)yU3=BLBIv`NiE3Ci9eq?# zWD_>4@$n_a1yS=a%{}_?hTW=ZudeLATO@zE{prQG)28?DsOh_Bt5A5twSN8j4+82n z-U7@5A{`w9-QE&?5-b7}SthnjQkM{r=w*@U?3ggyT2hilQgGR_rQWQ|)LGYhOR`GN z7m?(Y^yb_k#k!Am539En8z<+nlgDw8b%adU8cfBN#_+egE%zdmVbsjF)`F)&yI0HJuJMF0Q* literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/scale-vn.gif b/data/themes/clearlooks/clearlooks/scale-vn.gif new file mode 100644 index 0000000000000000000000000000000000000000..8068c5967220d2fd7ac6ff9db55305e75fde0252 GIT binary patch literal 511 zcmZ?wbhEHbU)o`-MfG7-tBAmu3x)%`P#MX=dN8o zckcADIg?uE^tH_CYH6t~zIXfFz3b=hT|U=STijDw+)|s}QkmUSn*E=Fp{J?(`RjYn zpWl1__}=sT_nzOrcWm3*|3L8j|CGM!DP7f5+N!5CRrja&+lJ* ze*4<<>(>~F1&+uH6@RiYGB8Lm=zs)4eqvzz=Wyncla7==_e0hrIaZD*R2c+jM41M2 z3Wi)|*>itGnWRSkp{JX!FOU@ zPT^b`O_}EAJ|U6GGV|sym?%6~cAl)(a+#$<>gozhW#u<*S}7#FPL@ShanByv{cF}~ zAJ%4-J;r)WNK$qE@y(mGWwqCwJ*vHT&vhYH6$Kp~Rvo!Vj~)uC-D7)nL7wfkkjgzB zHl3S_Is!UE%E}4?@1rCHG8h&x*8Pi;X<$fPc(|40zp2fIrbO2cC7A|`0tKcP4neE7 z7KMY3%mNC|%S0+2nmQ(PsJM6tIHsMN#p}0h%E@3SStd>)wmB?bSC(I#&nse}aY{sk RnN?zn(G0JxT2~YptO2d!&msT- literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/scaletrough-h.gif b/data/themes/clearlooks/clearlooks/scaletrough-h.gif new file mode 100644 index 0000000000000000000000000000000000000000..46f1a922a95a4b2e2100e5b3bf3c301cc76cad81 GIT binary patch literal 87 zcmZ?wbhEHblw;s$n8?7ec3#i5(|i9jFdW;qR`DkbBLf2ygAM}_faDpNG^X^gJpGn` q@tlyR?#=gP`uW=)dBiz4EPHioQyTa2O!w=Ntc#H)lPSD*PkhR P69cuJHztTMFjxZsCj2QO literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/sep-h.gif b/data/themes/clearlooks/clearlooks/sep-h.gif new file mode 100644 index 0000000000000000000000000000000000000000..26acc534e2d5c9092eefcf61be12ebc5aaff4494 GIT binary patch literal 40 scmZ?wbh9u|6k%XuXkcKtclq4^-~V+OfB+=Iz{K9tKl9+*|6B~#0QE8qo&W#< literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/sep-v.gif b/data/themes/clearlooks/clearlooks/sep-v.gif new file mode 100644 index 0000000000000000000000000000000000000000..52391a83f7d885c7a3387ff6116d9bcb97e01917 GIT binary patch literal 40 scmZ?wbh9u|WMU9uXkcKtclq4^-~V+OfB+=Iz{Kv-v;5@ixm*m^0P&Ix4FCWD literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/sizegrip.gif b/data/themes/clearlooks/clearlooks/sizegrip.gif new file mode 100644 index 0000000000000000000000000000000000000000..7e30f93023c8e9aa8ddc92e75768f86a12c0c889 GIT binary patch literal 77 zcmZ?wbh9u|6krfwn8?8J{`K=?+t&X7|DS<@K?jI|q5=#IOlmFtE2|G_9da%-%XGY2 g{Qha8!Z$~iOsT|8S&OO;<-A!{)EoXbih;oz05S_5+yDRo literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/tab-a.gif b/data/themes/clearlooks/clearlooks/tab-a.gif new file mode 100644 index 0000000000000000000000000000000000000000..a4f0ef6860e81e384da6414a36f37541f2d10b74 GIT binary patch literal 536 zcmZ?wbhEHblwpuyxXQqA@BX!Wx3As1e(m1nYu9d{yLSEDwae$Ooj-T(^09lj&)vIz z?%w5d_s#=E-~0dn|GoS7?%lq3?)Y8?Y63@O!xVqAFfuTRGU$K=L4IOj`*)zLz(Yr>|HP6Y ziA5IkFRb_?xyr=$#+tIzXM>!C`5Txe`cGyYaPR%M#By@)^2KqN?XztbIPZUdxOLWZHaq|E8lXn_1S&aUR)v=){(@n+{)=5|rC_>lO>wq1$&3-D44y zym_CM^*+<9w{PCRW0e$;d&kVg{PO4bZ*N)u2)uaeJw5NBeJwk?luW{hc(!6zu{Y8Q z4M|74MgJR`d|02v#v{j5AQO4u0MjH9@2;L5mk#WipyWEQ$1`}D?`#3R3X6mVjAqUA zY$}h5+-i8{&&)1o^WlO*M(_gmS#G>srCH7FVr5>o4<0mxuZ*4T<$7W3YesJGORHkD IRX7-|0gH0e;{X5v literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/tab-n.gif b/data/themes/clearlooks/clearlooks/tab-n.gif new file mode 100644 index 0000000000000000000000000000000000000000..f8cef6ec5235495d2379f797f189768f01cc2ec1 GIT binary patch literal 549 zcmZ?wbhEHblwpuyxXQrr|MU0n-`{`#{Qmp<_upT?fB*UU`}fb^zkWVvQuUm!>M32t zbNX85bhWfp7WdQ^_f!_Q)MmF-X1A1P|7T!mS+upKsrdi@|KC3YjR5L>4+5{>PXTId ztDe$S-P2aw(^UNY_O)Y&j|HV>2PI}RPysk1o1yrVg^__lm_Y|52=WsH+rI;y9WFXj z{U;WAcr3D*e__QJPodsrH{Jv%?PSqwSZ|@gSH1Usv4_ycp7ZI3R&xBVQn8H>Hu1mt zpBZ0UQ(czJ6faR#FD}v2#njhPBd*9VAjTv)rM|m+&Rj{RX?$Xfx)-&~5??-h*6PK4 zqBEJ87co~YpSP`hN0lPq(mgvQw=o|(x_po1(Zvc1%Z{-gIevNj$>Up(Dk{j$yuo~# z_2}`lmu@jD%E^lzmwNdA{f9>nncsg=l$8}@WBz;m-y_-A-`CG?tN;1!rg6apMaQOp zVsbGV3N1{0f7k>J91S*L(ZAyPUuPwgv$6tl_Ev literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/toolbutton-a.gif b/data/themes/clearlooks/clearlooks/toolbutton-a.gif new file mode 100644 index 0000000000000000000000000000000000000000..a6ec6f4029d57f391ce5dccc0e5e91050872802a GIT binary patch literal 554 zcmZ?wbh9u|lwgoxxXQrr{rCIt-`{`#{Qmp<_wPSHfB*jZ``6FkKY#xI@$)&8s^@f7 zPiZQ?cKO`7)5qpaYMIm5GN-GhrLwrEwz#LVxTQ9`r82vvG`qSqyQQi4`RjYnpWl1_ z_}>5j|Eo)r|Ns8~|2qhN|NR{VJ_D@*S^=~MXvgy@K$F{mhFABr756k1zXxf&_WbrW zke=TlO$<1JBeIMRhy(Hq1KU3b=fh4qQvJuRhE(2Bir`N=6Kml=`Pn z(iawyQDRh9QeMC~f5Os*3m51M3CS#3pu)6RSy^QZ<90?yeGv&6rp=p_4{kbmeB1Fg z>y%YDGpU~4eD2EebNV_uGFQ)CIC%BmU41RB+p5gxm|0#uXL@nr#VdVoZ5if|EYF|6 zP<{RUAM>%LH`0>sG6=tUH1k6HhdbS(%=}^ofej9hrLT?Tws<^n^wTQ z0$*8MSY%8TE?j6@-L^hju!NWU+tFrr8M76!r?=@wi>FCiR5)&5cXxNWtbu{T^~U@A N8=E-#fN#?f?J(zyAhm{Qe!N9jFzk`SW`a0Gjan-uvhG-UAgs zzV`h7wdc35{r~=*fttV(*)Sat2jmw9wtokhHJo&$`rRiOC}mpB56DQ-SQwyoT|jlo zRlhB_-=~~d!lJ?O+Ol996VueP2A!QDECtmy@&Z4;GnI(d)rm>8)JZTiOEfb{lt{8N zPnMKqo<4QbjLFOs*;p1Vl4N6BBDs)d2}=nZ`_lF73)!U>tzX1e!oGXm?v49)Z{4@+ zz|ms|j_l?+diuDx54$vnG&={+wX0XJ+`3l6!EyEUgZrniKYLtq>H7T}k1xM}e@}+@ z^K+hW95T;Jc<=w^`1^wK%<;qr=5?PL&S~#3P}p0^`@{0ZgM_4`Y+}|4b2>IM&t;dh zX%O)&dcw@EC_iV(WQIfS{G4&eS}q7J^PaBzQsc%-1{X>H`PPl!cy=Xp1PXXe){0$K Pa>`gGV6qGc6N5DXv_IO7 literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/toolbutton-n.gif b/data/themes/clearlooks/clearlooks/toolbutton-n.gif new file mode 100644 index 0000000000000000000000000000000000000000..b3a1949f73a3c5168da9ea2f0b17af755f34ee51 GIT binary patch literal 557 zcmZ?wbh9u|lwgoxxXQrr|MU0n-`{`#{Qmp<_upT?fB*UU`}fb^zkdGy`SUrGs^@f7 z-@AWpN>lN@+t;pLK6mc)u{o1k=Jd79>1t`I1PY$(sV(lQEN-dIZmG;}Db21f&2DKb ze*XI2^XK=TKfd?;{=Mh7@BRP(zq&N}`){B{-@gN`16l>N?DKmNc>R7#SM`*(>M2dt zJ#EE3O~vnD-+TZ3-g}_l$Jd_UzxMq0wg2D0GoS!RWS$O)1M&+4+rI;cm7R5@`j598 z2xnQ%56F17kaMDk@|xb1+j;KMdKDqUhMtT<4`%T#S>NFBQg%hE!NOoqh3n`4Gcq;R zGnq;VE2=d$scCdKX)rTubTMhPRcNv@&(_proaunA{#r~o;_>Xwbt!j$7U)nt;l|6&zZgF&mTU&W7oy&H?EuN>z_U^bN#_hc2iy5 z(*_&{>>M(0-@JMK@vSM3o+1awn+LysK6uCQdup|j;MxDc^msy4@(=*?+Iqm-Rm1b8o*t=Kp% lH)?zK{UD9k3{JhfD?Y!v%6;%)<1PUvZaJTd4fhootO1gB4aWcg literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/toolbutton-p.gif b/data/themes/clearlooks/clearlooks/toolbutton-p.gif new file mode 100644 index 0000000000000000000000000000000000000000..bed50998c4b782f5100526e1f6e13883a63f8ba8 GIT binary patch literal 527 zcmZ?wbh9u|lwgoxxXQqA?C{q2ub*E#f9~4pbLY+h1tcq*~OXJ*}2KtnaSCy$>;X%tuD;21_~A?7w0AyXC@b?CLi0j_SosY z$Byqkc6jf((|gYy-+S)xUIr=yM`ZJKKpc=?7})+DIN|5rcIS0j&xs7NmZM_5YD>0$_~sPUx?lXo*WdH>ve{T!xmlx|+A=Gfq69-5 zn;YAj`zN%qO7zN2nmT1--!uuSIdZH#jcjsD8&^ya5RhVHUCy>)`LYd5is z&YhbMY&o!2YN!0ZlbcST*v!VyFC~ANP5RpDGn=I4#l_dNos>B#|43ej?Zx9qe0-Om zv$4ywKmPRT$>%5H?>;@2`S+Zm=tcRvhUR=3hYQvWNeNC>3U(Sb5*M3Td1a-to=n*2 ze5g^*v4rEMAG7;JS<|j7Gd`xUvx}N6m~*o*TITe%%;{=r zsRW9j>!~g7sVr`(&2Fj8ZYj;KF3oOfDy}X~o&wa^2Gm>K(^lNmRQ&w*H3n3m1LA`0 zVqm?bkl>P%Id8e5oBQj11~QVD90hpR3EtXgY%M3?k(k+VP^M4a=3a&13C0!9d~>%i z=HFz&QfoQi?{yZdWbj?tLqGDXc8r`_lZ(<)Hsk{K9cgJ`w({b`^y_;dLo~ zQj(HYzL8duUba%=;%3ElZADSc5^)JWt>Lrgh?ymKu8gmhSm&4%y4v1KOtdO0scq(L zDbam7el?c${tlu{!JB-uI;EJnS{g!1PS|lVPEAP+E3@U~oIl<6PDT_bE60&fpFeT1 SGJN3p_507?Ki?G@7_0$PYlaH| literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/tree-d.gif b/data/themes/clearlooks/clearlooks/tree-d.gif new file mode 100644 index 0000000000000000000000000000000000000000..d353aacdbb6ce8c0e2f33d5f53cee021774cbde8 GIT binary patch literal 509 zcmZ?wbh9u|lwgoxxXQrr|MU0n-`{`#{Qmp<_upT?fB*UU`}fb^zkdGy`SbUWpWl0Y z?cV)s&tKnr{`}ta$M>G!zxVw1y<^+f{{R0UsO>vYFHj#)=jZnz0M!2a-uvhG-ao$g z9;ov1wdX*+x34i!88{-Frvu`E{KCNY??6X^hmKU|q$NcsbG%w6om4Sk^;kP)WeF2U z0F%Ot=|kLC;pd^)Ww6#F?4JtC_?rgxXt}yPKNYCp0m4 zGP5#EOq<0zbLNcZ>78uMY>U|>SQf8bxrA*cTc_kYHuja9ma?-iUCF+wa}Ud|16z*l z+{NC>&T;I_+0(~3PD*iH=HR(@isQ=Z+dQ4Oq_6REJiI1-{RPM4PG0H9oYI`Uyq`Wi ze*5WSz^Bij`FLfXvC6zy&uGogY^hMPAwbcoflJtM&Wi)h&FrF*WhYKta8}~yH)z|# z5tMS0T})o3>VqSr_jCpO1yg=5Og+KhDdw`|L-99{r7he_zct!)c76*UcY}1)cgA0`{(!GKfd?; z_O<`NK?)hD3>=Zo(*bcneqmtycfdW#Lr1FLrM>86j+HD|tB_KmhXP-RSoPVUm2!#S zxPI2C3vK>c_1DLS^CgSX%=0gQbl&#kSC1b(eDX8yi5t-cC(%Ch+ zL!=-`gkdVfyhW3nm(1_yTgb3VM0DZ0b@Le3G01W8^NBL9+r3+i@xZ}7yH<#b?-f6` z`}moI#}jvmGo58Te)an08!NSn<)=f`#2wrVs zW;a_9Qfc(GahiVUBC7)rQqE2{vD8U$_^hVuTf$>y@W5b7V;~EUfPkx(iN-26H))Qy c45nJlDR literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/tree-n.gif b/data/themes/clearlooks/clearlooks/tree-n.gif new file mode 100644 index 0000000000000000000000000000000000000000..d95032665347f3e2e2a99ebebc0e3ada11eb357c GIT binary patch literal 528 zcmZ?wbh9u|lwgoxxXQrr|MU0n-`{`#{Qmp<_upT?fB*UU`}fb^zkdGy`SbUWpWl0Y z?cV)sEv4DjrPK`S{xN``4b|zQ#Z`;D~IJ4u}Kt3j^Cf2d-of9jX2!okb^etkiptEeYZb zVGLQb)N3sR)3gQ;3(n{>4;rL;#f+CobTi1Lv$IrePB=3o=0k8#b(F+rXy8DlZmrvdeHh;NW|FjpO0<7ksmXpUXbx z=Xn2E_Q^Mnk0<$MKXS@)^2;%N5zm)Dke9;1#>4TjvAuy`*{J5gJI0m{IX$NfGd?al z+;c@OM~0J;rG-P)yv}2%po@`!V8AgO&fv7O9BRrc-2zUGX8!XHoF9ltElNKl@J7r- wV^>2a2d9^_OYAC>nH|fN)_DmiioR@Gop8|Vl-IU3H#hHSQHbnT;b5=^0D3Xjy#N3J literal 0 HcmV?d00001 diff --git a/data/themes/clearlooks/clearlooks/tree-p.gif b/data/themes/clearlooks/clearlooks/tree-p.gif new file mode 100644 index 0000000000000000000000000000000000000000..05aa8c28bc86870e879c2350f28b1847d76abe8e GIT binary patch literal 420 zcmV;V0bBk@Nk%v~VHf}y0K@I=#))J29^y5(cjl zv9hqSvzd8C5(x(h62HH`!Lz~%P%8%$3cm`>%?Sz#6V%eph!_gn&)wb7+|WZ77!=&x z9oy;Z3kvJW7##}>^7Quh3iI^~tr#Bm@-qDMkij0o1s(`OA*aCugM<$kXjt%&!9<4* z8Dz7lfulu>A2f9IAo9Zp4|yt9X!x)pB+Hd9UAEk?av_EdIA@y7$r5Kzmb)-;7)rFL O(W4bapje6`1OPkD{me!H literal 0 HcmV?d00001 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)