Author: junrue Date: Wed Jul 5 00:18:46 2006 New Revision: 176
Modified: trunk/README.txt trunk/docs/manual/api.texinfo trunk/docs/manual/reference.texinfo trunk/src/packages.lisp trunk/src/tests/uitoolkit/layout-tester.lisp trunk/src/uitoolkit/widgets/dialog.lisp trunk/src/uitoolkit/widgets/flow-layout.lisp trunk/src/uitoolkit/widgets/heap-layout.lisp trunk/src/uitoolkit/widgets/widget-generics.lisp trunk/src/uitoolkit/widgets/window.lisp Log: promoted mapchildren to a widget generic function and cleaned up its semantics, and got rid of with-children at the same time
Modified: trunk/README.txt ============================================================================== --- trunk/README.txt (original) +++ trunk/README.txt Wed Jul 5 00:18:46 2006 @@ -1,5 +1,5 @@
-Graphic-Forms README for version 0.4.0 +Graphic-Forms README for version 0.5.0 Copyright (c) 2006, Jack D. Unrue
Graphic-Forms is a user interface library implemented in Common Lisp focusing
Modified: trunk/docs/manual/api.texinfo ============================================================================== --- trunk/docs/manual/api.texinfo (original) +++ trunk/docs/manual/api.texinfo Wed Jul 5 00:18:46 2006 @@ -1107,6 +1107,13 @@ system. @xref{parent}. @end deffn
+@deffn GenericFunction mapchildren self func => result-list +Calls @code{func}, which is a function of two arguments, for each +child of @code{self} and places @code{func}'s return value in +@code{result-list}. @code{func}'s two arguments are @code{self} and +the current child. +@end deffn + @anchor{maximum-size} @deffn GenericFunction maximum-size self => size Returns a @ref{size} object describing the largest dimensions to which
Modified: trunk/docs/manual/reference.texinfo ============================================================================== --- trunk/docs/manual/reference.texinfo (original) +++ trunk/docs/manual/reference.texinfo Wed Jul 5 00:18:46 2006 @@ -126,7 +126,7 @@
@titlepage @title Graphic-Forms Programming Reference -@c @subtitle Version 0.4 +@c @subtitle Version 0.5 @c @author Jack D. Unrue
@page @@ -136,7 +136,7 @@
@ifnottex @node Top -@top Graphic-Forms Programming Reference (version 0.4) +@top Graphic-Forms Programming Reference (version 0.5) @insertcopying @end ifnottex
Modified: trunk/src/packages.lisp ============================================================================== --- trunk/src/packages.lisp (original) +++ trunk/src/packages.lisp Wed Jul 5 00:18:46 2006 @@ -423,6 +423,7 @@ #:location #:lock #:locked-p + #:mapchildren #:maximize #:maximized-p #:maximum-size @@ -493,7 +494,6 @@ #:vertical-scrollbar #:visible-item-count #:visible-p - #:with-children #:with-file-dialog #:with-font-dialog
Modified: trunk/src/tests/uitoolkit/layout-tester.lisp ============================================================================== --- trunk/src/tests/uitoolkit/layout-tester.lisp (original) +++ trunk/src/tests/uitoolkit/layout-tester.lisp Wed Jul 5 00:18:46 2006 @@ -172,24 +172,29 @@ (defmethod gfw:event-activate ((d child-menu-dispatcher) menu time) (declare (ignore time)) (gfw:clear-all menu) - (gfw:with-children (*layout-tester-win* kids) - (loop for k in kids - do (let ((it (gfw::append-item menu (gfw:text k) nil nil))) - (unless (null (sub-disp-class-of d)) - (setf (gfw:dispatcher it) (make-instance (sub-disp-class-of d)))) - (unless (null (check-test-fn d)) - (gfw:check it (funcall (check-test-fn d) k))))))) + (gfw:mapchildren *layout-tester-win* + (lambda (parent child) + (declare (ignore parent)) + (let ((it (gfw::append-item menu (gfw:text child) nil nil))) + (unless (null (sub-disp-class-of d)) + (setf (gfw:dispatcher it) (make-instance (sub-disp-class-of d)))) + (unless (null (check-test-fn d)) + (gfw:check it (funcall (check-test-fn d) child))))))) + +(defun find-victim (text) + (let ((victim nil)) + (gfw:mapchildren *layout-tester-win* + (lambda (parent child) + (declare (ignore parent)) + (if (string= (gfw:text child) text) + (setf victim child)))) + victim))
(defclass remove-child-dispatcher (gfw:event-dispatcher) ())
(defmethod gfw:event-select ((d remove-child-dispatcher) item time rect) (declare (ignorable time rect)) - (let ((text (gfw:text item)) - (victim nil)) - (gfw:with-children (*layout-tester-win* kids) - (loop for k in kids - do (if (string= (gfw:text k) text) - (setf victim k)))) + (let ((victim (find-victim (gfw:text item)))) (unless (null victim) (gfs:dispose victim) (gfw:layout *layout-tester-win*)))) @@ -198,12 +203,7 @@
(defmethod gfw:event-select ((d visibility-child-dispatcher) item time rect) (declare (ignorable time rect)) - (let ((text (gfw:text item)) - (victim nil)) - (gfw:with-children (*layout-tester-win* kids) - (loop for k in kids - do (if (string= (gfw:text k) text) - (setf victim k)))) + (let ((victim (find-victim (gfw:text item)))) (unless (null victim) (gfw:show victim (not (gfw:visible-p victim))) (gfw:layout *layout-tester-win*))))
Modified: trunk/src/uitoolkit/widgets/dialog.lisp ============================================================================== --- trunk/src/uitoolkit/widgets/dialog.lisp (original) +++ trunk/src/uitoolkit/widgets/dialog.lisp Wed Jul 5 00:18:46 2006 @@ -83,10 +83,13 @@ (error 'gfs:disposed-error)))
(defmethod cancel-widget ((self dialog)) - (with-children (self kids) - (loop for kid in kids - until (= (gfs::get-window-long (gfs:handle kid) gfs::+gwlp-id+) gfs::+idcancel+) - finally (return kid)))) + (let ((kid nil)) + (mapchildren self + (lambda (parent child) + (declare (ignore parent)) + (if (= (gfs::get-window-long (gfs:handle child) gfs::+gwlp-id+) gfs::+idcancel+) + (setf kid child)))) + kid))
(defmethod (setf cancel-widget) :before ((def-widget widget) (self dialog)) (if (or (gfs:disposed-p self) (gfs:disposed-p def-widget)) @@ -118,10 +121,13 @@ (error 'gfs:disposed-error)))
(defmethod default-widget ((self dialog)) - (with-children (self kids) - (loop for kid in kids - until (= (gfs::get-window-long (gfs:handle kid) gfs::+gwlp-id+) gfs::+idok+) - finally (return kid)))) + (let ((kid nil)) + (mapchildren self + (lambda (parent child) + (declare (ignore parent)) + (if (= (gfs::get-window-long (gfs:handle child) gfs::+gwlp-id+) gfs::+idok+) + (setf kid child)))) + kid))
(defmethod (setf default-widget) :before ((def-widget widget) (self dialog)) (if (or (gfs:disposed-p self) (gfs:disposed-p def-widget))
Modified: trunk/src/uitoolkit/widgets/flow-layout.lisp ============================================================================== --- trunk/src/uitoolkit/widgets/flow-layout.lisp (original) +++ trunk/src/uitoolkit/widgets/flow-layout.lisp Wed Jul 5 00:18:46 2006 @@ -171,11 +171,15 @@ ;;;
(defmethod compute-size ((layout flow-layout) (win window) width-hint height-hint) - (with-children (win kids) + (let ((kids (mapchildren win (lambda (parent child) + (declare (ignore parent)) + child)))) (flow-container-size layout (visible-p win) kids width-hint height-hint)))
(defmethod compute-layout ((layout flow-layout) (win window) width-hint height-hint) - (with-children (win kids) + (let ((kids (mapchildren win (lambda (parent child) + (declare (ignore parent)) + child)))) (flow-container-layout layout (visible-p win) kids width-hint height-hint)))
(defmethod initialize-instance :after ((layout flow-layout) &key)
Modified: trunk/src/uitoolkit/widgets/heap-layout.lisp ============================================================================== --- trunk/src/uitoolkit/widgets/heap-layout.lisp (original) +++ trunk/src/uitoolkit/widgets/heap-layout.lisp Wed Jul 5 00:18:46 2006 @@ -39,13 +39,13 @@
(defmethod compute-size ((self heap-layout) win width-hint height-hint) (let ((size (gfs:make-size))) - (with-children (win kids) - (loop for kid in kids - do (let ((kid-size (preferred-size kid width-hint height-hint))) - (setf (gfs:size-width size) (max (gfs:size-width size) - (gfs:size-width kid-size)) - (gfs:size-height size) (max (gfs:size-height size) - (gfs:size-height kid-size)))))) + (mapchildren win (lambda (parent kid) + (declare (ignore parent)) + (let ((kid-size (preferred-size kid width-hint height-hint))) + (setf (gfs:size-width size) (max (gfs:size-width size) + (gfs:size-width kid-size)) + (gfs:size-height size) (max (gfs:size-height size) + (gfs:size-height kid-size)))))) (incf (gfs:size-width size) (+ (left-margin-of self) (right-margin-of self))) (incf (gfs:size-height size) (+ (top-margin-of self) (bottom-margin-of self))) size)) @@ -64,8 +64,9 @@ vert-margin))) (new-pnt (gfs:make-point :x (left-margin-of self) :y (top-margin-of self))) (bounds (gfs:make-rectangle :size new-size :location new-pnt))) - (with-children (win kids) - (loop for kid in kids collect (cons kid bounds))))) + (mapchildren win (lambda (parent kid) + (declare (ignore parent)) + (cons kid bounds)))))
(defmethod perform ((self heap-layout) win width-hint height-hint) (let ((kids nil)
Modified: trunk/src/uitoolkit/widgets/widget-generics.lisp ============================================================================== --- trunk/src/uitoolkit/widgets/widget-generics.lisp (original) +++ trunk/src/uitoolkit/widgets/widget-generics.lisp Wed Jul 5 00:18:46 2006 @@ -204,6 +204,9 @@ (defgeneric locked-p (self) (:documentation "Returns T if this object's contents are locked from being modified."))
+(defgeneric mapchildren (self func) + (:documentation "Executes func for each direct child of self.")) + (defgeneric maximize (self flag) (:documentation "Set the object (or restore it from) the maximized state (not necessarily the same as the maximum size)."))
Modified: trunk/src/uitoolkit/widgets/window.lisp ============================================================================== --- trunk/src/uitoolkit/widgets/window.lisp (original) +++ trunk/src/uitoolkit/widgets/window.lisp Wed Jul 5 00:18:46 2006 @@ -61,52 +61,35 @@ (put-kbdnav-widget tc win)) (put-widget tc win))))
+(eval-when (:compile-toplevel :load-toplevel :execute) + (defmacro child-visitor-proper (hwnd lparam) + (let ((tc (gensym)) + (tmp-list (gensym)) + (child (gensym)) + (parent (gensym)) + (ancestor-hwnd (gensym))) + `(let* ((,tc (thread-context)) + (,child (get-widget ,tc ,hwnd)) + (,parent (get-widget ,tc (cffi:make-pointer ,lparam)))) + (unless (or (null ,parent) (null ,child)) + (let ((,ancestor-hwnd (gfs::get-ancestor (gfs:handle ,child) gfs::+ga-parent+)) + (,tmp-list (child-visitor-results ,tc))) + (if (cffi:pointer-eq (gfs:handle ,parent) ,ancestor-hwnd) + (setf (child-visitor-results ,tc) (push (call-child-visitor-func ,tc ,parent ,child) ,tmp-list))))))))) + #+lispworks (fli:define-foreign-callable ("child_window_visitor" :result-type :integer :calling-convention :stdcall) ((hwnd :pointer) (lparam :long)) - (let* ((tc (thread-context)) - (child (get-widget tc hwnd)) - (parent (get-widget tc (cffi:make-pointer lparam)))) - (unless (or (null parent) (null child)) - (call-child-visitor-func tc parent child))) + (child-visitor-proper hwnd lparam) 1)
#+clisp (defun child_window_visitor (hwnd lparam) - (let* ((tc (thread-context)) - (child (get-widget tc hwnd)) - (parent (get-widget tc (cffi:make-pointer lparam)))) - (unless (or (null child) (null parent)) - (call-child-visitor-func tc parent child))) + (child-visitor-proper hwnd lparam) 1)
-(defun mapchildren (win func) - ;; - ;; supplied closure should expect two parameters: - ;; parent window object - ;; current child widget - ;; - (let ((tc (thread-context))) - (setf (child-visitor-func tc) func) - (unwind-protect -#+lispworks (gfs::enum-child-windows (fli:make-pointer :address (cffi:pointer-address (gfs:handle win))) - (fli:make-pointer :symbol-name "child_window_visitor") - (cffi:pointer-address (gfs:handle win))) -#+clisp (let ((ptr (ffi:foreign-pointer (ffi:unsigned-foreign-address 0)))) - (setf ptr (ffi:set-foreign-pointer - (ffi:unsigned-foreign-address - (cffi:pointer-address (gfs:handle win))) - ptr)) - (gfs::enum-child-windows ptr - #'child_window_visitor - (cffi:pointer-address (gfs:handle win)))) - (setf (child-visitor-func tc) nil)) - (let ((tmp (reverse (child-visitor-results tc)))) - (setf (child-visitor-results tc) nil) - tmp))) - (defun register-window-class (class-name proc-ptr style bkgcolor &optional wndextra) (let ((retval 0)) (cffi:with-foreign-string (str-ptr class-name) @@ -153,17 +136,6 @@ (defun release-mouse () (gfs::release-capture))
-(eval-when (:compile-toplevel :load-toplevel :execute) - (defmacro with-children ((win var) &body body) - (let ((hwnd (gensym))) - `(let ((,var (mapchildren ,win (lambda (parent child) - (let ((,hwnd (gfs::get-ancestor - (gfs:handle child) - gfs::+ga-parent+))) - (if (cffi:pointer-eq (gfs:handle parent) ,hwnd) - (push child (child-visitor-results (thread-context))))))))) - ,@body)))) - ;;; ;;; methods ;;; @@ -242,6 +214,28 @@ (let ((sz (client-size self))) (perform (layout-of self) self (gfs:size-width sz) (gfs:size-height sz)))))
+(defmethod mapchildren ((self window) func) + (let ((tc (thread-context))) + (setf (child-visitor-func tc) func) + (unwind-protect +#+lispworks + (gfs::enum-child-windows (fli:make-pointer :address (cffi:pointer-address (gfs:handle self))) + (fli:make-pointer :symbol-name "child_window_visitor") + (cffi:pointer-address (gfs:handle self))) +#+clisp + (let ((ptr (ffi:foreign-pointer (ffi:unsigned-foreign-address 0)))) + (setf ptr (ffi:set-foreign-pointer + (ffi:unsigned-foreign-address + (cffi:pointer-address (gfs:handle self))) + ptr)) + (gfs::enum-child-windows ptr + #'child_window_visitor + (cffi:pointer-address (gfs:handle self)))) + (setf (child-visitor-func tc) nil)) + (let ((tmp (reverse (child-visitor-results tc)))) + (setf (child-visitor-results tc) nil) + tmp))) + (defmethod (setf maximum-size) :after (max-size (self window)) (unless (or (gfs:disposed-p self) (null (layout-of self))) (let ((size (constrain-new-size max-size (size self) #'min)))
graphic-forms-cvs@common-lisp.net