;;;-*- Mode:Common-Lisp; Package:PICTURES; Base:10 -*- ;;; ;;; ;;; ;;; TEXAS INSTRUMENTS INCORPORATED ;;; P.O. BOX 149149 ;;; AUSTIN, TEXAS 78714-9149 ;;; ;;; Copyright (C)1987,1988,1989,1990 Texas Instruments Incorporated. ;;; ;;; Permission is granted to any individual or institution to use, copy, modify, ;;; and distribute this software, provided that this complete copyright and ;;; permission notice is maintained, intact, in all copies and supporting ;;; documentation. ;;; ;;; Texas Instruments Incorporated provides this software "as is" without ;;; express or implied warranty. ;;; ;;; Authors: Delmar Hager, James Dutton, Teri Crowe ;;; Contributors: Kerry Kimbrough, Patrick Hogan, Eric Mielke (in-package "PICTURES") (DEFMETHOD view-selection ((view view)) (with-slots (selection) view (REMOVE nil (MAP 'LIST #'(lambda (graphic) (get-graphic graphic)) (scene-elements selection))))) (DEFMETHOD (SETF view-selection) (selection (view view)) (view-clear-selection view) (view-add-selection view selection)) (DEFUN get-graphic (grabber-rect) (LET ((grabber-graphic (grabber-graphic grabber-rect))) (WHEN (AND grabber-graphic (viewable-p grabber-graphic)) grabber-graphic))) (defmethod view-add-selection ((view view) graphic ) (declare (type (or graphic list) graphic)) (declare (values (or graphic list))) (WHEN graphic ;When "graphic" is equal to nil, ignore it. (IF (ATOM graphic) ;view-drag-select will call view-add-selection with a list (place-on-selection view graphic) (DOLIST (graphic-item graphic) (place-on-selection view graphic-item)))) graphic) (DEFUN place-on-selection (view graphic) "Attach the graphic to a highlight object in the selection scene" ;; a grabber-rect is the default highlight object (with-slots (selection) view (SETF (graphic-sensitivity selection ) :subselectable) (LET* ((selection-elements (scene-elements selection)) (elements-length (FILL-POINTER selection-elements)) (elements-dimension (ARRAY-DIMENSION selection-elements 0)) ) (OR (DOTIMES (pos elements-length ) (WHEN (EQ (grabber-graphic (ELT selection-elements pos)) graphic) (RETURN t))) ; IF the graphic is alread selected, return (PROGN ;there are no grabber rects in the scene and have to create a new one (IF (= elements-length elements-dimension) (scene-insert selection (make-grabber-rect view :highlight (view-highlight-color view))) (SETF (FILL-POINTER selection-elements) (1+ (FILL-POINTER selection-elements)))) (LET ((grabber-scene (ELT selection-elements (1- (FILL-POINTER selection-elements))))) (SETF (grabber-graphic ; set the graphic slot to the current graphic grabber-scene) graphic) ; (SETF (graphic-sensitivity grabber-scene) :subselectable) ; yes, make the grabber rect subselectable (draw-graphic grabber-scene view))) ; draw the highlight object ))) graphic ) (defmethod view-remove-selection ((view view) graphic ) (declare (type (or graphic list) graphic)) (declare (values (or graphic list))) (IF (ATOM graphic) (remove-from-selection view graphic) (DOTIMES (pos (LENGTH graphic)) (remove-from-selection view (ELT graphic pos)))) (repair-view view) graphic) (DEFUN remove-from-selection (view graphic) "Unattach the graphic from a highlight object in the selection scene" (with-slots (selection) view (DOTIMES (pos (LENGTH (scene-elements selection))) (LET ((scene-graphic (ELT (scene-elements selection) pos))) (WHEN (EQ (grabber-graphic scene-graphic) graphic) ;Is the graphic attached to a highlight object in the scene (view-damage view (grabber-graphic scene-graphic)) ; yes, erase the highlight object with the xor function (SETF (graphic-sensitivity scene-graphic) :hidden) ; hide the highlight objec (SETF (grabber-graphic scene-graphic) nil) ; unselect the graphic (RETURN))))) ) (DEFMETHOD view-clear-selection ((view view)) (with-slots (selection) view (LET* ((elements (scene-elements selection)) (elements-length (FILL-POINTER elements))) (WHEN (> elements-length 0) (DOTIMES (pos elements-length ) (LET* ((highlight (ELT elements pos)) (graphic (grabber-graphic highlight))) (WHEN (NOT (EQ (graphic-sensitivity highlight) :hidden)) ;is the highlight object alread hidden (draw-graphic highlight view) (graphic-damage graphic) ) (SETF (graphic-sensitivity highlight) :hidden) ; no, hide the highlight object (SETF (grabber-graphic highlight) nil))) ; unselect the graphic (SETF (graphic-sensitivity (view-selection-scene view)) :hidden) ) ;hide the selection-view (SETF (FILL-POINTER elements) 0))) ;No selected graphics in the scene (repair-view view)) (DEFMETHOD view-select-graphic ((view view) &key add ) (with-event (x y display) (PROGN (MULTIPLE-VALUE-BIND (x1 y1) (view-untransform-point view x y) (LET (( graphic (graphic-pick (view-graphic view) x1 y1 (* 2 (view-pixel-size view)))) (selection-elements (AND (view-selection view) (scene-elements (slot-value view 'selection))))) (IF graphic ;(AND graphic (NOT (EQL graphic (view-graphic view)))) ;Has a graphic been picked? (IF (AND (view-selection view) (DOTIMES (pos (LENGTH selection-elements)) (WHEN (EQ (grabber-graphic (ELT selection-elements pos)) graphic) (RETURN t)))) (unless add (view-move-graphic graphic view )) (PROGN (UNLESS add ; Yes, is the graphic to be added to the selection? (view-clear-selection view)) ; No, clear the selection. (view-add-selection view graphic) ; Add the graphic to the view selection. ;(view-move-graphic graphic view ) ) ) (view-clear-selection view) ; No, clear the view-selection )))) )) (DEFMETHOD view-move-graphic ((graphic graphic) (view view) &key (event :button-1)) (LET* ((world-extent (world-extent graphic)) (fixed-x (transform-x view (extent-rect-xmin world-extent))) (fixed-y (transform-y view (extent-rect-ymin world-extent))) (px1 (transform-x view (extent-rect-xmax world-extent))) (py1 (transform-y view (extent-rect-ymax world-extent))) (highlight-color (view-highlight-color view)) (selection-elements (scene-elements (view-selection-scene view))) (pixel-size (view-pixel-size view)) ) (with-event (x y display key) (LET* ((*px* px1 ) ( *py* py1) (*fixed-x* fixed-x) (*fixed-y* fixed-y) (*delta-fx* (- fixed-x x )) ( *delta-fy* (- fixed-y y)) (*delta-px* (- x *px* )) (*delta-py* (- y *py*)) ) (DECLARE (SPECIAL *px* *py* *fixed-x* *fixed-y* *delta-fx* *delta-fy* *delta-px* *delta-py* *transform*)) (WHEN (= *px* *fixed-x*) (SETF *px* (FLOOR (+ *px* pixel-size)) *delta-px* (FLOOR (+ *delta-px* pixel-size)))) (WHEN (= *py* *fixed-y*) (SETF *py* (FLOOR (+ *py* pixel-size)) *delta-py* (FLOOR (+ *delta-py* pixel-size)))) (with-event-mode (view `((:motion-notify ,event) (move-box)) `((:button-release ,event) (view-button-release t))) (LET ((display-after-func (display-after-function display)) (events-enabled-p (graphic-events-enabled-p view))) (UNWIND-PROTECT (progn (SETF (graphic-events-enabled-p view) nil) (SETF (display-after-function display) #'display-force-output) (drawbox-with-gc view highlight-color *fixed-x* *fixed-y* *px* *py*) (grab-pointer view #.(make-event-mask :button-release :pointer-motion) :owner-p t) (CATCH :release (LOOP (process-next-event display ))) (drawbox-with-gc view highlight-color *fixed-x* *fixed-y* *px* *py*) (SETF (display-after-function display) nil)) (PROGN (SETF (graphic-events-enabled-p view) events-enabled-p ) (ungrab-pointer display)) ) (SETF (display-after-function display) display-after-func)) (erase-grabber-rects view selection-elements (FILL-POINTER selection-elements)) (repair-view view) (move-selected-graphics view selection-elements (FILL-POINTER selection-elements) (- (view-untransform-x view *fixed-x*) (view-untransform-x view fixed-x )) (- (view-untransform-y view *fixed-y*) (view-untransform-y view fixed-y))))))) (repair-view view)) (DEFMETHOD view-unselect-graphic ((view view) ) (MULTIPLE-VALUE-BIND (x y) (pointer-position view) (MULTIPLE-VALUE-SETQ (x y) (view-untransform-point view x y)) (LET (( graphic (graphic-pick (view-graphic view) x y ))) (WHEN (AND graphic (NOT (EQL graphic (view-graphic view)))) (view-remove-selection view graphic) )))) (DEFMETHOD view-select-region ((view view) &key add ) (with-event (x y display) (LET* ((highlight-color (view-highlight-color view)) (*px* x ) ( *py* y) ( fixed-x x) ( fixed-y y) ) (DECLARE (SPECIAL *px* *py* )) (with-event-mode (view `((:motion-notify :button-3) (scale-rubberband ,fixed-x ,fixed-y)) '((:button-release :button-3) (view-button-release t))) (process-motion-notify-events view display fixed-x fixed-y *px* *py* highlight-color) (MULTIPLE-VALUE-BIND (x y) (view-untransform-point view fixed-x fixed-y) ;Transform the view coordinates to world coordinates. (MULTIPLE-VALUE-BIND (x1 y1) (view-untransform-point view *px* *py*) (UNLESS add (view-clear-selection view)) ;Clear the selection unless instructed (IF (< x1 x) (ROTATEF x x1)) (IF (< y1 y) (ROTATEF y y1)) (view-add-selection view (graphic-within (view-graphic view) x y (- x1 x ) (- y1 y))) )))))) (DEFMETHOD view-unselect-region ((view view) ) (with-event (x y display) (LET* ((highlight-color (view-highlight-color view)) (*px* x ) ( *py* y) ( fixed-x x) ( fixed-y y) ) (DECLARE (SPECIAL *px* *py* )) (with-event-mode (view '((:motion-notify :button-3) (LIST 'scale-rubberband fixed-x fixed-y)) '((:button-release :button-1) (view-button-release t))) (process-motion-notify-events view display fixed-x fixed-y *px* *py* highlight-color) (MULTIPLE-VALUE-BIND (x y) (view-untransform-point view fixed-x fixed-y) ;Transform the view coordinates to world coordinates. (MULTIPLE-VALUE-BIND (x1 y1) (view-untransform-point view *px* *py*) ;to add it to the existing selection. (view-remove-selection view (graphic-within (view-graphic view) x y1 (- x1 x ) (- y y1))) )))))) ;button release method used for user dialogs (DEFMETHOD view-button-release ((view view) &optional throw) (WHEN throw (THROW :release t))) (DEFMETHOD scale-rubberband ((view view) fixed-x fixed-y) (DECLARE (SPECIAL *px* *py* )) (with-slots (highlight-color display button-release-p) view (with-event (x y) (using-gcontext (gc :drawable view :function boole-xor :foreground highlight-color) (drawbox fixed-x fixed-y *px* *py*) (drawbox fixed-x fixed-y x y)) (SETF *px* x) (SETF *py* y) ))) (DEFMETHOD scale-rubberband-fixed-width ((view view) fixed-x fixed-y px) (DECLARE (SPECIAL *py* )) (with-slots (highlight-color display button-release-p) view (with-event (x y) (using-gcontext (gc :drawable view :function boole-xor :foreground highlight-color) (drawbox fixed-x fixed-y px *py*) (drawbox fixed-x fixed-y px y)) (SETF *py* y) ))) (DEFMETHOD scale-rubberband-fixed-height ((view view) fixed-x fixed-y py ) (DECLARE (SPECIAL *px* )) (with-slots (highlight-color display button-release-p) view (with-event (x y) (using-gcontext (gc :drawable view :function boole-xor :foreground highlight-color) (drawbox fixed-x fixed-y *px* py) (drawbox fixed-x fixed-y x py)) (SETF *px* x) ))) (DEFMETHOD move-box ((view view) ) (DECLARE (SPECIAL *px* *py* *fixed-x* *fixed-y* *delta-fy* *delta-fx* *delta-py* *delta-px*)) (with-slots (highlight-color display button-release-p selection) view (WHEN (> (LENGTH (scene-elements selection)) 0) (with-event (x y) (using-gcontext (gc :drawable view :function boole-xor :foreground highlight-color) (drawbox *fixed-x* *fixed-y* *px* *py*) (SETF *fixed-x* (+ x *delta-fx*) *fixed-y* (+ y *delta-fy*) *px* (- x *delta-px*) *py* (- y *delta-py*)) (drawbox *fixed-x* *fixed-y* *px* *py*))) ))) (DEFMACRO change-to-identity (transform) `(with-slots (t11 t12 t21 t22 t31 t32) ,transform (SETF t11 1 t12 0 t21 0 t22 1 t31 0 t32 0))) (DEFMETHOD rotate-box ((view view) ) (DECLARE (SPECIAL *px* *py* *fixed-x* *fixed-y* *transform* *rotate-vector*)) (with-slots (highlight-color display button-release-p) view (with-event (x y) (with-vector draw-vertices (copy-to-vector *rotate-vector* draw-vertices) (LET* ((sx (ELT draw-vertices 4)) (sy (ELT draw-vertices 5)) (angle (- (IF (= x *fixed-x*) (radians 0) (+ (ATAN (/ (- y *fixed-y*) (- x *fixed-x* ))) (IF (< (* (SIGNUM (- sx *fixed-x* ))(- x *fixed-x* )) 0) (radians 180) 0))) (IF (= *fixed-x* sx) 0 (ATAN (/ (- sy *fixed-y* ) (- sx *fixed-x* ))))) ; (radians 180)) )) (using-gcontext (gc :drawable view :function boole-xor :foreground highlight-color) (transform-point-seq *transform* draw-vertices) (round-vector draw-vertices) (draw-lines view gc draw-vertices ) (copy-to-vector *rotate-vector* draw-vertices) (change-to-identity *transform*) (rotate-transform *transform* angle (ELT *rotate-vector* 0) (ELT *rotate-vector* 1)) (transform-point-seq *transform* draw-vertices) (round-vector draw-vertices) (draw-lines view gc draw-vertices ) (SETF *px* (ELT draw-vertices 4)) (SETF *py* (ELT draw-vertices 5)) ))))))