88e320c0931f00cdad90c45e77a58b59539bf0f1
[gregoa/zavai.git] / src / app.vala
1 /*
2  * app - zavai main window
3  *
4  * Copyright (C) 2009  Enrico Zini <enrico@enricozini.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 using GLib;
22
23 namespace zavai {
24
25 public class Zavai : Gtk.Window, zavai.Resource
26 {
27         public bool visibility = true;
28         public signal void visibility_changed(bool visible);
29
30         zavai.Applet current;
31         string current_name;
32
33         public Zavai()
34         {
35                 title = "Zavai";
36                 current = null;
37                 current_name = null;
38                 destroy += Gtk.main_quit;
39                 set_events(get_events() | Gdk.EventMask.VISIBILITY_NOTIFY_MASK);
40                 visibility_notify_event += on_visibility;
41                 set_skip_pager_hint(true);
42                 set_skip_taskbar_hint(true);
43                 //set_type_hint(Gdk.WindowTypeHint.DESKTOP);
44         }
45
46         private bool on_visibility(Gdk.Event event)
47         {
48                 visibility = (event.visibility.state == Gdk.VisibilityState.UNOBSCURED);
49                 visibility_changed(visibility);
50                 return true;
51         }
52
53         public void toggle_visibility()
54         {
55                 if (visibility)
56                 {
57                         visible = false;
58                         visibility = false;
59                         visibility_changed(visibility);
60                         //zavai.app.iconify();
61                 } else {
62                         visible = true;
63                         present();
64                         set_skip_pager_hint(true);
65                         set_skip_taskbar_hint(true);
66                 }
67         }
68
69         public void ensure_visible()
70         {
71                 if (!visibility)
72                 {
73                         visible = true;
74                         present();
75                         set_skip_pager_hint(true);
76                         set_skip_taskbar_hint(true);
77                 }
78         }
79
80         public void show_applet(string name)
81         {
82                 zavai.Applet applet = zavai.registry.geta(name);
83
84                 // Remove the current applet
85                 if (current != null)
86                 {
87                         current.stop();
88                         remove(current);
89                         current = null;
90                         current_name = null;
91                 }
92
93                 // Add the new applet
94                 current = applet;
95                 current_name = name;
96                 add(current);
97                 current.start();
98                 current.show_all();
99         }
100
101         public void push_applet(string name)
102         {
103                 // Make the function idempotent
104                 if (current_name == name)
105                         return;
106
107 //stderr.printf("push applet %s -> %s\n", current_name, name);
108                 zavai.Applet applet = zavai.registry.geta(name);
109
110                 // Remove the current applet
111                 if (current != null)
112                 {
113 //stderr.printf("push applet remove %s\n", current_name);
114                         applet.back_link = current_name;
115                         current.stop();
116                         remove(current);
117                         current = null;
118                         current_name = null;
119                 }
120
121 //stderr.printf("push applet add %s\n", name);
122                 // Add the new applet
123                 current = applet;
124                 current_name = name;
125                 add(current);
126                 current.start();
127                 current.show_all();
128         }
129
130         public void shutdown()
131         {
132         }
133
134         public void run()
135         {
136                 set_size_request(300, 500);
137                 //fullscreen();
138                 show_all();
139         }
140 }
141 /*
142 class Zavai(gtk.Window, zavai.Resource):
143     def __init__(self, registry, name):
144         super(Zavai, self).__init__()
145         self.registry = registry
146         self.current = None
147         self.activate_resource("menu.main")
148
149     def activate_resource(self, name):
150         widget = self.registry.resource(name)
151         if widget is None:
152             widget = self.registry.resource("menu.main")
153         if isinstance(widget, gtk.Action):
154             widget.activate()
155         else:
156             self.show_widget(name, widget)
157 */
158
159 public abstract class Applet : Gtk.VBox, Resource
160 {
161         // 'label' property: label to show in window title or button names
162         protected string _label;
163         public string label {
164                 get { return this._label; }
165                 set {
166                         if (_label != value)
167                         {
168                                 _label = value;
169                                 label_changed();
170                         }
171                 }
172         }
173         public signal void label_changed();
174
175         protected Gtk.HBox button_box;
176
177         // 'back_link' property: link to use to "go back". If null, do not show
178         // a way to go back.
179         protected AppletLink _back_link = null;
180         public string back_link {
181                 get { return _back_link.target; }
182                 set {
183 //stderr.printf("Set back link of %s to %s\n", _label, value);
184                         if (value == null && _back_link != null)
185                         {
186                                 _back_link.target = value;
187                                 button_box.remove(_back_link);
188                         } else if (value != null) {
189                                 if (_back_link.target == null)
190                                 {
191                                         _back_link.target = value;
192                                         button_box.pack_end(_back_link, true, true, 0);
193                                         _back_link.show();
194                                 } else
195                                         _back_link.target = value;
196                         }
197                 }
198         }
199
200         public Applet()
201         {
202                 button_box = new Gtk.HBox(true, 0);
203                 this.homogeneous = false;
204                 this.spacing = 0;
205                 pack_end(button_box, false, true, 0);
206                 _back_link = new AppletStraightLink();
207         }
208 /*
209     name = gobject.property(type=str)
210     label = gobject.property(type=str)
211
212     def __init__(self, registry, name, label = None):
213         super(Applet, self).__init__()
214
215         self.zavai_registry = registry
216
217         self.props.name = name
218         if label is None:
219             self.props.label = zavai.default_label(name)
220         else:
221             self.props.label = label
222
223         self.back_link = zavai.LinkButton(registry, zavai.get_parent(name), _("Back"))
224         self.pack_end(self.back_link, False, False)
225
226     def add(self, widget):
227         self.pack_start(widget, True, True)
228 */
229
230         public void shutdown()
231         {
232                 stop();
233         }
234
235         public virtual void start() {}
236         public virtual void stop() {}
237 }
238
239 public class Menu : Applet
240 {
241         public Menu(string label)
242         {
243                 _label = label;
244         }
245
246         public void add_applet(string target)
247         {
248                 pack_start(new AppletPushLink(target), false, false, 0);
249         }
250
251         public void add_service_toggle(string service_name, string label_start, string label_stop)
252         {
253                 pack_start(new ServiceRequestLink(service_name, label_start, label_stop), false, false, 0);
254         }
255
256         public void add_widget(Gtk.Widget w)
257         {
258                 pack_start(w, false, false, 0);
259         }
260 }
261
262 public class BigButton : Gtk.Button
263 {
264         public BigButton()
265         {
266                 set_size_request(0, zavai.config.min_button_height);
267         }
268 }
269
270 public abstract class AppletLink : BigButton
271 {
272         protected string _target;
273         public string target {
274                 get { return _target; }
275                 set
276                 {
277                         if (_target != null)
278                         {
279                                 Applet a = zavai.registry.geta(_target);
280                                 a.label_changed -= on_label_changed;
281                         }
282                         bool was_shown = _target != null;
283                         _target = value;
284                         if (_target != null)
285                         {
286                                 Applet a = zavai.registry.geta(_target);
287                                 set_label(a.label);
288                                 a.label_changed += on_label_changed;
289                                 if (!was_shown) show();
290                         } else {
291                                 if (was_shown) hide();
292                         }
293                 }
294         }
295
296         private void on_label_changed(Applet a)
297         {
298                 set_label(a.label);
299         }
300
301         private abstract void on_clicked(Gtk.Button src);
302
303         public AppletLink(string? name = null)
304         {
305                 _target = null;
306                 target = name;
307
308                 clicked += on_clicked;
309         }
310 }
311
312 public class AppletStraightLink : AppletLink
313 {
314         private override void on_clicked(Gtk.Button src)
315         {
316 //stderr.printf("straight link: %s\n", _target);
317                 if (_target != null)
318                         zavai.app.show_applet(_target);
319         }
320
321         public AppletStraightLink(string? name = null)
322         {
323                 base(name);
324         }
325 }
326
327 public class AppletPushLink : AppletLink
328 {
329         private override void on_clicked(Gtk.Button src)
330         {
331 //stderr.printf("push link: %s\n", _target);
332                 if (_target != null)
333                         zavai.app.push_applet(_target);
334         }
335
336         public AppletPushLink(string? name = null)
337         {
338                 base(name);
339         }
340 }
341
342 public class ServiceRequestLink : Gtk.ToggleButton
343 {
344         protected string service_name;
345         protected string label_start;
346         protected string label_stop;
347
348         private void on_toggled(Gtk.Button src)
349         {
350                 Service s = zavai.registry.gets(service_name);
351                 if (get_active())
352                         s.request("servicerequestlink");
353                 else
354                         s.release("servicerequestlink");
355                 set_label(get_active() ? label_stop : label_start);
356         }
357
358         public ServiceRequestLink(string service_name, string label_start, string label_stop)
359         {
360                 this.service_name = service_name;
361                 this.label_start = label_start;
362                 this.label_stop = label_stop;
363                 set_size_request(0, zavai.config.min_button_height);
364                 toggled += on_toggled;
365
366                 set_label(get_active() ? label_stop : label_start);
367         }
368 }
369
370 public class CommandButton : Gtk.Button
371 {
372         private string command;
373
374         public CommandButton(string name, string command)
375         {
376                 label = name;
377                 this.command = command;
378                 clicked += on_clicked;
379                 set_size_request(0, zavai.config.min_button_height);
380         }
381
382         public void on_clicked()
383         {
384                 zavai.log.info("Run program: " + command);
385                 string[] args = command.split(" ");
386                 Pid pid;
387                 Process.spawn_async(
388                         Environment.get_home_dir(),
389                         args,
390                         null,
391                         SpawnFlags.SEARCH_PATH,
392                         null,
393                         out pid);
394         }
395 }
396
397
398 zavai.Zavai app;
399
400 }