Author: junrue
Date: Sun Feb 19 15:50:50 2006
New Revision: 11
Added:
trunk/src/uitoolkit/widgets/layout-classes.lisp
trunk/src/uitoolkit/widgets/layouts.lisp
Modified:
trunk/graphic-forms-uitoolkit.asd
trunk/src/packages.lisp
trunk/src/tests/uitoolkit/layout-tester.lisp
trunk/src/uitoolkit/system/user32.lisp
trunk/src/uitoolkit/widgets/event-generics.lisp
trunk/src/uitoolkit/widgets/layout-generics.lisp
trunk/src/uitoolkit/widgets/widget-classes.lisp
trunk/src/uitoolkit/widgets/window.lisp
Log:
flow layout implementation
Modified: trunk/graphic-forms-uitoolkit.asd
==============================================================================
--- trunk/graphic-forms-uitoolkit.asd (original)
+++ trunk/graphic-forms-uitoolkit.asd Sun Feb 19 15:50:50 2006
@@ -87,6 +87,7 @@
:components
((:file "widget-constants")
(:file "widget-classes")
+ (:file "layout-classes")
(:file "thread-context")
(:file "message-generics")
(:file "event-generics")
@@ -100,4 +101,5 @@
(:file "widget-with-items")
(:file "menu")
(:file "event")
- (:file "window")))))))))
+ (:file "window")
+ (:file "layouts")))))))))
Modified: trunk/src/packages.lisp
==============================================================================
--- trunk/src/packages.lisp (original)
+++ trunk/src/packages.lisp Sun Feb 19 15:50:50 2006
@@ -205,7 +205,9 @@
#:control
#:event-dispatcher
#:event-source
+ #:flow-layout
#:item
+ #:layout-manager
#:menu
#:menu-item
#:widget
@@ -305,7 +307,6 @@
#:column-order
#:columns
#:compute-outer-size
- #:compute-size
#:copy
#:copy-area
#:current-font
@@ -408,7 +409,6 @@
#:parent
#:paste
#:peer
- #:perform-layout
#:preferred-size
#:realize
#:redraw
Modified: trunk/src/tests/uitoolkit/layout-tester.lisp
==============================================================================
--- trunk/src/tests/uitoolkit/layout-tester.lisp (original)
+++ trunk/src/tests/uitoolkit/layout-tester.lisp Sun Feb 19 15:50:50 2006
@@ -67,8 +67,7 @@
(defun add-layout-tester-widget (primary-type sub-type)
(let* ((be (make-instance 'layout-tester-widget-events :id *button-counter*))
- (w (make-instance primary-type :dispatcher be))
- (pnt (gfi:make-point)))
+ (w (make-instance primary-type :dispatcher be)))
(setf (widget be) w)
(cond
((eql sub-type :push-button)
@@ -89,11 +88,8 @@
(setf (gfi:point-x pnt) (+ (gfi:point-x (gfw:location child))
(gfi:size-width (gfw:size child)))))))
|#
- (setf (gfi:point-x pnt) (* 77 (1- *button-counter*)))
(gfw:realize w *layout-tester-win* sub-type)
- (setf (gfw:text w) (funcall (toggle-fn be)))
- (gfw:pack w)
- (setf (gfw:location w) pnt)))
+ (setf (gfw:text w) (funcall (toggle-fn be)))))
(defmethod gfw:event-select ((d layout-tester-widget-events) time item rect)
(declare (ignorable time rect))
@@ -107,12 +103,11 @@
(let* ((mb (gfw:menu-bar *layout-tester-win*))
(menu (gfw:sub-menu mb 1)))
(gfw:clear-all menu)
- (gfw:with-children (*layout-tester-win* child-list)
- (mapc #'(lambda (child)
- (let ((it (make-instance 'gfw:menu-item)))
- (gfw:item-append menu it)
- (setf (gfw:text it) (gfw:text child))))
- child-list))))
+ (gfw:with-children (*layout-tester-win* kids)
+ (loop for k in kids
+ do (let ((it (make-instance 'gfw:menu-item)))
+ (gfw:item-append menu it)
+ (setf (gfw:text it) (gfw:text k)))))))
(defclass layout-tester-exit-dispatcher (gfw:event-dispatcher) ())
@@ -125,7 +120,8 @@
(let* ((menubar nil)
(fed (make-instance 'layout-tester-exit-dispatcher))
(cmd (make-instance 'layout-tester-child-menu-dispatcher)))
- (setf *layout-tester-win* (make-instance 'gfw:window :dispatcher (make-instance 'layout-tester-events)))
+ (setf *layout-tester-win* (make-instance 'gfw:window :dispatcher (make-instance 'layout-tester-events)
+ :layout-manager (make-instance 'gfw:flow-layout)))
(gfw:realize *layout-tester-win* nil :style-workspace)
(setf (gfw:size *layout-tester-win*) (gfi:make-size :width 250 :height 150))
(setf menubar (gfw:defmenusystem `(((:menu "&File")
@@ -136,6 +132,7 @@
(add-layout-tester-widget 'gfw:button :push-button)
(add-layout-tester-widget 'gfw:button :push-button)
(add-layout-tester-widget 'gfw:button :push-button)
+ (gfw:layout *layout-tester-win*)
(gfw:show *layout-tester-win*)))
(defun run-layout-tester ()
Modified: trunk/src/uitoolkit/system/user32.lisp
==============================================================================
--- trunk/src/uitoolkit/system/user32.lisp (original)
+++ trunk/src/uitoolkit/system/user32.lisp Sun Feb 19 15:50:50 2006
@@ -39,10 +39,9 @@
(load-foreign-library "user32.dll")
(defcfun
- ("GetAncestor" get-ancestor)
+ ("BeginDeferWindowPos" begin-defer-window-pos)
HANDLE
- (hwnd HANDLE)
- (flags UINT))
+ (numwin INT))
(defcfun
("BeginPaint" begin-paint)
@@ -89,6 +88,18 @@
(param LPVOID))
(defcfun
+ ("DeferWindowPos" defer-window-pos)
+ HANDLE
+ (posinfo HANDLE)
+ (hwnd HANDLE)
+ (hwndafter HANDLE)
+ (x INT)
+ (y INT)
+ (cx INT)
+ (cy INT)
+ (flags UINT))
+
+(defcfun
("DefWindowProcA" def-window-proc)
LRESULT
(hwnd HANDLE)
@@ -117,6 +128,11 @@
(hwnd HANDLE))
(defcfun
+ ("EndDeferWindowPos" end-defer-window-pos)
+ BOOL
+ (posinfo HANDLE))
+
+(defcfun
("EndPaint" end-paint)
BOOL
(hwnd HANDLE)
@@ -158,6 +174,12 @@
(:return-type ffi:int))
(defcfun
+ ("GetAncestor" get-ancestor)
+ HANDLE
+ (hwnd HANDLE)
+ (flags UINT))
+
+(defcfun
("GetAsyncKeyState" get-async-key-state)
SHORT
(virtkey INT))
Modified: trunk/src/uitoolkit/widgets/event-generics.lisp
==============================================================================
--- trunk/src/uitoolkit/widgets/event-generics.lisp (original)
+++ trunk/src/uitoolkit/widgets/event-generics.lisp Sun Feb 19 15:50:50 2006
@@ -121,7 +121,7 @@
(defgeneric event-mouse-down (dispatcher time point btn)
(:documentation "Implement this to respond to a mouse down event.")
(:method (dispatcher time point btn)
- (declare (ignorable dispatcher time ptn btn))))
+ (declare (ignorable dispatcher time point btn))))
(defgeneric event-mouse-enter (dispatcher time point btn)
(:documentation "Implement this to respond to a mouse passing into the bounds of an object.")
Added: trunk/src/uitoolkit/widgets/layout-classes.lisp
==============================================================================
--- (empty file)
+++ trunk/src/uitoolkit/widgets/layout-classes.lisp Sun Feb 19 15:50:50 2006
@@ -0,0 +1,44 @@
+;;;;
+;;;; layout-classes.lisp
+;;;;
+;;;; Copyright (C) 2006, Jack D. Unrue
+;;;; All rights reserved.
+;;;;
+;;;; Redistribution and use in source and binary forms, with or without
+;;;; modification, are permitted provided that the following conditions
+;;;; are met:
+;;;;
+;;;; 1. Redistributions of source code must retain the above copyright
+;;;; notice, this list of conditions and the following disclaimer.
+;;;;
+;;;; 2. Redistributions in binary form must reproduce the above copyright
+;;;; notice, this list of conditions and the following disclaimer in the
+;;;; documentation and/or other materials provided with the distribution.
+;;;;
+;;;; 3. Neither the names of the authors nor the names of its contributors
+;;;; may be used to endorse or promote products derived from this software
+;;;; without specific prior written permission.
+;;;;
+;;;; THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS "AS IS" AND ANY
+;;;; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DIS-
+;;;; CLAIMED. IN NO EVENT SHALL THE AUTHORS AND CONTRIBUTORS BE LIABLE FOR ANY
+;;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+;;;; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+;;;; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+;;;; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+;;;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+;;;;
+
+(in-package :graphic-forms.uitoolkit.widgets)
+
+(defclass layout-manager ()
+ ((style
+ :accessor style
+ :initarg :style
+ :initform nil))
+ (:documentation "Subclasses implement layout strategies on behalf of window objects."))
+
+(defclass flow-layout (layout-manager) ()
+ (:documentation "Window children are arranged in a row or column."))
Modified: trunk/src/uitoolkit/widgets/layout-generics.lisp
==============================================================================
--- trunk/src/uitoolkit/widgets/layout-generics.lisp (original)
+++ trunk/src/uitoolkit/widgets/layout-generics.lisp Sun Feb 19 15:50:50 2006
@@ -33,8 +33,8 @@
(in-package :graphic-forms.uitoolkit.widgets)
-(defgeneric compute-size (mgr win width-hint height-hint)
- (:documentation "Computes and returns the size of the window's client area based on this layout's strategy."))
+(defgeneric compute-size (layout win width-hint height-hint)
+ (:documentation "Computes and returns the size of the window's client area based on the layout's strategy."))
-(defgeneric perform-layout (mgr win)
- (:documentation "Lays out the children of the window based on this layout's strategy."))
+(defgeneric compute-layout (layout win width-hint height-hint)
+ (:documentation "Returns a list of conses (window . rectangle) describing the new bounds of each child window."))
Added: trunk/src/uitoolkit/widgets/layouts.lisp
==============================================================================
--- (empty file)
+++ trunk/src/uitoolkit/widgets/layouts.lisp Sun Feb 19 15:50:50 2006
@@ -0,0 +1,106 @@
+;;;;
+;;;; layouts.lisp
+;;;;
+;;;; Copyright (C) 2006, Jack D. Unrue
+;;;; All rights reserved.
+;;;;
+;;;; Redistribution and use in source and binary forms, with or without
+;;;; modification, are permitted provided that the following conditions
+;;;; are met:
+;;;;
+;;;; 1. Redistributions of source code must retain the above copyright
+;;;; notice, this list of conditions and the following disclaimer.
+;;;;
+;;;; 2. Redistributions in binary form must reproduce the above copyright
+;;;; notice, this list of conditions and the following disclaimer in the
+;;;; documentation and/or other materials provided with the distribution.
+;;;;
+;;;; 3. Neither the names of the authors nor the names of its contributors
+;;;; may be used to endorse or promote products derived from this software
+;;;; without specific prior written permission.
+;;;;
+;;;; THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS "AS IS" AND ANY
+;;;; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DIS-
+;;;; CLAIMED. IN NO EVENT SHALL THE AUTHORS AND CONTRIBUTORS BE LIABLE FOR ANY
+;;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+;;;; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+;;;; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+;;;; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+;;;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+;;;;
+
+(in-package :graphic-forms.uitoolkit.widgets)
+
+(defconstant +window-pos-flags+ (logior gfs::+swp-nozorder+
+ gfs::+swp-noownerzorder+
+ gfs::+swp-noactivate+
+ gfs::+swp-nocopybits+))
+
+(defun perform-layout (layout win)
+ "Calls compute-layout and then handles the actual moving and resizing of a window's children."
+ (let* ((win-size (client-size win))
+ (kids (compute-layout layout win (gfi:size-width win-size) (gfi:size-height win-size)))
+ (hdwp (gfs::begin-defer-window-pos (length kids))))
+ (loop for k in kids
+ do (let* ((rect (cdr k))
+ (sz (gfi:size rect))
+ (pnt (gfi:location rect)))
+ (if (gfi:null-handle-p hdwp)
+ (gfs::set-window-pos (gfi:handle (car k))
+ (cffi:null-pointer)
+ (gfi:point-x pnt)
+ (gfi:point-y pnt)
+ (gfi:size-width sz)
+ (gfi:size-height sz)
+ +window-pos-flags+)
+ (setf hdwp (gfs::defer-window-pos hdwp
+ (gfi:handle (car k))
+ (cffi:null-pointer)
+ (gfi:point-x pnt)
+ (gfi:point-y pnt)
+ (gfi:size-width sz)
+ (gfi:size-height sz)
+ +window-pos-flags+)))))
+ (unless (gfi:null-handle-p hdwp)
+ (gfs::end-defer-window-pos hdwp))))
+
+;;;
+;;; flow-layout methods
+;;;
+
+(defmethod compute-size ((layout flow-layout) (win window) width-hint height-hint)
+ (error "not yet implemented"))
+
+(defmethod compute-layout ((layout flow-layout) (win window) width-hint height-hint)
+ (let ((layout-style (gfw:style layout))
+ (entries nil)
+ (last-coord 0)
+ (last-dim 0))
+ (with-children (win kids)
+ (loop for k in kids
+ do (let ((kid-size (preferred-size k width-hint height-hint))
+ (pnt (gfi:make-point)))
+ (if (not (find :vertical layout-style))
+ (progn
+ (setf (gfi:point-x pnt) (+ last-coord last-dim))
+ (if (>= height-hint 0)
+ (setf (gfi:size-height kid-size) height-hint))
+ (setf last-coord (gfi:point-x pnt))
+ (setf last-dim (gfi:size-width kid-size)))
+ (progn
+ (setf (gfi:point-y pnt) (+ last-coord last-dim))
+ (if (>= width-hint 0)
+ (setf (gfi:size-width kid-size) width-hint))
+ (setf last-coord (gfi:point-y pnt))
+ (setf last-dim (gfi:size-height kid-size))))
+ (push (cons k (make-instance 'gfi:rectangle :size kid-size :location pnt)) entries))))
+ (reverse entries)))
+
+(defmethod initialize-instance :after ((layout flow-layout) &key style)
+ (unless (listp style)
+ (setf style (list style)))
+ (if (and (null (find :horizontal style)) (null (find :vertical style)))
+ (setf (slot-value layout 'style) '(:horizontal))
+ (setf (slot-value layout 'style) style)))
Modified: trunk/src/uitoolkit/widgets/widget-classes.lisp
==============================================================================
--- trunk/src/uitoolkit/widgets/widget-classes.lisp (original)
+++ trunk/src/uitoolkit/widgets/widget-classes.lisp Sun Feb 19 15:50:50 2006
@@ -36,9 +36,6 @@
(defclass event-dispatcher () ()
(:documentation "Instances of this class receive events on behalf of user interface objects."))
-(defclass layout-manager () ()
- (:documentation "Subclasses implement layout strategies on behalf of window objects."))
-
(defclass event-source (gfi:native-object)
((dispatcher
:accessor dispatcher
@@ -80,7 +77,7 @@
(defclass window (widget)
((layout-p
- :reader :layout-p
+ :reader layout-p
:initform t)
(layout-manager
:accessor layout-manager
Modified: trunk/src/uitoolkit/widgets/window.lisp
==============================================================================
--- trunk/src/uitoolkit/widgets/window.lisp (original)
+++ trunk/src/uitoolkit/widgets/window.lisp Sun Feb 19 15:50:50 2006
@@ -126,6 +126,7 @@
(visit-child-widgets ,win #'(lambda (parent child)
(if (gfw:ancestor-p parent child)
(push child ,var))))
+ (nreverse ,var)
,@body))
(defun register-workspace-window-class ()
@@ -215,6 +216,10 @@
(setf (slot-value win 'layout-p) t)
(layout win))
+(defmethod event-resize ((d dispatcher) time size type)
+ (declare (ignorable time size type))
+ (layout win)) ; FIXME: this is a big flaw in event handling -- need the window here!
+
(defmethod hide ((win window))
(gfs::show-window (gfi:handle win) gfs::+sw-hide+))