Full refund within 14 days of purchase date.
The Problem
Graphical User Interfaces are notoriously tricky and difficult to program: so much information to keep track of, events that must be handled, anticipating user actions, keeping all widgets properly updated, etc.
One aspect of good UI design is maintaining an accurate and consistent relationship between the User Interface state (at any given moment) and how all widgets should be presented when any given UI state is "active".
However, keeping this relationship well-behaved, consistent, and always accurate is a non-trivial exercise in programming GUI applications. And, worse still, when the total number of states and total number of widgets that must be managed is large, the problem increases dramatically in scale and complexity.
But why must this be so? Isn't there an easy way to handle this situation without all the work and pulling-of-hair that normally comes with it?
The Solution
With the GTK+ Widget State Manager (WSM) maintaining this relationship is made easy, logical and obvious.
Now, instead of having to keep track of what you need to do to every widget at every UI state change, simply call the WSM routine to invoke the new UI state and all widgets are updated automatically, guaranteeing consistency and accuracy 100% of the time.
Functionality
You do this by registering each widget needing to be managed (at widget creation) with the WSM library, defining exactly how the widget should appear for each defined UI state.
As delivered the WSM allows control of the following widget state settings:
Features
wsm_set_UIState( WSM_UISTATE_**APP-STATE** )
Advantages
Extensibility:
Deliverables:
Target Users:
Technical Requirements:
Installation:
#include "wsm.h"
// In this example, we have the following GUI states to manage:
// 1) No Connection to a Database - DBNOCONN
// 2) Connected to a DB in read-only mode - DBDISPLAY
// 3) Connected and able to edit DB - DBEDIT
// 4) Not connected but creating a new DB - DBCREATE
// All of these known states are referred to using their ENUM specifier:
// WSM_UISTATE_APPSTATE - where APPSTATE is one of the above values
void makeWidgets()
{
// A Connect Button that is only displayed when no DB Connection exists, otherwise not visible
button = gtk_button_new_with_label("Connect");
wsm_assign_visible(WSM_UISTATE_DBNOCONN, WSM_TRUE, button);
wsm_assign_visible(WSM_UISTATE_DBDISPLAY, WSM_FALSE, button);
wsm_assign_visible(WSM_UISTATE_DBEDIT, WSM_FALSE, button);
wsm_assign_visible(WSM_UISTATE_DBCREATE, WSM_FALSE, button);
// An Entry Area that is only editable when creating a database, otherwise read-only
entry = gtk_entry_new();
gtk_widget_set_tooltip_text("Name of the Database");
wsm_assign_editable(WSM_UISTATE_DBNOCONN, WSM_FALSE, entry);
wsm_assign_editable(WSM_UISTATE_DBDISPLAY, WSM_FALSE, entry);
wsm_assign_editable(WSM_UISTATE_DBEDIT, WSM_FALSE, entry);
wsm_assign_editable(WSM_UISTATE_DBCREATE, WSM_TRUE, entry);
// A 'SAVE' button that is sensitive only when editing a database, otherwise not selectable
button = gtk_button_new_with_label("SAVE");
wsm_assign_sensitive(WSM_UISTATE_DBNOCONN, WSM_FALSE, button);
wsm_assign_sensitive(WSM_UISTATE_DBDISPLAY, WSM_FALSE, button);
wsm_assign_sensitive(WSM_UISTATE_DBEDIT, WSM_TRUE, button);
wsm_assign_sensitive(WSM_UISTATE_DBCREATE, WSM_TRUE, button);
// A more complex and interesting example where we have:
// A Frame widget housing a Horizontal Box...
// ...this Box housing a Label and Entry Area
// Here we want to achieve the following:
// 1) frame (and all contents) is visible only when connected to a DB
// 2) entry area is editable only when in DB Edit and Create modes
frame = gtk_frame_new("WSM Example Frame");
hbox = gtk_hbox_new(FALSE, 0);
label = gtk_label_new("DB Description:");
entry = gtk_entry_new();
gtk_container_add(GTK_CONTAINER(hbox), label);
gtk_container_add(GTK_CONTAINER(hbox), entry);
gtk_container_add(GTK_CONTAINER(frame), hbox);
// set the entry area states
wsm_assign_editable(WSM_UISTATE_DBNOCONN, WSM_FALSE, entry);
wsm_assign_editable(WSM_UISTATE_DBDISPLAY, WSM_FALSE, entry);
wsm_assign_editable(WSM_UISTATE_DBEDIT, WSM_TRUE, entry);
wsm_assign_editable(WSM_UISTATE_DBCREATE, WSM_TRUE, entry);
// set the frame states
wsm_assign_visible(WSM_UISTATE_DBNOCONN, WSM_FALSE, frame);
wsm_assign_visible(WSM_UISTATE_DBDISPLAY, WSM_TRUE, frame);
wsm_assign_visible(WSM_UISTATE_DBEDIT, WSM_TRUE, frame);
wsm_assign_visible(WSM_UISTATE_DBCREATE, WSM_TRUE, frame);
// assign all other widgets appropriately as they are created
//...
}
int main(int argc, char **argv)
{
// make the widgets of our UI
make_widgets();
// Initialize UI Display State to NO DB Connection
wsm_set_UIState(WSM_UISTATE_DBNOCONN);
gtk_main();
exit(0);
}
Questions & Comments