Hi.
I am glad to announce Commander library which implements command pattern based on first class objects. In Commander every application action is implemented as separate class with #execute method and all state required for execution. Commands are reusable objects and applications provide various ways to access them: shortcuts, context menu, buttons, etc.. This information is attached to command classes as activator objects. Currently there are three types of activators: - CmdShortcutCommandActivator - CmdContextMenuCommandActivator - CmdDragAndDropCommandActivator Activators are declared in command class side methods marked with pragma #commandActivator. For example following method will allow RenamePackageCommand to be executed by shortcut in possible system browser:
And for context menu it will be:
Activators are always declared with application context where they can be applied (PackageBrowserContext in example). Application should provide such contexts with information about application state. Every widget can bring own context to interact with application as separate tool. For example system browser shows multiple panes which provide package context, class context and method context. And depending on context browser shows different menu and provides different shortcuts. For more details look at my blog http://dionisiydk.blogspot.fr/2017/04/commander-command-pattern-library.html and read docs here. Best regards, Denis |
Was is really necessary to introduce pragmas here?
Alexandre > On Apr 11, 2017, at 11:49 AM, Denis Kudriashov <[hidden email]> wrote: > > Hi. > > I am glad to announce Commander library which implements command pattern based on first class objects. > In Commander every application action is implemented as separate class with #execute method and all state required for execution. > > Commands are reusable objects and applications provide various ways to access them: shortcuts, context menu, buttons, etc.. This information is attached to command classes as activator objects. Currently there are three types of activators: > > - CmdShortcutCommandActivator > - CmdContextMenuCommandActivator > - CmdDragAndDropCommandActivator > > Activators are declared in command class side methods marked with pragma #commandActivator. For example following method will allow RenamePackageCommand to be executed by shortcut in possible system browser: > > RenamePackageCommand class>>packageBrowserShortcutActivator > <commandActivator> > ^CmdShortcutCommandActivator by: $r meta for: PackageBrowserContext > > And for context menu it will be: > > RenamePackageCommand class>>packageBrowserMenuActivator > <commandActivator> > ^CmdContextMenuCommandActivator byRootGroupItemFor: PackageBrowserContext > > Activators are always declared with application context where they can be applied (PackageBrowserContext in example). Application should provide such contexts with information about application state. Every widget can bring own context to interact with application as separate tool. For example system browser shows multiple panes which provide package context, class context and method context. And depending on context browser shows different menu and provides different shortcuts. > > For more details look at my blog http://dionisiydk.blogspot.fr/2017/04/commander-command-pattern-library.html and read docs here. > > Best regards, > Denis > > -- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;. |
Just in case of: I do not want my email to be read as I did not intent to.
You are doing a great work Denis. Keep going! Alexandre > On Apr 11, 2017, at 12:34 PM, Alexandre Bergel <[hidden email]> wrote: > > Was is really necessary to introduce pragmas here? > > Alexandre > > >> On Apr 11, 2017, at 11:49 AM, Denis Kudriashov <[hidden email]> wrote: >> >> Hi. >> >> I am glad to announce Commander library which implements command pattern based on first class objects. >> In Commander every application action is implemented as separate class with #execute method and all state required for execution. >> >> Commands are reusable objects and applications provide various ways to access them: shortcuts, context menu, buttons, etc.. This information is attached to command classes as activator objects. Currently there are three types of activators: >> >> - CmdShortcutCommandActivator >> - CmdContextMenuCommandActivator >> - CmdDragAndDropCommandActivator >> >> Activators are declared in command class side methods marked with pragma #commandActivator. For example following method will allow RenamePackageCommand to be executed by shortcut in possible system browser: >> >> RenamePackageCommand class>>packageBrowserShortcutActivator >> <commandActivator> >> ^CmdShortcutCommandActivator by: $r meta for: PackageBrowserContext >> >> And for context menu it will be: >> >> RenamePackageCommand class>>packageBrowserMenuActivator >> <commandActivator> >> ^CmdContextMenuCommandActivator byRootGroupItemFor: PackageBrowserContext >> >> Activators are always declared with application context where they can be applied (PackageBrowserContext in example). Application should provide such contexts with information about application state. Every widget can bring own context to interact with application as separate tool. For example system browser shows multiple panes which provide package context, class context and method context. And depending on context browser shows different menu and provides different shortcuts. >> >> For more details look at my blog http://dionisiydk.blogspot.fr/2017/04/commander-command-pattern-library.html and read docs here. >> >> Best regards, >> Denis >> >> > > -- > _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: > Alexandre Bergel http://www.bergel.eu > ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;. > > > > -- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;. |
In reply to this post by Denis Kudriashov
Nice work, I like the approach.
Did you inspire your work in how Dolphin and VAST implements menu creation, command execution, and so on? I find your solution similar to how Dolphin implements it, where even each Presenter is even queried about each command by using a command query and routing solution. Will you use this in the context of Calypso and friends? Regards! Esteban A. Maringolo 2017-04-11 11:49 GMT-03:00 Denis Kudriashov <[hidden email]>: > Hi. > > I am glad to announce Commander library which implements command pattern > based on first class objects. > In Commander every application action is implemented as separate class with > #execute method and all state required for execution. > > Commands are reusable objects and applications provide various ways to > access them: shortcuts, context menu, buttons, etc.. This information is > attached to command classes as activator objects. Currently there are three > types of activators: > > - CmdShortcutCommandActivator > - CmdContextMenuCommandActivator > - CmdDragAndDropCommandActivator > > Activators are declared in command class side methods marked with pragma > #commandActivator. For example following method will allow > RenamePackageCommand to be executed by shortcut in possible system browser: > > RenamePackageCommand class>>packageBrowserShortcutActivator > > <commandActivator> > ^CmdShortcutCommandActivator by: $r meta for: PackageBrowserContext > > > And for context menu it will be: > > > RenamePackageCommand class>>packageBrowserMenuActivator > <commandActivator> > ^CmdContextMenuCommandActivator byRootGroupItemFor: > PackageBrowserContext > > > Activators are always declared with application context where they can be > applied (PackageBrowserContext in example). Application should provide such > contexts with information about application state. Every widget can bring > own context to interact with application as separate tool. For example > system browser shows multiple panes which provide package context, class > context and method context. And depending on context browser shows different > menu and provides different shortcuts. > > For more details look at my blog > http://dionisiydk.blogspot.fr/2017/04/commander-command-pattern-library.html > and read docs here. > > Best regards, > Denis > > |
Yes in calypso and friends. On Tue, Apr 11, 2017 at 7:38 PM, Esteban A. Maringolo <[hidden email]> wrote: Nice work, I like the approach. |
In reply to this post by Esteban A. Maringolo
2017-04-11 19:38 GMT+02:00 Esteban A. Maringolo <[hidden email]>:
Thank's.
No. I actually not remember that there were first class commands in Dolphin. I remember kind of CommandDescription with selector/block inside. No hierarchy of commands. But I could be wrong. I was more inspired by OmniBrowser and AltBrowser commands. But there were no activators idea inside. (I never worked with VAST)
Yes. And Calypso extends it with specific activators: - ClyToolbarCommandActivator to build middle bar of browser (switch browser to instance/class side are commands) - ClyTableIconCommandActivator to decorate table rows with iconic buttons (to provide method icons like in Nautilus) |
In reply to this post by abergel
2017-04-11 17:34 GMT+02:00 Alexandre Bergel <[hidden email]>:
In details: Commander caches all activators for each command class. It searches all methods which supply them using pragma and store all retrieved instances in class variable. To lookup required commands users enumerate cached activators declared for given context:
This process is fast and not produces any garbage. Also activation methods are supposed to be packaged together with application which provide context for them. They can be in different package than commands. Commands are reusable and can be extended by multiple applications with different set of activation methods. For example in Calypso I will extract separate SystemCommands package which can be reused by other tools like inspector and debugger. And Calypso will "attach" these commands by own set of extension methods. |
> Was is really necessary to introduce pragmas here? > > In short: Commander needs pragma to query methods for command lookup. What alternative you could suggest? I would imagine that your activatorClass can lookup the command simply as: PackageCommand allSubclasses select: [ :c | c isEnabledFor: … ] Would this not work? I am personally not keen of using pragma. The worth is when you have no idea what a pragma does and looking for implementors or sender does not help. Here is an example: -=-=-=-=-=-=-=-=-=-=-=-= RadioButtonModel>>canDeselectByClick <api: #inspect> "Return true clicking on a selected radio button deselects it" ^ canDeselectByClick value -=-=-=-=-=-=-=-=-=-=-=-= No idea what is the effect of the #api: pragma. There is no implementor of it. I could also the example of the Fame metamodel. Anyway, the fact that I am kind of complaining should not prevent you from moving ahead. I would be happy having Calypso in the image, even if pragmas. Go go go! Cheers, Alexandre > > In details: > > Commander caches all activators for each command class. It searches all methods which supply them using pragma and store all retrieved instances in class variable. > > To lookup required commands users enumerate cached activators declared for given context: > activatorClass allDeclaredFor: aToolContext do: blockWithActivator > This process is fast and not produces any garbage. > > Also activation methods are supposed to be packaged together with application which provide context for them. They can be in different package than commands. > Commands are reusable and can be extended by multiple applications with different set of activation methods. > For example in Calypso I will extract separate SystemCommands package which can be reused by other tools like inspector and debugger. And Calypso will "attach" these commands by own set of extension methods. -- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;. |
On Wed, Apr 12, 2017 at 6:28 AM, Alexandre Bergel <[hidden email]> wrote:
The other way to look at it is we need to improve implementor/sender lookups around pragmas (speaking very generically. I don't know what the gaps are.) cheers -ben Here is an example: |
In reply to this post by abergel
2017-04-12 0:28 GMT+02:00 Alexandre Bergel <[hidden email]>:
This approach restricts command implementation and queries to single hierarchy which is not scale. For example in Calypso there is ShowClassRefsCommand which is shown as toolbar button in both system and method browsers. But this command is in ClassCommand hierarchy because it operates on collection of classes. We can lookup both MethodCommands and ClassCommands in method browser. But then we will have a lot of commands which we do not need in method browser. Another example is "browse" command which is accessed by cmd+b and from context menu of any browser pane. Here is how they all connected to Calypso browsers:
(ClyBrowserContext is superclass of any Calypso browser contexts) |
I see. But why not to let the class subscribe to what it needs?
Maybe something like: -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Command subclass: #ClyShowClassRefCommand ClyShowClassRefCommand class>>registerFor: aCommandActivator aCommandActivator add: self for: ClyButtonToolbarGroup. aCommandActivator add: self for: ClyBrowserContext. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= This is just a suggestion. Alexandre
--
_,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
|
2017-04-12 15:27 GMT+02:00 Alexandre Bergel <[hidden email]>:
I guess you mean:
How different applications will extend such registration? Probably they will need multiple version of #registerFor:. And system will need to find them somehow. For example by pragma. No? |
Free forum by Nabble | Edit this page |