18.5.11 Custom presentations
Presentations are not limited to the default ones shipped with Glamour. Instead, if you desire a specific kind of interaction for your browser, you are encouraged to create a new Presentation.
A simple example such a presentation would be one that would allow us to embed any widget from the underlying GUI framework. Glamour already comes with a MorphicPresentation which does nothing else but enable the display of Morphs provided by the Morphic framework of Pharo.
As an example, suppose we want to reuse the Smalltalk Inspector by embedding it in a larger browser for inspecting classes from a model. For this we can simply retrieve the morph of the Inspector on each class as in the code below:
| browser |
browser := GLMTabulator new.
browser title: 'Class Inspector'.
browser column: #classes; column: #inspector span: 2.
browser transmit to: #classes; andShow: [ :a |
title: 'Classes' ].
browser transmit to: #inspector; from: #classes; andShow: [ :a |
title: [ :class | 'Inspector on ', class name];
display: [ :class |
layoutPolicy: ProportionalLayout new;
addAllMorphs: ( Inspector openAsMorphOn: class ) paneMorphs;
yourself ] ].
browser openOn: MooseModel root allModels anyOne allModelClasses.
Executing the code leads to a user interface that spawns an Inspector for every selected class. Each of these Inspectors offers the same interaction as in the regular incarnation.
While it can be straightforward to build presentations that mirror the user interface widgets, it is desired to build presentations that provide a good abstraction for browsing. Four things are important to keep in mind:
- Presentations should focus primarily on data and on the goal of data interaction;
- They should provide an API suitable for scripting;
- Because ports are the means to propagate information to the outside of the pane, it is desirable for Presentations to populate at least one port (typically the
#selectionone). Ideally, it should also populate and react to other ports as well.
- Even if the Presentaion does not populate a port, it is advisable to at least allow for Actions to be defined for them. Thus, the user would have the option of using these Actions to populate ports or to change the model.