~ubuntu-branches/ubuntu/lucid/sawfish/lucid-updates

« back to all changes in this revision

Viewing changes to lisp/sawfish/ui/shell.jl

  • Committer: Bazaar Package Importer
  • Author(s): Christian Marillat
  • Date: 2002-01-20 17:42:28 UTC
  • Revision ID: james.westby@ubuntu.com-20020120174228-4q1ydztbkvfq1ht2
Tags: upstream-1.0.1.20020116
ImportĀ upstreamĀ versionĀ 1.0.1.20020116

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#| nokogiri-shell.jl -- shell displaying custom groups
 
2
 
 
3
   $Id: shell.jl,v 1.21 2001/09/08 06:55:05 jsh Exp $
 
4
 
 
5
   Copyright (C) 2000 John Harper <john@dcs.warwick.ac.uk>
 
6
 
 
7
   This file is part of sawfish.
 
8
 
 
9
   sawfish is free software; you can redistribute it and/or modify it
 
10
   under the terms of the GNU General Public License as published by
 
11
   the Free Software Foundation; either version 2, or (at your option)
 
12
   any later version.
 
13
 
 
14
   sawfish is distributed in the hope that it will be useful, but
 
15
   WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
   GNU General Public License for more details.
 
18
 
 
19
   You should have received a copy of the GNU General Public License
 
20
   along with sawfish; see the file COPYING.  If not, write to
 
21
   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 
22
|#
 
23
 
 
24
(define-structure sawfish.ui.shell
 
25
 
 
26
    (export initialize-shell
 
27
            destroy-shell
 
28
            run-shell)
 
29
 
 
30
    (open rep
 
31
          gui.gtk
 
32
          rep.system
 
33
          rep.regexp
 
34
          rep.io.files
 
35
          rep.io.timers
 
36
          sawfish.gtk.stock
 
37
          sawfish.gtk.widget
 
38
          sawfish.ui.group
 
39
          sawfish.ui.slot
 
40
          sawfish.ui.apply
 
41
          sawfish.ui.layout
 
42
          sawfish.ui.user-level
 
43
          sawfish.ui.config)
 
44
 
 
45
  (defvar *nokogiri-buttons* nil)
 
46
 
 
47
  (defvar *nokogiri-flatten-groups* nil)
 
48
  (defvar *nokogiri-single-level* nil)
 
49
 
 
50
  (define main-window)
 
51
  (define group-tree-widget)
 
52
  (define slot-box-widget)
 
53
 
 
54
  (define active-slots '())
 
55
 
 
56
  (define ok-widget)
 
57
  (define apply-widget)
 
58
  (define revert-widget)
 
59
  (define cancel-widget)
 
60
 
 
61
  (define (initialize-shell #!optional socket-id)
 
62
    (let ((vbox (gtk-vbox-new nil box-spacing))
 
63
          (hbox (gtk-hbutton-box-new))
 
64
          (s-scroller (and (not socket-id) (gtk-scrolled-window-new)))
 
65
          root-container)
 
66
 
 
67
      (setq main-window (if socket-id
 
68
                            (gtk-plug-new socket-id)
 
69
                          (gtk-window-new 'toplevel)))
 
70
      (if socket-id
 
71
          (progn
 
72
            (gtk-window-set-default-size main-window 400 300)
 
73
            (setq root-container main-window))
 
74
        (gtk-window-set-policy main-window nil t nil)
 
75
        (gtk-window-set-default-size main-window 550 400)
 
76
        (setq root-container (gtk-frame-new))
 
77
        (gtk-frame-set-shadow-type root-container 'out)
 
78
        (gtk-container-add main-window root-container))
 
79
 
 
80
      (setq slot-box-widget (gtk-vbox-new nil box-spacing))
 
81
 
 
82
      (gtk-container-border-width vbox box-border)
 
83
      (gtk-container-border-width slot-box-widget box-border)
 
84
      (when s-scroller
 
85
        (gtk-scrolled-window-set-policy s-scroller 'automatic 'automatic)
 
86
        (gtk-scrolled-window-add-with-viewport s-scroller slot-box-widget))
 
87
 
 
88
      (let ((group (get-group top-group)))
 
89
        (fetch-group group)
 
90
        (if (and (not *nokogiri-flatten-groups*)
 
91
                 (not *nokogiri-single-level*)
 
92
                 (group-sub-groups group))
 
93
            (let ((paned (gtk-hpaned-new))
 
94
                  (g-scroller (gtk-scrolled-window-new)))
 
95
              (setq group-tree-widget (make-group-tree (get-group top-group)))
 
96
              (gtk-container-border-width group-tree-widget box-border)
 
97
              (gtk-scrolled-window-set-policy g-scroller 'automatic 'automatic)
 
98
              (gtk-container-add vbox paned)
 
99
              (gtk-paned-add1 paned g-scroller)
 
100
              (gtk-paned-add2 paned (or s-scroller slot-box-widget))
 
101
              (gtk-paned-set-position paned 150)
 
102
              (gtk-scrolled-window-add-with-viewport g-scroller
 
103
                                                     group-tree-widget))
 
104
          (gtk-container-add vbox (or s-scroller slot-box-widget))))
 
105
 
 
106
      (unless socket-id
 
107
        (setq ok-widget (stock-button 'ok))
 
108
        (setq apply-widget (stock-button 'apply))
 
109
        (setq revert-widget (stock-button 'revert))
 
110
        (setq cancel-widget (stock-button 'cancel))
 
111
        (gtk-window-set-title main-window (_ "Sawfish configurator"))
 
112
        (gtk-widget-set-name main-window (_ "Sawfish configurator"))
 
113
        (gtk-window-set-wmclass main-window "main" "Nokogiri"))
 
114
 
 
115
      (gtk-signal-connect main-window "delete_event"
 
116
                          (if (not socket-id) on-quit capplet-delete-event))
 
117
 
 
118
      (unless socket-id
 
119
        (gtk-button-box-set-layout hbox 'end)
 
120
        (gtk-box-pack-end vbox hbox)
 
121
        (gtk-signal-connect ok-widget "clicked" on-ok)
 
122
        (gtk-signal-connect apply-widget "clicked" on-apply)
 
123
        (gtk-signal-connect cancel-widget "clicked" on-cancel)
 
124
        (gtk-signal-connect revert-widget "clicked" on-revert)
 
125
        (gtk-container-add hbox apply-widget)
 
126
        (gtk-container-add hbox revert-widget)
 
127
        (gtk-container-add hbox ok-widget)
 
128
        (gtk-container-add hbox cancel-widget))
 
129
 
 
130
      (gtk-container-add root-container vbox)
 
131
      (gtk-widget-show-all main-window)
 
132
      (set-button-states)
 
133
 
 
134
      (when socket-id
 
135
        (setq *nokogiri-apply-immediately* nil)
 
136
        (set-input-handler standard-input capplet-input)
 
137
        (add-hook '*nokogiri-slot-changed-hook* capplet-state-changed))
 
138
 
 
139
      (if group-tree-widget
 
140
          (progn
 
141
            (gtk-tree-select-item group-tree-widget 0)
 
142
            (mapc gtk-tree-item-expand
 
143
                  (gtk-container-children group-tree-widget)))
 
144
        (select-group (get-group top-group)))))
 
145
 
 
146
  (define (destroy-shell)
 
147
    (when main-window
 
148
      (gtk-widget-destroy main-window)
 
149
      (setq main-window nil)
 
150
      (setq group-tree-widget nil)
 
151
      (setq slot-box-widget nil)
 
152
      (setq ok-widget nil)
 
153
      (setq apply-widget nil)
 
154
      (setq revert-widget nil)
 
155
      (setq cancel-widget nil)))
 
156
 
 
157
  (define (on-quit)
 
158
    (destroy-shell)
 
159
    (throw 'nokogiri-exit t))
 
160
 
 
161
  (define (on-ok)
 
162
    (apply-slot-changes)
 
163
    (on-quit))
 
164
 
 
165
  (define (on-apply)
 
166
    (apply-slot-changes)
 
167
    (set-button-states))
 
168
 
 
169
  (define (on-cancel)
 
170
    (revert-slot-changes)
 
171
    (on-quit))
 
172
 
 
173
  (define (on-revert)
 
174
    (revert-slot-changes)
 
175
    (set-button-states))
 
176
 
 
177
  (define (set-button-states)
 
178
    (define (show-hide w state)
 
179
      ((if state gtk-widget-show gtk-widget-hide) w))
 
180
    (when apply-widget
 
181
      (show-hide apply-widget (eq *nokogiri-buttons* 'apply/revert/cancel/ok))
 
182
      (gtk-widget-set-sensitive apply-widget (changes-to-apply-p)))
 
183
    (when revert-widget
 
184
      (show-hide revert-widget (memq *nokogiri-buttons*
 
185
                                     '(revert/cancel/ok
 
186
                                       apply/revert/cancel/ok)))
 
187
      (gtk-widget-set-sensitive revert-widget (changes-to-revert-p)))
 
188
    (when ok-widget
 
189
      (gtk-widget-set-sensitive ok-widget (or (eq *nokogiri-buttons* 'ok)
 
190
                                              (changes-to-apply-p)
 
191
                                              (changes-to-revert-p))))
 
192
    (when cancel-widget
 
193
      (show-hide cancel-widget (memq *nokogiri-buttons*
 
194
                                     '(revert/cancel/ok
 
195
                                       apply/revert/cancel/ok)))))
 
196
 
 
197
;;; displaying custom groups
 
198
 
 
199
  (define (get-slots group)
 
200
    (fetch-group group)
 
201
    (filter slot-is-appropriate-p (group-slots group)))
 
202
 
 
203
  (define (display-flattened group)
 
204
 
 
205
    (define (iter book group slots)
 
206
      (when slots
 
207
        (let ((layout (layout-slots (group-layout group) slots)))
 
208
          (setq active-slots (nconc active-slots slots))
 
209
          (if (not *nokogiri-single-level*)
 
210
              (gtk-notebook-append-page
 
211
               book layout (gtk-label-new (_ (group-real-name group))))
 
212
            (gtk-box-pack-start book layout))
 
213
          (when (gtk-container-p layout)
 
214
            (gtk-container-border-width layout box-border))))
 
215
      (mapc (lambda (sub)
 
216
              (fetch-group sub)
 
217
              (let ((slots (get-slots sub)))
 
218
                (when (or slots (group-sub-groups group))
 
219
                  (iter book sub slots))))
 
220
            (get-sub-groups group)))
 
221
 
 
222
    (let ((notebook (if (not *nokogiri-single-level*)
 
223
                        (let ((x (gtk-notebook-new)))
 
224
                          (gtk-notebook-set-scrollable x 1)
 
225
                          (gtk-notebook-popup-enable x)
 
226
                          x)
 
227
                      (gtk-vbox-new nil 0))))
 
228
      (iter notebook group (get-slots group))
 
229
      (gtk-widget-show notebook)
 
230
      (gtk-container-add slot-box-widget notebook)))
 
231
 
 
232
  (define (display-unflattened group)
 
233
    (let* ((slots (get-slots group)))
 
234
      (gtk-container-add
 
235
       slot-box-widget (layout-slots (group-layout group) slots))
 
236
      (setq active-slots (nconc active-slots slots))))
 
237
 
 
238
  (define (add-group-widgets group)
 
239
    (if (and *nokogiri-flatten-groups* (group-sub-groups group))
 
240
        (display-flattened group)
 
241
      (display-unflattened group))
 
242
    (update-all-dependences))
 
243
 
 
244
  (define (remove-group-widgets group)
 
245
    (mapc (lambda (s)
 
246
            (let ((w (slot-gtk-widget s)))
 
247
              (when (gtk-widget-parent w)
 
248
                (gtk-container-remove (gtk-widget-parent w) w))
 
249
              (set-slot-layout s nil))) active-slots)
 
250
    (setq active-slots '())
 
251
    (mapc (lambda (w)
 
252
            (gtk-container-remove slot-box-widget w))
 
253
          (gtk-container-children slot-box-widget)))
 
254
 
 
255
  (define (run-shell #!optional socket-id)
 
256
    (initialize-configs)
 
257
    (initialize-shell socket-id)
 
258
    (catch 'nokogiri-exit
 
259
      (recursive-edit)))
 
260
 
 
261
  (add-hook '*nokogiri-slot-changed-hook* set-button-states t)
 
262
  (add-hook '*nokogiri-group-selected-hook* add-group-widgets)
 
263
  (add-hook '*nokogiri-group-deselected-hook* remove-group-widgets)
 
264
 
 
265
  (define-config-item 'nokogiri-buttons
 
266
                      '*nokogiri-buttons*
 
267
                      (lambda ()
 
268
                        (set-button-states)
 
269
                        (setq *nokogiri-apply-immediately*
 
270
                              (memq *nokogiri-buttons*
 
271
                                    '(ok revert/cancel/ok)))))
 
272
 
 
273
;;; capplet interfacing
 
274
 
 
275
  ;; called when there's input available on stdin
 
276
  (define (capplet-input)
 
277
    (let ((tem (read-line standard-input)))
 
278
      (condition-case nil
 
279
          (progn
 
280
            (cond ((string-match "apply" tem) (on-apply))
 
281
                  ((string-match "revert" tem) (on-revert))
 
282
                  ((string-match "ok" tem) (on-ok))
 
283
                  ((string-match "cancel" tem) (on-cancel)))
 
284
            (write standard-output ?\001)
 
285
            (flush-file standard-output))
 
286
        (end-of-stream))))
 
287
 
 
288
  (define (capplet-delete-event)
 
289
    (gtk-widget-hide main-window)
 
290
    (make-timer on-quit 10)
 
291
    ;; return t so no destroy - if the timer fires we'll destroy then
 
292
    t)
 
293
 
 
294
  (define (capplet-state-changed)
 
295
    (write standard-output ?c)
 
296
    (flush-file standard-output))
 
297
 
 
298
  (define (capplet-no-group)
 
299
    (write standard-output ?g)
 
300
    (flush-file standard-output)))