On 4/28/05, rpgoldman@real-time.com rpgoldman@real-time.com wrote:
- one thing that seems odd is the lack of a conventional selection concept, which we see in the now-standard direct manipulation interfaces. I.e., you select an object and that provides the focus of all commands. I'm not sure that providing this is even feasible with CLIM, because of its radically different paradigm.
Agreed. I don't think the omission requires a rethinking of CLIM from the ground up - you can certainly implement the notion of a selection yourself if you wanted to - but a standard approach and some utilities might make life easier. I have some thoughts on how to address this, and I think they can be implemented in terms of the spec (I haven't worked out specifics of what it would look like). It could be nice to provide the functionality ourselves so users don't have to reinvent the wheel. I've tried several times (unsuccessfully) to elicit discussion of this on IRC - perhaps the mailing list is a more appropriate forum. :)
I can imagine two approachs to this. The first would be to do it manually, undercutting some of the beauty of the CLIM command framework. Keep track of the current selection as a slot within the application frame, enable commands which are applicable to the selected object, disable commands that are no longer applicable, and use the value of the selected slot directly within your commands. Gadget callbacks or even commands on presentations would select/deselect objects, update the selection slot, enable/disable commands, etc. If you wanted command input at an interactor to work as expected, you'd need to define two versions of the commands, one which uses the 'invisible' selection from the selection slot and one to use from the command line which prompted for an argument as usual. I think this is more or less how apps written in a conventional toolkit end up doing things.
As an example I'll use a graphical file manager, where the frame represents the view of one directory of files. The application frame would contain a slot with a list of the currently selected files. You would define commands in response to the click, control-click, shift-click gestures which modify the current selection and redisplay the folder contents to reflect the modified selection. Commands such as com-delete-files would be defined with no arguments, and would act on the value of selection slot. To avoid confusing users, you want to disable com-delete-files and similar commands when the selection is empty.
The second (and more interesting) approach would be to extend the CLIM command framework to support a more conventional notion of selected objects. I think this can be reduced to simply a programmatic way of transparently providing default arguments to commands, ideally sensitive to context. I'll return to the file manager example. Using this approach you could define commands operating on files (such as com-delete-files) as taking an argument of type (sequence pathname). If a user enters the command at an interactor, it would prompt for a list a of pathnames. When selected from a menu the application can choose to provide default values however it wishes (from a gadget-value, some internal state, whatever), prompting only for any remaning arguments (preferrably via a dialog), or executing immediately if there are no more required arguments. For determining the current selection, applications could define their own selection commands as before, or McCLIM could supply an optional mechanism allowing you to select presentations within a stream pane. The method supplying the values for the (sequence pathnames) argument in our file manager would simply query this selection. Some rethinking of the behavior of the right-button menu also becomes necessary.
I'm not certain what the ideal interface would look like. Specifically, I'm not sure how you'd want to match arguments (by name? by presentation type? both? a specific argument to a specific command? by some extra data tagged on when the argument was declared?). I imagine a generic function which would be called on each argument of a chosen command which would have the first shot at providing a value for the command before the user is prompted. Application writers would define methods to provide the desired behavior for things like our file manager. It may be useful to specialize on the frame, context in which the command was invoked (:interactor, :frame-menu, :right-button-menu, etc), command name, argument name, and argument presentation type. Did I miss anything? There are many other ways I could imagine to acheive similar ends.
I'm sure an app could do most of this stuff within the existing spec. I haven't worked out exactly how, but providing a customized read-frame-command might be start. It's possible there is some hook in the spec doing exactly what I want that I've overlooked.
A tester for commands (similar to the tested user in CLIM presentation translators) which could be specialized on context would make both approaches easier (ex. command menu items could be greyed out if they are not applicable to the current selection or state of the application).
Something to keep in mind for hypothetical CLIM 3.0 discussions, anyway..