Re: Subclasses
Espen S Johnsen <[email protected]> 07 Feb 2006 00:14:05 +0100
| Newsgroups | gmane.lisp.clg.devel |
|---|---|
| Message-ID | <[email protected]> |
Espen S Johnsen <[email protected]> writes: > And then about subclassing... With the code in CVS it is now possible to > do subclassing without explicit registering the type with the gobject > system first. Adding slots with instance allocation should work as > expected (but gtk 2.8 is recommended when doing this). It is still not > possible to specialize on gtk "methods" but many methods where this > would be useful, just emit a signal. So by overriding default class > signal handlers, it should be possible to customize the behavior of > subclasses. I've added a macro to do this, with the following syntax: > > (define-signal-handler signal-name ((object class) &rest args) > (do-something) > (call-next-handler) > (do-more)) > > Call-next-handler is more or less equivalent to call-next-method in > standard methods. I found an article¹ about writing custom widgets in Pyton and decided to write the example in Lisp. It is not very advanced, but it could easily be extended to do something more useful. The next article is promised to do that. Anyway here is the example (it requires the latest code which may not propagate into anonymous CVS until a few hours²): (defclass egg-clock-face (drawing-area) (cr) (:metaclass gobject-class)) (define-signal-handler expose-event ((clock egg-clock-face) event) (unless (slot-boundp clock 'cr) (setf (slot-value clock 'cr) (gdk:cairo-create (widget-window clock)))) (with-slots (cr) clock (cairo:with-context (cr) (with-slots (gdk:x gdk:y gdk:width gdk:height) event (cairo:rectangle cr gdk:x gdk:y gdk:width gdk:height)) (cairo:clip cr) (multiple-value-bind (width height) (widget-get-size-allocation clock) (let* ((x (/ width 2)) (y (/ height 2)) (radius (- (min (/ width 2) (/ height 2)) 5))) (cairo:circle cr x y radius) (cairo:set-source-color cr 1.0 1.0 1.0) (cairo:fill cr t) (cairo:set-source-color cr 0 0 0) (cairo:stroke cr) (loop for tick from 0 below 12 do (cairo:with-context (cr) (let ((inset (if (zerop (mod tick 3)) (* 0.2 radius) (progn (setf (cairo:line-width cr) (* 0.5 (cairo:line-width cr))) (* 0.1 radius))))) (cairo:move-to cr (+ x (* (- radius inset) (cos (* tick (/ pi 6))))) (+ y (* (- radius inset) (sin (* tick (/ pi 6)))))) (cairo:line-to cr (+ x (* radius (cos (* tick (/ pi 6))))) (+ y (* radius (sin (* tick (/ pi 6)))))) (cairo:stroke cr)))))))) nil) #+sbcl(sb-int:set-floating-point-modes :traps nil) #+cmu(ext:set-floating-point-modes :traps nil) (make-instance 'window :child (make-instance 'egg-clock-face :visible t) :visible t) ¹http://www.pygtk.org/articles/cairo-pygtk-widgets/cairo-pygtk-widgets.htm ²A work around would be to do (make-instance 'egg-clock-face) before defining the signal handler -- Espen ------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Do you grep through log files for problems? Stop! Download the new AJAX search engine that makes searching your log files as easy as surfing the web. DOWNLOAD SPLUNK! http://sel.as-us.falkag.net/sel?cmd=lnk&kid3432&bid#0486&dat1642