Detail View Implementation Plan for Release 0.4
This is the plan for implementation of the first cut at a Detail View, expected to be released in Chandler 0.4.
Summary of the Build Plan
The Detail View will be built using a top-down staged approach. We'll start by building something simple from the existing container blocks, and rapidly get it functioning. Then we'll start working from the bottom up to build support in CPIA for the specialized blocks needed for the Detail View. Along the way we'll be looking to make improvements to CPIA in areas that cause difficulty. We'll try to be careful to anticipate potential changes in the way attributes are organized in ContentItems, and the UI Design in general. Hopefully this staged approach will help us determine some design issues that are not yet clear: e.g. the best way for blocks to communicate changes among themselves. Some issues are beyond the scope of the 0.4 timeframe (e.g. extensibility), but we'll try to be mindful of these areas during implementation so we'll have a better idea how to tackle them on the next release.
Implementation Stages
We plan to use a staged approach in building the Detail View. It's a complicated block, and there are lots of unknowns, so we plan to start with a very simple framwork, and then fill in the details section by section.
The first stage will be to create a dummy looks-only version of the View. This will visually demonstrate overall layout of the second-tier blocks. The Top Level block will be populated with dummy blocks that will use a solid color, or some other means, to identify the areas defined for the second tier blocks. Basic resizing functionality should work at this level, so we can grow the view and observe how the second-tier blocks grow or move.
The second stage will be connecting the Detail View to the SummaryView. We'll verify at this stage that the SelectionChangedEvent is being recieved and propigated to the second tier views as appropriate. Some additional functionality will be needed from a second-tier block so we can see that it's working. Ideally we'll show some form of title such as the Headline, and some useful portion of the item such as the
NotesArea. At this point it should
start to be useful: you can browse from item to item and see the body of an Mail or the notes associated with a Task or Event.
When the second stage is completed, we should have something that looks like this:
The third stage will be the initial fleshing out of the second-tier blocks. We'll look at each of these blocks and decide:
- Can it be reasonably built from existing blocks?
- Does it affect overall layout or affect other blocks?
- Are there significant unknowns in implementation or behavior of this piece?
The general idea will be to build the pieces that we can do quickly imediately, and defer construction of blocks that we don't fully understand or blocks that might need to be significantly changed later. In some cases we may use component blocks that are not the right ones, but give us basic functionality, with the asumption that it will be straightforward to replace the components with the right ones when they become available.
The fourth stage will be constructing the missing blocks needed for the Detail View. There are several blocks that are generally useful which appear in the Detail View that don't yet exist in CPIA. An example is the "expanding" block, which grows and shrinks when the user clicks on a triangle icon. I don't think CPIA has this block yet. We'll build it and plug it into CPIA, and into the Detail View.
At this point we should have most of the Detail View implemented, working, and looking more or less as designed. This would be a good point to do a review of how well it works, anticipated changes, open issues, etc.
The fifth stage is a total redesign and rebuild based on feedback from customers (above). Seriously now, we'll want to make adjustments based on feedback and changing requirements.
The sixth stage will be polishing the user experience, tying up loose ends, code cleanup, and addressing any usability issues that affect the Detail View from other parts of CPIA.
Top Level View
The root block of the Detail View is built from a BoxContainer block. It listens to the SelectionChangedEvent, and displays the associated ContentItem. The root block has several Children that also have access to the SelectionChanged Event and the current selected ContentItem. An EventBoundary surrounds the root block, and also any Children that don't need access to the SelectionChangedEvent (see below).
There are two parts of Chandler's Chrome that interact with the Detail View. The most obvious is the SummaryView, which selects the item to be displayed in the Detail View. Additionally, there is a
ToolBar that operates on the selected item as a whole. Some of the controls in the
ToolBar perform markup modifications that must be reflected in the Detail View. Examples are the "Junk" button, which essentially disables most of the blocks inside the Detail View. Reply and Forward buttons also affect parts of the Detail View, such as the
NotesArea. Communication with the
ToolBar will probably be done via Events in a way that's similar to our use of the SelectionChanged Event.
In general, the second tier blocks each provide interaction with a subset of the current item's attributes. E.g. the
NotesArea block just provides access to the ContainedNotes attribute. However there are two complications: 1) The current selected ContentItem may actually be
multiple ContentItems that are linked by stamping. 2) Individual blocks may have several states that alter the way they present their attributes. The root block is the logical place to put code to help deal with these complications. Specifically, we'll deal with 1 by implementing a uniform attribute access scheme (
below) to provide a single programatic way to access any attribute, which insulate the Detail View code from the details of whether that attribute lives in a different ContentItem linked by stamping. I'm not yet sure what we'll want to do about 2. It could be that support for enabling and disabling second-tier blocks should live here, so that globals decisions like how to handle items considered "Junk" are localized instead of being spread out among all the second tier blocks.
Questions:
- Are there other events that this block needs to send or receive? DataChangedEvent?
Composite Blocks
The Detail View is actually a hierarchy of BoxContainers, since the second-tier blocks are themselves composed out of smaller blocks. I'm using the terms "Composition" and "Composite Block" to refer to blocks that are BoxContainers containing other CPIA Blocks. At some point down the hierarchy we get to leaf nodes where the CPIA blocks are no longer Composite Blocks, they have associated Widgets that provide features beyond simple containment. These "Widget" blocks may have more than one wxWidget associated with a single block. I think of these as multi-widget blocks. An example is a "labeled field", which provides edit text for entry and a static text label next to it. Deciding the right granularity of the leaf nodes is a design decision: we can build some branches out of Composite Blocks and others out of multi-widget blocks. There's a trade-off in terms of performance, flexability and ease of use between these two implementations. In general, multi-widget blocks are less flexible but perform better and are easier to use because there's only one CPIA block used. We'll want to have the flexability of Composite Blocks near the root of our hierarchy, but we'll want to use multi-widget blocks as we get farther away.
Here's a quick overview of how we expect to build each of the second-tier blocks in the Detail View.
- MarkupBar - This will be a Toolbar block populated with ToolbarItems. The ToobarItems will include Choice, ComboBox, and Image Button blocks.
- FromAndToArea - Initially built from a View block containing simple StaticText and EditText blocks, we may eventually transition to LabeledField blocks.
- CoreArea - This View block contains two ComboBox blocks for the RemindMe and Recurrence blocks. It also contains an EditText block that will transition to a DateTime block when it becomes available.
- StampedEmailArea - This needs to be an Expandable block once they become available. Until then, we can just use a StaticText block that will show the expanded form of the Mail.
- NotesArea - This EditText block is one of the few straightforward blocks for 0.4. However, we need to be careful about how all EditText blocks interact with the Edit menu. For a later release we may need to support some of the common MIME types sent in Mail, e.g. HTML, images, etc.
- MessagesArea - This View block has two sub-blocks: MessageLog which is multiline StaticText that gets updated periodically; and MessageStats which has two StaticText blocks that describe the last change - one with a Contact who made the change, and one with the DateTime of the change.
- SharingBar - This View block contains an EditText block, a RadioBox with two Choices, and a Text Button block.
- LabelingArea - Not sure about this area yet. Once they are available, it should be an Expandable Tray block, but in the meantime it will probably just be a View. The Child blocks are also ill-defined, but probably ComboBox blocks that allow the user to choose from several existing labels, but also there will be a way to make new labels here probably through one or two EditText blocks.
Blocks Needed for Implementation
Here's a list of multi-widget blocks that we'll want to add to CPIA.
- Labeled Text Field - Edit text widget with a static text label to the left of it.
- Date/Time Field - Edit text that displays either a single date and time, or a date time range. Ideally this has flexible input semantics that allow the user to edit any section of the text and type shorthand to get validated results. It also has some iconic buttons to allow bumping values up and down in various portions of the field. Perl has a great date parser that can do a good job of conversion from string to DateTime. We'll probably look into the support provided by the "time" and "calendar" modules and start by using the strptime() function for an intial parser.
- Expandable Block - a block with an expander button that allows it to grow from its contracted size to its expanded size. This acts a lot like a splitter window in that it has two child panes and a visual control for adjustment between them.
- Expandable Tray - when an Expandable block is at the edge of a window, it can look like a tray that pulls out from the window. We'll probably build a CPIA block for this to take advantage of the great look and feel provided on some platforms, and it may look like a more generic expandable block on platforms that can't display the nice "tray" behavior.
Open Issues
There are three issues that deserve special mention:
- Events and Interaction - how we organize all the communication between blocks and sub-blocks.
- Extensibility - how we extend the Detail View to support Contacts, and 3rd party Items.
- Attribute Access - dealing with anticipated changes to the ContentModel with respect to stamping.
Events and Iteraction
Handling the interaction between the different blocks in the UI will probably be done with Events. I'll probably build direct item references between blocks so the event sending can be somewhat localized. Which Events will be used, and how they will be dispatched is still an open issue in my mind. I'll be looking at how Menus interact with the selection to see if there is a model that can be adopted for Toolbar blocks, or some of my other blocks to help with the interaction. Hopefully whatever we build will not preclude displaying multiple Detail Views.
Extensibility
Will we be able to support Contacts, and 3rd party Items? I think we can tackle these issues after 0.4.
Uniform Attribute Access
The Content Model for Stamping is still an open issue. If we can find a way for the code in the Detail View to be insulated from changes in that model it would be a good thing. One idea is to use the __getattr__ and __setattr__ hooks to capture access to attributes and redirect them as appropriate. This may be difficult because Andi is already using __getattr__ for the repository. We could probably work around this by creating an "accessor" object that has a reference to the actual ContentItem, and uses its own __getattr__ to map the attributes from the ContentItem(s) onto itself. The drawback is that there's another object that needs to be communicated down through the hierarchy of blocks to each view.
--
DonnDenman - 24 May 2004