******************** DUIM-Gadgets Library ******************** .. current-library:: duim .. current-module:: duim-gadgets Overview ======== The elements that comprise a Graphical User Interface (GUI) are arranged in a hierarchical ordering of object classes. At the top level of the DUIM hierarchy there are three main classes, :class:``, :class:``, and :class:``, all of which are subclasses of :drm:``. The DUIM-Gadgets library contains classes that define a wide variety of gadgets for use in your GUI applications, such as push buttons, radio buttons, and check boxes. The library also provides the necessary functions, generic functions, and macros for creating and manipulating these classes. The library contains a single module, *duim-gadgets*, from which all the interfaces described in this chapter are exposed. `DUIM-Gadgets Module`_ contains complete reference entries for each exposed interface. Gadgets are the basic behavioral GUI element (above the level of events). - Gadgets do not *need* to have a visual presence, though in practice every gadget provided by DUIM does, since all general instances of :class:`` are also general instances of :class:``. - Many classes of gadget maintain some kind of state for their behavior, and in practice some of this is usually reflected in the UI. For example, you can tell that a check box is selected just by looking at it. - They handle events and turn these into callbacks, for convenience. Some of the more important types of gadget are as follows: Buttons A wide variety of buttons are provided by DUIM. These include not only standard buttons such as push buttons and radio buttons, but items that can be placed within menus. Action gadgets An action gadget is any gadget that can be used to perform an action, such as a button, or menu command. Value gadgets A value gadget is any gadget that can have a value associated with it. In principle, this is true of the majority of gadgets, but the value of a gadget is more important for certain types of gadget (for instance, lists or radio boxes) than for others (for instance, push buttons). Value range gadgets Value range gadgets are those value gadgets for which the possible value sits within a defined range. This includes gadgets such as scroll bars and sliders. Collection gadgets Collection gadgets are those gadgets that can contain a number of "child" gadgets, the specification of which can be described in terms of a Dylan collection, and includes gadgets such as list controls and groups of buttons. Usually, the behavior of each of the "child" gadgets is interdependent in some way; for example, only one button in a group of radio buttons may be selected at any time. With collection gadgets, you can specify the "child" gadgets very simply, without having to worry about defining each "child" explicitly. Each of these types of gadget is described in more detail in subsequent sections, and full reference entries for every interface exposed in the DUIM-Gadgets library are available in `DUIM-Gadgets Module`_. For a more general introduction to the gadgets provided in DUIM, see the tour in the *Building Applications using DUIM* book. See the same book for a more practical example of implementing an application using the DUIM library. Callbacks and keys ================== When an event occurs in a user interface (for example, a button is pressed, a menu command is chosen, or an item in a list is double-clicked), you usually want some operation to be performed. If the user of your application chooses the *File > Open* command, a File Open dialog should be displayed. If the user clicks on an *OK* button in a dialog, the dialog should be dismissed and the appropriate changes to the application state to be performed. In DUIM, you can provide this functionality by specifying a function known as a *callback*. Generally speaking, a callback gets passed a single argument, which is the gadget that is affected. Thus, the argument passed to the callback for a button is the button itself. Callbacks do not need to have a return value, although they are not forbidden either. If a value is returned by a callback function, then it is just ignored. Callbacks are used in preference to event handlers because Dylan does not let you write methods that specialize on individual instances. In languages such as C, you uniquely name each element in an interface, and then provide behavior for each element by writing event handlers that contain case statements that let you discriminate on individual elements. This is a somewhat inelegant solution. Instead, in Dylan you specify the names of the callbacks for each element in an interface when you *create* the elements. It is then a simple matter for the system to know what behavior goes with what elements, and is much less tedious than having to write many cumbersome methods for :gf:`handle-event`. In Dylan, you use events in order to create new kinds of class. If you were creating a new kind of button, you would need to define a new method for :gf:`handle-event` in order to describe what happens when you click on an instance of that button. You would then write callbacks to deal with particular instance of the new class of button. By contrast with callbacks, you can also provide functions in DUIM known as *keys*, which are specific to collection gadgets. A key is used to set the value of some aspect of the collection gadget for which the key is defined. With keys, therefore, the values returned by the function are fundamental to the operation of the gadget. There are two keys that are generally used by gadgets, known as the value key and the label key. The value key is a function that is used to calculate the value of the gadget for which the key is defined. The label key is used to calculate the printed representation, or label, of all the items in a collection gadget. Gadget protocols ================ Gadgets are objects that make up an interface: the menus, buttons, sliders, check lists, tool bars, menu bars, and so on. Gadget classes may support three protocols, *value*, *items*, and *activate*. - Gadgets that support the *value* protocol respond to the :gf:`gadget-value` message, a value-changed callback, and have a setter function associated with them. - Gadgets that support the *items* protocol respond to :gf:`gadget-items` and have a gadget setter function associated with them. - Gadgets that support the *activate* protocol have an activation callback associated with them. Gadgets have a set of slots, or properties, associated with them: :gf:`gadget-label`, :gf:`gadget-value`, :gf:`gadget-items`, and :gf:`gadget-enabled?`. Every gadget has some or all of these properties. :gf:`gadget-label` This slot holds the label that appears on the gadget on the screen. If a gadget does not have a label, the :gf:`gadget-label` function returns ``#f``. :gf:`gadget-value` This slot holds the value(s) of the gadget. If a gadget does not have any values, the :gf:`gadget-value` function returns ``#f``. :gf:`gadget-items` This slot is a list of the contents of the gadget. If the gadget does not have items, for example a button, :gf:`gadget-items` returns nothing. :gf:`gadget-enabled?` This slot tests whether or not the gadget is active. All gadgets have a :gf:`gadget-enabled?` slot. An introduction to the protocols supported by different sorts of gadget can also be found in the *Building Applications using DUIM* book. The class hierarchy for DUIM-Gadgets ==================================== This section presents an overview of the available classes of gadget, and describes the class hierarchy present. In each table below, classes that support the *items* protocol are displayed in *bold text*, and classes that support the activate protocol are displayed using *italic text*. *Note:* In `Subclasses of the \ class`_, every subclass shown supports the *items* protocol, though for clarity, no bold is used. All subclasses of ** support the *value* protocol. These are described in `Subclasses of \`_, `Subclasses of \`_, and `Subclasses of \`_. The class and its subclasses ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The base class for the majority of DUIM gadgets is the ** class, which is itself a subclass of **. All other DUIM gadgets are subclasses of **, with the exception of **, **, and **. The immediate subclasses of ** are shown in `Overall class hierarchy for the DUIM-Gadgets library`_. Only :class:`` and :class:`` have any subclasses defined. See `Subclasses of \`_ and `Subclasses of \`_ for details of these subclasses. The :class:`` class provides a number of subclasses that allow particular parts of a user interface to be created: :class:`` Use this class to add a menu to the menu bar of any application frame. Menus themselves contain commands created using the menu-specific button and collection gadgets described in `Subclasses of \`_ and `Subclasses of \`_. :class:`` This class is used to add a tool bar to an application frame. A tool bar is a row of buttons that duplicates the functionality of the most commonly used menu commands, thereby providing the user with quick access to the most useful operations in the application. :class:`` This is a generic scrolling gadget that can be used in a number of situations. :class:`` A viewport can be used to create a generic pane for displaying specialized contents that you may have defined. Use this class when there is no other class provided for displaying the objects in question. :class:`` This class can be used to split the current view in half. This allows the user, for example, to create a second view of the same document. The :class:`` class provides a number of subclasses that allow general spatial and grouping capability, in addition to the layout functionality described in :doc:`DUIM-Layouts Library `. These are as follows: :class:`