Principles of Declarative-Centric GUI systems
- Models of screens, forms, and widget placement are put into data. The form of that could be relational tables, XML, CSV, etc. See DataDictionary for examples.
- Upon start-up or log-in, a copy of the "master layout" is made so that changes to GUI items are only temporary and/or kept isolated to a given user. For example, if a user resizes a screen or if certain fields are hidden for a user due to security levels, these changes don't affect the original or "virgin" template. The copies can be kept across sessions or deleted after each session.
- One of the limitations of XML and other text-based approaches is that you cannot easily see on-line changes to the layout for testing or debugging unless you alter the XML text itself during activity. If one uses a database or database-like structure from the get-go, then viewing the state as it changes is more natural. In practice XML would be turned into some kind of internal database-like structure anyhow. Generally the question then becomes whether that "structure" is relational or non-relational (navigational). A tree-based structure is used in the DocumentObjectModel. FoxPro and certain Oracle tools use relational or semi-relational representations.
- Behavior is generally handled using EventDrivenProgramming. Event-handling code can be put into a master table/file, or attached to individual widgets, like they are in HTML "onClick" tags. Generally, a central table/file makes it easier to alter priorities or sequences of events, if the framework supports such. It also makes it easier to define parallel events for multiple languages. However, centralization complicates the design.
- Events are passed a dictionary-array-like structure that provides information about the event, such as the keyboard key (if any) that triggered it. Some events may have a return value that indicates success or failure, such as validation passage.
- One generally does not create new reusable widgets from scratch using such frameworks. Integration of new widgets into the framework would be done by a "framework expert" rather than an application developer or GUI designer.
- Declarative GUI systems may not be suitable for game development or in situations where heavy use of specialized, fast graphics is needed. They are ideally suited for language-neutral frameworks that attempt to divorce GUI design and IDE's from a specific language. They are also well suited for RemoteGuiProtocols, especially if non-TuringComplete is a desired goal for client-side content for security reasons.
Some kind of API is needed to read or write attributes. Some prefer "path-oriented" approaches where there is a composition hierarchy (example: windowX.frameY.widgetZ.attributeA.value). Another is the "compound key" approach. For example, each attribute may be referenced via 3 "keys":
- Window
- Widget
- Attribute name
Example API calls:
custName = attribValue("order_form", "customer_name", "content")
Xcoord = attribValue("order_form", "customer_name", "x_coordinate")
setAttrib("order_form", "customer_name", "content", "Fred Jones")
There may still be sub-form level containers or widget groupers of some sort (perhaps even orthogonal), but each widget still has a unique name/ID within a given window. This allows grouping or containment to be changed without impacting existing code.
Inernally, "applicationID" and "userID" may also be part of the "key", but these are generally determined from context, such as a global (per user) "sessionInfo" object or structure, and thus don't need to be explicit parameters for the vast majority if widget calls.
See also: NonOopGuiMethodologies, EventDrivenProgramming
CategoryUserInterface