|
Re: Ideas for a new command system: msg#00045gnome.mono.monodevelop.general
On dg, 2005-04-10 at 00:04 -0300, Rafael Teixeira wrote: > Looks very nice. Just performance-wise I would be carefull to > transform the attributes metadata into some indexed form when first > scanning for command handlers to avoid repetitive reflection costs... Yeah, that's the plan. > May be a premature optimization, but I can't help thinking it will > effectively be needed to attain adequate UI responsiveness. > > Have fun, > > > > On Apr 8, 2005 9:22 PM, Lluis Sanchez <lluis@xxxxxxxxxx> wrote: > > Hi! > > > > The next target in my quest for improving the architecture of MD is the > > command system. There are two reasons why I don't like the current > > design: > > > > * It is not possible to change the behavior of a command depending > > on the context in which it is run. For example, the Delete > > command deletes the selected text in the editor, but we should > > be able to use the same command for deleting the selected file > > in the solution pad (if the pad has the focus), or whatever. Any > > addin should be able to provide a custom behavior for an > > existing command. > > * It is not easy to handle the status of commands. Commands can be > > enabled/disabled using conditions, but conditions must be > > specified in the addin XML file and are very limited. > > > > What I propose is a very different approach, so feedback is greatly > > welcome (BTW, the main concept is taken from MS's MFC class library, not > > a great library, but I like the approach it uses for command handling). > > > > First of all, there is a global list of commands, which is independent > > from where those commands are used. The command list would be > > defined/extended in the addin xml like this: > > > > <Extension path = "/SharpDevelop/Commands"> > > <Command id = "EditCommands.Copy" > > _label = "Copy" > > icon = "Icons.16x16.CopyIcon" > > shortcut = "Control|C"/> > > <Command id = "EditCommands.Paste" > > _label = "_Paste" > > icon = "Icons.16x16.PasteIcon" > > shortcut = "Control|V"/> > > <Command id = "EditCommands.Delete" > > _label = "_Delete" > > icon = "Icons.16x16.DeleteIcon" > > shortcut = "Del"/> > > </Extension> > > > > Then, we can define menus and toolbars by refering those commands: > > > > <Extension path = > > "/SharpDevelop/Views/ProjectBrowser/ContextMenu/ProjectFileNode"> > > <MenuItem id = "Copy" command = "EditCommands.Copy"/> > > <MenuItem id = "Paste" command = "EditCommands.Paste"/> > > <MenuItem id = "Delete" command = "EditCommands.Delete"/> > > </Extension> > > > > The big change is how commands are executed. Instead of implementing a > > single class for each command, we can implement command handler methods > > in any class. For example, to handle the Delete command in the text > > editor I would write a handler like this: > > > > [CommandHandler (EditCommands.Delete)] > > void OnDeleteCommand () > > { > > // Delete the selection > > } > > > > If we want to implement the Delete command in a custom pad, we would add > > a similar command handler in that pad. So, we have two handlers for the > > same command in two different classes. Which one of them will be > > executed when clicking on the Delete menu item? It depends on the > > context. > > > > When the command is clicked, the command manager looks for a command > > handler by following a command route. This route begins at the widget > > that has the focus and goes up in the parent chain. This means that if > > we are editing some text in the editor, the delete command handler in > > the editor will be executed. If we move the focus to the solution pad, > > then the pad will get the commands. > > > > The command manager will also automatically disable or hide commands for > > which there isn't a handler in the active command route. This gives a > > lot a consistency to the menu and toolbars, since options and buttons > > will be grayed out when they can't be used (and there is no need to > > write code for this, it comes for free). > > > > If the status of a command depends on some internal logic, we can > > implement that logic in some special command update handlers. For > > example: > > > > [CommandUpdateHandler (EditCommands.Delete)] > > void OnUpdateDeleteCommand (CommandInfo commandInfo) > > { > > if (the_selected_tree_node_can_be_deleted()) { > > commandInfo.Enabled = true; > > commandInfo.Text = "Delete " + current_node.Name; > > } else { > > commandInfo.Enabled = false; > > } > > } > > > > The command manager will look for a command update handler in the > > current command route. If found, it will call the handler and will > > update the menu items and buttons linked to that command accordingly. If > > not found, it will disable them. > > > > This is more or less the idea. There are many more details, such as > > being able to customize the command route, defining global command > > handlers for global commands, menu builders for the "Windows" menu list, > > etc., but I just described the fundamental idea. > > > > Comments? > > Lluis. > > > > _______________________________________________ > > Monodevelop-list mailing list > > Monodevelop-list@xxxxxxxxxxxxxxxx > > http://lists.ximian.com/mailman/listinfo/monodevelop-list > > > > |
|
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| Previous by Date: | German Translation: 00045, Gustav Schauwecker |
|---|---|
| Next by Date: | Re: AW: UML CanvasItem: 00045, Lluis Sanchez |
| Previous by Thread: | Re: Ideas for a new command systemi: 00045, Rafael Teixeira |
| Next by Thread: | Problem running monodevelop on linux: 00045, Steve Willcock |
| Indexes: | [Date] [Thread] [Top] [All Lists] |
| News | FAQ | advertise |