This was a posting by [Jos Decoster] posted to comp.lang.tcl a while back providing some help to the [Bwidget] developer. [http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&safe=off&selm=3B419A28.D2A4FE34%40retarget.com&rnum=2] ---- '''1. Creating a widget with BWidget:''' Introduction: Creating a new widget using BWidgets can help you a lot. You declare the arguments for the new widgets, eventually include some other widgets, write a create, configure, cget and destroy procedure and of you go. A good source for information are the BWidget widgets themselves. The way to create a new widget base an BWidgets has changes since version 1.2.1. This small document tries to explain how to create new BWidgets based on the CVS release of 28-jun-2001. This document is not trying to cover the complete BWidget functionality but only those parts I regularly use to create new widgets. I'll explain how I use BWidgets based on a small example: the TitleFrame included in the BWidget distribution. '''2. Widget declaration:''' Each widget needs it own namespace. In a 'namespace eval' statement, the widget is declared as follows: namespace eval TitleFrame { Widget::define TitleFrame titleframe Widget::declare TitleFrame { {-relief TkResource groove 0 frame} {-borderwidth TkResource 2 0 frame} {-font TkResource "" 0 label} {-foreground TkResource "" 0 label} {-state TkResource "" 0 label} {-background TkResource "" 0 frame} {-text String "" 0} {-ipad Int 4 0 "%d >=0"} {-side Enum left 0 {left center right}} {-baseline Enum center 0 {top center bottom}} {-fg Synonym -foreground} {-bg Synonym -background} {-bd Synonym -borderwidth} } Widget::addmap TitleFrame "" :cmd {-background {}} Widget::addmap TitleFrame "" .l {-background {} -foreground {} -text {} -font {}} Widget::addmap TitleFrame "" .l {-state {}} Widget::addmap TitleFrame "" .p {-background {}} Widget::addmap TitleFrame "" .b {-background {} -relief {} -borderwidth {}} Widget::addmap TitleFrame "" .b.p {-background {}} Widget::addmap TitleFrame "" .f {-background {}} } The first command to execute when defining a new widget is the Widget::define command. This command's arguments are as follows: Widget::define ?includedClass? ?includedClass? ... This defines the new widget class, tells BWidget what the filename (without the .tcl extension) should be for this class and what other classes this widget will use. IE: Widget::define ListBox listbox DragSite DropSite DynamicHelp Says that the new ListBox widget is in a file called listbox(.tcl) and that it needs a copy of the DragSite, DropSite and DynamicHelp libraries. The Widget::define command does several things. It creates a proc called :: for the new widget as well as a ::use proc. It also specifically calls the ::use proc for any widget that is declared as required by the widget. This ensures that all the necessary libraries get loaded before this widget is truly defined or used. Finally, Widget::define binds the event for the widget class to the default Widget::destroy command which does all the necessary cleanup for a BWidget. Any custom cleanup should be defined in a proc for the widget class, and that proc should call Widget::destroy in turn for the final cleanup. The widget::declare statement declares the megawidget options. Possible megawidget option types are: Enum Int Boolean String Flag Synonym TkResource BwResource An option is declared as: