home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1991: Code Warrior / bincue / Code Warrior.bin / Development Platforms (Moof!) / LISP Related / Goal-Plan-Code Editor / library / ken-objects.lisp < prev    next >
Encoding:
Text File  |  1990-07-06  |  18.1 KB  |  433 lines  |  [TEXT/CCL ]

  1.  
  2. ;=====================================================================
  3. ;  GPC Editor
  4. ;
  5. ;  Name: ken-objects.lisp
  6. ;  
  7. ;  Various objects used in the GPC Editor.
  8. ;
  9. ;---------------------------------------------------------------------
  10. ; Date        Name  Comments   
  11. ;---------------------------------------------------------------------
  12. ; 10/13/88    lhh   Initial Documentation
  13. ;=====================================================================
  14.  
  15. ;;; load this file into the objects available for the system. 
  16. ;;; ???
  17. ;;; Why is the statement 'in-package' needed
  18. ;;;???
  19.  
  20. (provide "ken-objects")
  21. (in-package "ken-objects")
  22.  
  23. ;;; Shadow nothing.
  24. (export '(*alist-dialog-item* cell-contents full-cell-contents value-cell-contents
  25.           *pane* *paned-window* 
  26.           *selection-dialog* ))
  27.  
  28. ;;; Require nothing.
  29. (use 'ccl)
  30. ;;; Import nothing.
  31.  
  32.  
  33. ;;;;****************************************************************************
  34. ;;;; The Actual Contents
  35. ;;;;****************************************************************************
  36.  
  37. ;;;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  38. ;;;; *alist-dialog-item*
  39. ;;;; A kind of *sequence-dialog-item* that supports displaying alists.
  40. ;;;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  41.  
  42. (defobject *alist-dialog-item* *sequence-dialog-item*)
  43.  
  44. (defobfun (cell-contents *alist-dialog-item*) (cell)
  45.    (car (usual-cell-contents cell)))
  46.  
  47. (defobfun (full-cell-contents *alist-dialog-item*) (cell)
  48.   (elt (table-sequence) (cell-to-index cell)))
  49.  
  50. (defobfun (value-cell-contents *alist-dialog-item*) (cell)
  51.   (cdr (full-cell-contents cell)))
  52.  
  53. #| 11/13/87 unfinished
  54. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  55. ;+++ *size-it-window* - UNFINISHED AS OF 11/13/87
  56. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  57. #|
  58. size-it-window is a subclass of *window* which allows the user to size and
  59. position the window on creation (NOT appearance) with the mouse.  When asked
  60. to exist if
  61.    option-key is depressed             then use user mouse input to position
  62.                                        and size the window
  63.    command-key is depressed            then use user mouse input to position
  64.                                        and size the window and store these
  65.                                        globally for this class of window
  66. otherwise if
  67.    size and/or position is given       use these
  68. otherwise if
  69.    global defaults (see command-key)   use these
  70.       for this class are given
  71. otherwise                              use *window* defaults
  72.  
  73. The work of maintaining the global list of defaults is done by function exist.
  74. |#
  75.  
  76. (setq *size-it-defaults* '())
  77.  
  78. (defobject *size-it-window* *window*)
  79.  
  80. (defobfun (exist *size-it-window*) (&rest init-list)
  81.   (let* ((window-type (getf init-list :window-type :document))
  82.          (given-pos (getf init-list :window-pos '()))
  83.          (given-size (getf init-list :window-size '()))
  84.          (class-defaults (assoc (ask (car (object-parents (self))) object-name) 
  85.                                 *size-it-defaults*))
  86.          (global-defaults '(#@(6 44) #@(502 150)))
  87.          (defaults (list (cond (given-pos)
  88.                                ((car class-defaults))
  89.                                (t (car global-defaults)))
  90.                          (cond (given-size)
  91.                                ((cadr class-defaults))
  92.                                (t (cadr global-defaults)))))
  93.          (settings (cond ((option-key-p) (get-settings defaults window-type))
  94.                          ((command-key-p) (set-class-defaults
  95.                                            (get-settings defaults window-type)))
  96.                          (t defaults))))
  97.     (usual-exist
  98.      (init-list-default init-list 
  99.                         :window-position (car settings)
  100.                         :window-size (cadr settings)))))
  101.  
  102. (defobfun (get-settings *size-it-window*) (defaults window-type)
  103.   (with-cursor 2
  104.     (let ((default-pos (car defaults))
  105.           (default-size (cadr defaults))
  106.           (start (loop (when (mouse-down-p)
  107.                          (return (local-to-global 
  108.                                   (ask (front-window) 
  109.                                     (window-mouse-position)))))))
  110.           (end (loop (when (not (mouse-down-p)) 
  111.                        (return (local-to-global
  112.                                 (ask (front-window) 
  113.                                   (window-mouse-position))))))))
  114.       (if (double-click-spacing-p start end)
  115.         (adjust-window-settings (list (start default-size))
  116.                                 window-type)
  117.         (adjust-window-settings (list (start (subtract-points end start)))
  118.                                 window-type)))))
  119.  
  120. (setq w (oneof *size-it-window*))
  121. |# 11/13/87 unfinished
  122.  
  123.  
  124. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  125. ;+++ *paned-window*
  126. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  127. #|
  128. Paned windows organize a set of windows so that all may be activated, deactivated,
  129. selected, and closed at once.  Panes can be any window object but :document-with-
  130. grow and :document-with-zoom, since changing the size of a pane is not yet
  131. supported.  Also, overlapping of panes is not checked yet either, so WATCH OUT!
  132.  
  133. |#
  134.  
  135. (defobject *pane* *window*)
  136. (defobfun (exist *pane*) (init-list)
  137.   (declare (special *paned-window*))
  138.   (let ((my-window (getf init-list :my-window nil))
  139.         (window-type (getf init-list :window-type :document)))
  140.     (cond ((equal window-type :document-with-zoom)
  141.            (error "Panes may not be of type :document-with-zoom."))
  142.           ((equal window-type :document-with-grow)
  143.            (error "Panes may not be of type :document-with-grow."))
  144.           ((and my-window (not (typep my-window *paned-window*)))
  145.            (error ":my-window ~a must be a *paned-window*." my-window))
  146.           (t (have 'my-window my-window)
  147.              (usual-exist 
  148.               (init-list-default init-list
  149.                                  :window-show nil))))))
  150. (defobfun (window-select-event-handler *pane*) ()
  151.   (if (null my-window)
  152.     (usual-window-select-event-handler)
  153.     (ask my-window (window-select-event-handler))))
  154. (defobfun (window-close *pane*) ()
  155.   (if (null my-window)
  156.     (usual-window-close)
  157.     (ask my-window (window-close))))
  158. (defobfun (window-deactivate-event-handler *pane*) ()
  159.   (if (null my-window)
  160.     (usual-window-deactivate-event-handler)
  161.     (ask my-window (window-deactivate-event-handler))))
  162. (defobfun (window-activate-event-handler *pane*) ()
  163.   (if (null my-window)
  164.     (usual-window-activate-event-handler)
  165.     (ask my-window (window-activate-event-handler))))
  166.           
  167.  
  168. (defobject *paned-window* *window*)
  169. (defobfun (exist *paned-window*) (init-list)
  170.   (declare (special *pane*))
  171.   (let ((panes (getf init-list :panes '())))
  172.     (have 'panes (cond
  173.                   ((null panes) '())
  174.                   ((notevery #'(lambda (thing) (typep thing *pane*)) panes)
  175.                    (error "All panes must inherit from ~a." *pane*))
  176.                   (t (muliple-value-bind 
  177.                       (check msg)
  178.                       (ok-regions-p 
  179.                        (mapcar #'(lambda (p)
  180.                                    (ask p
  181.                                      (unless (ownp 'wptr)
  182.                                        (exist))))
  183.                                panes))
  184.                       (if check panes (error msg))))))
  185.     (usual-exist 
  186.      (init-list-default init-list
  187.                         :window-show nil))))
  188. (defobfun (add-panes *paned-window*) (&rest the-panes)
  189.   (declare (special *pane*))
  190.   (let ((w (self)))
  191.     (if (and (mapc #'(lambda (p) (typep p *pane*)) the-panes)
  192.              (ok-regions-p (append (mapcar #'(lambda (p)
  193.                                                (ask p
  194.                                                  (unless (ownp 'wptr)
  195.                                                    (exist))))
  196.                                            the-panes) 
  197.                                    panes)))
  198.       (mapcar #'(lambda (p) 
  199.                   (ask p (setf my-window w))
  200.                   (ask w (pushnew p panes)))
  201.               the-panes)
  202.       (error "All panes, even ~a, must inherit from ~a."
  203.              p
  204.              *pane*))))
  205.  
  206.  
  207. ;;; window-select-event-handler shadows the default handler, which would
  208. ;;;   deactivate all the panes.  This version activates all the panes and
  209. ;;;   moves them as a block to the front of the window list.
  210. ;
  211. (defobfun (window-select-event-handler *paned-window*) ()
  212.   (unless (find (front-window) panes)
  213.     (ask (front-window) (window-deactivate-event-handler))
  214.     (window-activate-event-handler)))
  215.  
  216. ;;; window-activate-event-handler shadows the default handler, which would
  217. ;;;   ignore the window panes.  This version activates all panes as well.
  218. ;
  219. (defobfun (window-activate-event-handler *paned-window*) ()
  220.   (do ((counter 0 (1+ counter)))
  221.       ((= (length panes) counter) 
  222.        (progn
  223.          (_hilitewindow :ptr wptr :word #xFFFF)
  224.          (usual-window-activate-event-handler)))
  225.     (ask (nth counter panes)
  226.       (_hilitewindow :ptr wptr :word #xFFFF)
  227.       (usual-window-activate-event-handler)
  228.       (set-window-layer counter))))
  229.  
  230. ;;; window-deactivate-event-handler shadows the default handler, which would
  231. ;;;   ignore the window panes.  This version deactivates all panes as well.
  232. ;
  233. (defobfun (window-deactivate-event-handler *paned-window*) ()
  234.   (do ((counter (length panes) (1- counter)))
  235.       ((= 0 counter) (usual-window-deactivate-event-handler))
  236.     (ask (nth counter panes)
  237.       (usual-window-deactivate-event-handler))))
  238.  
  239. ;;; window-close shadows the default window-close, which would
  240. ;;;   ignore the window panes.  This version closes all panes as well.
  241. ;
  242. (defobfun (window-close *paned-window*) ()
  243.   (do ((counter (length panes) (1- counter)))
  244.       ((= 0 counter) (usual-window-close))
  245.     (ask (nth counter panes)
  246.       (usual-window-close))))
  247.  
  248. ;;; make-paned-window takes a window and a list of panes.  It remakes (if nec.)
  249. ;;;   the window as a *paned-window* with the given list of panes (also remade
  250. ;;;   as *pane*'s, if nec.) as its panes, checking that the rectangles of all
  251. ;;;   of the panes do not overlap, and the union of all the rectangles lies
  252. ;;;   within the window's content region.
  253. ;
  254. (defobfun (ok-regions-p *window*) (panes)
  255.   (let ((scratch-region (new-region))
  256.         (the-union (new-region)))
  257.     (set-empty-region the-union)
  258.     (do ((counter (1- (length panes)) (1- counter)))
  259.         ((= -1 counter) 
  260.          (if (empty-region-p
  261.               (difference-region the-union
  262.                                  (rref wptr window.contrgn)
  263.                                  scratch-region))
  264.            (progn
  265.              (dispose-region scratch-region)
  266.              (dispose-region the-union)
  267.              (values t nil)
  268.            (progn
  269.              (dispose-region scratch-region)
  270.              (dispose-region the-union)
  271.              (values nil
  272.                      (format nil 
  273.                              "The panes must all be within ~a's content region." 
  274.                              (self)))))))
  275.       (ask (nth counter panes)
  276.         (if (not 
  277.              (empty-region-p 
  278.               (intersect-region the-union 
  279.                                 (rref wptr window.strucrgn) 
  280.                                 scratch-region)))
  281.           (progn
  282.            (dispose-region scratch-region)
  283.            (dispose-region the-union)
  284.            (values nil "The panes may not overlap."))
  285.           (copy-region 
  286.            (union-region the-union 
  287.                          (rref wptr window.strucrgn)
  288.                          scratch-region)
  289.            the-union))))))
  290.  
  291. (defun make-paned-window (window &rest panes)
  292.   (declare (special *paned-window*))
  293.   (when (ask window (ok-regions-p panes))
  294.     (ask
  295.       (unless (typep window *paned-window*)
  296.         (apply #'remake-object window
  297.                *paned-window* 
  298.                (object-parents window)))
  299.       (have 'panes
  300.             (mapcar #'(lambda (w) (make-pane w window)) panes)))
  301.     window))
  302.           
  303.  
  304. #|
  305. *selection-dialog*
  306.  
  307. Selection dialogs contain a prompt, a table, an ok-button, and a cancel-button.
  308.  
  309. The function GET-SELECTION is used to create selection dialogs.  The user makes 
  310. a selection in the table and presses either button.  If ok-button is pressed, 
  311. then the selection is returned.  If cancel-button is pressed, then :cancel is 
  312. returned.
  313.  
  314. Selection dialogs are always modal.  Therefore, if cancel-button is pressed,
  315. a throw to :cancel will be made, with :cancel returned.  Unless GET-SELECTION
  316. is called from withing a catch form, the throw will continue to the Listener.
  317.  
  318. GET-SELECTION accepts any even number of arguments.  The arguments should
  319. alternate between keywords and values (like the argument to oneof).  GET-
  320. SELECTION accepts the standard window init-list options, but you usually
  321. need supply only :window-title.  In addition, GET-SELECTION accepts the
  322. following pseudo-keyword arguments:
  323.  
  324. :prompt             The prompt string to display in the dialog.
  325.  
  326. :item-list          A list of items to display in the dialog.
  327.  
  328. :table-height       The height of the selection table defaults to 4
  329.                     unless this keyword and value are given.  The value
  330.                     should be an integer number of CELLS.
  331.  
  332. :dialog-width       The width of the dialog is not computed automatically.
  333.                     The default width is 200 pixels.  Specify a different 
  334.                     width using :dialog-width.  It should be an integer 
  335.                     number of PIXELS.
  336.  
  337. :position           The upper right corner of the dialog defaults to #@(100 50).
  338.                     unless this keyword and value are given.  The value
  339.                     should be a POINT, ie of the form #@(... ...).
  340.  
  341. :|#
  342.  
  343. (defobject *selection-dialog* *dialog*)
  344.  
  345. (defobfun (exist *selection-dialog*) (&rest init-list)
  346.   (declare (special *screen-height* *screen-width*)
  347.            (special *button-dialog-item* *sequence-dialog-item*
  348.                     *static-text-dialog-item*))
  349.   (let* ((item-list (getf init-list :item-list ()))
  350.          (list-length (length item-list))
  351.          (table-height (* 16 (min (- *screen-height* 122)
  352.                                   (getf init-list :table-height 4))))
  353.          (dialog-height (+ 56 table-height))
  354.          (dialog-width (max 150 (getf init-list :dialog-width 150)))
  355.          (dialog-position (getf init-list :position #@(100 50)))
  356.          (prompt (getf init-list :prompt "Select one and press OK:"))
  357.          (the-prompt (oneof *static-text-dialog-item*
  358.                             :dialog-item-position #@(1 1) 
  359.                             :dialog-item-text prompt))
  360.          (ok-button (oneof *button-dialog-item*
  361.                            :dialog-item-position (make-point 
  362.                                                   (- dialog-width 39)
  363.                                                   (- dialog-height 20))
  364.                            :dialog-item-text " OK "
  365.                            :dialog-item-enabled-p nil))
  366.          (the-table (oneof *sequence-dialog-item*
  367.                            :dialog-item-position #@(1 19) 
  368.                            :table-sequence item-list
  369.                            :table-vscrollp t
  370.                            :table-hscrollp nil
  371.                            :dialog-item-size (make-point 
  372.                                               (- dialog-width 2)
  373.                                               table-height)
  374.                            :cell-size (make-point
  375.                                        (- dialog-width 19)
  376.                                        16)
  377.                            :dialog-item-action
  378.                            (nfunction
  379.                             dialog-item-action
  380.                             (lambda ()
  381.                               (ask ok-button 
  382.                                 (unless (dialog-item-enabled-p)
  383.                                   (dialog-item-enable)))
  384.                               (ask my-dialog (set-default-button ok-button))
  385.                               (usual-dialog-item-action)))))
  386.          (cancel-button (oneof *button-dialog-item*
  387.                                :dialog-item-position (make-point 
  388.                                                       4 
  389.                                                       (- dialog-height 20))
  390.                                :dialog-item-text " Cancel "
  391.                                :dialog-item-action 
  392.                                (nfunction
  393.                                 dialog-item-action
  394.                                 (lambda ()
  395.                                   (usual-dialog-item-action)
  396.                                   (return-from-modal-dialog :cancel))))))
  397.     (ask ok-button (fhave 'dialog-item-action
  398.                           (nfunction 
  399.                            dialog-item-action
  400.                            (lambda ()
  401.                              (usual-dialog-item-action)
  402.                              (return-from-modal-dialog
  403.                               (ask the-table 
  404.                                 (cell-contents (car (selected-cells)))))))))
  405.     (usual-exist
  406.      (init-list-default init-list
  407.                         :window-type :double-edge-box
  408.                         :window-size (make-point dialog-width dialog-height)
  409.                         :window-position dialog-position 
  410.                         :window-show t
  411.                         :window-title (getf init-list
  412.                                             :window-title "Select")
  413.                         :dialog-items (list the-table the-prompt cancel-button
  414.                                             ok-button)))))
  415.  
  416. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  417. ;+++ get-object-descendants
  418. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  419. ;
  420. ; This function recursively finds the descendants of its argument.
  421. ; Of course it only works for hierarchies created using defobject.
  422. ;
  423. (defun get-object-descendants (thing)
  424.   (let ((kids (ask thing object-children)))
  425.     (when kids
  426.       (nconc (mapcar '(lambda (thing)
  427.                          (ask thing object-name))
  428.                       kids)
  429.               (apply #'nconc
  430.                      (mapcar #'get-object-descendants
  431.                              kids))))))
  432.