Attribute Editor API Update Proposal
We'd like Attribute Editors to be written by a wide variety of authors in the open source community, and we'd like to see them used in several different contexts. In writting the Attribute Editor Block I became aware that the API makes it difficult to write some of the Attribute Editors that I had envisioned. I'd like to propose that we rework the API to make it as easy as possible to write a variety of Attribute Editors, even though that may make it harder to implement the contexts in which they appear. There may also be performance issues, especially with Table/Grid, which uses an Attribute Editor for each cell.
My goals for the new API are these:
- Provide a way for the Attribute Editors (AEs) to have some state
- Make the decision of when to create a control (widget) private to the AE
- Allow the AE to decide how many controls to create
- Provide a single-inheritance Python class hierarchy to make it easy to write new AEs
There are a lot of little issues surrounding Attribute Editors and their implementation. They include things like validation, event binding and handling, storage management, etc.
I propose that we do a two pass implementation. In the first pass we outline the API we'd like, and try to implement it in rough form, as a proof-of-concept. Then in the second pass we work out the details and make sure the most important issues are solved.
The key issue is how to provide storage to the Attribute Editor. In the current implementation the AEs have no storage - they are stateless except for a single control that exists only when the value is being edited. If an AE is going to be able to be flexible, it will need to keep some state. For instance, it may want to create more than one control - how can it keep track of these controls? And it will want to bind its own event handlers to the controls, so it will need to be able to find its state during a callback.
The natural way to provide state is by allowing an Attribute Editor access to its own instance variables. This means creating a new instance for each location where an AE appears. For the Attribute Editor Block this is no big deal. But for a Grid/Table this means creating a new instance for each cell of the grid before displaying it. I think the performance will be good enough that this won't be a problem. If it turns out to be too slow, we can add some flags to the Attribute Editor classes to tell us if they actually need to be instantiated at render time or just at edit time.
Here is the rough outline of what I'd like to see in the API. A control just refers to any widget created by the Attribute Editor. The notation "..." means other parameters to be determined:
- __init__(self, parentID, item, attribute, style) - construct an instance of the AE
- Draw(self, dc, rect, ...) - renders in the specified DC, rect, etc - usually whatever is outside the control(s)
- onBeginEdit(self, ...) - put the AE into edit mode - usually causes it to create its control(s)
- onEndEdit(self, ...) - exit edit mode - usually causes it to destroy its control(s)
- finalize(self, ...) - prepare to end interaction - usually does validation and updates attribute value
- create(self, ...) - creates the control(s)and binds event handlers
- destroy(self, ...) - deletes the control(s)
- onKey(self, ...) - handles keystrokes inside the control(s)
- onClick(self, ...) - handles mouse clicks inside the control(s)
- For Events that appear in the Calendar, we may want multiple attributes associated with a single AE
- How should we support List/Dictionary attributes?
- Is supporting Python properties worth the added complication?
- Style handling. Can a single style structure be used for both AE matching, and providing font/color style?
- Can we use AEs inside a Toolbar?
- Validation and preserving previous values needs more thought.
- Completion and other user feedback during interaction - some support needs to be in the framework.
- 07 Dec 2004