General Toolkit --------------- Overview -------- - Everything is an widget. - An widget is a visual or layout element that can be shown, hidden, drawn, receive events and participate in geometry negotiation. - If an widget cannot handle an event it receives it should pass that event on to its parent. (Button and key events, etc.) - An widget need not produce visual output. For instance, an hbox simple arranges its children. - Widgets have no children. - Every widget has a container for a parent. (No exceptions). - A container is a type of widget. A container contains 1 or more children and manages their size and position. It also defines a few more functions that allow widgets to ask their parents (the container) to be resized. - All widget and container functions are expected to be valid. A NULL function is an error. (If the function should do nothing then create a simple function that just returns). This includes specifying a valid "event" function for widgets which do not receive events (such as some containers). Children of the container may pass events up the widget tree so it is necessary (and even desired) to define an event function for such containers. Widgets ------- Variables --------- "visible" - This flag is set if the widget is visible. This simply means that the widget should participate in geometry negotiation. That is, the widget may not necessarily be mapped on the screen yet. "mapped" - This flag is set if the widget is mapped on the screen. Which means that it is ready for drawing. "parent" - The parent container of the widget. "requisition" - The child's requested size. "allocation" - The child's allocated size. "private" - Private storage which depends on the particular type of widget. Currently this is used to store the GdkWindow for each widget. "user_data" - A hook onto which users can place data. Functions --------- "destroy" - This function should destroy the widget and free all associated memory. "show" - Make the widget visible. (Not the same as mapping). "hide" - Make the widget invisible. "map" - Map the widget. "unmap" - Unmap the widget. "draw" - Draw the widget (and any children). "expose" - Draw only the widget. (Do not draw children). "clear" - Clear the widgets background area. (This is useful when a parent changes its background color and it needs to tell its children to redraw their background.) "event" - Handle an event. If the widget cannot handle the event then it should pass it along to its parent. (Only widgets which create their own GdkWindow's will receive events). "size_request" - Fill in the size requisition structure. "size_allocate" - Accept the size allocated. This means resizing the widget and sending size allocations to children (if the widget is a container). Containers ---------- Variables --------- "widget" - The first member of the container structure is the widget structure. This allows containers to be freely cast into widgets. It also means containers need to fill in the widget structure when they are created. "border_width" - The width of the border that surrounds the widget. All containers should recognize and act upon the setting of this variable. "spacing" - The spacing between children. Containers which manage multiple children should recognize this variable if at all possible. Functions --------- "add" - Add the specified widget to the container. Give an error if the widget cannot be added. "remove" - Remove the specified widget from the container. Give an error if the widget cannot be removed. "need_resize" - This is called be children which are in need of a resize. Most of the time the correct response is to call the "need_resize" function of the containers parent with itself as the widget in need of resize. Data and Observers ------------------ Data ---- In order to handle communication between widgets and between widgets and the user program, the concept of a piece of data is needed. For the most part, widgets provide a visual interface to a piece of data. In the case of a button, the data is the buttons state. In the case of a slider, the data is the sliders position (value), lowera and upper bounds and the step and page increments. We'd like to be able to "observe" the data and get notifications when it changes. Two new data structures are added to facilitate this. The "GtkData" type specifies the basic operations for data. Data can have a unique type. Data can be "attached" to and "detached" from. And data can notify all attached observers that it has been modified. Lastly, data can notify all attached observers that is is being destroyed. Observer -------- The "GtkObserver" type specifies the basic operations for an observer. An observer can attach itself to a piece of data and then receive notification of changes to that data. It will also receive notification of the data's destruction (if that occurs). Other UI elements ----------------- Widgets and containers provide a basic mechanism for creating the rest of the user interface. Widgets include such items as labels, pixmaps, images, scales, etc. Containers include such items as horizontal and vertical boxes as well as some more unusual containers. Such as frames, alignments and even buttons. Labels, images and pixmaps -------------------------- Labels, images and pixmaps are simply what they sound like. They display a label, image or pixmap. They inherit their parents background color so that they may be used in buttons. Labels are somewhat special in that they don't create their own window, but instead use their parents window for drawing. Buttons ------- Buttons are containers which have a single child. The button handles tracking of button presses and releases. The children of a button should not handle button presses or releases and should pass those events to their parents (like any well behaved widget should). HBoxes and VBoxes ----------------- Horizontal and vertical boxes arrange their children as their name implies...horizontally and vertically. Menubars and Menus ------------------ Menubars are containers which hold menu items. The menu items are arranged horizontally and packed to the left side of the menubar. Menu items themselves receive button and key press events, but simply pass them to their parent. (Which is either a menu or menubar). Menus are containers which also hold menu items. The menu items are arranged vertically and packed to the top of the menu. Menu items are also containers. They can hold only 1 child, a menu. Unlike normal containers, menu items do not determine the size and positioning of their child. This is done by their parent. This allows the menu (or menubar) to correctly position the submenu. Menu items display a label. They can have optional accelerators which are displayed to the right of the label and/or a radio or check button displayed to the left of the label. Menu items contain a state variable which can be set by their parent. The setting of this variable determines how the menu item is drawn (normal, selected) and whether the submenu (if one exists) is displayed.