-
Notifications
You must be signed in to change notification settings - Fork 7
Add a new plugin to Pyramid
Pyramid makes it easy to add plugins. A plugin is a module that adds new functionalities to the editor. It provides access to various information and systems linked to the editor, such as the list of root elements, the list of selected elements, the command execution system with integrated history, the properties presentation panel, the editor view, etc.
To add a plugin, simply create a new class and register it in the PyramidPluginManager singleton. The new class must implement 3 methods:
-
#addPanelsOn:, takes aPyramidWindowobject as argument. Used to modify the editor view. -
#configureBuilder:, takes aPyramidEditorBuilderobject as argument. Used to configure the editor builder. -
#connectOn:, takes aPyramidEditorobject as argument. Used to Retrieve information from the editor.
We want to add a plugin that display the executed commands in the Transcript. It can be toggle on and off with a button.
To create such plugin we need to follow this steps:
- Create the plugin class
- Register the class in the
PyramidPluginManagersingleton. - Create the view object and / or class.
- Connect the view object to the Pyramid Editor View using
#addPanelsOn:method. - Create the business classes
- Connect the business object to the Pyramid Editor View using
#connectOn:method.
We create a class named PyramidLogPlugin that uses the trait TPyramidPlugin. The trait contains the 3 necessary methods.
Object << #PyramidLogPlugin
traits: {TPyramidPlugin};
slots: { #logSwitchModel . #logSwitchButton . #logCommandExecutor };
tag: 'plugin-log';
package: 'Pyramid'To automaticly register the plugin to the PyramidPluginManager we can override the initialize class method. If the class is loaded in another Pharo image, it will be automaticly register to the PyramidPluginManager of the new image.
initialize
"Add this method on class side to install the plugin when the class is loaded."
PyramidPluginManager uniqueInstance addPlugin: selfIn our example the view consist of a button that can be toggle on and off. To do that we will create a model that indicate if the button is toggle or not. Then we will create a SpButtonPresenter and connect it to our model.
First, we create the model.
Object << #PyramidLogSwitchModel
slots: { #toggle };
tag: 'plugin-log';
package: 'Pyramid'PyramidLogSwitchModel >> initialize [
toggle := true ].
PyramidLogSwitchModel >> toggle [
^ toggle ].
PyramidLogSwitchModel >> toggle: anObject [
toggle := anObject ].Secodly, we create a button in the plugin.
PyramidLogPlugin>> logSwitchButton [
^ logSwitchButton ].
PyramidLogPlugin>> logSwitchModel [
^ logSwitchModel ].
PyramidLogPlugin>> initialize [
logSwitchModel := PyramidLogSwitchModel new.
logSwitchButton := SpButtonPresenter new.
logSwitchButton action: [
self logSwitchModel toggle: self logSwitchModel toggle not.
self updateButtonIconAndHelp ].
self updateButtonIconAndHelp ].
PyramidLogPlugin >> updateButtonIconAndHelp [
self logSwitchButton icon: self logSwitchModel asIcon.
self logSwitchButton adapter ifNotNil: [ :adapater |
adapater widgetDo: [ :w |
w setBalloonText: self logSwitchModel asHelp ] ] ].PyramidLogSwitchModel >> asIcon [
self toggle
ifTrue: [ ^ self iconNamed: #checkboxSelected ]
ifFalse: [ ^ self iconNamed: #checkboxUnselected ] ].
PyramidLogSwitchModel >> asHelp [
self toggle
ifTrue: [
^ 'The command used will be displayed in the Transcript. Click to desactivate.' ]
ifFalse: [
^ 'The command used will not be displayed in the Transcript. Click to activate.' ] ].We can change the view on 7 differents place in Pyramid.
-
topLeft, add a Button with an icon. Use a
PyramidToolbarPanelBuilderwith the method#makeButtonWithIcon:order:. -
topCenter, add a Button with an icon. Use a
PyramidToolbarPanelBuilderwith the method#makeButtonWithIcon:order:. -
topRight, add a Button with an icon. Use a
PyramidToolbarPanelBuilderwith the method#makeButtonWithIcon:order:. -
space, add a
BlSpacepreview in the center (you should avoid to change this view). Use aPyramidPresenterPanelBuilderwith the method#makePresenter:. -
tabLeft, add a "tab" with a title, an icon and a
SpPresenterto display. Use aPyramidTabPanelBuilderwith the method#makeTab:label:icon:order:. -
tabRight, add a "tab" with a title, an icon and a
SpPresenterto display. Use aPyramidTabPanelBuilderwith the method#makeTab:label:icon:order:. -
selectionMenu, add a menu that will change according to the number of selected items. Use a
PyramidMenuPanelBuilderwith the methods#addGroupEmptySelection:order:,#addGroupSingleSelection:order:and#addGroupMultiSelection:order:.
In our example we want to add a button on the top-right. We need to change the #addPanelsOn: method.
PyramidLogPlugin >> addPanelsOn: aPyramidSimpleWindow [
aPyramidSimpleWindow at: #topLeft addItem: [ :builder |
builder makeButtonWithIcon: self logSwitchButton order: 200 ] ].
The order is used to choose the display order of the different added views.
| Plugin | #topLeft | #topCenter | #topRight |
|---|---|---|---|
| PyramidPluginDynamicLayout | -9999 : Change left layout | 9999 : Change right layout | |
| PyramidSavePlugin | 1 : Save | ||
| PyramidSavePlugin | 2 : Save (project menu) | ||
| PyramidSpacePlugin | 5 : refresh the BlSpace | ||
| PyramidHistoryPlugin | 1 : undo | ||
| PyramidHistoryPlugin | 2 : redo |
| Plugin | #tabLeft | #tabRight |
|---|---|---|
| (default) | fisrt : Properties view | |
| PyramidTreePlugin | 1 : Tree | |
| PyramidPluginSelection | 1 : Playground |
The plugin will detect each time a command is executed by the PyramidMainCommandExecutor. The PyramidMainCommandExecutor can be decorated with a PyramidCommandExecutorDecorator so we will create a class that inherits it.
PyramidCommandExecutorDecorator << #PyramidLogCommandExecutor
slots: {#logSwitchModel};
tag: 'plugin-log';
package: 'Pyramid'PyramidLogCommandExecutor >> logSwitchButton [
^ logSwitchButton ].
PyramidLogCommandExecutor >> logSwitchModel [
^ logSwitchModel ].
PyramidLogCommandExecutor >> use: aCommand on: aCollection with: arguments [
"This method should be implemented."
"I use the command with the wrappee."
self wrappee use: aCommand on: aCollection with: arguments.
"I then print in the transcript the log only if the model allows it."
self logSwitchModel toggle ifFalse: [ ^ self ].
Transcript crShow: '[Pyramid] - Use of: <' , aCommand class name , '>
with: ' , arguments printString , '
on: ' , aCollection printString ].We now have to add the command executor decorator to the editor.
PyramidLogPlugin >> logCommandExecutor [
^ logCommandExecutor ].
PyramidLogPlugin >> initialize [
logSwitchModel := PyramidLogSwitchModel new.
logCommandExecutor := PyramidLogCommandExecutor new.
logSwitchButton := SpButtonPresenter new.
logCommandExecutor logSwitchModel: logSwitchModel.
logSwitchButton action: [
self logSwitchModel toggle: self logSwitchModel toggle not.
self updateButtonIconAndHelp ].
self updateButtonIconAndHelp ].
PyramidLogPlugin >> connectOn: aPyramidEditor [
| executor |
executor := aPyramidEditor propertiesManager commandExecutor.
self logCommandExecutor wrappee: executor.
aPyramidEditor propertiesManager commandExecutor:
self logCommandExecutor ].