Application ~~~~~~~~~~~ Or app for short. This is the user application program that uses libmbtk for its GUI. Backend ~~~~~~~ An libmbtk backend is an object (C structure and associated code) that talks to the graphic device, typically through an external lib. There are multiple backend implementations available, for example the xlib backend uses xlib calls to directly talk to X11. Display ~~~~~~~ An application using libmbtk will typically decide which backend implementation it wants to use and will create a display using that backend. The application could create multiple, independent displays in the same process, sequentially (init one, use it, discard it, init the another, use it, discard it) or in parallel. Such displays can use the same or different backends. But such multi-backend or multi-display usage is extremely rare. The most important use of the backend API is when multiple backends are available, the application can decide runtime which one to use. This is especially useful if backends are dynamically linked from plugins, so the user can install the app and one or more backend plugins then the app can figure which backends are available and choose and initialize the preferred one from those. Then the app goes on to create a single display using that backend and all windows of the app will be within that single display. Window ~~~~~~ A GUI window created inside a displays. A display can host zero or more windows. A window can be created only in an already initialized display. Widget ~~~~~~ A widget is an atomic element of the GUI. The actual GUI is built as a tree of widgets. The root of the tree is attached to a window. There are two kind of widgets: layout and functional. A layout widget, such as a hbox or vbox is used to arrange multiple child widgets and have no other practical function. Layout widgets are rarely leaf nodes of the tree. Layout widgets are usually invisible. However, it is possible to make layout widgets visible by enabling their frame drawn or changing their background color. A functional widget is typically a leaf node or at least it is very close to the leaves and is used to implement an actual interactive function. For example a label is a functional widget and is always a leaf node, it can not have child widgets. It is functional because it has a text string printed so it always has a visible effect and it is created for that effect. A button is a functional widget, which is created for interaction. However, a button is usually not a leaf node: it hosts a child widget, typically a label or pixmap. (But the child widget can be anything, so it can be a hbox that has a pixmap and a label.) The definitive difference is that a functional widget can not arrange its child widget(s) while a layout widget can. Arrangement means calculating the sizes and coordinates of the child widgets. Widget has properties (states included). Some properties are specific to the widget type, e.g. a label has a text string while a vbox or a checkbox doesn't. There is a set of properties (some states included) that are common to all widgets. Notable examples are boolean states like "activated", "hidden", "disabled". Every widget has and implements these, but how exactly they are implemented is up to the widget code. Events ~~~~~~ Events are low level, generated by the backend. For example a key press, a mouse click, characters on stdin available are all events. Events are specific to a window, not to a widget. The app rarely needs to deal with events. Callbacks ~~~~~~~~~ Callbacks are high level and are made from libmbtk to the app upon changes in widget states or timers expiring or events received. A callback is typically bound to a widget instance. An app installs callbacks on widgets to get notified on events/changes related to the widget. Handler ~~~~~~~ A widget code defines the GUI appearance but does not handle events. A handler is an object (struct and code) that is bound to one widget or a group of widgets and reacts on events. A handler typically updates widget states and generates callbacks as configured. For example the toggle handler operates checkboxes and toggle buttons. A toggle handler is associated with a single widget and it toggles the "activated" state of that widget every time the user does a left mouse button click-and-release sequence over the widget. The toggle handler is installed on a widget after widget creation using the mbtk_handler_toggle_install() call. Most widgets will automatically set a default handler, e.g. a button widget will set pushb, a checkbox will set toggle as handler. This way the app code doesn't have to add boilerplate code for each widget creation just to set the obvious default handler. The app still needs to call handler installation functions when it wants to change how a widget is handled. Libmbtk keeps track on the widget hierarchy and widget focus. Upon an event, it figures which widget is affected. If the given widget has a handler installed on it, it is called with the event. If there is no handler or the handler returns "not handled", libmbtk traverses one level up in the widget tree and retries at the parent widget. This is repeated until a handler reports event handled or until the root widget's handler refused to handle the event (in which case the event is discarded.)