Невозможно получить доступ к координатам мыши относительно виджета CANVAS

Я работаю с SBCL для Linux на машине AMD64.
Функция ANIMTEST создает окно LTK с виджетом CANVAS. Два предмета, БАРЬЕР и СЛЕДУЮЩАЯ, живут на холсте. Оба вращаются непрерывно, с БАРЬЕРОМ в центре холста и FOLLOWER, предназначенным следовать за мышью, которая не работает, как предполагалось. Моя первая попытка (см. Комментарий) привела к тому, что абсолютные экранные координаты мыши интерпретировались как относительные координаты внутри холста без учета смещения между ними. После поиска по ltk.lisp и документам я нашел SCREEN-MOUSE-X/Y (вторая попытка, см. Комментарий). Мне кажется, что я использую SCREEN-MOUSE-X & -Y в соответствии с документацией, но почему он не работает? = Примечание = Файл, который содержит ANIMTEST и пакеты, которые его поддерживают, загружаются и запускаются без ошибок. Определенные мной функции (UCTK-BEAM и т. Д.) Проверены и работают нормально.

(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)))))

Заранее спасибо!

2 ответа

Решение

Чтобы захватить положение мыши в виджете холста, я не вызываю функции экранной мыши, а связываю события движения и нажатия кнопки. Обратному вызову передается структура события, которая содержит слоты event-x и event-y, которые являются координатами холста. Таким образом, вы не только получаете правильные значения напрямую, но и более эффективно, поскольку вам не нужно опрашивать положение мыши - вы получаете обновления автоматически, когда она изменяется. В вашем случае вы можете либо обновить барьер при перемещении мыши, либо просто сохранить координаты мыши в переменной, которую вы читаете внутри цикла обновления.

Хотя все еще кажется, что функции CANVASX/Y не работают должным образом, LTK предлагает WINDOW-X/-Y вернуть координаты экрана X и Y виджета, так что вы можете написать следующее для достижения желаемого эффекта:

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

Это предполагает, что курсор мыши находится на том же экране, что и виджет холста с именем CNVS.

Другие вопросы по тегам