Groups and the dbox_container object, Properties (private symbols) – Crunch CRiSP File Editor 6 User Manual
Page 65

Page 65
group is very similar to a normal group, but was designed to solve a different problem, and first came to life
with the implementation of the DBOX_STATUS_BAR attribute. As described previously, the menu bar, tool
bar, and status bars are all similar in that they are actually a collection of appropriate sub-objects.
The grouping mechanism is used for the status bars, tool bars, and menu bars as a way of associating the
individual components with the parent object.
Groups and sub-groups are very similar: the main difference is that a DBOX_GROUP_START declaration
terminates the definition of the prior object and creates a new DBOX_CHILD, with all subsequent object
definitions being a branch of the tree of the DBOX_CHILD (up until the matching DBOX_GROUP_END). A
DBOX_SUB_GROUP_START declaration terminates the current object definition, but creates a new branch
of objects, attached to the just created object (i.e. no DBOX_CHILD object is created).
The primary purpose of the sub-group is to support nesting of objects for the object types which need
multiple components to create one user interface object.
Groups and the DBOX_CONTAINER object
The previous two sections have described the DBOX_GROUP_START and DBOX_SUB_GROUP_START
mechanisms, and why they are needed. The third evolution of this functionality is the DBOX_CONTAINER
object. As mentioned for DBOX_GROUP_START, when a new group is started, a new object is created, a
DBOX_CHILD object. A DBOX_CHILD object has no semantics of its own, and in fact no widget or window
exists for such an object. This is fine for the normal layout rules.
However, say you want to create a grouping of objects but you want to make them appear or disappear as
and when needed? (The X11 API refers to this as managing or unmanaging a window; Windows refers to
this is showing or hiding a window). You can create some interesting effects by creating a group of objects
and not actually showing them; eventually when the user performs some action you manage or show the
sub-objects all at once. A good example (and the first implementation of this) is the Options
→
Language
editing modes menu. This dialog box consists of 5 sub-dialogs. The main dialog box has a fixed set of
options at the left and the normal OK/Help/CANCEL at the bottom of the window. In the middle of the dialog
box is a set of objects. The objects displayed is dependent on the set of options being looked at (e.g. File
conversion, Language modes, Filters, etc). This effectively implements a tabbed-dialog box style of
interface, although the look of the dialog does not resemble a tabbed dialog box.
The point of the DBOX_CONTAINER object is that all five layouts of this dialog box are created on
invocation but only one of the layouts is made visible at any one time. (That is, you will see five
DBOX_CONTAINER definitions if you examine the macro source in src/crunch/gui/setup.cr).
By creating sub-objects as children of a DBOX_CONTAINER it is very easy to manage or unmanage the
container object itself rather than the sub-objects contained within the DBOX_CONTAINER object. The
effect of this is that there is a near instantaneous change in visibility of the sub-objects. This same
mechanism could be implemented without using a DBOX_CONTAINER but the code becomes not only
more cumbersome to maintain (you need separate code to manage and unmanage each of the sub-
objects), but also you will see a flickering effect (dialog box in-fighting) as the objects fight for real-estate
before being pulled under the water.
The way this all works is to create a DBOX_CONTAINER object, just like any other object, but to use the
DBOX_SUB_GROUP_START attribute to create a sub-grouping of objects which are all children of the
owning container.
Properties (private symbols)
When you write a macro to create and handle a dialog box, one problem you will need to decide about is
whether to allow multiple instances of that dialog box. Many dialog boxes in CRiSP are single instance
dialog boxes, e.g. when you select a menu or icon entry to invoke a dialog box it will create that dialog box.
Subsequent attempts to invoke that entry whilst the dialog box is on display will simply result in the existing
dialog box being popped to the top of the display.
There is nothing preventing you from creating multiple instances of a dialog box, but you can end up
needing a bit of state information to manage them. For a simple dialog box, you may be able to implement
the functionality without the use of any global variables. Sometimes you will need to use gloabl variables to
track the state of user selections, etc. But global variables are a real nuisance when it comes to dialog boxes
that can be created multiple times - the values of the global variables becomes difficult to track. You can use
a list structure instead of a primitive but this can be difficult.
Consider a very simple dialog box which has a single button and a label. The label displays a number and