Configuration of Slab

For quick instructions, jump to the final section Recommended Configuration of Slab

Structure of BWidget and Slab

BWidget defines commands such as ::Button in the global namespace, and commands such as ::Button::create, ::Bitmap::get in child namespaces of the global namespace. These commands are registered with the Tcl autoloader, using the tclPkgSetup command in the package's pkgIndex.tcl file. The true BWidget commands are loaded only when they are needed, using Tcl's integration of the unknown command and the autoloader. This "lazy loading" means that the command "package require BWidget" does not immediately load the whole of the BWidget package.

Slab uses the tcl::tm module mechanism for defining and loading packages instead of the pkgIndex.tcl mechanism. It defines all its commands in the ::Slab namespace and its children, with each widget having its own module and namespace (e.g. ::Slab::Button). All auxiliary files are also implemented as modules.

Slab can operate in this mode, with widget creation effected by, for example,

    package require Slab::Button
    Slab::Button .b
However, Slab can be configured to provide greater compatibility with existing BWidget code, and this is often more convenient.

Configuration Options

Slab can be used in four ways:

  1. This is the mode described above. The whole of Slab is confined to the ::Slab namespace and its children. Subpackages (such as Slab::Button) must be loaded by "package require" in the usual way. In this mode, the confinement of Slab means that Slab and BWidget can be loaded into the same interpreter and be used in the same script.
  2. As (a), but "lazy loading" is provided (as in BWidget): subpackages are automatically loaded when their commands are used, and there is no need to load subpackages (e.g. "package require Slab::Button") before using them. Slab remains confined to the ::Slab namespace and its children, and Slab and BWidget can be loaded into the same interpreter and be used in the same script.
  3. As (b), but with namespace imports to provide good BWidget compatibility with minimum proliferation of namespaces. Commands such as ::Slab::Button are imported to the global namespace; and commands in child namespaces of ::Slab, such as ::Slab::SelectColor::menu, (but excluding "create" commands) are imported - for example ::Slab::SelectColor::menu is imported to ::SelectColor::menu (with creation of the ::SelectColor namespace for this purpose). The idiom
            Button::create $w
    although legal in BWidget, is used much less frequently than
            Button $w
    and so these "create" commands are not included among the imports.
  4. (the default) As (c), but with further namespace imports for full BWidget compatibility. All "create" commands are imported, for example ::Slab::Button::create is imported as ::Button::create, although this requires the creation of a namespace for each class. In this mode, code that uses BWidget should run unaltered, as long as it does not access BWidget internals.
The different modes of operation represent different compromises between self-containment of Slab, and compatibility with code written for BWidget.
  1. Namespace ::Slab and its children are used; "package require" is needed to load subpackages such as Slab::Button.
  2. As for (a), but with loader commands defined in child namespaces so that per-class modules (e.g. Slab::Button) are loaded when their commands are called, with no need to use "package require".
  3. In addition to the above, loader commands in the namespaces ::Bitmap, ::DragSite, ::DropSite, ::DynamicHelp, ::SelectColor, and ::SelectFont; and in the global namespace (such as the command ::Button) so that most exported commands can be called without using the namespace prefix Slab::.
  4. As for (c), plus a namespace for each widget not already listed, e.g. ::Button, which contains a loader command ::Button::create: thus all exported commands can be called without using "package require" or the namespace prefix Slab::.

Changing the Configuration

::Slab::setMode ?newValue?

The command ::Slab::setMode is available for changing the mode of operation after Slab has been loaded. The command has "set" semantics, and can change the mode among the values 1, 2 and 3. The mode cannot be changed to or from 0 - the user must set the mode value to 0 before loading Slab if and only if this value is required.

Recommended Configuration of Slab