bwidget-1.x/tree.tclwith a very simple patch:
- Add an header for loading the canvas extension
package require Paved::canvas 1.1
- Replace the following lines
Widget::tkinclude Tree canvas .c \
...
eval [list canvas $path.c] [Widget::subcget $path .c] -xscrollincrement 8with Widget::tkinclude Tree Paved::canvas .c \
...
eval [list Paved::canvas $path.c] [Widget::subcget $path .c] -xscrollincrement 8- Then, I would have been able to create and use an extended BWidget::Tree in this raw way:
package require BWidget ; # my upgraded version Tree .t .t.c configure -tile xyz.gif ...This would be a quick and easy solution.I didn't like this solution because it was just a temporary patch; I would be forced to reapply this patch for every next BWidget release. This is maintenance !So, a better idea raised after reading Designing SNIT widgets as mixins.Instead of patching the original code, I could adapt and extended it at ""run-time""" !Just a quick experiment:
package require Paved::canvas 1.1 # create a standard BWidget-tree Tree .mytree # transform the internal canvas in a paved-canvas Paved::canvas .mytree.c # then show the tiled background (assuming "xyz.gif" be in current directory) .mytree.c configure -tile xyz.gifIt works ! Now .mytree is a BWidget::Tree with a tiled background.Seeing is believing ...
Now, it's time to wrap all this stuff with a good snit widgetadaptor ...
package require snit
package require BWidget
package require Paved::canvas
snit::widgetadaptor Paved::TreeAdaptor {
# pseudo-component (see the constructor)
component internalCanvas
delegate option -tile to internalCanvas
delegate option -tileorigin to internalCanvas
delegate option -bgzoom to internalCanvas
delegate option * to hull
delegate method * to hull
constructor {args} {
installhull $win
# a BWidget-Tree uses a canvas sub-widget for drawing the tree.
# This internal canvas is named ".c".
# BWidget-Tree provides an undocumented (and steady) method
# for accessing this feature
# internalCanvas is 'pseudo' Snit component.
# Being already within $win, you shouldn't install it;
# just provide a reference
set internalCanvas [Tree::getcanvas $win]
Paved::canvasAdaptor $internalCanvas
$win configurelist $args
}
}
namespace eval Paved { ; }
# this command *creates* a *new* Paved::Tree widget
# (in contrast with Paved::TreelAdaptor
# that wraps a pre-existing Tree widget)
proc Paved::Tree {path args} {
eval TreeAdaptor [::Tree $path] $args
return $path
}then, when you need to create a Paved::Tree, you only need:package require Paved::Tree Paved::Tree .mytree -tile $myGif ..... other options ...the big plus is that the internal canvas is hidden, so that you apply the -tile option to the paved-tree, not to the internal canvas ...Moreover, now you are able to adapt (at run-time) pre-existing Tree widgets with just one line:
# be "$tt" your pre-existing Tree-widget you want to be tiled.
Paved::TreeAdaptor $tt -tile $myGifFrom now, $tt is a Paved::Tree, 100% identical to an original Bwidget::Tree (both for its visual-look and for its programming interface).Thanks again to William Duquette for its powerful Snit.

