Use C++ style overload resolution.
Annotate for file src/mandelbrot/mandelbrotwidget.lisp
2009-04-14 tobias 1 ;;; Copyright (C) 2009 Tobias Rautenkranz <tobias@rautenkranz.ch>
14:32:06 ' 2 ;;;
' 3 ;;; This program is free software: you can redistribute it and/or modify
' 4 ;;; it under the terms of the GNU General Public License as published by
' 5 ;;; the Free Software Foundation, either version 3 of the License, or
' 6 ;;; (at your option) any later version.
' 7 ;;;
' 8 ;;; This program is distributed in the hope that it will be useful,
' 9 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
' 10 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
' 11 ;;; GNU General Public License for more details.
' 12 ;;;
' 13 ;;; You should have received a copy of the GNU General Public License
' 14 ;;; along with this program. If not, see <http://www.gnu.org/licenses/>.
' 15
2010-04-03 tobias 16 (in-package :kde.examples)
17:19:09 ' 17 (declaim (optimize (debug 3)))
2009-04-02 tobias 18
22:16:06 ' 19 (defun zoom-in-factor ()
' 20 0.8)
' 21
' 22 (defun zoom-out-factor ()
' 23 (/ (zoom-in-factor)))
' 24
' 25 (defclass mandelbrotwidget (qt:widget)
' 26 ((pixmap :accessor pixmap :initform nil)
' 27 (pixmap-scale :accessor pixmap-scale)
' 28 (pixmap-offset :accessor pixmap-offset)
' 29 (center :accessor center :initform #C(-0.5d0 0d0))
' 30 (scale :accessor scale :initform 0.007d0)
' 31 (update-pixmap-slot :accessor update-pixmap-slot)
' 32 (render :accessor render-thread)
' 33 (last-drag-pos :accessor last-drag-pos :initform nil))
' 34 (:metaclass cxx:class))
' 35
' 36 (defun update-pixmap (mandelbrotwidget image scale)
' 37 (when (null (last-drag-pos mandelbrotwidget))
' 38 (setf (pixmap mandelbrotwidget)
' 39 (qt:pixmap.from-image image))
' 40 (setf (pixmap-offset mandelbrotwidget) #c(0 0))
' 41 (setf (pixmap-scale mandelbrotwidget) scale)
' 42 (cxx:update mandelbrotwidget)))
' 43
' 44 (defparameter *render-control* (make-instance 'render-control))
' 45 (defun setup-slot (mandelbrotwidget)
' 46 (setf (update-pixmap-slot mandelbrotwidget)
' 47 (qt:make-slot #'(lambda (image scale)
' 48 (update-pixmap mandelbrotwidget image scale))
' 49 (mapcar #'find-class
' 50 '(qt:image double-float))))
' 51 (qt:connect (done-signal *render-control*)
' 52 (update-pixmap-slot mandelbrotwidget)
' 53 qt:+queued-connection+))
' 54
' 55 (defun draw-rendering (painter widget)
2009-04-17 tobias 56 (cxx:set-pen painter #xFFFFFF) ;; FIXME make qt:+white+ work
2009-04-02 tobias 57 (cxx:draw-text painter (cxx:rect widget)
22:16:06 ' 58 (value qt:+align-center+)
' 59 "Rendering initial image, please wait..."))
' 60
' 61 (defun complex-floor (complex)
' 62 "Applys FLOOR to the real and imaginary part of COMPLEX."
' 63 (complex (floor (realpart complex)
' 64 (imagpart complex))))
' 65
' 66 (defun draw-scaled-pixmap (painter widget)
' 67 (cxx:save painter) ;; FIXME make with- macro
' 68 (let* ((scale-factor (/ (pixmap-scale widget)
' 69 (scale widget)))
' 70 (pixmap-size (complex (cxx:width (pixmap widget))
' 71 (cxx:height (pixmap widget))))
' 72 (new-size (* scale-factor pixmap-size))
' 73 (new-center (+ (pixmap-offset widget) (/ (- pixmap-size new-size) 2))))
' 74 (cxx:translate painter (realpart new-center) (imagpart new-center))
' 75 (cxx:scale painter scale-factor scale-factor)
' 76 (let ((exposed (cxx:adjusted (cxx:map-rect (cxx:inverted (cxx:matrix painter))
' 77 (cxx:rect widget))
' 78 -1 -1 1 1)))
' 79 (cxx:draw-pixmap painter exposed (pixmap widget) exposed)))
' 80 (cxx:restore painter))
' 81
' 82
' 83 (defun draw-pixmap (painter widget)
' 84 (if (= (scale widget) (pixmap-scale widget))
' 85 (cxx:draw-pixmap painter
' 86 (floor (realpart (pixmap-offset widget)))
' 87 (floor (imagpart (pixmap-offset widget)))
' 88 (pixmap widget))
' 89 (draw-scaled-pixmap painter widget)))
' 90
2009-04-12 tobias 91 (defmethod cxx:paint-event ((widget mandelbrotwidget) event)
13:34:59 ' 92 (declare (ignore event))
2009-04-02 tobias 93 (qt:with-painter (painter widget)
22:16:06 ' 94 (cxx:fill-rect painter (cxx:rect widget)
2009-04-17 tobias 95 #x000) ;; FIXME qt:+black+
2009-04-02 tobias 96 (if (null (pixmap widget))
22:16:06 ' 97 (draw-rendering painter widget)
' 98 (draw-pixmap painter widget))))
' 99
2009-04-12 tobias 100 (defmethod cxx:resize-event ((widget mandelbrotwidget) event)
13:34:59 ' 101 (declare (ignore event))
2009-04-02 tobias 102 (when (slot-boundp widget 'render)
22:16:06 ' 103 (setf (stop-p *render-control*) t)
' 104 (join-thread (slot-value widget 'render)))
' 105 (queue-image widget))
' 106
2009-04-12 tobias 107 (defmethod cxx:key-press-event ((widget mandelbrotwidget) event)
2009-04-02 tobias 108 (enum-cases (cxx:key event)
22:16:06 ' 109 (qt:+key-up+
' 110 (scroll widget #C(0d0 -5d0)))
' 111 (qt:+key-down+
' 112 (scroll widget #C(0d0 5d0)))
' 113 (qt:+key-left+
' 114 (scroll widget #C(-5d0 0d0)))
' 115 (qt:+key-right+
' 116 (scroll widget #C(5d0 0d0)))
' 117 (qt:+key-plus+
' 118 (zoom widget (zoom-in-factor)))
' 119 (qt:+key-minus+
' 120 (zoom widget (zoom-out-factor)))))
' 121
2009-04-12 tobias 122 (defmethod cxx:mouse-press-event ((widget mandelbrotwidget) event)
2009-04-02 tobias 123 (when (enum= (cxx:button event) qt:+left-button+)
22:16:06 ' 124 (setf (last-drag-pos widget) (complex (cxx:x event)
' 125 (cxx:y event)))))
' 126
2009-04-12 tobias 127 (defmethod cxx:wheel-event ((widget mandelbrotwidget) event)
2009-04-02 tobias 128 (zoom widget (expt (zoom-in-factor) (/ (cxx:delta event) (* 8 15.0)))))
22:16:06 ' 129
2009-04-12 tobias 130 (defmethod cxx:mouse-move-event ((widget mandelbrotwidget) event)
2010-04-03 tobias 131 (when (logand (cxx:buttons event) (value qt:+left-button+))
2009-04-02 tobias 132 (incf (pixmap-offset widget)
22:16:06 ' 133 (- (complex (cxx:x event)
' 134 (cxx:y event))
' 135 (last-drag-pos widget)))
' 136 (setf (last-drag-pos widget) (complex (cxx:x event)
' 137 (cxx:y event)))
' 138 (cxx:update widget)))
' 139
2009-04-12 tobias 140 (defmethod cxx:mouse-release-event ((widget mandelbrotwidget) event)
2009-04-02 tobias 141 (when (enum= (cxx:button event) qt:+left-button+)
22:16:06 ' 142 (incf (pixmap-offset widget)
' 143 (- (complex (cxx:x event)
' 144 (cxx:y event))
' 145 (last-drag-pos widget)))
' 146 (setf (last-drag-pos widget) nil)
' 147 (let ((pixmap-size (complex (cxx:width (pixmap widget))
' 148 (cxx:height (pixmap widget))))
' 149 (size (complex (cxx:width widget)
' 150 (cxx:height widget))))
' 151 (scroll widget (- (/ (- size pixmap-size) 2) (pixmap-offset widget))))))
' 152
' 153 (defun queue-image (widget)
' 154 (setf (stop-p *render-control*) nil)
' 155 ;; FIXME do not creating a new thread on every invokation
' 156 (setf (render-thread widget)
' 157 (make-thread (make-render-function (center widget)
' 158 (scale widget)
' 159 (cxx:width widget)
' 160 (cxx:height widget)
' 161 *render-control*))))
' 162
' 163 (defun zoom (widget factor)
' 164 (setf (scale widget) (* (scale widget) factor))
' 165 (cxx:update widget)
' 166 (queue-image widget))
' 167
' 168 (defun scroll (widget delta)
' 169 (incf (center widget) (* (scale widget) delta))
' 170 (cxx:update widget)
' 171 (queue-image widget))