Miniboxtk is written in plain C89, a language that does not feature modern OOP constructs. Miniboxtk is still implemented in an object oriented manner. Take widgets for example. There is a base structure, mbtk_widget_t. This holds all the fields that are common to all widgets. A specific widget implementation, e.g. the standard mbtk_label_t has all these fields plus may have some more. This is implemented by mandating two things: - every widget must have its own, unique widget struct type - every such struct must have it's first field the same mbtk_widget_t w; Because of these requirements, an mbtk_label_t *lab can be passed on simply as "lab" to functions that specifically work on labels (e.g. mbtk_label_get_str()) or as a generic widget as "&lab->w" for functions that require a widget pointer (e.g. mbtk_box_add_widget() second argument). There are three kind of functions manipulating widgets: 1. truly widget-specific functions; for example mbtk_label_get_str() will operate only on labels and it is implemented in widget/label.c 2. generic functions that can operate on any widget; for example mbtk_widget_set_padding() can set the padding of any widget 3. pseudo widget-specific functions; for example mbtk_label_set_padding() sets the padding on a mbtk_label_t, but the actual implementation is just an inline function wrapper around mbtk_widget_set_padding(). The reason for having pseudo widget-specific wrappers is to move bugs from runtime errors to compile time warnings. Sticking to the label example: - always create and track labels as mbtk_label_t (and not as mbtk_widget_t) - always use mbtk_label_*() functions to manipulate the label itself, never mbtk_widget_*() functions - use ->w only when another specific widget's call requires a generic widget pointer, e.g. when packing the label in a box This allows the C compiler to track your widgets by type. If something gets mixed up, and one part of the code creates a label while another part of the code calls the wrong widget functions, e.g. button functions on it, that will result in warnings. This makes it easier to detect such bugs, such wrong or mismatched assumptions on what a specific widget is. There are a few places of the API where a generic widget is passed on instead of a specific widget type. A callback function always gets a (mbtk_widget_t *). This is because the callback system is widget-agnostic.