ReactiveUI is going to be a new user interface for Squeak. It will be able to be a drop-in replacement for Morphic and MVC.
ReactiveUI will run in a Site and will use the APIs provided by a SiteBrowser.
No code yet; only the ideas below. This project will not be started until the Unnamed Grand Project has been released, and this will be built using UGP as a base.
This is done by:
These are defined at a higher level than the requirements above:
ReactiveUI will run on a Canvas. It can run within Morphic, MVC, or full-screen. It will be a "Reactive User Interface" as the name suggests; it will always be responsive by intelligently using threads.
Every 100ms, the whole UI will be redrawn with optimisations that prevent things that are current from being re-redrawn.
The root Canvas of ReactiveUI will have some widget that takes the place of the PasteUpMorph in Morphic. This contains sub-widgets. This main widget will receive all events and cause all redraws, and will pass events down to it's subwidgets. Subwidgets then pass those events to their subwidgets etc. Events are things like keypresses, mouse movements etc.
There will be a core set of sub-widgets which can draw themselves very quickly: buttons, lists boxes, sliders, tables etc which form the core widget set. They store enough state in themselves to draw themselves WITHOUT CALLING METHODS on their targets. In this way, reactiveness is guaranteed.
If a sub-widget is not in this core set of trusted quickly drawing widgets, then it will be forced to draw itself in a separate thread of execution.
When targets change, these widgets will update their state (somehow). This will happen in separate threads and will not affect drawing operation timing at all. There are two ways I can think of for updating state: (1) use the magic Object>>addDependant:... APIs, or (2) after each redraw fork off a thread to check if the target has changed.
The following threads are needed:
The drawing thread draws the display. This thread draws the whole display and then sleeps until the next screen refresh. Trusted widgets (the built-in ones) have >>drawOn: invoked directly by this thread, but untrusted widgets are drawn in a managed forked thread to preserve reactiveness. If untrusted widgets do not finish drawing themselves before the next screen refresh, the progress of their drawing is replaced on screen with a "widget is busy" canvas until the thread completes.
Widgets are assumed to have already done all of their layout and content filling; the draw method should be as fast as possible. Drawing theads should never block.
XXX this is slow. It is faster if each widget can redraw itself in event-handling code.
Events are received from the input devices and occur on a particular sub-canvas - either as a mouse event or as a keyboard event on the canvas which has keyboard focus. Events should be delivered in sequence through a SharedQueue; this is done to prevent, for example, keyboard or mouse events from arriving and being processed out of order. Writing to an event queue should be non-blocking; reading from and event queue should block until an event is available.
XXX this is potentially slow - event reactivity would depend on the scheduler's behaviour.
The layout can be computed at any stage. Typically, it would be eagerly computed rather than lazily computed.
Events carry the Canvas of the current Widget with them so that the widget can quickly redraw itself without needing to recurse the entire drawing graph again.
Two different event streams are used: one for when the user edits text and manipulates widgets, and another for the application's updates to widgets. When the user edits things, the model should be updated, but when a widget's value is modified (e.g. as a result of the model changing by other means), no update events should be propogated (cf: Swing's JTextField's setText(...) method, which is used for both and causes headaches).
A timer or stepper could also provide a source of events for animations.
Idea: perhaps applications should be able to insert their own events, e.g. command events can either come from the keyboard or from a tool bar.
Every widget has a minimum size, maximum size and preferred size (cf: Swing's JComponent).
Every widget can be greedy (taking all available space), conservative (only taking the required space) or static (having a preferred size and sticking to it).
The Core widgets are "built-in" and trusted; they are drawn in the same thread as the GUI. Core widgets use a model but store enough state to very quickly redraw themselves.
Core widgets include:
Lists would have a model that keeps track of the current selection and items in the list.
Items in the list are lazily loaded; it is possible to have a list of items on the UI which can't fit in memory.
From these components, more complex components such as dialogs can be built.
A document is a collection of paragraphs. Types of paragraphs include:
Each paragraph can be locked by a particular user for editing, allowing multiple users to edit the document at the same time. Changes to a document can be recorded on a per-paragraph basis so that changes between versions of the document can be viewed.
A document is stored as a list of paragraphs (cf: Swing elements).
Also stored in that document are formatting changes - changes of margin, alignment, number of columns, whether a particular paragraph is floating or not, etc. It's a good idea to look at the OpenDoc format for suggestions.
Code can be a type of paragraph! This will allow automatic formatting and execution inline.
Page Information
|
Wiki Information |
Recent PBwiki Blog Posts |