CPIA, Chandler Presentation and Interaction Architecture, is the user-interface framework that we use to build Chandler.
Most UI frameworks (like wxWidgets) are all about user interface and not about either the data that the UI displays nor the interaction between different elements of the user interface. To use those frameworks you need to write code that populates the user interface elements, stores the data and manages much of the interaction between UI elements.
In contrash CPIA automatically manages the storage of the data, changes to it, and display of it for you.
CPIA handles data using Chandler’s built in Repository. The Repository looks a lot like a persistent object database, it stores Items, which are organized into classes where each class contains a well defined set of attribute value pairs. Items are used to store e-mails, tasks, calendar events, other user data, and even Python objects.
Collections, another type of Item, are sets of Items. For example, the set of all e-mail items is a collection. Collections can be combined using Boolean set operations and filters to make new collections.
CPIA stores the state of the UI in Blocks. Blocks are Items, they are Python objects persisted in Chandler's Repository.
A typical CPIA Block might have an attribute called contents which contains either a Collection or Items that the Block displays. For example a Table Block would automatically display all of the items of its contents attribute in a list. It also would automatically handle the editing of data in the table. So instead of writing code to read data into a table, handle the editing, and store the changed data, all you need to do in Chandler is set the contents attribute of the CPIA Block.
Collections are dynamic. For instance, when new e-mails arrive, the collection of all e-mails is automatically updated. CPIA Blocks are notified when their contents change and automatically update their display.
Blocks come in many flavors. Besides the table block mentioned above, there's a list block and a tree block. There are container blocks that lay out their child blocks, e.g. tables, lists and trees, horizontally or vertically, or separated with a splitter. There are menu blocks and toolbar blocks.
The Attribute Editor block displays and edits an attribute of an item. It uses knowledge of the kind of data of the attribute along with explicit formatting hints to decide what user interface to display and edit the attribute, e.g. edit box, drop down list, check box, etc., automatically adapting to different kinds of data.
Blocks are organized into trees. For example container blocks layout children blocks, the menubar contains children menus, which may contain children submenus, toolbars contain child toolbar items. In fact all of the user interface is just a tree of Blocks.
It's often the case that an item, for example your collection of e-mails, needs to be displayed with a particular user interface, or tree of blocks.
There is a special block called the TrunkParentBlock, which is responsible for mapping a tree of blocks to an item. In Chandler it's responsible for choosing the calendar view tree of blocks to view calendar items, and choosing the detail view tree of blocks to view a particular kind of the item in the summary view.
When a new tree of blocks is displayed, its menu and toolbar blocks are reflected in the user interface. This allows a tree of blocks to provide new application functionalities.
Blocks are not user interface widgets. Instead, they contain the data necessary to construct user-interface widgets and they save the state of user-interface widgets.
For example, a table block might contain the contents that a widget displays, the scroll position of the table, an indication of which attributes to display in which columns. Before a block can be displayed, a widget is constructed and initialized to the data stored in the block. Unlike widgets, Blocks persist across invocations of the application. The widget is the user interface element that you actually see on the screen. In the model view controller paradigm, the block is the model and the widget is the view.
Although blocks are intended to be independent of the widget, and support different widget frameworks, today CPIA only supports wxWidget widgets.
The "interaction" part of CPIA is provided by CPIA Events. CPIA Events are items in the repository which exist completely outside the user interface. A menu or toolbar Block refers to a particular CPIA Event. When that menu is chosen or the toolbar button is pressed the CPIA event is dispatched to one or more Blocks.
An example of an Event is the SelectItem Event. It is broadcast whenever the user selects an item in the Table. A block that handles the event might be a TrunkParentBlock, that chooses the detail view tree of blocks to display the item. Almost all the communicatation between bocks happens using CPIA Events.
Almost all the information about the Event, e.g. what to do, how to dispatch it, are attributes of the Event.
Events describe high-level application functionality, e.g. Cut/Copy/Paste, not low level events like mouse moved, keypress, or button press events.
CPIA Scripts are able to drive the application with little more than dispatching a series of CPIA Events.