Update of /project/mcclim/cvsroot/mcclim
In directory clnet:/tmp/cvs-serv8927
Modified Files:
frames.lisp presentation-defs.lisp presentations.lisp
Log Message:
drag-and-drop, not quite working yet
--- /project/mcclim/cvsroot/mcclim/frames.lisp 2006/03/10 21:58:12 1.114
+++ /project/mcclim/cvsroot/mcclim/frames.lisp 2006/03/12 23:09:27 1.115
@@ -1566,46 +1566,162 @@
(buffer-rectangle))
(stream-replay stream buffer-rectangle))))))))
-(defgeneric frame-drag-and-drop-highlighting (frame to-presentation state))
+(defgeneric frame-drag-and-drop-highlighting
+ (frame to-presentation stream state))
(defmethod frame-drag-and-drop-highlighting
- ((frame standard-application-frame) to-presentation state)
- )
+ ((frame standard-application-frame) to-presentation stream state)
+ (highlight-presentation-1 to-presentation stream state))
-(defun frame-drag-and-drop (translator-name command-table object presentation
- context-type frame event window x y)
- (let* ((translators (mapcan (lambda (trans)
+(defun frame-drag-and-drop (translator-name command-table
+ from-presentation context-type frame event window
+ x y)
+ (declare (ignore command-table))
+ (let* ((*dragged-presentation* from-presentation)
+ (*dragged-object* (presentation-object from-presentation))
+ (translators (mapcan (lambda (trans)
(and (typep trans 'drag-n-drop-translator)
- (test-presentation-translator
- trans presentation context-type frame
- window x y :event event)))
+ (funcall (tester trans)
+ (presentation-object
+ from-presentation)
+ :presentation from-presentation
+ :context-type context-type
+ :frame frame
+ :window window
+ :x x
+ :y y
+ :event event)))
(find-presentation-translators
- (presentation-type presentation)
+ (presentation-type from-presentation)
context-type
(frame-command-table frame))))
+ ;; Try to run the feedback and highlight functions of the translator
+ ;; that got us here.
(translator (or (find translator-name translators :key #'name)
(car translators)))
- (tester (tester translator))
- (drag-type (from-type translator))
- (feedback-fn (feedback translator))
- (hilite-fn (highlighting translator))
- (drag-context (make-fake-input-context drag-c-type))
- (*dragged-object* object)
- (destination-object nil))
- (multiple-value-bind (x0 y0)
- (stream-pointer-position window)
- (funcall feedback-fn *application-frame* object window
- x0 y0 x0 y0 :highlight)
- (tracking-pointer (window :context-type `(or ,(mapcar #'from-type
- translators))
- :highlight nil)
- (:presentation (&key presentation event x y)
- )
- (:pointer-motion (&key event x y)
- (multiple-value-bind (presentation translator)
- (find-innermost-presentation-match drag-context window
- x y :event event)))
- (:presentation-button-press (&key presentation x y))
- (:presentation-button-release (&key presentation x y))
- (:button-press (&key x y))
- (:button-release (&key x y))))))
+ (initial-feedback-fn (feedback translator))
+ (initial-hilite-fn (highlighting translator))
+ (destination-presentation nil)
+ (initial-x x)
+ (initial-y y)
+ (last-presentation nil)
+ (feedback-activated nil)
+ (feedback-fn initial-feedback-fn)
+ (hilite-fn initial-hilite-fn)
+ (last-event nil))
+ ;; We shouldn't need to use find-innermost-presentation-match
+ ;; This repeats what tracking-pointer has already done, but what are you
+ ;; gonna do?
+ (flet ((find-dest-translator (presentation window x y)
+ (loop for translator in translators
+ when (and (presentation-subtypep
+ (presentation-type presentation)
+ (destination-ptype translator))
+ (test-presentation-translator translator
+ presentation
+ context-type frame
+ window x y))
+ do (return-from find-dest-translator translator))
+ nil)
+ (do-feedback (window x y state do-it)
+ (when do-it
+ (funcall feedback-fn frame from-presentation window
+ initial-x initial-y x y state)))
+ (do-hilite (presentation window state)
+ (when presentation
+ (funcall hilite-fn frame presentation window state)))
+ (last-window ()
+ (event-sheet last-event))
+ (last-x ()
+ (pointer-event-x last-event))
+ (last-y ()
+ (pointer-event-y last-event)))
+ ;; :highlight nil will cause the presentation that is the source of the
+ ;; dragged object to be unhighlighted initially.
+ (block do-tracking
+ (tracking-pointer (window :context-type `(or ,(mapcar #'from-type
+ translators))
+ :highlight nil
+ :multiple-window t)
+ (:presentation (&key presentation window event x y)
+ (let ((dest-translator (find-dest-translator presentation window
+ x y)))
+ (do-feedback (last-window) (last-x) (last-y)
+ :unhighlight feedback-activated)
+ (setq feedback-activated t
+ last-event event)
+ (do-hilite last-presentation (last-window) :unhighlight)
+ (setq last-presentation presentation
+ feedback-fn (feedback dest-translator)
+ hilite-fn (highlighting dest-translator))
+ (do-hilite presentation window :highlight)
+ (do-feedback window x y :highlight t)
+ (document-drag-n-drop dest-translator presentation
+ context-type frame event window
+ x y)))
+ (:pointer-motion (&key event window x y)
+ (do-feedback (last-window) (last-x) (last-y)
+ :unhighlight feedback-activated)
+ (setq feedback-activated t
+ last-event event)
+ (do-hilite last-presentation (last-window) :unhighlight)
+ (setq last-presentation nil)
+ (do-feedback window x y :highlight t)
+ (document-drag-n-drop translator nil
+ context-type frame event window
+ x y))
+ ;; XXX only support finish-on-release for now.
+ #-(and)(:presentation-button-press ())
+ (:presentation-button-release (&key presentation event)
+ (setq destination-presentation presentation
+ last-event event)
+ (return-from do-tracking nil))
+ #-(and)(:button-press ())
+ (:button-release (&key event)
+ (setq last-event event)
+ (return-from do-tracking nil))))
+ ;;
+ ;; XXX Assumes x y from :button-release are the same as for the preceding
+ ;; button-motion; is that correct?
+ (do-feedback (last-window) (last-x) (last-y)
+ :unhighlight feedback-activated)
+ (do-hilite last-presentation (last-window) :unhighlight)
+ (if destination-presentation
+ (let ((final-translator (find-dest-translator destination-presentation
+ (last-window)
+ (last-x)
+ (last-y))))
+ (if final-translator
+ (funcall (destination-translator final-translator)
+ *dragged-object*
+ :presentation *dragged-presentation*
+ :destination-object (presentation-object
+ destination-presentation)
+ :destination-presentation destination-presentation
+ :context-type context-type
+ :frame frame
+ :event event
+ :window window
+ :x x
+ :y y)
+ (values nil nil)))
+ (values nil nil)))))
+
+(defun document-drag-n-drop
+ (translator presentation context-type frame event window x y)
+ (when *pointer-documentation-output*
+ (let ((s *pointer-documentation-output*))
+ (window-clear s)
+ (with-end-of-page-action (s :allow)
+ (with-end-of-line-action (s :allow)
+ (document-presentation-translator translator
+ presentation
+ context-type
+ frame
+ event
+ window
+ x y
+ :stream s
+ :documentation-type :pointer))))))
+
+
--- /project/mcclim/cvsroot/mcclim/presentation-defs.lisp 2006/03/10 21:58:13 1.51
+++ /project/mcclim/cvsroot/mcclim/presentation-defs.lisp 2006/03/12 23:09:27 1.52
@@ -2002,30 +2002,44 @@
(destination-translator :reader destination-translator
:initarg :destination-translator)))
+
+(defvar *dragged-presentation* nil
+ "Bound to the presentation dragged in a drag-and-drop context")
(defvar *dragged-object* nil
"Bound to the object dragged in a drag-and-drop context")
+()
;;; According to the Franz User's guide, the destination object is
;;; available in the tester, documentation, and translator function
;;; as destination-object. Therefore OBJECT is the dragged object. In
;;; our scheme the tester function, translator function etc. is
;;; really called on the destination object. So, we do a little
-;;; shuffling of arguments here.
+;;; shuffling of arguments here. We don't do that for the destination
+;;; translator because we can call that ourselves in frame-drag-and-drop.
+;;;
+;;; Also, in Classic CLIM the destination presentation is passed as a
+;;; destination-presentation keyword argument; hence the presentation argument
+;;; is the dragged presentation.
(defmethod initialize-instance :after ((obj drag-n-drop-translator)
- &key tester documentation
+ &key documentation
pointer-documentation
- translator-function)
+ destination-translator)
+ ;; This is starting to smell...
(flet ((make-adapter (func)
- (lambda (object &rest args)
- (apply func *dragged-object* :destination-object object args))))
- (setf (slot-value obj 'tester) (make-adapter tester))
+ (lambda (object &rest args &key presentation &allow-other-keys)
+ (if *dragged-presentation*
+ (apply func
+ *dragged-object*
+ :presentation *dragged-presentation*
+ :destination-object object
+ :destination-presentation presentation
+ args)
+ (apply func object args)))))
(setf (slot-value obj 'documentation) (make-adapter documentation))
(when pointer-documentation
(setf (slot-value obj 'pointer-documentation)
- (make-adapter pointer-documentation)))
- (setf (slot-value obj 'translator-function)
- (make-adapter translator-function))))
+ (make-adapter pointer-documentation)))))
(defmacro define-drag-and-drop-translator
(name (from-type to-type destination-type command-table
@@ -2048,17 +2062,14 @@
(with-keywords-removed (args (:feedback :highlighting))
`(progn
(define-presentation-translator ,name
- (,from-type ,to-type
+ (,from-type ,to-type ,command-table
,@args
:feedback #',feedback :highlighting #',highlighting
:destination-ptype ',real-dest-type
:destination-translator #',(make-translator-fun arglist body)
:translator-class drag-n-drop-translator)
- (object presentation context-type frame event window x y)
- (frame-drag-and-drop ',name ',command-table object
+ (presentation context-type frame event window x y)
+ (frame-drag-and-drop ',name ',command-table
presentation context-type
frame event window x y))))))
-
-
-
--- /project/mcclim/cvsroot/mcclim/presentations.lisp 2006/03/10 21:58:13 1.72
+++ /project/mcclim/cvsroot/mcclim/presentations.lisp 2006/03/12 23:09:27 1.73
@@ -1497,17 +1497,20 @@
(defmethod call-presentation-translator
((translator presentation-translator) presentation context-type
frame event window x y)
- (multiple-value-bind (object ptype options)
- (funcall (translator-function translator)
- (presentation-object presentation)
- :presentation presentation
- :context-type context-type
- :frame frame
- :event event
- :window window
- :x x
- :y y)
- (values object (or ptype context-type) options)))
+ ;; Let the translator return an explict ptype of nil to, in effect, abort the
+ ;; presentation throw.
+ (multiple-value-call
+ #'(lambda (object &optional (ptype context-type) options)
+ (values object ptype options))
+ (funcall (translator-function translator)
+ (presentation-object presentation)
+ :presentation presentation
+ :context-type context-type
+ :frame frame
+ :event event
+ :window window
+ :x x
+ :y y)))
(defmethod call-presentation-translator
((translator presentation-action) presentation context-type