PROCEDURE Do (m: Model; name: Domains.OpName; op: Domains.Operation);
PROCEDURE LastOp (m: Model): Domains.Operation;
PROCEDURE Bunch (m: Model);
PROCEDURE StopBunching (m: Model);
PROCEDURE Era (m: Model): LONGINT;
END Models.
Picture 5.6a Model-View-Controller Separation
A model is one component of a Model-View-Controller triple. A model represents some data, without knowing how these data may be represented. Representation is performed by a view. There may be several views displaying the same model simultaneously, and possibly in different ways.
After a model has been modified, a model message is broadcast in the domain to which this model belongs (e.g. the domain of the document of which the model is a part). Model messages are received by the appropriate views, such that these views can update the display according to the model modification which was performed.
A modification of a model may be permanent, or reversible. To indicate a permanent modification, the procedures BeginModification/EndModification must be called before/after the modification(s). Reversible modifications ("undoable" operations) are implemented as Domains.Operation objects. Several operations on the same model can be combined into one (i.e. as a whole undoable/redoable) operation with the BeginScript/EndScript pair of procedures.
A model may be a container, i.e. contain embedded views. An embedded view can communicate with the model in which it is embedded via a Context. A container model provides a context for each embedded view. Using its context, a view can inquire its current size, or it can try to change its size.
TYPE Model
Interface, Extension
A model represents data, which may be presented by a view.
Models are allocated by specific model directories, e.g. by Texts.dir.
Models are used by commands which can operate on the data that is represented by the model.
Models are extended whenever new kinds of displayable data need to be represented.
PROCEDURE (m: Model) Clone (): Model
Default, Extension
Result type is narrowed to a model.
Clone is used as part of a copy operation.
Clone is sometimes extended in order to yield a narrower result type, as is done here for (s: Store) Clone (): Store.
result.domain = NIL
TYPE Context
Interface
A context object is part of the model-view recursion scheme of Oberon. A context is generated and maintained by a container model, and there is one context for every view embedded in the model. The context is carried by the view, so the view can communicate with its context (i.e. with the model in which it is embedded).
A Context is used for the communication between container and contained view.
A Context is extended for every container model.
PROCEDURE (c: Context) ThisModel (): Model
Default
Returns the context's model. NIL may be returned if the context doesn't want to disclose its identity.
ThisModel returns NIL as default, but may be overriden to return the context's model.
Returns the width and height of the contained view in its container.
w >= 0 & h >= 0
PROCEDURE (c: Context) SetSize (w, h: LONGINT)
interface
Requests the container to adapt the size of c's view to the given width and height. The container may or may not grant this request.
PROCEDURE (c: Context) Normalize (): BOOLEAN
Determines whether the contained view should normalize its persistent state upon externalization, and whether it should not make a modification of this state undoable.
As an example, consider the scroll position of a text view: if the view is in a root context, i.e. in the outermost view level, it should write out position 0 (i.e. "normalized") as its current scroll position upon externalization, and it shouldn't make scroll operations undoable. However, if embedded in a non-root context, it should write out its current scroll position, and should make a scroll operation undoable.
Normalize is called in a view's Externalize procedure and when it must be determined whether an operation needs to be undoable or not.
PROCEDURE (c: Context) Consider (VAR p: Proposal)
Emtpy
If an embedded view wants its container to do something, it must ask for such a change by sending the container a Proposal via the Consider procedure. The container may, but need not, cooperate in an appropriate way. Oberon/F currently doesn't predefine proposals of its own.
TYPE Message
Interface, Extension
Base type for all model messages.
Messages are used to transmit information from a model to all views which display this model.
Messages are extended to describe specific kinds of information to be transmitted.
model: Model model # NIL
The model that has been changed.
era-: LONGINT
Used internally.
TYPE UpdateMsg
Extension
All model messages which notify about a model modification must be extensions of UpdateMsg. A basic (unextended) UpdateMsg indicates that the message's model has changed in some unspecified way.
UpdateMsgs are used to notify all views displaying a given model about a change of this model.
UpdateMsgs are extended in order to update the display in more specific ways than to redraw the whole view (i.e. faster and with less screen flicker), i.e. to allow partial updates.
TYPE NeutralizeMsg
Extension
This message is sent by the framework to indicate that marks (selection marks and the like) should be removed.
TYPE Proposal
Interface, Extension
Base type for all proposals. A proposal is a message which a view can send to the model in which it is embedded.
PROCEDURE Broadcast (model: Model; VAR msg: Message)
Broadcast msg for model. Before broadcasting, parameter model is assigned to the message's model-field. The broadcast is actually performed only if model.domain # NIL.
Broadcast is called by models whenever models need to transmit information to the views by which they are displayed.
model # NIL 20
msg.model = model
PROCEDURE Domaincast (d: Domains.Domain; VAR msg: Message)
This procedure sends a message to a particular domain, or does nothing if the domain is NIL.
PROCEDURE BeginModification (m: Model)
If model m is modified in a way that cannot be undone, the modification(s) must be bracketed by calls to BeginModification and EndModification.
m # NIL 20
PROCEDURE EndModification (m: Model)
If model m is modified in a way that cannot be undone, the modification(s) must be bracketed by calls to BeginModification and EndModification.
To make a sequence of undoable operations undoable as a whole, the sequence should be bracketed by calls to BeginScript and EndScript. The same script which has been returned in BeginScript must be passed to EndScript.
m # NIL 20
script # NIL 21
PROCEDURE Do (m: Model; name: Domains.OpName; op: Domains.Operation)
This procedure is called to execute an operation on a model. The operation's Do procedure is called, and the operation is recorded for a later undo.
m # NIL 20
op # NIL 21
op.inUse
PROCEDURE LastOp (m: Model): Domains.Operation
This procedure returns the most recently executed operation on the given model. It can be used to bunch several actions into one operation, e.g. if a character is typed into a text, it may be bunched with the previously inserted character; such that an undo operates on the whole text typed in, and not on one character per undo.
m # NIL 20
PROCEDURE Bunch (m: Model)
Notify model that another action was bunched to the most recently executed operation.
m # NIL 20
PROCEDURE StopBunching (m: Model)
Prevents any further bunching on this model's current operation.