On Jan 15, 2005, at 7:35 AM, Anthony Juckel wrote:
This message doesn't pertain to the internal development of McCLIM, but is rather a general CLIM question. The only CLIM mailing list that I've found seems to have next to no traffic on it, so this seemed the best place to send my questions. Perhaps it would be prudent (if messages like this become a hassle) to create a mcclim-user mailing list on common-lisp.net?
If we get to that point, sure, though I don't think we're quite there yet :) For the moment these kinds of discussions tend to point out shortcomings in McCLIM and for that reason are valuable to have on the developer's list. Also, few of here are experienced users of the commercial CLIM implementation, so in a sense we're all finding the true way together.
What is the proper way to go about defining presentation types with their associated methods, especially accept? For some background, I'm working on an application for working with a set of objects that I've defined. In defining these objects, I've done some MOP-ery to allow me to specify for a given slot on an object, which values are allowed:
(defclass my-class () ((slot-a :allowed-values ("some" "allowed" "values"))) (:metaclass restricted-slot-value-class))
I've also got the necessary machinery to easily get the allowable values for a given slot of an object. Now, I'd like to use this machinery to ease the creation of dialogs pertaining to these objects. For example, if a user is needing to supply a value for slot-a, I'd like to display a menu to the user containing the valid values.
The way that I've tried to accomplish this is that I've created a presentation type for each slot in the object (I know there must be a more general solution...). Then I've defined an accept method for these presentation types. Now, in my accept method, I'm trying to use menu-choose as follows:
There are a couple of ways you can go here, depending on how much flexibility you need in accepting the values. CLIM has useful presentation types for accepting one of several values, MEMBER and COMPLETION. The accept method for COMPLETION doesn't directly present a menu; it's a text field in which one can use tab completion and get a menu by right clicking. I'll return to just using a menu in a second.
You can define presentation types that inherit from completion or directly use the COMPLETION type to accept values (either within ACCEPTING-VALUES) or elsewhere:
(setf (slot-value obj 'slot-a) (accept `(completion ,(allowed-values 'slot-a)) stream))
This is nice because it can be abstracted in a function in the obvious way.
You could also define a presentation type that uses the slot name as an argument:
(define-presentation-type slot-val (slot-name) :inherit-from t) (define-presentation-method accept (type slot-val) stream view &key) (accept `(completion ,(allowed-values ,slot-name)) stream view))
(clim:define-presentation-method clim:accept ((type slot-a) stream view &key &allow-other-keys) (declare (ignore view)) (clim:menu-choose (allowed-values 'slot-a)))
I then create a dialog using accepting-values, which in turn calls this accept method. This isn't giving me the desired behavior though.
I believe that's because the control flow within accepting-values is very strange. I'm a bit surprised that this works at all. Are you looking for a pop-up menu, or a list of choices embedded in the dialog? The right way to do this is probably with gadgets and gadget views. Gadget views are not implemented yet in McCLIM, but they are certainly on our list. In an ideal world the view in a dialog for the completion type would present a pop-up menu.
If you do implement a custom accept method like this, you should probably define your own view and specialize this method on the view so that you can textually input values in other input contexts.
When I click on the input field for slot-a, I do get the proper menu displayed, but when I first choose an option, it doesn't appear to have any effect, but does redisplay the menu again. After choosing a menu option a second time, the choice does indeed seem to stick.
What do you mean by "choose an option;" another option in the dialog box? It's possible that a recent update to the dialog code would fix your problem. Otherwise I'd need to see your code to figure out what's going on as I certainly haven't considered yet doing things like calling menu-choose within accepting values.
Am I just missing a step, or have I wondered down a wrong path entirely? Does anyone have any advice for how better to handle such a situation?
There are a lot of different paths :)
Tim