Question

I am working with SBCL for Linux on an AMD64 machine.
Function ANIMTEST instantiates an LTK window with a CANVAS widget. Two items, BARRIER and FOLLOWER, live in the canvas. Both spin continuously, with BARRIER at the center of the canvas and FOLLOWER intended to follow the mouse, which is not working as intended. My first attempt (see comment) resulted in absolute screen coordinates of the mouse being interpreted as relative coordinates within the canvas with no account of the offset between the two. After searching through ltk.lisp and docs, I found SCREEN-MOUSE-X/Y (Second Attempt, see comment). I feel like I am using SCREEN-MOUSE-X & -Y according to the documentation, but why is it not working? = Note = The file that contains ANIMTEST and the packages that support it load and run with no errors. Functions I have defined (UCTK-BEAM, etc.) are tested and run fine.

(defun animtest ()
      "Test a spinning figure in LTK"
      (with-ltk ()
        (let* ((cnvs (make-instance 'canvas :width 400 :height 400))
           (barrier (uctk-beam 200 200 40 20))
           (follower (uctk-beam 0 40 40 20))
           (slp-time 50) ; in ms
           (bar-theta 0)
           (fol-theta 0))
          (labels ((update ()
             (draw barrier nil)
             (draw follower nil)
             (incf bar-theta (/ pi 15))
             (incf fol-theta (/ pi 15))
             (geo:set-theta barrier bar-theta)
             (geo:set-theta follower fol-theta)
             (geo:set-center follower 
                     ;== FIRST ATTEMPT ==
                     (cons (screen-mouse-x cnvs)
                       (screen-mouse-y cnvs)))
                     ; == SECOND ATTEMPT ==
                     ;(cons (canvasx cnvs (screen-mouse-x cnvs))
                    ;   (canvasy cnvs (screen-mouse-y cnvs))))
             (after slp-time #'update)))
        (pack cnvs :fill :both :expand 1)
        (update)))))

Thanks in advance!

Était-ce utile?

La solution

To grab the mouse position in a canvas widget, I don't call the screen-mouse functions, but rather bind the motion and button press events. The callback gets passed the event structure which contains the slots event-x and event-y which are canvas coordinates. Not only are you getting the right values directly this way, but also it is more efficient, as you don't have to poll the mouse position - you get updates automatically when it changes. In your case you could either choose to update the barrier on mouse-move or alternatively, just store the mouse coordinates in a variable you read inside your update loop.

Autres conseils

Although it still appears that the CANVASX/Y functions do not work as intended, LTK offers WINDOW-X/-Y to return the X and Y screen coordinates of a widget such that you can write the following to achieve the desired effect:

(cons (- (screen-mouse-x) (window-x cnvs))
      (- (screen-mouse-y) (window-y cnvs)))

This assumes that the mouse cursor is on the same screen as the canvas widget named CNVS.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top