[graphic-forms-cvs] r168 - in trunk: . docs/manual src src/tests/uitoolkit src/uitoolkit/graphics src/uitoolkit/system src/uitoolkit/widgets

junrue at common-lisp.net junrue at common-lisp.net
Sun Jul 2 18:32:28 UTC 2006


Author: junrue
Date: Sun Jul  2 14:32:26 2006
New Revision: 168

Added:
   trunk/src/uitoolkit/widgets/font-dialog.lisp
Modified:
   trunk/docs/manual/api.texinfo
   trunk/graphic-forms-uitoolkit.asd
   trunk/src/packages.lisp
   trunk/src/tests/uitoolkit/image-unit-tests.lisp
   trunk/src/tests/uitoolkit/windlg.lisp
   trunk/src/uitoolkit/graphics/font-data.lisp
   trunk/src/uitoolkit/graphics/font.lisp
   trunk/src/uitoolkit/graphics/graphics-generics.lisp
   trunk/src/uitoolkit/graphics/image.lisp
   trunk/src/uitoolkit/system/comdlg32.lisp
   trunk/src/uitoolkit/system/system-constants.lisp
   trunk/src/uitoolkit/system/system-types.lisp
   trunk/src/uitoolkit/widgets/file-dialog.lisp
   trunk/src/uitoolkit/widgets/widget-classes.lisp
   trunk/src/uitoolkit/widgets/widget-utils.lisp
Log:
implemented font-dialog, refactored font-data and font classes, implemented show-common-dialog to centralize system dialog invocation

Modified: trunk/docs/manual/api.texinfo
==============================================================================
--- trunk/docs/manual/api.texinfo	(original)
+++ trunk/docs/manual/api.texinfo	Sun Jul  2 14:32:26 2006
@@ -377,18 +377,17 @@
 @end itemize
 The @ref{with-file-dialog} macro wraps the creation of a
 @code{file-dialog} and subsequent retrieval of the file paths selected
-by the user. However, applications may choose to implements these
+by the user. However, applications may choose to implement these
 steps manually, in which case the @ref{file-dialog-paths} function can
 be used to obtain the user's selection(s). Unless the
 @code{:multiple-select} style keyword is specified, there will at most
 be one selected file returned. In either case, zero is returned if the
-user cancelled the dialog. Also, manual construction of an instance
+user cancelled the dialog. Manual construction of an instance
 must be followed by an explicit call to @ref{dispose}.@*@*
-Like other system dialogs, @code{file-dialog} is derived from @ref{widget}
-rather than @ref{dialog} since the majority of its functionality is
-implemented by the system and is not directly extensible by applications.
- at strong{NOTE:} A future release of Graphic-Forms will provide a
-customization mechanism.@*@*
+Like other system dialogs in Graphic-Forms, @code{file-dialog} is
+derived from @ref{widget} rather than @ref{dialog} since the majority
+of its functionality is implemented by the system. @strong{NOTE:} A
+future release will provide a customization mechanism.@*@*
 @deffn Initarg :default-extension
 Specifies a default extension to be appended to a file name if
 the user fails to provide one. Any embedded periods @samp{.} will
@@ -424,8 +423,7 @@
 @end deffn
 @deffn Initarg :owner
 A value is required for this initarg, and it may be either a
- at ref{window} or a @ref{dialog}. The file dialog will remain above the
-specified @code{owner} in the window system Z-order.
+ at ref{window} or a @ref{dialog}.
 @end deffn
 @deffn Initarg :style
 This initarg accepts a list of keyword symbols, as follows:
@@ -448,7 +446,7 @@
 for data to be saved.
 @item :show-hidden
 This keyword enables the dialog to display files marked @sc{hidden} by
-the system. @strong{Note:} files marked both @sc{hidden} and
+the system. @strong{NOTE:} files marked both @sc{hidden} and
 @sc{system} will not be displayed in any case. Also, be aware that
 using this keyword effectively overrides the user's preference
 settings.
@@ -462,8 +460,73 @@
 @end deffn
 @end deftp
 
+ at anchor{font-dialog}
+ at deftp Class font-dialog
+This class provides a standard dialog for choosing attributes
+of a @ref{font}, either from scratch or relative to an existing font.
+A variety of style options may be selected, including strikeout
+and font color.@*@*
+The @ref{with-font-dialog} macro wraps the creation of a @code{font-dialog}
+and provides a new font object based on the user's selections. However,
+applications may choose to implement these steps manually, in which case
+the @ref{font-dialog-results} function can be called to obtain the results
+of the user's selections. Manual construction of an instance must be followed
+by an explicit call to @ref{dispose}.@*@*
+Like other system dialogs in Graphic-Forms, @code{font-dialog} is derived
+from @ref{widget} rather than @ref{dialog} since the majority of its
+functionality is implemented by the system. @strong{NOTE:} A future release
+will provide a customization mechanism.@*
+ at deffn Initarg :gc
+This required initarg accepts a @ref{graphics-context} object providing
+context for the font selection, such as when the set of fonts to be offered
+depends on a printer device.
+ at end deffn
+ at deffn Initarg :initial-color
+This initarg accepts a @ref{color} object which the font dialog
+will use for its initial color selection (as long as the @code{:no-effects}
+style is @strong{not} set).
+ at end deffn
+ at deffn Initarg :initial-font
+This initarg accepts a @ref{font} object which the font dialog
+will use for its initial font attribute selections. If not
+specified, the dialog will be set to the system font's attributes.
+ at end deffn
+ at deffn Initarg :owner
+A value is required for this initarg, and it may be either a
+ at ref{window} or a @ref{dialog}.
+ at end deffn
+ at deffn Initarg :style
+This initarg accepts a list of keyword symbols, as follows:
+ at table @code
+ at item :all-fonts
+This is a convenience style, used by default if no other font
+criteria are specified, that enables the dialog to offer all
+possible fonts.
+ at item :fixed-pitch-fonts
+Enables the dialog to offer fixed pitch fonts.
+ at item :no-effects
+Causes the font dialog to hide the controls that
+allow the user to specify strikeout, underline, and text color
+attributes.
+ at item :printer-fonts
+Enables the dialog to offer fonts supported by the printer associated
+with the graphics-context supplied via the @code{:gc} initarg.
+ at item :screen-fonts
+Enables the dialog to offer screen fonts supported by the system.
+ at item :truetype-fonts
+Enables the dialog to offer TrueType fonts.
+ at item :wysiwyg-fonts
+Enables the dialog to offer the intersection of the sets of fonts
+available on the screen and the printer associated with the
+graphics-context specified by the @code{:gc} initarg.
+ at end table
+ at end deffn
+ at end deftp
+
 @anchor{group}
 @deftp Class group layout children location size style
+ at strong{NOTE:} this class is not yet fully implemented
+and does not yet participate in the layout protocol.@*@*
 A @code{group} represents a logical rectangular aggregation
 of @ref{window} children which has the following properties
 and behaviors:
@@ -970,11 +1033,12 @@
 @end deffn
 
 @anchor{file-dialog-paths}
- at deffn Function file-dialog-paths dlg
+ at deffn Function file-dialog-paths dlg => @sc{list}
 Interrogates the data structure associated with an instance of
 @ref{file-dialog} to obtain the paths for selected files. This return
 value is either @sc{nil} if the user cancelled the dialog, or a list
-of file @sc{namestring}s.
+of file @sc{namestring}s. Use this function when manually constructing
+a file dialog. @xref{with-file-dialog}.
 @end deffn
 
 @deffn GenericFunction focus-p self
@@ -982,6 +1046,19 @@
 otherwise.
 @end deffn
 
+ at anchor{font-dialog-results}
+ at deffn Function font-dialog-results dlg gc => @ref{font}, @ref{color}
+Interrogates the data structure associated with an instance of
+ at ref{font-dialog} to obtain the @ref{font} and @ref{color}
+corresponding to selections made by the user, and returns
+them via @sc{values}. The @code{gc} parameter should be the same
+ at ref{graphics-context} object with which the dialog was created.
+If the user cancelled the dialog, the font value will be @sc{nil}.
+Also, the color value will be @sc{nil} if the dialog was created with
+the @code{:no-effects} style keyword. Use this function when manually
+constructing a font dialog. @xref{with-font-dialog}.
+ at end deffn
+
 @deffn GenericFunction give-focus self
 Places keyboard focus on @code{self}.
 @end deffn
@@ -1173,8 +1250,18 @@
 @anchor{with-file-dialog}
 @deffn Macro with-file-dialog (owner style paths &key default-extension filters initial-directory initial-filename text) &body body
 This macro wraps the instantiation of a standard file open/save dialog
-and the subsequent retrieval of the user's file
-selections. @xref{file-dialog}.
+and the subsequent retrieval of the user's file selections (supplied to @code{body}
+via @code{paths}). @xref{file-dialog}.
+ at end deffn
+
+ at anchor{with-font-dialog}
+ at deffn Macro with-font-dialog (owner style font color &key gc initial-color initial-font) &body body
+This macro wraps the instantiation of a standard font dialog and binds
+ at code{font} to a font object, and @code{color} to a @ref{color} object,
+corresponding to the attributes selected by the user. If the user cancels
+the dialog, @code{font} will be @sc{nil}. In addition, @code{color} will also
+be @sc{nil} if the dialog was created with the @code{:no-effects} style
+keyword. @xref{font-dialog}.
 @end deffn
 
 
@@ -1226,6 +1313,7 @@
 @strong{NOTE:} A future release will provide additional graphics
 classes.
 
+ at anchor{color}
 @deftp Structure color red green blue
 This is a structure representing a color using three bytes in the RGB colorspace.
 @end deftp
@@ -1304,6 +1392,7 @@
 may use to position graphical elements. @xref{font}.
 @end deftp
 
+ at anchor{graphics-context}
 @deftp Class graphics-context
 This subclass of @ref{native-object} wraps a native device context,
 hence instances of this class are used to perform drawing operations.
@@ -1425,8 +1514,11 @@
 Returns a color object corresponding to the current background color.
 @end deffn
 
- at deffn GenericFunction data-obj self
-Returns the data structure representing the raw form of the object.
+ at deffn GenericFunction data-object self &optional gc => object
+Returns the data structure representing the raw data form of the
+object.  The @code{gc} argument must be supplied when calling this
+function on a @ref{font}, and the value must be a
+ at ref{graphics-context}.
 @end deffn
 
 @deffn GenericFunction depth self

Modified: trunk/graphic-forms-uitoolkit.asd
==============================================================================
--- trunk/graphic-forms-uitoolkit.asd	(original)
+++ trunk/graphic-forms-uitoolkit.asd	Sun Jul  2 14:32:26 2006
@@ -113,6 +113,7 @@
                        (:file "panel")
                        (:file "dialog")
                        (:file "file-dialog")
+                       (:file "font-dialog")
                        (:file "layout")
                        (:file "heap-layout")
                        (:file "flow-layout")))))))))

Modified: trunk/src/packages.lisp
==============================================================================
--- trunk/src/packages.lisp	(original)
+++ trunk/src/packages.lisp	Sun Jul  2 14:32:26 2006
@@ -140,7 +140,7 @@
     #:copy-color
     #:copy-font-data
     #:copy-font-metrics
-    #:data-obj
+    #:data-object
     #:depth
     #:descent
     #:draw-arc
@@ -231,6 +231,7 @@
     #:event-dispatcher
     #:event-source
     #:file-dialog
+    #:font-dialog
     #:flow-layout
     #:heap-layout
     #:item
@@ -393,6 +394,7 @@
     #:file-dialog-paths
     #:focus-index
     #:focus-p
+    #:font-dialog-results
     #:foreground-color
     #:give-focus
     #:grid-line-width
@@ -492,6 +494,7 @@
     #:visible-p
     #:with-children
     #:with-file-dialog
+    #:with-font-dialog
 
 ;; conditions
   ))

Modified: trunk/src/tests/uitoolkit/image-unit-tests.lisp
==============================================================================
--- trunk/src/tests/uitoolkit/image-unit-tests.lisp	(original)
+++ trunk/src/tests/uitoolkit/image-unit-tests.lisp	Sun Jul  2 14:32:26 2006
@@ -58,7 +58,7 @@
             (assert-equal (gfs:size-width size1) (gfs:size-width size2) path)
             (assert-equal (gfs:size-height size1) (gfs:size-height size2) path))
           (gfg:load im path)
-          (setf d3 (gfg:data-obj im))
+          (setf d3 (gfg:data-object im))
           (assert-equal (gfg:depth d1) (gfg:depth d3) path)
           (let ((size1 (gfg:size d1))
                 (size2 (gfg:size d3)))

Modified: trunk/src/tests/uitoolkit/windlg.lisp
==============================================================================
--- trunk/src/tests/uitoolkit/windlg.lisp	(original)
+++ trunk/src/tests/uitoolkit/windlg.lisp	Sun Jul  2 14:32:26 2006
@@ -118,6 +118,17 @@
                          :initial-directory #P"c:/")
     (print paths)))
 
+(defun choose-font-dlg (disp item time rect)
+  (declare (ignore disp item time rect))
+  (let ((gc (make-instance 'gfg:graphics-context :widget *main-win*)))
+    (unwind-protect
+        (gfw:with-font-dialog (*main-win* nil font color :gc gc)
+          (if color
+            (print color))
+          (if font
+            (print (gfg:data-object font gc))))
+      (gfs:dispose gc))))
+
 (defclass dialog-events (gfw:event-dispatcher) ())
 
 (defmethod gfw:event-close ((disp dialog-events) (dlg gfw:dialog) time)
@@ -231,16 +242,17 @@
                                                    :style '(:workspace)))
     (setf menubar (gfw:defmenu ((:item "&File"
                                  :submenu ((:item "E&xit" :callback #'windlg-exit-fn)))
+                                           (:item "&Custom Dialogs"
+                                            :submenu ((:item "&Modal"       :callback #'open-modal-dlg)
+                                                      (:item "&Modeless"    :callback #'open-modeless-dlg)))
                                            (:item "&System Dialogs"
-                                            :submenu ((:item "&Open File" :callback #'open-file-dlg)
-                                                      (:item "&Save File" :callback #'save-file-dlg)))
-                                           (:item "&User Dialogs"
-                                            :submenu ((:item "&Modal"    :callback #'open-modal-dlg)
-                                                      (:item "&Modeless" :callback #'open-modeless-dlg)))
+                                            :submenu ((:item "&Choose Font" :callback #'choose-font-dlg)
+                                                      (:item "&Open File"   :callback #'open-file-dlg)
+                                                      (:item "&Save File"   :callback #'save-file-dlg)))
                                            (:item "&Windows"
-                                            :submenu ((:item "&Borderless" :callback #'create-borderless-win)
-                                                      (:item "&Mini Frame" :callback #'create-miniframe-win)
-                                                      (:item "&Palette"    :callback #'create-palette-win))))))
+                                            :submenu ((:item "&Borderless"  :callback #'create-borderless-win)
+                                                      (:item "&Mini Frame"  :callback #'create-miniframe-win)
+                                                      (:item "&Palette"     :callback #'create-palette-win))))))
     (setf (gfw:menu-bar *main-win*) menubar)
     (gfw:show *main-win* t)))
 

Modified: trunk/src/uitoolkit/graphics/font-data.lisp
==============================================================================
--- trunk/src/uitoolkit/graphics/font-data.lisp	(original)
+++ trunk/src/uitoolkit/graphics/font-data.lisp	Sun Jul  2 14:32:26 2006
@@ -33,50 +33,99 @@
 
 (in-package :graphic-forms.uitoolkit.graphics)
 
-(defun compute-font-weight (style)
-  (if (null (find :bold style))
-    gfs::+fw-normal+
-    gfs::+fw-bold+))
-
-(defun compute-font-precis (style)
-  (if (find :truetype-only style)
-    (return-from compute-font-precis gfs::+out-tt-only-precis+))
-  (if (find :outline style)
-    (return-from compute-font-precis gfs::+out-outline-precis+))
-  gfs::+out-default-precis+)
-
-(defun compute-font-pitch (style)
-  (if (find :fixed style)
-    (return-from compute-font-pitch gfs::+fixed-pitch+))
-  (if (find :variable style)
-    (return-from compute-font-pitch gfs::+variable-pitch+))
-  gfs::+default-pitch+)
+(defun pntsize->lfheight (hdc pntsize)
+  (let ((log-height (gfs::get-device-caps hdc gfs::+logpixelsy+)))
+    (- (floor (+ (/ (* pntsize log-height) 72) 0.5)))))
 
-(defun data->font (hdc data)
-  (let ((hfont (cffi:null-pointer))
+(defun lfheight->pntsize (hdc lfheight)
+  (let ((log-height (gfs::get-device-caps hdc gfs::+logpixelsy+)))
+    (floor (* (+ (- lfheight) 0.5) 72) log-height)))
+
+(defun style->logfont (style lf-ptr)
+  (cffi:with-foreign-slots ((gfs::lfweight gfs::lfitalic gfs::lfunderline
+                             gfs::lfstrikeout gfs::lfoutprec gfs::lfpitchandfamily)
+                            lf-ptr gfs::logfont)
+    (setf gfs::lfweight    (if (find :bold style)      gfs::+fw-bold+ gfs::+fw-normal+))
+    (setf gfs::lfitalic    (if (find :italic style)    1 0))
+    (setf gfs::lfunderline (if (find :underline style) 1 0))
+    (setf gfs::lfstrikeout (if (find :strikeout style) 1 0))
+    (setf gfs::lfoutprec   (cond
+                             ((find :truetype-only style) gfs::+out-tt-only-precis+)
+                             ((find :outline       style) gfs::+out-outline-precis+)
+                             (t                           gfs::+out-default-precis+)))
+    (setf gfs::lfpitchandfamily (cond
+                                  ((find :fixed style)    gfs::+fixed-pitch+)
+                                  ((find :variable style) gfs::+variable-pitch+)
+                                  (t                      gfs::+default-pitch+)))))
+
+(defun logfont->style (lf-ptr)
+  (let ((style nil))
+    (cffi:with-foreign-slots ((gfs::lfweight gfs::lfitalic gfs::lfunderline
+                               gfs::lfstrikeout gfs::lfoutprec gfs::lfpitchandfamily)
+                              lf-ptr gfs::logfont)
+      (if (= gfs::lfweight gfs::+fw-bold+)
+        (push :bold style))
+      (unless (zerop gfs::lfitalic)
+        (push :italic style))
+      (unless (zerop gfs::lfunderline)
+        (push :underline style))
+      (unless (zerop gfs::lfstrikeout)
+        (push :strikeout style))
+      (case gfs::lfoutprec
+        (#.gfs::+out-tt-only-precis+ (push :truetype-only style))
+        (#.gfs::+out-outline-precis+ (push :outline       style)))
+      (case gfs::lfpitchandfamily
+        (#.gfs::+fixed-pitch+        (push :fixed         style))
+        (#.gfs::+variable-pitch+     (push :variable      style))))
+    style))
+
+(defun data->logfont (hdc data)
+  (let ((lf-ptr (cffi:foreign-alloc 'gfs::logfont))
         (style (font-data-style data)))
-    (cffi:with-foreign-object (lf-ptr 'gfs::logfont)
-      (gfs:zero-mem lf-ptr gfs::logfont)
-      (cffi:with-foreign-slots ((gfs::lfheight gfs::lfweight gfs::lfitalic gfs::lfunderline
-                                 gfs::lfstrikeout gfs::lfcharset gfs::lfoutprec
-                                 gfs::lfpitchandfamily gfs::lffacename)
-                                lf-ptr gfs::logfont)
-        (setf gfs::lfheight (- (floor (+ (/ (* (font-data-point-size data)
-                                               (gfs::get-device-caps hdc gfs::+logpixelsy+))
-                                            72)
-                                         0.5))))
-        (setf gfs::lfweight (compute-font-weight style))
-        (setf gfs::lfitalic (if (null (find :italic style)) 0 1))
-        (setf gfs::lfunderline (if (null (find :underline style)) 0 1))
-        (setf gfs::lfstrikeout (if (null (find :strikeout style)) 0 1))
-        (setf gfs::lfcharset (font-data-char-set data))
-        (setf gfs::lfoutprec (compute-font-precis style))
-        (setf gfs::lfpitchandfamily (compute-font-pitch style))
-        (cffi:with-foreign-string (str (font-data-face-name data))
-          (let ((lffacename-ptr (cffi:foreign-slot-pointer lf-ptr 'gfs::logfont 'gfs::lffacename)))
-            (gfs::strncpy lffacename-ptr str (1- gfs::+lf-facesize+))
-            (setf (cffi:mem-aref lffacename-ptr  :char (1- gfs::+lf-facesize+)) 0))))
-      (setf hfont (gfs::create-font-indirect lf-ptr))
-      (if (gfs:null-handle-p hfont)
-        (error 'gfs:win32-error :detail "create-font-indirect failed")))
+    (gfs:zero-mem lf-ptr gfs::logfont)
+    (cffi:with-foreign-slots ((gfs::lfheight gfs::lfcharset gfs::lffacename) lf-ptr gfs::logfont)
+      (setf gfs::lfheight (pntsize->lfheight hdc (font-data-point-size data)))
+      (setf gfs::lfcharset (font-data-char-set data))
+      (style->logfont style lf-ptr)
+      (cffi:with-foreign-string (str (font-data-face-name data))
+        (let ((lffacename-ptr (cffi:foreign-slot-pointer lf-ptr 'gfs::logfont 'gfs::lffacename)))
+          (gfs::strncpy lffacename-ptr str (1- gfs::+lf-facesize+))
+          (setf (cffi:mem-aref lffacename-ptr :char (1- gfs::+lf-facesize+)) 0))))
+    lf-ptr))
+
+(defun logfont->data (hdc lf-ptr)
+  (let ((char-set 0)
+        (face-name "")
+        (point-size 0)
+        (style nil))
+    (cffi:with-foreign-slots ((gfs::lfheight gfs::lfcharset gfs::lffacename) lf-ptr gfs::logfont)
+      (setf point-size (lfheight->pntsize hdc gfs::lfheight))
+      (setf char-set gfs::lfcharset)
+      (setf style (logfont->style lf-ptr))
+      (let ((lffacename-ptr (cffi:foreign-slot-pointer lf-ptr 'gfs::logfont 'gfs::lffacename)))
+        (setf face-name (cffi:foreign-string-to-lisp lffacename-ptr))))
+    (gfg:make-font-data :char-set char-set
+                        :face-name face-name
+                        :point-size point-size
+                        :style style)))
+
+(defun data->font (hdc data)
+  (let ((hfont (cffi:null-pointer)))
+    (setf hfont (gfs::create-font-indirect (data->logfont hdc data)))
+    (if (gfs:null-handle-p hfont)
+      (error 'gfs:win32-error :detail "create-font-indirect failed"))
     hfont))
+
+(defun font->data (hdc hfont)
+  (cffi:with-foreign-object (lf-ptr 'gfs::logfont)
+    (gfs:zero-mem lf-ptr gfs::logfont)
+    (if (zerop (gfs::get-object hfont (cffi:foreign-type-size 'gfs::logfont) lf-ptr))
+      (error 'gfs:win32-error :detail "get-object failed"))
+    (logfont->data hdc lf-ptr)))
+
+(defmethod print-object ((self font-data) stream)
+  (print-unreadable-object (self stream :type t)
+    (format stream "face name: ~a " (font-data-face-name self))
+    (format stream "point size: ~d " (font-data-point-size self))
+    (format stream "style: ~a " (font-data-style self))
+    (format stream "char-set: ~d" (font-data-char-set self))))

Modified: trunk/src/uitoolkit/graphics/font.lisp
==============================================================================
--- trunk/src/uitoolkit/graphics/font.lisp	(original)
+++ trunk/src/uitoolkit/graphics/font.lisp	Sun Jul  2 14:32:26 2006
@@ -37,12 +37,17 @@
 ;;; methods
 ;;;
 
-(defmethod gfs:dispose ((fn font))
-  (let ((hgdi (gfs:handle fn)))
+(defmethod data-object ((self font) &optional gc)
+  (if (or (gfs:disposed-p self) (gfs:disposed-p gc))
+    (error 'gfs:disposed-error))
+  (font->data (gfs:handle gc) (gfs:handle self)))
+
+(defmethod gfs:dispose ((self font))
+  (let ((hgdi (gfs:handle self)))
     (unless (gfs:null-handle-p hgdi)
       (gfs::delete-object hgdi)))
-  (setf (slot-value fn 'gfs:handle) nil))
+  (setf (slot-value self 'gfs:handle) nil))
 
-(defmethod initialize-instance :after ((font font) &key gc data &allow-other-keys)
+(defmethod initialize-instance :after ((self font) &key gc data &allow-other-keys)
   (if gc
-    (setf (slot-value font 'gfs:handle) (data->font (gfs:handle gc) data))))
+    (setf (slot-value self 'gfs:handle) (data->font (gfs:handle gc) data))))

Modified: trunk/src/uitoolkit/graphics/graphics-generics.lisp
==============================================================================
--- trunk/src/uitoolkit/graphics/graphics-generics.lisp	(original)
+++ trunk/src/uitoolkit/graphics/graphics-generics.lisp	Sun Jul  2 14:32:26 2006
@@ -36,7 +36,7 @@
 (defgeneric background-color (self)
   (:documentation "Returns a color object corresponding to the current background color."))
 
-(defgeneric data-obj (self)
+(defgeneric data-object (self &optional gc)
   (:documentation "Returns the data structure representing the raw form of the object."))
 
 (defgeneric depth (self)

Modified: trunk/src/uitoolkit/graphics/image.lisp
==============================================================================
--- trunk/src/uitoolkit/graphics/image.lisp	(original)
+++ trunk/src/uitoolkit/graphics/image.lisp	Sun Jul  2 14:32:26 2006
@@ -72,15 +72,16 @@
       (gfs::delete-object hgdi)))
   (setf (slot-value im 'gfs:handle) nil))
 
-(defmethod data-obj ((im image))
-  (when (gfs:disposed-p im)
+(defmethod data-object ((self image) &optional gc)
+  (declare (ignore gc))
+  (when (gfs:disposed-p self)
     (error 'gfs:disposed-error))
-  (image->data (gfs:handle im)))
+  (image->data (gfs:handle self)))
 
-(defmethod (setf data-obj) ((id image-data) (im image))
-  (unless (gfs:disposed-p im)
-    (gfs:dispose im))
-  (setf (slot-value im 'gfs:handle) (data->image id)))
+(defmethod (setf data-object) ((id image-data) (self image))
+  (unless (gfs:disposed-p self)
+    (gfs:dispose self))
+  (setf (slot-value self 'gfs:handle) (data->image id)))
 
 (defmethod initialize-instance :after ((image image) &key file size &allow-other-keys)
   (cond
@@ -108,7 +109,7 @@
 (defmethod load ((im image) path)
   (let ((data (make-instance 'image-data)))
     (load data path)
-    (setf (data-obj im) data)
+    (setf (data-object im) data)
     data))
 
 (defmethod size ((image image))

Modified: trunk/src/uitoolkit/system/comdlg32.lisp
==============================================================================
--- trunk/src/uitoolkit/system/comdlg32.lisp	(original)
+++ trunk/src/uitoolkit/system/comdlg32.lisp	Sun Jul  2 14:32:26 2006
@@ -39,6 +39,11 @@
 (load-foreign-library "comdlg32.dll")
 
 (defcfun
+  ("ChooseFontA" choose-font)
+  BOOL
+  (struct LPTR))
+
+(defcfun
   ("CommDlgExtendedError" comm-dlg-extended-error)
   DWORD)
 

Modified: trunk/src/uitoolkit/system/system-constants.lisp
==============================================================================
--- trunk/src/uitoolkit/system/system-constants.lisp	(original)
+++ trunk/src/uitoolkit/system/system-constants.lisp	Sun Jul  2 14:32:26 2006
@@ -142,6 +142,35 @@
 (defconstant +cderr-nohook+                #x000b)
 (defconstant +cderr-registermsgfail+       #x000C)
 
+(defconstant +cf-screenfonts+          #x00000001)
+(defconstant +cf-printerfonts+         #x00000002)
+(defconstant +cf-both+                 #x00000003)
+(defconstant +cf-showhelp+             #x00000004)
+(defconstant +cf-enablehook+           #x00000008)
+(defconstant +cf-enabletemplate+       #x00000010)
+(defconstant +cf-enabletemplatehandle+ #x00000020)
+(defconstant +cf-inittologfontstruct+  #x00000040)
+(defconstant +cf-usestyle+             #x00000080)
+(defconstant +cf-effects+              #x00000100)
+(defconstant +cf-apply+                #x00000200)
+(defconstant +cf-ansionly+             #x00000400)
+(defconstant +cf-scriptsonly+          #x00000400)
+(defconstant +cf-novectorfonts+        #x00000800)
+(defconstant +cf-nooemfonts+           #x00000800)
+(defconstant +cf-nosimulations+        #x00001000)
+(defconstant +cf-limitsize+            #x00002000)
+(defconstant +cf-fixedpitchonly+       #x00004000)
+(defconstant +cf-wysiwyg+              #x00008000)
+(defconstant +cf-forcefontexist+       #x00010000)
+(defconstant +cf-scalableonly+         #x00020000)
+(defconstant +cf-ttonly+               #x00040000)
+(defconstant +cf-nofacesel+            #x00080000)
+(defconstant +cf-nostylesel+           #x00100000)
+(defconstant +cf-nosizesel+            #x00200000)
+(defconstant +cf-selectscript+         #x00400000)
+(defconstant +cf-noscriptsel+          #x00800000)
+(defconstant +cf-novertfonts+          #x01000000)
+
 (defconstant +cferr-choosefontcodes+       #x2000)
 (defconstant +cferr-nofonts+               #x2001)
 (defconstant +cferr-maxlessthanmin+        #x2002)

Modified: trunk/src/uitoolkit/system/system-types.lisp
==============================================================================
--- trunk/src/uitoolkit/system/system-types.lisp	(original)
+++ trunk/src/uitoolkit/system/system-types.lisp	Sun Jul  2 14:32:26 2006
@@ -127,6 +127,23 @@
   (biclrused DWORD)
   (biclrimp DWORD))
 
+(defcstruct choosefont
+  (structsize DWORD)
+  (howner     HANDLE)
+  (hdc        HANDLE)
+  (logfont    LPTR)
+  (pointsize  INT)
+  (flags      DWORD)
+  (color      COLORREF)
+  (data       LPARAM)
+  (hookfn     LPTR)  ; FIXME: not yet used, but eventually should be CFHookProc
+  (templname  :string)
+  (hinstance  HANDLE)
+  (style      :string)
+  (fonttype   WORD)
+  (minsize    INT)
+  (maxsize    INT))
+
 (defcstruct drawtextparams
   (cbsize UINT)
   (tablength INT)

Modified: trunk/src/uitoolkit/widgets/file-dialog.lisp
==============================================================================
--- trunk/src/uitoolkit/widgets/file-dialog.lisp	(original)
+++ trunk/src/uitoolkit/widgets/file-dialog.lisp	Sun Jul  2 14:32:26 2006
@@ -74,12 +74,12 @@
 ;;; methods
 ;;;
 
-(defmethod compute-style-flags ((dlg file-dialog) &rest extra-data)
+(defmethod compute-style-flags ((self file-dialog) &rest extra-data)
   (declare (ignore extra-data))
   (let ((std-flags (logior gfs::+ofn-dontaddtorecent+ gfs::+ofn-hidereadonly+
                            gfs::+ofn-notestfilecreate+ gfs::+ofn-overwriteprompt+
                            gfs::+ofn-explorer+)))
-    (loop for sym in (style-of dlg)
+    (loop for sym in (style-of self)
           do (cond
                ((eq sym :add-to-recent)
                   (setf std-flags (logand std-flags (lognot gfs::+ofn-dontaddtorecent+))))
@@ -91,8 +91,8 @@
                   (setf std-flags (logior std-flags gfs::+ofn-forceshowhidden+)))))
     (values std-flags 0)))
 
-(defmethod gfs:dispose ((dlg file-dialog))
-  (let ((ofn-ptr (gfs:handle dlg)))
+(defmethod gfs:dispose ((self file-dialog))
+  (let ((ofn-ptr (gfs:handle self)))
     (unless (cffi:null-pointer-p ofn-ptr)
       (cffi:with-foreign-slots ((gfs::ofnfile gfs::ofnfilter gfs::ofntitle
                                  gfs::ofninitialdir gfs::ofndefext)
@@ -106,9 +106,9 @@
         (unless (cffi:null-pointer-p gfs::ofndefext)
           (cffi:foreign-free gfs::ofndefext)))
       (cffi:foreign-free ofn-ptr)
-      (setf (slot-value dlg 'gfs:handle) (cffi:null-pointer)))))
+      (setf (slot-value self 'gfs:handle) (cffi:null-pointer)))))
 
-(defmethod initialize-instance :after ((dlg file-dialog) &key default-extension filters initial-directory initial-filename owner style text)
+(defmethod initialize-instance :after ((self file-dialog) &key default-extension filters initial-directory initial-filename owner style text)
   ;; FIXME: implement an OFNHookProc to process CDN_SELCHANGE
   ;; so that the file buffer can be resized as needed for
   ;; multi-select mode.
@@ -137,7 +137,7 @@
         (gfs::strncpy file-buffer tmp-str 1023))
       (setf (cffi:mem-ref file-buffer :char) 0))
     (multiple-value-bind (std-style ex-style)
-        (compute-style-flags dlg)
+        (compute-style-flags self)
       (cffi:with-foreign-slots ((gfs::ofnsize gfs::ofnhwnd gfs::ofnhinst gfs::ofnfilter
                                  gfs::ofncustomfilter gfs::ofnmaxcustfilter gfs::ofnfilterindex
                                  gfs::ofnfile gfs::ofnmaxfile gfs::ofnfiletitle gfs::ofnmaxfiletitle
@@ -168,12 +168,11 @@
               gfs::ofnpvreserved    (cffi:null-pointer)
               gfs::ofndwreserved    0
               gfs::ofnexflags       ex-style)))
-    (setf (slot-value dlg 'gfs:handle) ofn-ptr)
-    (setf (slot-value dlg 'open-mode) (find :open style))))
+    (setf (slot-value self 'gfs:handle) ofn-ptr)
+    (setf (slot-value self 'open-mode) (find :open style))))
 
-(defmethod show ((dlg file-dialog) flag)
+(defmethod show ((self file-dialog) flag)
   (declare (ignore flag))
-  (let ((ofn-ptr (gfs:handle dlg))
-        (fn (if (open-mode dlg) #'gfs::get-open-filename #'gfs::get-save-filename)))
-    (if (and (zerop (funcall fn ofn-ptr)) (/= (gfs::comm-dlg-extended-error) 0))
-      (error 'gfs:comdlg-error :detail "file dialog function failed"))))
+  (if (open-mode self)
+    (show-common-dialog self #'gfs::get-open-filename)
+    (show-common-dialog self #'gfs::get-save-filename)))

Added: trunk/src/uitoolkit/widgets/font-dialog.lisp
==============================================================================
--- (empty file)
+++ trunk/src/uitoolkit/widgets/font-dialog.lisp	Sun Jul  2 14:32:26 2006
@@ -0,0 +1,144 @@
+;;;;
+;;;; font-dialog.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 +font-dialog-flags+ (logior gfs::+cf-effects+ gfs::+cf-inittologfontstruct+))
+
+;;;
+;;; helper functions
+;;;
+
+(defun font-dialog-results (dlg gc)
+  (if (or (gfs:disposed-p dlg) (gfs:disposed-p gc))
+    (error 'gfs:disposed-error))
+  (cffi:with-foreign-slots ((gfs::logfont gfs::color) (gfs:handle dlg) gfs::choosefont)
+    (values (make-instance 'gfg:font :handle (gfs::create-font-indirect gfs::logfont))
+            (gfg::rgb->color gfs::color))))
+
+(defun lookup-default-font ()
+  (let ((lf-ptr (cffi:foreign-alloc 'gfs::logfont)))
+    (gfs:zero-mem lf-ptr gfs::logfont)
+    (gfs::get-object (gfs::get-stock-object gfs::+system-font+)
+                     (cffi:foreign-type-size 'gfs::logfont)
+                     lf-ptr)
+    lf-ptr))
+
+(defmacro with-font-dialog ((owner style font color &key gc initial-color initial-font) &body body)
+  (let ((dlg (gensym)))
+   `(let ((,font nil)
+          (,color nil)
+          (,dlg (make-instance 'font-dialog
+                               :gc ,gc
+                               :initial-color ,initial-color
+                               :initial-font ,initial-font
+                               :owner ,owner
+                               :style ,style)))
+      (unwind-protect
+          (progn
+            (unless (zerop (show ,dlg t))
+              (multiple-value-bind (f c) (font-dialog-results ,dlg ,gc)
+                (setf ,font f)
+                (setf ,color c))
+              , at body))
+        (gfs:dispose ,dlg)))))
+
+;;;
+;;; methods
+;;;
+
+(defmethod compute-style-flags ((self font-dialog) &rest extra-data)
+  (declare (ignore extra-data))
+  (let ((std-flags (logior gfs::+cf-both+ +font-dialog-flags+)))
+    (loop for sym in (style-of self)
+          do (ecase sym
+               ;; primary styles
+               ;;
+               (:all-fonts
+                 (setf std-flags (logior gfs::+cf-both+ +font-dialog-flags+)))
+               (:fixed-pitch-fonts
+                 (setf std-flags (logior gfs::+cf-fixedpitchonly+ +font-dialog-flags+)))
+               (:printer-fonts
+                 (setf std-flags (logior gfs::+cf-printerfonts+ +font-dialog-flags+)))
+               (:screen-fonts
+                 (setf std-flags (logior gfs::+cf-screenfonts+ +font-dialog-flags+)))
+               (:truetype-fonts
+                 (setf std-flags (logior gfs::+cf-ttonly+ +font-dialog-flags+)))
+               (:wsyiwyg-fonts
+                 (setf std-flags (logior gfs::+cf-both+
+                                         gfs::+cf-scalableonly+
+                                         gfs::+cf-wysiwyg+
+                                         +font-dialog-flags+)))
+
+               ;; styles that can be combined
+               ;;
+               (:no-effects
+                 (setf std-flags (logand std-flags (lognot gfs::+cf-effects+))))))
+    (values std-flags 0)))
+
+(defmethod gfs:dispose ((self font-dialog))
+  (let ((cf-ptr (gfs:handle self)))
+    (unless (cffi:null-pointer-p cf-ptr)
+      (cffi:with-foreign-slots ((gfs::logfont) cf-ptr gfs::choosefont)
+        (unless (cffi:null-pointer-p gfs::logfont)
+          (cffi:foreign-free gfs::logfont)))
+      (cffi:foreign-free cf-ptr)))
+  (setf (slot-value self 'gfs:handle) (cffi:null-pointer)))
+
+(defmethod initialize-instance :after ((self font-dialog) &key gc initial-color initial-font owner &allow-other-keys)
+  (if (null gc)
+    (error 'gfs:toolkit-error :detail ":gc initarg is required"))
+  (if (null owner)
+    (error 'gfs:toolkit-error :detail ":owner initarg is required"))
+  (if (gfs:disposed-p owner)
+    (error 'gfs:disposed-error))
+  (let ((cf-ptr (cffi:foreign-alloc 'gfs::choosefont))
+        (lf-ptr (if initial-font
+                  (gfg::data->logfont (gfs:handle gc) (gfg:data-object initial-font gc))
+                  (lookup-default-font))))
+    (multiple-value-bind (std-style ex-style) (compute-style-flags self)
+      (declare (ignore ex-style))
+      (cffi:with-foreign-slots ((gfs::structsize gfs::howner gfs::hdc gfs::logfont
+                                 gfs::flags gfs::color)
+                                cf-ptr gfs::choosefont)
+        (setf gfs::structsize (cffi:foreign-type-size 'gfs::choosefont)
+              gfs::howner     (gfs:handle owner)
+              gfs::hdc        (gfs:handle gc)
+              gfs::logfont    lf-ptr
+              gfs::flags      std-style
+              gfs::color      (if initial-color (gfg:color->rgb initial-color) 0))))
+    (setf (slot-value self 'gfs:handle) cf-ptr)))
+
+(defmethod show ((self font-dialog) flag)
+  (declare (ignore flag))
+  (show-common-dialog self #'gfs::choose-font))

Modified: trunk/src/uitoolkit/widgets/widget-classes.lisp
==============================================================================
--- trunk/src/uitoolkit/widgets/widget-classes.lisp	(original)
+++ trunk/src/uitoolkit/widgets/widget-classes.lisp	Sun Jul  2 14:32:26 2006
@@ -130,6 +130,9 @@
     :initform t))
   (:documentation "This class represents the standard file open/save dialog."))
 
+(defclass font-dialog (widget) ()
+  (:documentation "This class represents the standard font dialog."))
+
 (defclass widget-with-items (widget)
   ((items
     :accessor items

Modified: trunk/src/uitoolkit/widgets/widget-utils.lisp
==============================================================================
--- trunk/src/uitoolkit/widgets/widget-utils.lisp	(original)
+++ trunk/src/uitoolkit/widgets/widget-utils.lisp	Sun Jul  2 14:32:26 2006
@@ -107,6 +107,13 @@
           (error 'gfs:win32-error :detail "create-window failed"))
         hwnd))))
 
+(defun show-common-dialog (dlg dlg-func)
+  (let* ((struct-ptr (gfs:handle dlg))
+         (retval (funcall dlg-func struct-ptr)))
+    (if (and (zerop retval) (not (zerop (gfs::comm-dlg-extended-error))))
+      (error 'gfs:comdlg-error :detail (format nil "~a failed" (symbol-name dlg-func))))
+    retval))
+
 (defun get-widget-text (w)
   (if (gfs:disposed-p w)
     (error 'gfs:disposed-error))



More information about the Graphic-forms-cvs mailing list