[ABU] 13-feb-2006 After developing [Paved Widgets], an extension of some standard widgets with tiling support, I was tempted to adapt the [BWidget::Tree] providing a tiled background to him, too. After inspecting its code (BWidget::Tree is pure-tcl code), I discovered that the ''graphical-tree'' is drawn over an internal [canvas] widget. My first idea was to upgrade its code bwidget-1.x/tree.tcl with 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 8 with 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.gif It works ! Now ''.mytree'' is a [BWidget::Tree] with a tiled background. Seeing is believing ... [http://web.tiscali.it/irrational/tcl/paved1.1/doc/images/demoTree.gif] 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 $myGif From 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]. ---- Category [snit]