]> git.donarmstrong.com Git - lilypond.git/blob - scm/framework-gnome.scm
(<gnome-outputter>): New class.
[lilypond.git] / scm / framework-gnome.scm
1 ;;;; framework-gnome.scm --
2 ;;;;
3 ;;;;  source file of the GNU LilyPond music typesetter
4 ;;;; 
5 ;;;; (c)  2004 Jan Nieuwenhuizen <janneke@gnu.org>
6
7 (define-module (scm framework-gnome)
8   :use-module (oop goops)
9   #:export (<gnome-outputter>))
10
11 ;;(define this-module (current-module))
12
13 (use-modules (guile) (oop goops) (lily))
14
15 (use-modules
16  (gnome gtk)
17  (gnome gtk gdk-event)
18  ;;
19 ;; (scm output-gnome)
20  )
21  
22 ;; the name of the module will change to canvas rsn
23 (if (resolve-module '(gnome gw canvas))
24     (use-modules (gnome gw canvas))
25     (use-modules (gnome gw libgnomecanvas)))
26
27 (define SCROLLBAR-SIZE 20)
28 (define BUTTON-HEIGHT 25)
29 (define PANELS-HEIGHT 80)
30
31 (define PIXELS-PER-UNIT 2)
32 (define OUTPUT-SCALE (* 2.5 PIXELS-PER-UNIT))
33
34 ;; helper functions -- sort this out
35 (define (stderr string . rest)
36   ;; debugging
37   (if #t
38       (begin
39         (apply format (cons (current-error-port) (cons string rest)))
40         (force-output (current-error-port)))))
41
42
43 ;; Hmm, actually, the only vars really needed by output-gnome are
44 ;; * (root (canvas go))
45 ;; * location
46 ;; * item-locations
47 ;; * pixels-per-unit
48 ;; * text-items
49 ;;
50 ;; so this class could be split in two parts / records?
51 (define-class <gnome-outputter> ()
52   (page-stencils ;;#:init-value '#()
53    #:init-keyword #:page-stencils #:accessor page-stencils)
54   (window #:init-value (make <gtk-window> #:type 'toplevel) #:accessor window)
55   (scrolled #:init-value (make <gtk-scrolled-window>) #:accessor scrolled)
56   (canvas #:init-value #f #:accessor canvas)
57   (page-number #:init-value 0 #:accessor page-number)
58   (pixels-per-unit #:init-value PIXELS-PER-UNIT #:accessor pixels-per-unit)
59   (text-items #:init-value '() #:accessor text-items)
60   (location #:init-value #:f #:accessor location)
61   (item-locations #:init-value (make-hash-table 31) #:accessor item-locations)
62   (window-width #:init-keyword #:window-width #:accessor window-width)
63   (window-height #:init-keyword #:window-height #:accessor window-height)
64   (canvas-width #:init-keyword #:canvas-width #:accessor canvas-width)
65   (canvas-height #:init-keyword #:canvas-height #:accessor canvas-height))
66
67 ;;(define-method (initialize (go <gnome-outputter>))
68 ;; )
69
70 (define (setup go)
71   (let* ((button (make <gtk-button> #:label "Exit"))
72          (next (make <gtk-button> #:label "Next"))
73          (prev (make <gtk-button> #:label "Previous"))
74          (vbox (make <gtk-vbox> #:homogeneous #f))
75          (hbox (make <gtk-hbox> #:homogeneous #f)))
76
77     (set-size-request (window go) (window-width go) (window-height go))
78
79     (new-canvas go)
80
81     (add (window go) vbox)
82     (add vbox (scrolled go))
83     
84     (add (scrolled go) (canvas go))
85
86     ;; buttons
87     (add vbox hbox)
88     (set-size-request hbox (window-width go) BUTTON-HEIGHT)
89
90     ;; hmm?
91     ;;(set-child-packing vbox hbox #f #f 0 'end)
92     ;;(set-child-packing hbox button #f #f 0 'end)
93     
94     (set-size-request button (quotient (window-width go) 2) BUTTON-HEIGHT)
95     (add hbox next)
96     (add hbox prev)
97     (add hbox button)
98
99     ;; signals
100     (gtype-instance-signal-connect
101      button 'clicked (lambda (b) (gtk-main-quit)))
102     (gtype-instance-signal-connect
103      next 'clicked (lambda (b) (dump-page go (1+ (page-number go)))))
104     (gtype-instance-signal-connect
105      prev 'clicked (lambda (b) (dump-page go (1- (page-number go)))))
106     (gtype-instance-signal-connect
107      (window go) 'key-press-event key-press-event)
108     
109     (show-all (window go))))
110
111
112 (define-public (output-framework-gnome outputter book scopes fields basename)
113   (let* ((book-paper (ly:paper-book-book-paper book))
114          
115          (hsize (ly:output-def-lookup book-paper 'hsize))
116          (vsize (ly:output-def-lookup book-paper 'vsize))
117          (page-width (inexact->exact (ceiling (* OUTPUT-SCALE hsize))))
118          (page-height (inexact->exact (ceiling (* OUTPUT-SCALE vsize))))
119          ;;(page-width (inexact->exact (ceiling hsize)))
120          ;;(page-height (inexact->exact (ceiling vsize)))
121
122          (screen-width (gdk-screen-width))
123          (screen-height (gdk-screen-height))
124          (desktop-height (- screen-height PANELS-HEIGHT))
125
126          (go (make <gnome-outputter>
127                #:page-stencils (list->vector (ly:paper-book-pages book))
128                #:canvas-width page-width
129                #:canvas-height page-height
130                #:window-width
131                ;; huh, *2 -- pixels-per-unit?
132                (min (+ SCROLLBAR-SIZE (* page-width 2)) screen-width)
133                #:window-height
134                (min (+ BUTTON-HEIGHT SCROLLBAR-SIZE (* page-height 2))
135                     desktop-height))))
136
137     (setup go)
138     (dump-page go 0)
139     (gtk-main)))
140
141
142 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
143 ;;;; gnome stuff  --- move to framework-gnome
144 ;;(define (dump-page (go <gnome-outputter>) number)
145
146 (define output-gnome-module
147   (make-module 1021 (list (resolve-interface '(scm output-gnome)))))
148
149 (define-public (gnome-output-expression go expr)
150   (stderr "HI\n")
151   (let ((m output-gnome-module))
152
153     ;; this does not seem to work?
154     ;;/home/janneke/cvs/savannah/lilypond/lilypond/share/lilypond/scm/output-gnome.scm:267:27: While evaluating arguments to canvas in expression (canvas go):
155     ;;/home/janneke/cvs/savannah/lilypond/lilypond/share/lilypond/scm/output-gnome.scm:267:27: Unbound variable: go
156
157     (module-define! m 'go go)
158
159     (eval expr m)))
160
161
162
163 (define (dump-page go number)
164   (if (or (not (page-stencils go))
165           (< number 0)
166           (>= number (vector-length (page-stencils go))))
167       (stderr "No such page: ~S\n" (1+ number))
168       
169       (let ((old-canvas (canvas go)))
170         (new-canvas go)
171         (set! (page-number go) number)
172         
173         ;; no destroy method for gnome-canvas-text?
174         ;;(map destroy (gtk-container-get-children main-canvas))
175         ;;(map destroy text-items)
176
177         ;;Hmm
178         ;;(set! main-canvas canvas)
179         (set! (text-items go) '())
180         ;;(ly:outputter-dump-stencil output-canvas
181         ;;                         (vector-ref page-stencils page-number))
182         (stderr "page-stencil ~S: ~S\n"
183                 (page-number go)                
184                 (vector-ref (page-stencils go) (page-number go)))
185         
186         (ly:interpret-stencil-expression 
187          ;;(vector-ref (page-stencils go) (page-number go))
188          (ly:stencil-expr (vector-ref (page-stencils go) (page-number go)))
189          gnome-output-expression go '(0 . 0))
190         
191         (if old-canvas (destroy old-canvas))
192         (add (scrolled go) (canvas go))
193         (show (canvas go)))))
194
195 (define x-editor #f)
196 (define (get-x-editor)
197   (if (not x-editor)
198       (set! x-editor (getenv "XEDITOR")))
199   x-editor)
200
201 (define ifs #f)
202 (define (get-ifs)
203   (if (not ifs)
204       (set! ifs (getenv "IFS")))
205   (if (not ifs)
206       (set! ifs "       "))
207   ifs)
208       
209 (define (spawn-editor location)
210   (let* ((line (car location))
211          (column (cadr location))
212          (file-name (caddr location))
213          (template (substring (get-x-editor) 0))
214          
215          ;; Adhere to %l %c %f?
216          (command
217           (regexp-substitute/global
218            #f "%l" (regexp-substitute/global
219                     #f "%c"
220                     (regexp-substitute/global
221                      #f "%f" template 'pre file-name 'post)
222                     'pre (number->string column)
223                     'post)
224            'pre (number->string line) 'post)))
225     
226     (stderr "spawning: ~s\n" command)
227     (if (= (primitive-fork) 0)
228         (let ((command-list (string-split command #\ )));; (get-ifs))))
229           (apply execlp command-list)
230           (primitive-exit)))))
231           
232 (define location-callback spawn-editor)
233
234 (define (item-event item event . data)
235   (case (gdk-event:type event)
236     ((enter-notify) (gobject-set-property item 'fill-color "red"))
237     ((leave-notify) (gobject-set-property item 'fill-color "black"))
238     ((button-press)
239      (let ((location (hashq-ref item-locations item #f)))
240        (if location
241            (location-callback location)
242            (stderr "no location\n"))))
243     ((2button-press) (gobject-set-property item 'fill-color "red")))
244   #t)
245
246 (define (scale-canvas factor)
247   (set! pixels-per-unit (* pixels-per-unit factor))
248   (set-pixels-per-unit main-canvas pixels-per-unit)
249   (for-each
250    (lambda (x)
251      (let ((scale (gobject-get-property x 'scale))
252            (points (gobject-get-property x 'size-points)))
253        ;;(gobject-set-property x 'scale pixels-per-unit)
254        (gobject-set-property x 'size-points (* points factor))))
255      text-items))
256
257 (define (key-press-event item event . data)
258   (let ((keyval (gdk-event-key:keyval event))
259         (mods (gdk-event-key:modifiers event)))
260     (cond ((and (or (eq? keyval gdk:q)
261                     (eq? keyval gdk:w))
262                 (equal? mods '(control-mask modifier-mask)))
263            (gtk-main-quit))
264           ((and #t ;;(null? mods)
265                 (eq? keyval gdk:plus))
266            (scale-canvas 2))
267           ((and #t ;; (null? mods)
268                 (eq? keyval gdk:minus))
269            (scale-canvas 0.5))
270           ((or (eq? keyval gdk:Page-Up)
271                (eq? keyval gdk:BackSpace))
272            (dump-page (1- page-number)))
273           ((or (eq? keyval gdk:Page-Down)
274                (eq? keyval gdk:space))
275            (dump-page (1+ page-number))))
276     #f))
277
278 ;;(define (new-canvas go <gnome-outputter>)
279 (define (new-canvas go)
280   (set! (canvas go) (make <gnome-canvas>))
281   (set-size-request (canvas go) (window-width go) (window-height go))
282   (set-scroll-region (canvas go) 0 0 (canvas-width go) (canvas-height go))
283   (set-pixels-per-unit (canvas go) (pixels-per-unit go))
284   (make <gnome-canvas-rect>
285     #:parent (root (canvas go))
286     #:x2 (canvas-width go) #:y2 (canvas-height go)
287     #:fill-color "white"))
288