[graphic-forms-cvs] r151 - in trunk/src: tests/uitoolkit uitoolkit/graphics uitoolkit/system uitoolkit/widgets
junrue at common-lisp.net
junrue at common-lisp.net
Mon Jun 5 17:18:10 UTC 2006
Author: junrue
Date: Mon Jun 5 13:18:09 2006
New Revision: 151
Modified:
trunk/src/tests/uitoolkit/layout-tester.lisp
trunk/src/uitoolkit/graphics/font.lisp
trunk/src/uitoolkit/system/user32.lisp
trunk/src/uitoolkit/widgets/button.lisp
trunk/src/uitoolkit/widgets/control.lisp
trunk/src/uitoolkit/widgets/event.lisp
trunk/src/uitoolkit/widgets/label.lisp
trunk/src/uitoolkit/widgets/widget-utils.lisp
Log:
enabled and fixed the :check-box, :radio-button, and :toggle button styles; fixed a problem with creating a font with an existing font handle
Modified: trunk/src/tests/uitoolkit/layout-tester.lisp
==============================================================================
--- trunk/src/tests/uitoolkit/layout-tester.lisp (original)
+++ trunk/src/tests/uitoolkit/layout-tester.lisp Mon Jun 5 13:18:09 2006
@@ -35,7 +35,7 @@
(defconstant +btn-text-before+ "Push Me")
(defconstant +btn-text-after+ "Again!")
-(defconstant +label-text+ "Test Label")
+(defconstant +label-text+ "Label")
(defconstant +margin-delta+ 4)
(defconstant +spacing-delta+ 3)
@@ -86,30 +86,51 @@
(declare (ignore win))
"Test Panel")
+(defun create-button-toggler (be)
+ (let ((flag nil))
+ (lambda ()
+ (if (null flag)
+ (progn
+ (setf flag t)
+ (format nil "~d ~a" (id be) +btn-text-before+))
+ (progn
+ (setf flag nil)
+ (format nil "~d ~a" (id be) +btn-text-after+))))))
+
(defun add-layout-tester-widget (widget-class subtype)
- (let* ((be (make-instance 'layout-tester-widget-events :id *widget-counter*))
- (w (make-instance widget-class :parent *layout-tester-win* :dispatcher be)))
+ (let ((be (make-instance 'layout-tester-widget-events :id *widget-counter*))
+ (w nil))
(cond
- ((eql subtype :push-button)
- (setf (toggle-fn be) (let ((flag nil))
- (lambda ()
- (if (null flag)
- (progn
- (setf flag t)
- (format nil "~d ~a" (id be) +btn-text-before+))
- (progn
- (setf flag nil)
- (format nil "~d ~a" (id be) +btn-text-after+))))))
+ ((or (eql subtype :check-box)
+ (eql subtype :push-button)
+ (eql subtype :radio-button)
+ (eql subtype :toggle-button))
+ (setf w (make-instance widget-class
+ :parent *layout-tester-win*
+ :dispatcher be
+ :style (list subtype)))
+ (setf (toggle-fn be) (create-button-toggler be))
(setf (gfw:text w) (funcall (toggle-fn be))))
((eql subtype :image-label)
;; NOTE: we are leaking a bitmap handle by not tracking the
;; image being created here
+ (setf w (make-instance widget-class
+ :parent *layout-tester-win*
+ :dispatcher be))
(setf (gfg:background-color w) (gfg:background-color *layout-tester-win*))
(let ((tmp-image (make-instance 'gfg:image :file "happy.bmp")))
(gfg:with-image-transparency (tmp-image (gfs:make-point))
(setf (gfw:image w) tmp-image))))
((eql subtype :text-label)
- (setf (gfw:text w) (format nil "~d ~a" (id be) +label-text+))))
+ (setf w (make-instance widget-class
+ :parent *layout-tester-win*
+ :dispatcher be
+ :style '(:sunken)))
+ (setf (gfw:text w) (format nil "~d ~a" (id be) +label-text+)))
+ (t
+ (setf w (make-instance widget-class
+ :parent *layout-tester-win*
+ :dispatcher be))))
(incf *widget-counter*)))
(defmethod gfw:event-select ((d layout-tester-widget-events) btn time rect)
@@ -365,6 +386,9 @@
(let ((menubar nil)
(pack-disp (make-instance 'pack-layout-dispatcher))
(add-btn-disp (make-instance 'add-child-dispatcher))
+ (add-checkbox-disp (make-instance 'add-child-dispatcher :subtype :check-box))
+ (add-radio-disp (make-instance 'add-child-dispatcher :subtype :radio-button))
+ (add-toggle-disp (make-instance 'add-child-dispatcher :subtype :toggle-button))
(add-panel-disp (make-instance 'add-child-dispatcher :widget-class 'test-panel
:subtype :panel))
(add-image-label-disp (make-instance 'add-child-dispatcher :widget-class 'gfw:label
@@ -385,9 +409,12 @@
(:item "&Children"
:submenu ((:item "Add"
:submenu ((:item "Button" :dispatcher add-btn-disp)
+ (:item "Checkbox" :dispatcher add-checkbox-disp)
(:item "Label - Image" :dispatcher add-image-label-disp)
(:item "Label - Text" :dispatcher add-text-label-disp)
- (:item "Panel" :dispatcher add-panel-disp)))
+ (:item "Panel" :dispatcher add-panel-disp)
+ (:item "Radiobutton" :dispatcher add-radio-disp)
+ (:item "Toggle" :dispatcher add-toggle-disp)))
(:item "Remove" :dispatcher rem-menu-disp
:submenu ((:item "")))
(:item "Visible" :dispatcher vis-menu-disp
Modified: trunk/src/uitoolkit/graphics/font.lisp
==============================================================================
--- trunk/src/uitoolkit/graphics/font.lisp (original)
+++ trunk/src/uitoolkit/graphics/font.lisp Mon Jun 5 13:18:09 2006
@@ -44,4 +44,5 @@
(setf (slot-value fn 'gfs:handle) nil))
(defmethod initialize-instance :after ((font font) &key gc data &allow-other-keys)
- (setf (slot-value font 'gfs:handle) (data->font (gfs:handle gc) data)))
+ (if gc
+ (setf (slot-value font 'gfs:handle) (data->font (gfs:handle gc) data))))
Modified: trunk/src/uitoolkit/system/user32.lisp
==============================================================================
--- trunk/src/uitoolkit/system/user32.lisp (original)
+++ trunk/src/uitoolkit/system/user32.lisp Mon Jun 5 13:18:09 2006
@@ -476,6 +476,12 @@
(id UINT))
(defcfun
+ ("LoadBitmapA" load-bitmap)
+ HANDLE
+ (hinst HANDLE)
+ (name LPTR)) ; LPTR to make it easier to pass constants like +obm-checkboxes+
+
+(defcfun
("LoadImageA" load-image)
HANDLE
(instance HANDLE)
Modified: trunk/src/uitoolkit/widgets/button.lisp
==============================================================================
--- trunk/src/uitoolkit/widgets/button.lisp (original)
+++ trunk/src/uitoolkit/widgets/button.lisp Mon Jun 5 13:18:09 2006
@@ -49,15 +49,15 @@
;; primary button styles
;;
((eq sym :check-box)
- (setf std-flags (logior std-flags gfs::+bs-checkbox+)))
+ (setf std-flags (logior std-flags gfs::+bs-autocheckbox+)))
((eq sym :default-button)
(setf std-flags (logior std-flags gfs::+bs-defpushbutton+)))
((or (eq sym :push-button) (eq sym :cancel-button))
(setf std-flags (logior std-flags gfs::+bs-pushbutton+)))
((eq sym :radio-button)
- (setf std-flags (logior std-flags gfs::+bs-radiobutton+)))
+ (setf std-flags (logior std-flags gfs::+bs-autoradiobutton+)))
((eq sym :toggle-button)
- (setf std-flags (logior std-flags gfs::+bs-pushbox+)))))
+ (setf std-flags (logior std-flags gfs::+bs-autocheckbox+ gfs::+bs-pushlike+)))))
(if (null style)
(logior std-flags gfs::+bs-pushbutton+))
(values std-flags 0)))
@@ -85,15 +85,33 @@
(init-control btn))
(defmethod preferred-size ((self button) width-hint height-hint)
- (let ((size (widget-text-size self gfs::+dt-singleline+)))
- (if (>= width-hint 0)
- (setf (gfs:size-width size) width-hint)
- (setf (gfs:size-width size) (+ (gfs:size-width size)
- (* +horizontal-button-text-margin+ 2))))
- (if (>= height-hint 0)
- (setf (gfs:size-height size) height-hint)
- (setf (gfs:size-height size) (+ (gfs:size-height size)
- ( * +vertical-button-text-margin+ 2))))
+ (let ((text-size (widget-text-size self gfs::+dt-singleline+))
+ (size (gfs:make-size))
+ (b-width (* (border-width self) 2))
+ (need-cb-size (intersection '(:check-box :radio-button) (style-of self)))
+ (cb-size (check-box-size)))
+ (cond
+ ((>= width-hint 0)
+ (setf (gfs:size-width size) width-hint))
+ (need-cb-size
+ (setf (gfs:size-width size) (+ +horizontal-button-text-margin+
+ (gfs:size-width cb-size)
+ (gfs:size-width text-size))))
+ (t
+ (setf (gfs:size-width size) (+ b-width
+ (* +horizontal-button-text-margin+ 2)
+ (gfs:size-width text-size)))))
+ (cond
+ ((>= height-hint 0)
+ (setf (gfs:size-height size) height-hint))
+ (need-cb-size
+ (setf (gfs:size-height size) (+ (* +vertical-button-text-margin+ 2)
+ (max (gfs:size-height text-size)
+ (gfs:size-height cb-size)))))
+ (t
+ (setf (gfs:size-height size) (+ b-width
+ (* +vertical-button-text-margin+ 2)
+ (gfs:size-height text-size)))))
size))
(defmethod text ((self button))
@@ -103,6 +121,4 @@
(set-widget-text self str))
(defmethod text-baseline ((self button))
- (let ((font (gfg:font self))
- (gc (make-instance 'gfg:graphics-context :widget self)))
- (+ +vertical-button-text-margin+ (gfg:ascent (gfg:metrics gc font)))))
+ (widget-text-baseline self +vertical-button-text-margin+))
Modified: trunk/src/uitoolkit/widgets/control.lisp
==============================================================================
--- trunk/src/uitoolkit/widgets/control.lisp (original)
+++ trunk/src/uitoolkit/widgets/control.lisp Mon Jun 5 13:18:09 2006
@@ -103,12 +103,14 @@
(defmethod gfg:font ((self control))
(let ((font (font-of self)))
(unless font
- (let ((result (gfs::send-message (gfs:handle self) gfs::+wm-getfont+ 0 0)))
+ (let ((result (gfs::send-message (gfs:handle self) gfs::+wm-getfont+ 0 0))
+ (gc nil))
(if (zerop result)
- (let ((gc (make-instance 'gfg:graphics-context :widget self)))
- (unwind-protect
+ (unwind-protect
+ (progn
+ (setf gc (make-instance 'gfg:graphics-context :widget self))
(setf font (gfg:font gc)))
- (gfs:dispose gc))
+ (gfs:dispose gc))
(setf font (make-instance 'gfg:font :handle (cffi:make-pointer result))))))
font))
Modified: trunk/src/uitoolkit/widgets/event.lisp
==============================================================================
--- trunk/src/uitoolkit/widgets/event.lisp (original)
+++ trunk/src/uitoolkit/widgets/event.lisp Mon Jun 5 13:18:09 2006
@@ -314,8 +314,15 @@
(textcolor (text-color-of widget))
(ret-val 0))
(when widget
- (if (not (typep widget 'label))
- (error 'gfs:toolkit-error :detail "incorrect widget type received WM_CTLCOLORSTATIC"))
+#|
+ ;; temporarily disabling this until I decide whether this sort
+ ;; of sanity check really makes sense (for one thing, I didn't
+ ;; expect buttons with BS_CHECKBOX or BS_RADIOBUTTON to send
+ ;; WM_CTLCOLORSTATIC, but I guess it makes sense).
+ ;;
+ (if (not (or (typep widget 'button) (typep widget 'label)))
+ (warn 'gfs:toolkit-warning :detail "incorrect widget type received WM_CTLCOLORSTATIC"))
+|#
(let ((font (font-of widget)))
(if font
(gfs::select-object hdc (gfs:handle font))))
Modified: trunk/src/uitoolkit/widgets/label.lisp
==============================================================================
--- trunk/src/uitoolkit/widgets/label.lisp (original)
+++ trunk/src/uitoolkit/widgets/label.lisp Mon Jun 5 13:18:09 2006
@@ -39,7 +39,7 @@
(defun compute-image-style-flags (style)
(let ((flags (logior gfs::+ss-bitmap+ gfs::+ss-realsizeimage+ gfs::+ss-centerimage+)))
- (when (find :raised style)
+ (when (find :raised style) ; FIXME: this style not yet working
(setf flags (logand (lognot gfs::+ss-sunken+) flags))
(setf flags (logior flags gfs::+ss-etchedframe+)))
(when (find :sunken style)
@@ -50,23 +50,23 @@
(defun compute-text-style-flags (style)
(let ((flags 0))
(unless (intersection style (list :beginning :center :end))
- (setf flags gfs::+ss-leftnowordwrap+))
+ (setf flags (logior gfs::+ss-center+ gfs::+ss-centerimage+ flags)))
(loop for sym in style
do (cond
;; primary text static styles
;;
((eq sym :beginning)
- (setf flags gfs::+ss-leftnowordwrap+)) ; FIXME: i18n
+ (setf flags (logior flags gfs::+ss-leftnowordwrap+))) ; FIXME: i18n
((eq sym :center)
- (setf flags gfs::+ss-center+))
+ (setf flags (logior flags gfs::+ss-center+)))
((eq sym :end)
- (setf flags gfs::+ss-right+)) ; FIXME: i18n
+ (setf flags (logior flags gfs::+ss-right+))) ; FIXME: i18n
;; styles that can be combined
;;
((eq sym :ellipsis)
(setf flags (logior flags gfs::+ss-endellipsis+)))
- ((eq sym :raised)
+ ((eq sym :raised) ; FIXME: this style not yet working
(setf flags (logand (lognot gfs::+ss-sunken+) flags))
(setf flags (logior flags gfs::+ss-etchedframe+)))
((eq sym :sunken)
@@ -169,55 +169,54 @@
(setf (image label) image))))
(init-control label))
-(defmethod preferred-size ((label label) width-hint height-hint)
- (declare (ignorable width-hint height-hint))
- (let* ((hwnd (gfs:handle label))
+(defmethod preferred-size ((self label) width-hint height-hint)
+ (let* ((hwnd (gfs:handle self))
(bits (gfs::get-window-long hwnd gfs::+gwl-style+))
- (b-width (border-width label))
- (sz nil))
+ (b-width (* (border-width self) 2)))
(if (= (logand bits gfs::+ss-bitmap+) gfs::+ss-bitmap+)
- (let ((image (image label)))
+ (let ((image (image self)))
(if image
- (gfg:size image)
+ (let ((size (gfg:size image)))
+ (gfs:make-size :width (+ (gfs:size-width size) b-width)
+ :height (+ (gfs:size-height size) b-width)))
(gfs:make-size)))
- (let ((flags (logior gfs::+dt-editcontrol+ gfs::+dt-expandtabs+)))
+ (let ((flags (logior gfs::+dt-editcontrol+ gfs::+dt-expandtabs+))
+ (size nil))
(if (and (= (logand bits gfs::+ss-left+) gfs::+ss-left+) (> width-hint 0))
(setf flags (logior flags gfs::+dt-wordbreak+)))
- (setf sz (widget-text-size label flags))
+ (setf size (widget-text-size self flags))
(if (>= width-hint 0)
- (setf (gfs:size-width sz) width-hint))
+ (setf (gfs:size-width size) width-hint)
+ (incf (gfs:size-width size) b-width))
(if (>= height-hint 0)
- (setf (gfs:size-height sz) height-hint))
- (incf (gfs:size-width sz) (* b-width 2))
- (incf (gfs:size-height sz) (* b-width 2))
- sz))))
+ (setf (gfs:size-height size) height-hint)
+ (incf (gfs:size-width size) b-width))
+ size))))
-(defmethod text ((label label))
- (get-widget-text label))
+(defmethod text ((self label))
+ (get-widget-text self))
-(defmethod (setf text) (str (label label))
- (let* ((hwnd (gfs:handle label))
+(defmethod (setf text) (str (self label))
+ (let* ((hwnd (gfs:handle self))
(orig-flags (gfs::get-window-long hwnd gfs::+gwl-style+))
(etch-flags (logior (logand orig-flags gfs::+ss-etchedframe+)
(logand orig-flags gfs::+ss-sunken+))))
(multiple-value-bind (std-flags ex-flags)
- (compute-style-flags label nil nil str)
+ (compute-style-flags self nil nil str)
(declare (ignore ex-flags))
(gfs::set-window-long hwnd gfs::+gwl-style+ (logior etch-flags
std-flags
gfs::+ws-child+
gfs::+ws-visible+))))
- (set-widget-text label str))
+ (set-widget-text self str))
(defmethod text-baseline ((self label))
- (if (= (logand (gfs::get-window-long (gfs:handle self) gfs::+gwl-style+)
- gfs::+ss-bitmap+)
- gfs::+ss-bitmap+)
- (let ((image (image self)))
- (if image
- (gfs:size-height (gfg:size image))
- 0))
- (let ((font (gfg:font self))
- (gc (make-instance 'gfg:graphics-context :widget self))
- (b-width (border-width self)))
- (+ b-width (gfg:ascent (gfg:metrics gc font))))))
+ (let ((b-width (border-width self)))
+ (if (= (logand (gfs::get-window-long (gfs:handle self) gfs::+gwl-style+)
+ gfs::+ss-bitmap+)
+ gfs::+ss-bitmap+)
+ (let ((image (image self)))
+ (if image
+ (+ (gfs:size-height (gfg:size image)) b-width)
+ b-width))
+ (widget-text-baseline self 0))))
Modified: trunk/src/uitoolkit/widgets/widget-utils.lisp
==============================================================================
--- trunk/src/uitoolkit/widgets/widget-utils.lisp (original)
+++ trunk/src/uitoolkit/widgets/widget-utils.lisp Mon Jun 5 13:18:09 2006
@@ -33,6 +33,9 @@
(in-package #:graphic-forms.uitoolkit.widgets)
+(defvar *check-box-size* nil)
+
+
(defun translate-and-dispatch (msg-ptr)
(gfs::translate-message msg-ptr)
(gfs::dispatch-message msg-ptr))
@@ -148,6 +151,50 @@
(gfs::with-hfont-selected (hdc hfont)
(gfg::text-bounds hdc (text widget) dt-flags 0)))))
+;;;
+;;; This algorithm adapted from the calculate_best_bounds()
+;;; function in ui_core_implementation.cpp from the
+;;; Adobe Source Libraries / UI Core Widget API
+;;;
+(defun widget-text-baseline (widget top-margin)
+ (let ((size (gfw:size widget))
+ (b-width (border-width widget))
+ (font (gfg:font widget))
+ (gc (make-instance 'gfg:graphics-context :widget widget))
+ (baseline 0))
+ (unwind-protect
+ (let ((metrics (gfg:metrics gc font)))
+ (setf baseline (+ b-width
+ top-margin
+ (gfg:ascent metrics)
+ (floor (/ (- (gfs:size-height size)
+ (+ (gfg:ascent metrics) (gfg:descent metrics)))
+ 2)))))
+ (gfs:dispose gc))
+ baseline))
+
+(defun check-box-size ()
+ (if *check-box-size*
+ (return-from check-box-size (gfs:copy-size *check-box-size*)))
+ (let ((hbitmap (gfs::load-bitmap (cffi:null-pointer)
+ (cffi:make-pointer gfs::+obm-checkboxes+))))
+ (if (gfs:null-handle-p hbitmap)
+ ;; if for some reason the OBM_CHECKBOXES resource could not be retrieved,
+ ;; use scrollbar system metric values as a rough approximation
+ ;;
+ (return-from check-box-size
+ (gfs:make-size :width (gfs::get-system-metrics gfs::+sm-cxvscroll+)
+ :height (gfs::get-system-metrics gfs::+sm-cyvscroll+))))
+
+ (unwind-protect
+ (cffi:with-foreign-object (bm-ptr 'gfs::bitmap)
+ (cffi:with-foreign-slots ((gfs::width gfs::height) bm-ptr gfs::bitmap)
+ (gfs::get-object hbitmap (cffi:foreign-type-size 'gfs::bitmap) bm-ptr)
+ (setf *check-box-size* (gfs:make-size :width (floor (/ gfs::width 4))
+ :height (floor (/ gfs::height 3))))))
+ (gfs::delete-object hbitmap)))
+ (gfs:copy-size *check-box-size*))
+
(defun extract-foreign-strings (buffer)
(let ((strings nil))
(do ((curr-ptr buffer))
More information about the Graphic-forms-cvs
mailing list