File: image-viewer.lisp

package info (click to toggle)
cl-mcclim 0.9.6.dfsg.cvs20100315-1
  • links: PTS
  • area: main
  • in suites: squeeze, wheezy
  • size: 6,624 kB
  • ctags: 13,512
  • sloc: lisp: 106,015; makefile: 47; sh: 15
file content (112 lines) | stat: -rw-r--r-- 4,834 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
;;; -*- Mode: Lisp; Package: CLIM-DEMO -*-

;;;  (c) copyright 2008 by
;;;           Troels Henriksen (athas@sigkill.dk)

;;; This library is free software; you can redistribute it and/or
;;; modify it under the terms of the GNU Library General Public
;;; License as published by the Free Software Foundation; either
;;; version 2 of the License, or (at your option) any later version.
;;;
;;; This library is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
;;; Library General Public License for more details.
;;;
;;; You should have received a copy of the GNU Library General Public
;;; License along with this library; if not, write to the
;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;;; Boston, MA  02111-1307  USA.

;;; A simple program for displaying images of formats known to McCLIM.

(in-package :clim-demo)

(defclass image-viewer-gadget (value-gadget)
  ()
  (:documentation "An abstract gadget for displaying images. The
value of the gadget is the image being displayed.")
  (:default-initargs :value nil))

(defmethod (setf gadget-value) :after (new-value (gadget image-viewer-gadget)
                                                 &key &allow-other-keys)
  (handle-repaint gadget (or (pane-viewport-region gadget)
                             (sheet-region gadget))))

(defclass image-viewer-pane (image-viewer-gadget basic-gadget)
  ()
  (:documentation "A concrete gadget for displaying images. The
value of the gadget is the image being displayed."))

(defmethod handle-repaint ((pane image-viewer-pane) region)
  (declare (ignore region))
  ;; Clear the old image.
  (with-bounding-rectangle* (x1 y1 x2 y2) (sheet-region pane)    
    (draw-rectangle* (sheet-medium pane) x1 y1 x2 y2 :ink +background-ink+))
  ;; Draw the new one, if there is one.
  (when (gadget-value pane)
    (let ((image-height (pattern-height (gadget-value pane)))
          (image-width (pattern-width (gadget-value pane))))
      ;; Try to ensure there is room for the new image.
      (change-space-requirements pane :height image-height :width image-width)
      ;; Draw it in the center.
      (handler-case (draw-pattern*
                     pane (gadget-value pane)
                     (/ (- (bounding-rectangle-width pane) image-width)
                        2)
                     (/ (- (bounding-rectangle-height pane) image-height)
                        2))
        (error ()
          (with-text-style (pane (make-text-style nil :italic nil))
            (draw-text* pane (format nil "Error while drawing image")
                        0 0 :align-y :top)))))))

(define-application-frame image-viewer ()
  ((%image-pathname :accessor image-pathname
                    :initarg :image-pathname
                    :initform nil))
  (:menu-bar t)
  (:panes
   (viewer (make-pane 'image-viewer-pane))
   (interactor :interactor
               :text-style (make-text-style :sans-serif nil nil)
               :min-height 100))
  (:layouts
   (default (vertically ()
              (4/5 (labelling (:label "Image")
                     viewer))
              (1/5 interactor))))
  (:top-level ((lambda (frame)
                 (default-frame-top-level frame)))))

(define-image-viewer-command (com-display-image :name t :menu t)
    ((image-pathname 'pathname
      :default (user-homedir-pathname) :insert-default t))
  (if (probe-file image-pathname)
      (let* ((type (funcall (case (readtable-case *readtable*)
                              (:upcase #'string-upcase)
                              (:downcase #'string-downcase)
                              (t #'identity))
                            (pathname-type image-pathname)))
             (format (find-symbol type (find-package :keyword)))
             (viewer (find-pane-named *application-frame* 'viewer)))
        (handler-case (progn
                        (setf (gadget-value viewer)
                              (make-pattern-from-bitmap-file image-pathname :format format)
                              (image-pathname *application-frame*) image-pathname)
                        (format t "~A image loaded succesfully" type))
          (unsupported-bitmap-format ()
            (format t "Image format ~A not recognized" type))))
      (format t "No such file: ~A" image-pathname)))

(define-image-viewer-command (com-blank-image :name t :menu t)
    ()
  (setf (gadget-value (find-pane-named *application-frame* 'viewer)) nil))

(defun image-viewer (&key (new-process t))
  (flet ((run ()
           (let ((frame (make-application-frame 'image-viewer)))
             (run-frame-top-level frame))))
    (if new-process
        (clim-sys:make-process #'run :name "Image viewer")
        (run))))