Update of /project/mcclim/cvsroot/mcclim/Backends/gtkairo In directory clnet:/tmp/cvs-serv4775
Modified Files: BUGS cairo-ffi.lisp event.lisp frame-manager.lisp gadgets.lisp gtk-ffi.lisp medium.lisp Log Message: * medium.lisp (TEXT-STYLE-HEIGHT): McCLIM wants height = ascent + descent. Make it so.
* cairo-ffi.lisp (*CAIRO-ERROR-MODE*, DEF-CAIRO-FUN): New variable and macro for cairo_status checking. (CAIRO_*): Use def-cairo-fun for (nearly) all functions taking a cairo context as an argument.
* gtk-ffi.lisp (gtkscrolltype): New enum. (gtk_range_set_adjustment, gtk_adjustment_get_value, gtk_adjustment_set_value): New functions.
* gadgets.lisp (GTK-CHECK-BUTTON, GTK-RADIO-BUTTON, GTK-VSCALE, GTK-HSCALE, GTK-VSCROLLBAR, GTK-HSCROLLBAR): Subclass the abstract gadgets directly. (NATIVE-SLIDER, NATIVE-SCROLLBAR): New class. (CLIMI::SHOW-VALUE-P, CLIMI::DECIMAL-PLACES, CLIMI::NUMBER-OF-QUANTA): New accessors. (HANDLE-REPAINT): Removed. (MAKE-GADGET-EVENT): Removed. (SCROLLBAR-CHANGE-VALUE-EVENT, MAGIC-GADGET-EVENT): New classes. (MAKE-SCALE): Set initial adjustment value. (MAKE-SCROLLBAR): Compute page size from thumb-size. Set step and page increments to zero. Set initial adjustment value. (CONNECT-NATIVE-SIGNALS): Replaced clicked-handler with magic-clicked-handler; collapsed identical methods. ((CONNECT-NATIVE-SIGNALS NATIVE-SCROLLBAR)): Establish change-value handler. (HANDLE-EVENT): Replaced gadget-event with magic-gadget-event; collapsed identical methods. ((HANDLE-EVENT SCROLLBAR-CHANGE-VALUE-EVENT)): New method. (UPDATE-SCROLLBAR-ADJUSTMENT): New function. ((SETF GADGET-MIN-VALUE), (SETF GADGET-MAX-VALUE), (SETF GADGET-VALUE), (SETF CLIMI::SCROLL-BAR-VALUES)): New methods on native-scrollbar. ((REALIZE-NATIVE-WIDGET GTK-CHECK-BUTTON), (REALIZE-NATIVE-WIDGET GTK-RADIO-BUTTON)): Set initial value.
* event.lisp (DEFINE-SIGNAL): Let callers specify return-type and arguments. (CLICKED-HANDLER): Renamed to magic-clicked-handler. Make an instance of magic-gadget-event. (SCROLLBAR-CHANGE-VALUE-HANDLER): New function.
--- /project/mcclim/cvsroot/mcclim/Backends/gtkairo/BUGS 2006/04/23 10:42:39 1.3 +++ /project/mcclim/cvsroot/mcclim/Backends/gtkairo/BUGS 2006/04/23 17:36:28 1.4 @@ -18,13 +18,13 @@ Colored buttons (clim-fig) are missing.
5b. - the slider is not quite right. + the slider needs tick marks
-(WORK IN PROGRESS) 5c. +(FIXED) 5c. Inheriting from the standard gadget panes is bogus anyway, we should build them from scratch.
-5d. +(FIXED) 5d. Default gadget values aren't being used.
6. @@ -76,5 +76,10 @@ 14. Climacs doesn't draw itself until the window is resized.
-15. +(FIXED) 15. The text cursor does not show the correct vertical position in climacs. + +16. + Scroll panes are now native widgets, but don't really behave. The + scroll test works a little, many other examples don't. See comment + in update-scrollbar-adjustment. --- /project/mcclim/cvsroot/mcclim/Backends/gtkairo/cairo-ffi.lisp 2006/04/23 10:42:39 1.2 +++ /project/mcclim/cvsroot/mcclim/Backends/gtkairo/cairo-ffi.lisp 2006/04/23 17:36:28 1.3 @@ -25,6 +25,29 @@ (in-package :clim-gtkairo)
+(defvar *cairo-error-mode* :warn + "NIL, :WARN, or :BREAK.") + +(defmacro def-cairo-fun (name rtype &rest args) + (let* ((str (string-upcase name)) + (actual (intern (concatenate 'string "%-" str) :clim-gtkairo)) + (wrapper (intern str :clim-gtkairo)) + (argnames (mapcar #'car args))) + `(progn + (cffi:defcfun (,name ,actual) + ,rtype + ,@args) + (defun ,wrapper ,argnames + (multiple-value-prog1 + (,actual ,@argnames) + (when *cairo-error-mode* + (let ((status (cairo_status ,(car argnames)))) + (unless (eq status :success) + (warn "~A returned with status ~A" ,name status)) + (when (eq *cairo-error-mode* :break) + (break))))))))) + + ;; user-visible structures
(cffi:defcstruct cairo_text_extents @@ -125,11 +148,11 @@ :void (cr :pointer))
-(defcfun "cairo_save" +(def-cairo-fun "cairo_save" :void (cr :pointer))
-(defcfun "cairo_restore" +(def-cairo-fun "cairo_restore" :void (cr :pointer))
@@ -156,21 +179,21 @@ ;;; (height :int) ;;; (stride :int))
-(defcfun "cairo_set_operator" +(def-cairo-fun "cairo_set_operator" :void (cr :pointer) (op cairo_operator))
;;; Colors
-(defcfun "cairo_set_source_rgb" +(def-cairo-fun "cairo_set_source_rgb" :void (cr :pointer) (red :double) (green :double) (blue :double))
-(defcfun "cairo_set_source_rgba" +(def-cairo-fun "cairo_set_source_rgba" :void (cr :pointer) (red :double) @@ -178,73 +201,73 @@ (blue :double) (alpha :double))
-(defcfun "cairo_set_source" +(def-cairo-fun "cairo_set_source" :void (cr :pointer) (pattern :pointer))
-(defcfun "cairo_set_tolerance" +(def-cairo-fun "cairo_set_tolerance" :void (cr :pointer) (tolerance :double))
-(defcfun "cairo_set_fill_rule" +(def-cairo-fun "cairo_set_fill_rule" :void (cr :pointer) (fill_rule cairo_fill_rule))
-(defcfun "cairo_set_line_width" +(def-cairo-fun "cairo_set_line_width" :void (cr :pointer) (w :double))
-(defcfun "cairo_set_line_cap" +(def-cairo-fun "cairo_set_line_cap" :void (cr :pointer) (line_cap cairo_line_cap))
-(defcfun "cairo_set_line_join" +(def-cairo-fun "cairo_set_line_join" :void (cr :pointer) (line_join cairo_line_join))
-(defcfun "cairo_set_dash" +(def-cairo-fun "cairo_set_dash" :void (cr :pointer) (dashes :pointer) ;*double (ndash :int) (offset :double))
-(defcfun "cairo_set_miter_limit" +(def-cairo-fun "cairo_set_miter_limit" :int (cr :pointer) (limit :double))
;;; Transformations
-(defcfun "cairo_translate" +(def-cairo-fun "cairo_translate" :void (cr :pointer) (tx :double) (ty :double))
-(defcfun "cairo_scale" +(def-cairo-fun "cairo_scale" :void (cr :pointer) (sx :double) (sy :double))
-(defcfun "cairo_rotate" +(def-cairo-fun "cairo_rotate" :void (cr :pointer) (angle :double))
-(defcfun "cairo_set_matrix" +(def-cairo-fun "cairo_set_matrix" :void (cr :pointer) (matrix :pointer))
-(defcfun "cairo_identity_matrix" +(def-cairo-fun "cairo_identity_matrix" :void (cr :pointer))
@@ -278,23 +301,23 @@
;;; Path creation functions
-(defcfun "cairo_new_path" +(def-cairo-fun "cairo_new_path" :void (cr :pointer))
-(defcfun "cairo_move_to" +(def-cairo-fun "cairo_move_to" :void (cr :pointer) (x :double) (y :double))
-(defcfun "cairo_line_to" +(def-cairo-fun "cairo_line_to" :void (cr :pointer) (x :double) (y :double))
-(defcfun "cairo_curve_to" +(def-cairo-fun "cairo_curve_to" :void (cr :pointer) (x1 :double) @@ -304,7 +327,7 @@ (x3 :double) (y3 :double))
-(defcfun "cairo_arc" +(def-cairo-fun "cairo_arc" :void (cr :pointer) (xc :double) @@ -313,7 +336,7 @@ (angle1 :double) (angle2 :double))
-(defcfun "cairo_arc_negative" +(def-cairo-fun "cairo_arc_negative" :void (cr :pointer) (xc :double) @@ -322,19 +345,19 @@ (angle1 :double) (angle2 :double))
-(defcfun "cairo_rel_move_to" +(def-cairo-fun "cairo_rel_move_to" :void (cr :pointer) (dx :double) (dy :double))
-(defcfun "cairo_rel_line_to" +(def-cairo-fun "cairo_rel_line_to" :void (cr :pointer) (dx :double) (dy :double))
-(defcfun "cairo_rel_curve_to" +(def-cairo-fun "cairo_rel_curve_to" :void (cr :pointer) (dx1 :double) @@ -344,7 +367,7 @@ (dx3 :double) (dy3 :double))
-(defcfun "cairo_rectangle" +(def-cairo-fun "cairo_rectangle" :void (cr :pointer) (x :double) @@ -352,35 +375,35 @@ (w :double) (h :double))
-(defcfun "cairo_close_path" +(def-cairo-fun "cairo_close_path" :void (cr :pointer))
-(defcfun "cairo_stroke" +(def-cairo-fun "cairo_stroke" :void (cr :pointer))
-(defcfun "cairo_fill" +(def-cairo-fun "cairo_fill" :void (cr :pointer))
-(defcfun "cairo_copy_page" +(def-cairo-fun "cairo_copy_page" :void (cr :pointer))
-(defcfun "cairo_show_page" +(def-cairo-fun "cairo_show_page" :void (cr :pointer))
;;; Insideness testing
-(defcfun "cairo_in_stroke" +(def-cairo-fun "cairo_in_stroke" :int (cr :pointer) (x :double) (y :double))
-(defcfun "cairo_in_fill" +(def-cairo-fun "cairo_in_fill" :int (cr :pointer) (x :double) @@ -388,7 +411,7 @@
;;; Rectangular extents
-(defcfun "cairo_stroke_extents" +(def-cairo-fun "cairo_stroke_extents" :void (cr :pointer) (x1 :pointer) ;*double @@ -397,7 +420,7 @@ (y2 :pointer) ;*double )
-(defcfun "cairo_fill_extents" +(def-cairo-fun "cairo_fill_extents" :void (cr :pointer) (x1 :pointer) ;*double @@ -406,12 +429,12 @@ (y2 :pointer) ;*double )
-(defcfun "cairo_reset_clip" +(def-cairo-fun "cairo_reset_clip" :void (cr :pointer))
;; Note: cairo_clip does not consume the current path -(defcfun "cairo_clip" +(def-cairo-fun "cairo_clip" :void (cr :pointer))
@@ -421,14 +444,14 @@ ;; This interface is for dealing with text as text, not caring about the ;; font object inside the the cairo_t.
-(defcfun "cairo_select_font_face" +(def-cairo-fun "cairo_select_font_face" :void (cr :pointer) (family :string) (slant cairo_font_slant) (weight cairo_font_weight))
-(defcfun "cairo_set_font_size" +(def-cairo-fun "cairo_set_font_size" :void (cr :pointer) (size :double)) @@ -438,50 +461,50 @@ ;;; (cr :pointer) ;;; (matrix :pointer))
-(defcfun "cairo_show_text" +(def-cairo-fun "cairo_show_text" :void (cr :pointer) (string :string))
-(defcfun "cairo_show_glyphs" +(def-cairo-fun "cairo_show_glyphs" :void (cr :pointer) (glyphs :pointer) (num_glyphs :int))
-;;;(defcfun "cairo_current_font" +;;;(def-cairo-fun "cairo_current_font" ;;; :pointer ;;; (cr :pointer)) ;;; -(defcfun "cairo_font_extents" +(def-cairo-fun "cairo_font_extents" :void (cr :pointer) (extents :pointer))
-;;;(defcfun "cairo_set_font" +;;;(def-cairo-fun "cairo_set_font" ;;; :void ;;; (cr :pointer) ;;; (font :pointer))
-(defcfun "cairo_text_extents" +(def-cairo-fun "cairo_text_extents" :void (cr :pointer) (string :string) ;### utf_8 (extents :pointer))
-(defcfun "cairo_glyph_extents" +(def-cairo-fun "cairo_glyph_extents" :void (cr :pointer) (glyphs :pointer) (num_glyphs :int) (extents :pointer))
-(defcfun "cairo_text_path" +(def-cairo-fun "cairo_text_path" :void (cr :pointer) (string :string)) ;### utf_8
-(defcfun "cairo_glyph_path" +(def-cairo-fun "cairo_glyph_path" :void (cr :pointer) (glyphs :pointer) @@ -500,7 +523,7 @@
;;; Image functions
-;;;(defcfun "cairo_show_surface" +;;;(def-cairo-fun "cairo_show_surface" ;;; :void ;;; (cr :pointer) ;;; (surface :pointer) @@ -509,11 +532,11 @@
[112 lines skipped] --- /project/mcclim/cvsroot/mcclim/Backends/gtkairo/event.lisp 2006/04/23 10:18:45 1.3 +++ /project/mcclim/cvsroot/mcclim/Backends/gtkairo/event.lisp 2006/04/23 17:36:28 1.4 @@ -106,16 +106,24 @@ (gtk-main-iteration port #-(and sbcl (not win32)) t) (dequeue port))))
-(defmacro define-signal (name (widget event) &body body) - (let ((impl (intern (concatenate 'string (symbol-name name) "-IMPL")))) - ;; jump through a trampoline so that C-M-x works without having to restart: - `(progn - (defun ,impl (,widget ,event) - ,@body) - (cffi:defcallback ,name :void - ((widget :pointer) (event :pointer) (data :pointer)) - data - (,impl widget event))))) +(defmacro define-signal (name+options (widget event &rest args) &body body) + (destructuring-bind (name &key (return-type :void)) + (if (listp name+options) + name+options + (list name+options)) + (let ((impl (intern (concatenate 'string (symbol-name name) "-IMPL"))) + (args (if (symbolp event) + `((,event :pointer) ,@args) + (cons event args)))) + ;; jump through a trampoline so that C-M-x works without having to + ;; restart: + `(progn + (defun ,impl (,widget ,@(mapcar #'car args)) + ,@body) + (cffi:defcallback ,name ,return-type + ((widget :pointer) ,@args (data :pointer)) + data + (,impl widget ,@(mapcar #'car args)))))))
(define-signal noop-handler (widget event))
@@ -298,7 +306,30 @@ (make-instance 'climi::window-destroy-event :sheet (widget->sheet widget *port*))))
-(define-signal clicked-handler (widget event) +;; native widget handlers: + +(define-signal magic-clicked-handler (widget event) (declare (ignore event)) (when (boundp '*port*) ;hack alert - (enqueue (make-gadget-event (widget->sheet widget *port*))))) + (enqueue + (make-instance 'magic-gadget-event + :sheet (widget->sheet widget *port*))))) + +#-sbcl +(define-signal (scrollbar-change-value-handler :return-type :int) + (widget (scroll gtkscrolltype) (value :double)) + (enqueue (make-instance 'scrollbar-change-value-event + :scroll-type scroll + :value value + :sheet (widget->sheet widget *port*))) + 1) + +#+sbcl +;; :double in callbacks doesn't work: +(define-signal (scrollbar-change-value-handler :return-type :int) + (widget (scroll gtkscrolltype) (lo :unsigned-int) (hi :int)) + (enqueue (make-instance 'scrollbar-change-value-event + :scroll-type scroll + :value (sb-kernel:make-double-float hi lo) + :sheet (widget->sheet widget *port*))) + 1) --- /project/mcclim/cvsroot/mcclim/Backends/gtkairo/frame-manager.lisp 2006/04/17 18:40:27 1.1 +++ /project/mcclim/cvsroot/mcclim/Backends/gtkairo/frame-manager.lisp 2006/04/23 17:36:28 1.2 @@ -65,9 +65,6 @@ (defmethod make-pane-2 ((type (eql 'clim:scroll-bar-pane)) &rest initargs &key orientation) - ;; doesn't really work yet - (call-next-method) - #+(or) (apply #'make-instance (if (eq orientation :vertical) 'gtk-vscrollbar --- /project/mcclim/cvsroot/mcclim/Backends/gtkairo/gadgets.lisp 2006/04/23 10:18:45 1.2 +++ /project/mcclim/cvsroot/mcclim/Backends/gtkairo/gadgets.lisp 2006/04/23 17:36:28 1.3 @@ -20,26 +20,37 @@ (in-package :clim-gtkairo)
(defclass gadget-event (window-event) ()) +(defclass magic-gadget-event (gadget-event) ())
-(defun make-gadget-event (sheet) - (make-instance 'gadget-event :sheet sheet)) +(defclass scrollbar-change-value-event (gadget-event) + ((scroll-type :initarg :scroll-type :accessor event-scroll-type) + (value :initarg :value :accessor event-value)))
;;;; Classes
-;; FIXME: Hier implementieren wir die Widgets nicht vollstaendig selbst, -;; sondern erben von den Standard-Widgets. Damit das gut geht, muessen -;; wir unten deren Redisplay-Methoden unterdruecken... Besser waere es -;; vielleicht, von TOGGLE-BUTTON statt TOGGLE-BUTTON-PANE zu erben und -;; alles selbst zu machen. Mindestens COMPOSE-SPACE muesste man dann -;; hier implementieren. (defclass gtk-button (native-widget-mixin push-button) ()) -(defclass gtk-check-button (native-widget-mixin toggle-button-pane) ()) -(defclass gtk-radio-button (native-widget-mixin toggle-button-pane) ()) -(defclass gtk-vscale (native-widget-mixin slider-pane) ()) -(defclass gtk-hscale (native-widget-mixin slider-pane) ()) -(defclass gtk-vscrollbar (native-widget-mixin scroll-bar-pane) ()) -(defclass gtk-hscrollbar (native-widget-mixin scroll-bar-pane) ()) + +(defclass gtk-check-button (native-widget-mixin toggle-button) ()) +(defclass gtk-radio-button (native-widget-mixin toggle-button) ()) + +(defclass native-slider (native-widget-mixin climi::slider-gadget) + ((climi::show-value-p :type boolean + :initform nil + :initarg :show-value-p + :accessor climi::gadget-show-value-p) + (climi::decimal-places :initform 0 + :initarg :decimal-places + :reader climi::slider-decimal-places) + (climi::number-of-quanta :initform nil + :initarg :number-of-quanta + :reader climi::slider-number-of-quanta))) +(defclass gtk-vscale (native-slider) ()) +(defclass gtk-hscale (native-slider) ()) + +(defclass native-scrollbar (native-widget-mixin scroll-bar) ()) +(defclass gtk-vscrollbar (native-scrollbar) ()) +(defclass gtk-hscrollbar (native-scrollbar) ())
;;;; Constructors @@ -51,7 +62,9 @@ button))
(defmethod realize-native-widget ((sheet gtk-check-button)) - (gtk_check_button_new_with_label (climi::gadget-label sheet))) + (let ((widget (gtk_check_button_new_with_label (climi::gadget-label sheet)))) + (gtk_toggle_button_set_active widget (if (gadget-value sheet) 1 0)) + widget))
(defun make-scale (fn sheet) (let* ((min (df (gadget-min-value sheet))) @@ -61,6 +74,8 @@ (gtk_scale_set_digits widget (climi::slider-decimal-places sheet)) (gtk_scale_set_draw_value widget (if (climi::gadget-show-value-p sheet) 1 0)) + (gtk_adjustment_set_value (gtk_range_get_adjustment widget) + (df (gadget-value sheet))) widget))
(defmethod realize-native-widget ((sheet gtk-vscale)) @@ -72,10 +87,9 @@ (defun make-scrollbar (fn sheet) (let* ((min (df (gadget-min-value sheet))) (max (df (gadget-max-value sheet))) - (l (- max min)) - (adjustment - ;; FIXME! - (gtk_adjustment_new 0.0d0 min max (/ l 100) (/ l 10) l))) + (page-size (df (climi::scroll-bar-thumb-size sheet))) + (adjustment (gtk_adjustment_new 0.0d0 min max 0.0d0 0.0d0 page-size))) + (gtk_adjustment_set_value adjustment (df (gadget-value sheet))) (funcall fn adjustment)))
(defmethod realize-native-widget ((sheet gtk-vscrollbar)) @@ -89,74 +103,108 @@ (some #'sheet-direct-mirror (sheet-children (gadget-client sheet)))) (group (if first (gtk_radio_button_get_group (mirror-widget first)) - (cffi:null-pointer)))) - (gtk_radio_button_new_with_label group (climi::gadget-label sheet)))) + (cffi:null-pointer))) + (result + (gtk_radio_button_new_with_label group (climi::gadget-label sheet)))) + (gtk_toggle_button_set_active + result + (if (eq sheet (gadget-value (gadget-client sheet))) 1 0)) + result))
;;;; Event definition
(defmethod connect-native-signals ((sheet native-widget-mixin) widget) - (connect-signal widget "clicked" 'clicked-handler)) + (connect-signal widget "clicked" 'magic-clicked-handler))
-(defmethod connect-native-signals ((sheet gtk-vscale) widget) - (connect-signal widget "value-changed" 'clicked-handler)) +(defmethod connect-native-signals ((sheet native-slider) widget) + (connect-signal widget "value-changed" 'magic-clicked-handler))
-(defmethod connect-native-signals ((sheet gtk-hscale) widget) - (connect-signal widget "value-changed" 'clicked-handler)) - -(defmethod connect-native-signals ((sheet gtk-vscrollbar) widget) - (connect-signal widget "value-changed" 'clicked-handler)) - -(defmethod connect-native-signals ((sheet gtk-hscrollbar) widget) - (connect-signal widget "value-changed" 'clicked-handler)) +(defmethod connect-native-signals ((sheet native-scrollbar) widget) + ;; (connect-signal widget "value-changed" 'magic-clicked-handler) + (connect-signal widget "change-value" 'scrollbar-change-value-handler))
;;;; Event handling
-(defmethod handle-event ((pane gtk-button) (event gadget-event)) +(defmethod handle-event ((pane gtk-button) (event magic-gadget-event)) (activate-callback pane (gadget-client pane) (gadget-id pane)))
-(defmethod handle-event ((pane gtk-check-button) (event gadget-event)) +(defmethod handle-event ((pane gtk-check-button) (event magic-gadget-event)) (setf (gadget-value pane :invoke-callback t) (not (gadget-value pane))))
-(defmethod handle-event ((pane gtk-radio-button) (event gadget-event)) +(defmethod handle-event ((pane gtk-radio-button) (event magic-gadget-event)) (setf (gadget-value pane :invoke-callback t) (not (gadget-value pane))))
-(defmethod handle-event ((pane gtk-vscale) (event gadget-event)) - (setf (gadget-value pane :invoke-callback t) - (gtk_range_get_value (mirror-widget (sheet-direct-mirror pane))))) - -(defmethod handle-event ((pane gtk-hscale) (event gadget-event)) +(defmethod handle-event ((pane native-slider) (event magic-gadget-event)) (setf (gadget-value pane :invoke-callback t) (gtk_range_get_value (mirror-widget (sheet-direct-mirror pane)))))
-(defmethod handle-event ((pane gtk-vscrollbar) (event gadget-event)) +(defmethod handle-event ((pane native-scrollbar) (event magic-gadget-event)) (setf (gadget-value pane :invoke-callback t) (gtk_range_get_value (mirror-widget (sheet-direct-mirror pane)))))
-(defmethod handle-event ((pane gtk-hscrollbar) (event gadget-event)) - (setf (gadget-value pane :invoke-callback t) - (gtk_range_get_value (mirror-widget (sheet-direct-mirror pane))))) +(defun clamp (low x hi) + (min (max low x) hi))
+(defmethod handle-event + ((pane native-scrollbar) (event scrollbar-change-value-event)) + (case (event-scroll-type event) + (:jump + (let ((value + (clamp (gadget-min-value pane) + (event-value event) + (gadget-max-value pane)))) + (setf (gadget-value pane :invoke-callback nil) value) + (drag-callback pane (gadget-client pane) (gadget-id pane) value))) + (:step_backward + (scroll-up-line-callback pane (gadget-client pane) (gadget-id pane))) + (:step_forward + (scroll-down-line-callback pane (gadget-client pane) (gadget-id pane))) + (:page_backward + (scroll-up-page-callback pane (gadget-client pane) (gadget-id pane))) + (:page_forward + (scroll-down-page-callback pane (gadget-client pane) (gadget-id pane)))))
-;;; Workarounds +;;; COMPOSE-SPACE
-(defmethod handle-repaint ((pane native-widget-mixin) region) - (declare (ignore region)) - ;; siehe oben - ) +;; KLUDGE: this is getting called before the sheet has been realized. +(defmethod compose-space ((gadget native-widget-mixin) &key width height) + (declare (ignore width height)) + (let* ((widget (native-widget gadget)) + (widgetp widget)) + (unless widgetp + (setf widget (realize-native-widget gadget))) + (prog1 + (cffi:with-foreign-object (r 'gtkrequisition) + (gtk_widget_size_request widget r) + (cffi:with-foreign-slots ((width height) r gtkrequisition) + (make-space-requirement :width width :height height))) + (unless widgetp + (gtk_widget_destroy widget)))))
;;; Vermischtes
(defmethod (setf gadget-value) :after + (value (gadget native-slider) &key invoke-callback) + (declare (ignore invoke-callback)) + (with-gtk () + (let ((mirror (sheet-direct-mirror gadget))) + (when mirror + ;; see hack in magic-clicked-handler + (gtk_adjustment_set_value + (gtk_range_get_adjustment (mirror-widget mirror)) + (df value)))))) + +(defmethod (setf gadget-value) :after (value (gadget gtk-radio-button) &key invoke-callback) (declare (ignore invoke-callback)) (with-gtk () (let ((mirror (sheet-direct-mirror gadget))) (when mirror - ;; see hack in clicked-handler + ;; see hack in magic-clicked-handler (gtk_toggle_button_set_active (mirror-widget mirror) (if value 1 0))))))
@@ -166,21 +214,47 @@ (with-gtk () (let ((mirror (sheet-direct-mirror gadget))) (when mirror - ;; see hack in clicked-handler + ;; see hack in magic-clicked-handler (gtk_toggle_button_set_active (mirror-widget mirror) (if value 1 0))))))
-;; KLUDGE: this is getting called before the sheet has been realized. -(defmethod compose-space ((gadget native-widget-mixin) &key width height) - (declare (ignore width height)) - (let* ((widget (native-widget gadget)) - (widgetp widget)) - (unless widgetp - (setf widget (realize-native-widget gadget))) - (prog1 - (cffi:with-foreign-object (r 'gtkrequisition) - (gtk_widget_size_request widget r) - (cffi:with-foreign-slots ((width height) r gtkrequisition) - (make-space-requirement :width width :height height))) - (unless widgetp - (gtk_widget_destroy widget))))) + +;;; Scroll bars. + +;; This is all totally broken. Why does thumb-size default to 1/4 when it's +;; not a ratio but given in value units? Why is min==max all the time? +;; And why doesn't this work! :-( +(defun update-scrollbar-adjustment (sheet) + (with-gtk () + (let* ((min (df (gadget-min-value sheet))) + (max (df (gadget-max-value sheet))) + (value (df (gadget-value sheet))) + (page-size (df (climi::scroll-bar-thumb-size sheet)))) + (gtk_range_set_adjustment + (mirror-widget (sheet-direct-mirror sheet)) + (gtk_adjustment_new value min max 0.0d0 0.0d0 page-size))))) + +(defmethod (setf gadget-min-value) :after (new-value (pane native-scrollbar)) + (declare (ignore new-value)) + (update-scrollbar-adjustment pane)) + +(defmethod (setf gadget-max-value) :after (new-value (pane native-scrollbar)) + (declare (ignore new-value)) + (update-scrollbar-adjustment pane)) + +(defmethod (setf gadget-value) + :after (new-value (pane native-scrollbar) &key invoke-callback) + (declare (ignore new-value invoke-callback)) + (update-scrollbar-adjustment pane)) + +(climi::defmethod* (setf climi::scroll-bar-values) + (min-value max-value thumb-size value (scroll-bar native-scrollbar)) + (setf (slot-value scroll-bar 'climi::min-value) min-value + (slot-value scroll-bar 'climi::max-value) max-value + (slot-value scroll-bar 'climi::thumb-size) thumb-size + (slot-value scroll-bar 'climi::value) value) + (update-scrollbar-adjustment scroll-bar)) + +(defmethod port-set-mirror-region :after + ((port gtkairo-port) (mirror native-scrollbar) mirror-region) + (update-scrollbar-adjustment (widget->sheet (mirror-widget mirror) port))) --- /project/mcclim/cvsroot/mcclim/Backends/gtkairo/gtk-ffi.lisp 2006/04/23 10:18:45 1.3 +++ /project/mcclim/cvsroot/mcclim/Backends/gtkairo/gtk-ffi.lisp 2006/04/23 17:36:28 1.4 @@ -261,6 +261,11 @@ :copy :invert :xor :clear :and :and_reverse :and_invert :noop :or :equiv :or_reverse :copy_invert :or_invert :nand :nor :set)
+(cffi:defcenum gtkscrolltype + :none :jump :step_backward :step_forward :page_backward :page_forward + :step_up :step_down :page_up :page_down :step_left :step_right :page_left + :page_right :start :end) +
;;; GTK functions
@@ -633,10 +638,20 @@ :pointer (range :pointer))
+(defcfun "gtk_range_set_adjustment" + :void + (range :pointer) + (adjustment :pointer)) + (defcfun "gtk_adjustment_get_value" :double (range :pointer))
+(defcfun "gtk_adjustment_set_value" + :void + (adjustment :pointer) + (value :double)) + (defcfun "gtk_adjustment_new" :pointer (value :double) --- /project/mcclim/cvsroot/mcclim/Backends/gtkairo/medium.lisp 2006/04/23 10:42:39 1.4 +++ /project/mcclim/cvsroot/mcclim/Backends/gtkairo/medium.lisp 2006/04/23 17:36:28 1.5 @@ -708,22 +708,25 @@ (text-style-height text-style (metrik-medium (port medium))))
(defmethod text-style-height (text-style (medium metrik-medium)) - (with-cairo-medium (medium) - (ceiling - (with-slots (cr) medium - (sync-sheet medium) - (cairo_identity_matrix cr) - (sync-text-style medium text-style t) - (cffi:with-foreign-object (res 'cairo_font_extents) - (cairo_font_extents cr res) - ;; ### let's hope that cairo respects - ;; height = ascent + descent. - ;; - ;; No, it expressly doesn't. Cairo documentation states that - ;; height includes additional space that is meant to give more - ;; aesthetic line spacing than ascent+descent would. Is that a - ;; problem for us? --DFL - (slot res 'cairo_font_extents 'height)))))) +;;; (with-cairo-medium (medium) +;;; (ceiling +;;; (with-slots (cr) medium +;;; (sync-sheet medium) +;;; (cairo_identity_matrix cr) +;;; (sync-text-style medium text-style t) +;;; (cffi:with-foreign-object (res 'cairo_font_extents) +;;; (cairo_font_extents cr res) +;;; ;; ### let's hope that cairo respects +;;; ;; height = ascent + descent. +;;; ;; +;;; ;; No, it expressly doesn't. Cairo documentation states that +;;; ;; height includes additional space that is meant to give more +;;; ;; aesthetic line spacing than ascent+descent would. Is that a +;;; ;; problem for us? --DFL +;;; (slot res 'cairo_font_extents 'height))))) + ;; OK, so it _does_ matter (see bug 15). + (+ (text-style-ascent text-style medium) + (text-style-descent text-style medium)))
;;; TEXT-STYLE-WIDTH