can't find package tile
while executing
"package require tile"
(in namespace eval "::request" script line 34)
invoked from within
"namespace eval ::request $script"
("::try" body line 12)
OUTPUT BUFFER:
# -------------------------------------------------------------------------
# --- scrolledwidget.tcl
# -------------------------------------------------------------------------
# Revision history of this code:
#
# Scrodget:
# Scrodget enables user to create easily a widget with its scrollbar.
# Scrollbars are created by Scrodget and scroll commands are automatically
# associated to a scrollable widget with Scrodget::associate.
#
# scrodget was inspired by ScrolledWidget (BWidget)
#
# Copyright (c) 2005 :
#
# This program is free software; you can redistibute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation.
#
# See the file "license" for information on usage and
# redistribution of this program, and for a disclaimer of all warranties.
#
# -------------------------------------------------------------------------
# scrolledwidget:
# 07.11.2011: Johann [dot] Oberdorfer [at] googlemail [dot] com
#
# A TclOO approach, just to see how difficult it would be to convert a
# snit widget to tcloo. In fact it was an easy one!
# -enjoy-
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
package require TclOO
package require tile
package provide scrolledwidget 0.2
namespace eval ::scrolledwidget {
namespace export scrolledwidget
# this is a tk-like wrapper around the class,
# so that object creation works like other Tk widgets
proc scrolledwidget {path args} {
set obj [ScrolledWidget create tmp $path {*}$args]
rename $obj ::$path
return $path
}
oo::class create ScrolledWidget {
variable widgetOptions
variable widgetCompounds
variable auto
variable isHidden
variable GridIdx
constructor {path args} {
my variable widgetOptions
my variable widgetCompounds
my variable isHidden
my variable GridIdx
set widgetCompounds(internalW) {}
array set widgetOptions {
-scrollsides se
-autohide 0
}
# for each 'side' (n,s,w,e)
# define the position {row,col} within the 3x3 grid
array set GridIdx {
n { 0 1 }
s { 2 1 }
w { 1 0 }
e { 1 2 }
}
# attributes for south/north (or east/west) are paired
set isHidden(ns) 0
set isHidden(ew) 0
set win [ttk::frame $path -class ScrolledWidget]
if { [tk windowingsystem] eq "aqua" } {
set sb "scrollbar"
} else { set sb ttk::scrollbar }
set widgetCompounds(frame) $win
set widgetCompounds(northScroll) [$sb $win.northScroll -orient horizontal]
set widgetCompounds(southScroll) [$sb $win.southScroll -orient horizontal]
set widgetCompounds(eastScroll) [$sb $win.eastScroll]
set widgetCompounds(westScroll) [$sb $win.westScroll]
# fix against deprecated scrollbar set/get syntax
$widgetCompounds(northScroll) set 0 1
$widgetCompounds(southScroll) set 0 1
$widgetCompounds(eastScroll) set 0 1
$widgetCompounds(westScroll) set 0 1
# 3 x 3 grid ;
# the central cell (1,1) is for the internal widget.
# +-----+-----+----+
# | | n | |
# +-----+-----+----+
# | w |inter| e |
# +-----+-----+----+
# | | s | |
# +-----+-----+----+
# Cells e or w are for vertical scrollbars
# Cells n or s are for horizontal scrollbars
# Note that scrollbars may be hidden.
grid rowconfig $win 1 -weight 1 -minsize 0
grid columnconfig $win 1 -weight 1 -minsize 0
# we must rename the widget command since it clashes with
# the object being created
set win ${path}_
rename $path $win
my SetAutohide $widgetOptions(-autohide)
my SetScrollsides $widgetOptions(-scrollsides)
my configure {*}$args
}
# public methods starts with lower case declaration names,
# whereas private methods starts with uppercase naming
method cget { {opt "" } } {
my variable widgetOptions
if { [string length $opt] == 0 } {
return [array get widgetOptions]
}
if { [info exists widgetOptions($opt) ] } {
return $widgetOptions($opt)
}
return -code error "# unknown option"
}
method configure { args } {
my variable widget
my variable widgetOptions
if {[llength $args] == 0} {
# return all custom options
return [array get widgetOptions]
} elseif {[llength $args] == 1} {
# return configuration value for this option
set opt $args
if { [info exists widgetOptions($opt) ] } {
return $widgetOptions($opt)
}
return [$widget cget $opt]
}
# error checking
if {[expr {[llength $args]%2}] == 1} {
return -code error "value for \"[lindex $args end]\" missing"
}
# process the new configuration options...
array set opts $args
foreach opt [array names opts] {
set val $opts($opt)
# overwrite with new value
if { [info exists widgetOptions($opt)] } {
set widgetOptions($opt) $val
}
# some options need action from the widgets side...
switch -- $opt {
-scrollsides {
if { ! [regexp -expanded {^[nesw]*$} $val] } {
return -code error "# bad scrollsides \"$opt\": only n,s,w,e allowed"
}
my SetScrollsides $val
}
-autohide {
my SetAutohide $val
}
default {
return -code error "unknown configuration option: \"$opt\" specified"
}
}
}
}
method associate { args } {
my variable widgetCompounds
switch -- [llength $args] {
0 { return $widgetCompounds(internalW) }
1 { set w [lindex $args 0] }
default {
return -code error \
"wrong # args: should be \"$ $widgetCompounds(frame) associate ?widget?\""
}
}
if { $w != {} && ! [winfo exists $w] } {
return -code error "error: widget \"$w\" does not exist"
}
# detach previously associated-widget (if any)
catch {
grid forget $widgetCompounds(internalW)
$widgetCompounds(internalW) configure -xscrollcommand {} -yscrollcommand {}
}
set widgetCompounds(internalW) $w
$widgetCompounds(eastScroll) configure -command "$w yview"
$widgetCompounds(westScroll) configure -command "$w yview"
$widgetCompounds(northScroll) configure -command "$w xview"
$widgetCompounds(southScroll) configure -command "$w xview"
$w configure \
-xscrollcommand "[self] auto_setScrollbar $widgetCompounds(northScroll) $widgetCompounds(southScroll)" \
-yscrollcommand "[self] auto_setScrollbar $widgetCompounds(eastScroll) $widgetCompounds(westScroll)"
catch {raise $w $widgetCompounds(frame)}
grid $w -in $widgetCompounds(frame) -row 1 -column 1 -sticky news
}
method auto_setScrollbar { sbA sbB {first 0} {last 1} } {
my variable widgetOptions
my variable auto
my variable isHidden
set sideA [my WhichSide $sbA]
set orient [my WhichOrient $sbA]
if { $auto($orient) } {
if { $first == 0 && $last == 1 } {
if { ! $isHidden($orient) } {
grid forget $sbA
grid forget $sbB
set isHidden($orient) 1
}
} else {
if { $isHidden($orient) } {
my ShowScrollbar $sbA $widgetOptions(-scrollsides)
my ShowScrollbar $sbB $widgetOptions(-scrollsides)
set isHidden($orient) 0
}
}
}
$sbA set $first $last
$sbB set $first $last
}
# from the scrollbar's name, derive its 'side'
# i.e. [WhichSide $widgetCompounds(westScroll]) returns 'w'
method WhichSide { sb } {
return [string index [winfo name $sb] 0]
}
# from the scrollbar's name, derive its 'orientation'
# return values are: "ns" or "ew"
# note: [my WhichSide $widgetCompounds(northScroll)] returns 'ew' (i.e. horizontal)
method WhichOrient { sb } {
set side [my WhichSide $sb]
if { [string first $side "ns"] >= 0 } {
set orient ew
} else {
set orient ns
}
return $orient
}
method SetScrollsides {sides} {
my variable widgetOptions
my variable widgetCompounds
my variable isHidden
set widgetOptions(-scrollsides) $sides
if { ! $isHidden(ew) } {
my ShowScrollbar $widgetCompounds(northScroll) $widgetOptions(-scrollsides)
my ShowScrollbar $widgetCompounds(southScroll) $widgetOptions(-scrollsides)
}
if { ! $isHidden(ns) } {
my ShowScrollbar $widgetCompounds(eastScroll) $widgetOptions(-scrollsides)
my ShowScrollbar $widgetCompounds(westScroll) $widgetOptions(-scrollsides)
}
}
# note: both scrollbars have the same orientation
method HandleAutohide { sbA sbB } {
my variable widgetOptions
my variable auto
my variable isHidden
set sideA [my WhichSide $sbA]
set orient [my WhichOrient $sbA]
if { $auto($orient) } {
# 1/true : check if scrollbar should be hidden
# (based on the scrollbar's visible range)
my auto_setScrollbar $sbA $sbB {*}[$sbA get]
} else {
# 0/false : if scrollbars are hidden, then show them
if { $isHidden($orient) } {
my ShowScrollbar $sbA $widgetOptions(-scrollsides)
my ShowScrollbar $sbB $widgetOptions(-scrollsides)
set isHidden($orient) 0
}
}
}
method BoolValue {x} {
if { [string is boolean $x] } {
if { "$x" } { return 1 } else { return 0 }
}
return -code error "# not a boolean value"
}
method SetAutohide {value} {
my variable widgetOptions
my variable widgetCompounds
my variable auto
set value1 $value
# normalize boolean value (if boolean)
catch { set value1 [my BoolValue $value1] }
switch -- $value1 {
0 -
none { set auto(ew) 0 ; set auto(ns) 0 }
vertical { set auto(ew) 0 ; set auto(ns) 1 }
horizontal { set auto(ew) 1 ; set auto(ns) 0 }
1 -
both { set auto(ew) 1 ; set auto(ns) 1 }
default { return -code error \
"# bad autohide \"$value\": must be none,vertical,horizontal,both or a boolean value"
}
}
set widgetOptions(-autohide) $value
my HandleAutohide $widgetCompounds(northScroll) $widgetCompounds(southScroll)
my HandleAutohide $widgetCompounds(eastScroll) $widgetCompounds(westScroll)
}
method ShowScrollbar {sb validSides} {
my variable GridIdx
set side [my WhichSide $sb]
if { [string first $side $validSides] != -1 } {
set r [lindex $GridIdx($side) 0]
set c [lindex $GridIdx($side) 1]
set sticky [my WhichOrient $sb]
grid $sb -row $r -column $c -sticky $sticky
} else {
grid forget $sb
}
}
}
}
# demo code...
if {1} {
package require scrolledwidget 0.2
namespace import scrolledwidget::*
# create a scrolledwidget, a text, and associate it
set sc [scrolledwidget .sc]
pack $sc -side top -fill both -expand 1 -padx 2 -pady 2
set txt [text .txt -wrap none \
-relief sunken -borderwidth 2 \
-bg green \
-bd 5]
$sc associate $txt
$txt insert end \
{
This text widget
has been associated to a scrolledwidget widget(-object).
Resize the window or type some text to observe behaviour of the scrollbars
....
}
# both vertical scrollbars
$sc configure -scrollsides se -autohide true
# puts "xxx [$sc cget -scrollsides] xxx"
# puts "xxx [$sc cget -autohide] xxx"
}