1

I'm currently learning McCLIM. Trying to figure out how to define a command, that will react to keystroke. For a app named superapp I have a function

(defun show (text)
  (lambda (gadget)
    (declare (ignore gadget))
 (with-slots (text-field) *application-frame*
(setf (gadget-value text-field)
   text))))

which show some text on it's screen pane. It works fine for pane-buttons in activate-callback. However, this

(define-superapp-command (com-greet :name t :keystroke (#\g :control)) ()
 (show "Hey"))

doesn't work. I know that I defined it right, since it works well with (frame-exit *application-frame*). So I just don't understand something else.

EDIT: SO, this is the working variant

(define-application-frame superapp ()
 ()
 (:panes
  (tf1
   :push-button
       :label "Left"
       :activate-callback (show "HI"))
  (app :application
   :display-time nil
   :height 400
   :width 600)
  (screen :text-field))
 (:layouts
  (default
   (with-slots (text-field) *application-frame*
               (vertically ()
                screen
                (tabling (:grid t)
                 (list tf1 app)))))))

(defun show (text)
 (lambda (gadget)
   (declare (ignore gadget))
  (setf (gadget-value (find-pane-named *application-frame* 'screen)) 
    text)))

(define-superapp-command (com-greet :name t :keystroke (#\g)) ()
 (setf (gadget-value (find-pane-named *application-frame* 'screen)) 
 "text"))
Andrew S.
  • 467
  • 3
  • 12
  • How about formatting the code readable? That might help. The what is the purpose of the `lambda`? – Rainer Joswig Nov 05 '18 at 20:23
  • It doesn't look like this here, I damaged the code while copying, I guess. Lambda, well, not sure really, since I was just copying blocks of code from demos trying to figure stuff out. So that's a thing from demos. – Andrew S. Nov 05 '18 at 20:28
  • But what is LAMBDA supposed to do? – Rainer Joswig Nov 05 '18 at 20:29
  • I don't know. I suspect it might some way to connect to the gadget? To declare that this function is not, like, general purpose. I don't see ahything strange, since in source code you could find some fucntions, which just call themselves, nothing else, or other weird things. I understand that it looks like it does nothing. – Andrew S. Nov 05 '18 at 20:33
  • How about removing the LAMBDA when you don't now what it does. It returns a function. If that function never gets called, nothing ever will happen. – Rainer Joswig Nov 05 '18 at 20:35
  • But surely I've checked this. It doesn't work without it. For reason I have no idea about, but still. – Andrew S. Nov 05 '18 at 20:36
  • How should it work? SHOW returns a function. Who calls that function? Nobody. – Rainer Joswig Nov 05 '18 at 20:37
  • Well, if somebody explains this too, I would be glad. But can't you check it yourself, I mean, just https://github.com/McCLIM/McCLIM/blob/master/Examples/calculator.lisp – Andrew S. Nov 05 '18 at 20:38
  • But that has nothing to do with a COMMAND like you are defining one. The code you showed does something entirely different. – Rainer Joswig Nov 05 '18 at 20:41
  • Well, I defined a similar function. Now I want to use it in command. Is that impossible? – Andrew S. Nov 05 '18 at 20:43
  • But why the LAMBDA? You can't just copy totally unrelated code and believe it will work. Ask yourself: what is the purpose of the LAMBDA? If you can't answer that question, try it out with some examples outside of CLIM. If you don't know what a LAMBDA does, you need to learn this first. It's not difficult, but it's basic Lisp knowledge needed in many places. – Rainer Joswig Nov 05 '18 at 20:47
  • I could answer that question directly, but it helps you more, if you actually try it out yourself, since it is a basic concept of functional programming. – Rainer Joswig Nov 05 '18 at 20:48
  • I know, what lambda does. It's just a function without name. I don't really understand all the error messages this package shows, since it worked with lambda, I just didn't touch it. – Andrew S. Nov 05 '18 at 20:50
  • Now, if you know what LAMBDA does: SHOW returns a function. Your command calls SHOW. Nobody calls the function it returns. That's why it does nothing. Thus you should not return a function. SHOW should do something and not return a function. – Rainer Joswig Nov 05 '18 at 20:54

1 Answers1

2
(defun show (text)
   (setf (gadget-value (slot-value *application-frame* 'text-field))
         text))

In above function you try to get a gadget from a slot. This is not the way to do. Use FIND-PANE-NAMED instead. Give it a frame and the name of the pane. It will return that PANE.

(define-application-frame superapp ()
 ((text-field :initform nil))
 (:panes
  (tf1
   :push-button
       :label "Left"
       :activate-callback (show "HI"))

Again, you now use SHOW in a totally different context. Now it SHOULD return a LAMBDA, which gets the gadget as an argument.

  (app :application
   :display-time nil
   :height 400
   :width 600)
  (screen :text-field))
 (:layouts
  (default
   (with-slots (text-field) *application-frame*
               (vertically ()
                (setf text-field screen)
                (tabling (:grid t)
                 (list tf1 app)))))))

Now the code in :layouts looks wrong. You should not set the slot text-field in there. Actually you should not have a slot TEXT-FIELD at all. Just use in your call back the function FIND-PANE-NAMED. Here you just define a layout.

Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346