This document describes the common philosophy to integrating OOFILE into application frameworks. This is a first pass at these classes, after spending a while looking for common elements in the PowerPlant, TCL, zApp, OWL and TurboVision frameworks. Please provide as much comment as possible.
The philosophy of GUI integration is based around making life easy for existing programs, as well as new ones. Inheritance is NOT used to add behaviour, so your class hierarchy doesn't change. Where behaviour can be standardized, a call to a "helper" class wraps our behaviour. eg: a dbDocHelper would be called in response to a command, possibly handling a standard Add command.
See "guicases.txt" which describes the typical events in a gui database application in terms of Use Cases.
See also "guihooks.txt" which describes the points
Class Responsibilities relating to database applications
1) Ownership implies creating/destroying an object
2) Obey refers to some command travelling up the chain
3) An Application may have a single document, representing a fixed database, or
support the paradigm of multiple documents, with possible limit on how many
can be opened concurrently.
4) Document and ListWindow may be combined in frameworks lacking an explicit
Document class (eg: with zApp)
Application
Owns Documents that manage different document types
Owns Application level alerts and dialogs, eg: About box
Obeys Display Application-level windows
Document
Owns relevant data files/databases
Owns Browser windows
Owns Editor windows
Creates/Opens databases
Defines database, including runtime definition of Relationships
Obeys Edit/Delete/Create record
ListWindow
Owns browser panes
Knows structure of database classes shown
Receives a dbView to display
Obeys Sort listed records
Obeys Search to change list of records
EditWindow
Owns editing panes, including embedded tables
Knows structure of database classes edited
Receives a dbTable subclass to edit
Obeys Save/Cancel current record
Obeys Move To Another record (first, prev, next etc.)
OVERALL DESIGN
The first approach to the gui classes will re-implement classes for each environment. This is because
1) it's easier to get started
2) in some cases it won't be possible to inherit methods due to parameters (eg: window types) varying according to the framework we use.
3) the GUI integration classes are designed to be a very lightweight set, working cleanly with the chosen framework.
ABSTRACTIONS PROVIDED
From the view of a typical database application, we can categorize:
Browsing
- displaying lists of records, possibly 100,000's of records, too large for
memory-based displays
- commands (probably attached to buttons)
- navigate (First, Prev, Next, Last)
- change records (Add, Delete, Modify, View)
- search
- sort
- philosophic difference between single record screens
- any time record is shown, change is allowed
- explicit Modify vs View commands
- browser display may change when no records
- because file empty
- because selection empty
- scrollable browser areas will often not occupy the entire window, but may have
a button or descriptive area above or below.
- browsers have a header area that displays column titles and later will allow
mouse responses - click to sort, drag columns, drag dividers etc.
Editing
- link edit fields to database
- link embedded tables on screens to related files
- handle multiple dialogs corresponding to several pages on same object
- navigation buttons, with philosophic difference on moving to another record
- save is implied
- user alerted if changes made, and asked if want to save
Note:
A lot of the Browser behaviour would be expected to spill over into the GUI report-writer.
DETAILED ISSUES and FRAMEWORK BEHAVIOUR NEEDED
Scrolling Browsers
Most frameworks have a mechanism for linking the scrolling of the window to a given feedback function or pane within the window.
A common need is non-scrolling areas adjacent to our dbBrowsePane. At this stage it seems like we can get away with leaving it to the framework. If this fails, we will have to abstract things with a nesting of:
dbBrowseWrapper
someOtherPane
dbBrowsePane
someOtherPane
The scroller would in this nested case send scrolling messages to dbBrowseWrapper which would forward them to dbBrowsePane. This should only be necessary if we have a framework which insists on a single pane within its scrolling windows.
EDIT HANDLING - INHERITANCE vs LINKING
The first round of GUI integration classes was with zApp. This framework is more sophisticated than others with edit forms - it automates the process of storing data in the edit fields. By inheriting from the standard edit fields, and override StoreData(), we had a very simple way of updating the database.
However, this approach is not provided for us in other frameworks. It would be easier to move between frameworks if OOFILE worked very similarly in all cases.
Most importantly, if OOFILE links to edit fields by subclassing, this removes your freedom to subclass for your own reasons.
For the above reasons, it was decided that the general philosophy should be that OOFILE communicates with edit fields via an intermediate dbFieldLink.
This abstraction gives us a lot of flexibility - a dbFieldLink subclass could communicate with a different source of data (eg: a comms link) to update a field.
MULTIPLE-PAGE EDITING
This first gui release will probably not include support, but here's an outline.
Issues:
1) the same fields often show up on subsequent pages, so editing in one page
must flow through to the others.
2) for speed reasons (and sometimes to limit memory leaks) we may hide dialogs
rather than destroying them, as we move to the next page. This may occur only
when moving between pages, or dialogs may persist (hidden) for the life of
the program.
BROWSER PANES
The issue of column widths and horizontal scrolling is a complex one. Let's confine the panes to the case where the containing window has scrollbars and the contents of the pane scroll in reaction, similar to a WP document.
There are three choices for setting the width of the pane
1) a fixed width, based on an ideal document/window width
2) a fixed width, totalling all the specified column widths
3) a variable width with the window changing size
In 1) and 3) we have to decide how to divide space amongst columns. Given each column (field) has some ideal entry width, the intuitively appealing approach is simply proportionally dividing the browser width. This runs into problems when mixing text and numeric data. In many scenarios, it is more desirable to lock some columns at a fixed width and make the others proportional. For example, a date or serial number is of little use if only a portion of the column is visible. (In the case of dates, a more sophisticated future version might change the date display format to match changing width.)