Implemented the concept of 'profile'
[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
32     public Zavai()
33     {
34         title = "Zavai";
35         current = null;
36         destroy += Gtk.main_quit;
37         set_events(get_events() | Gdk.EventMask.VISIBILITY_NOTIFY_MASK);
38         visibility_notify_event += on_visibility;
39         set_skip_pager_hint(true);
40         set_skip_taskbar_hint(true);
41         //set_type_hint(Gdk.WindowTypeHint.DESKTOP);
42
43         zavai.registry.register(this);
44     }
45
46     private bool on_visibility(Gdk.Event event)
47     {
48         visibility = (event.visibility.state == Gdk.VisibilityState.UNOBSCURED);
49         //visible = visibility;
50         visibility_changed(visibility);
51         return true;
52     }
53
54     public void toggle_visibility()
55     {
56         if (visibility)
57         {
58             visible = false;
59             visibility = false;
60             visibility_changed(visibility);
61             //zavai.app.iconify();
62         } else {
63             visible = true;
64             present();
65             set_skip_pager_hint(true);
66             set_skip_taskbar_hint(true);
67         }
68     }
69
70     public void ensure_visible()
71     {
72         if (!visibility)
73         {
74             visible = true;
75             present();
76             set_skip_pager_hint(true);
77             set_skip_taskbar_hint(true);
78         }
79     }
80
81     public void ensure_hidden()
82     {
83         if (visibility)
84         {
85             visible = false;
86             visibility = false;
87             visibility_changed(visibility);
88         }
89     }
90
91     public void show_applet(Applet applet)
92     {
93         // Remove the current applet
94         if (current != null)
95         {
96             current.stop();
97             remove(current);
98             current = null;
99         }
100
101         // Add the new applet
102         current = applet;
103         add(current);
104         current.start();
105         current.show_all();
106     }
107
108     public void push_applet(Applet applet)
109     {
110         // Make the function idempotent
111         if (current == applet)
112             return;
113
114         // Remove the current applet
115         if (current != null)
116         {
117 //stderr.printf("push applet remove %s\n", current_name);
118             applet.back_link = current;
119             current.stop();
120             remove(current);
121             current = null;
122         }
123
124 //stderr.printf("push applet add %s\n", name);
125         // Add the new applet
126         current = applet;
127         add(current);
128         current.start();
129         current.show_all();
130     }
131
132     public void back()
133     {
134         if (current != null)
135             current.back();
136     }
137
138     public void back_to_main()
139     {
140         show_applet(zavai.ui.main.status);
141     }
142
143     public void shutdown()
144     {
145     }
146
147     public void run()
148     {
149         set_size_request(300, 500);
150         //fullscreen();
151         if (zavai.config.profile == "laptop")
152         {
153             visibility = false;
154             zavai.app.ensure_hidden();
155             zavai.ui.wm.raise_icon.update_icon();
156         } else {
157             show_all();
158         }
159     }
160
161     public void run_script(string command)
162     {
163         zavai.log.info("Run program: " + command);
164         string[] args = command.split(" ");
165         Pid pid;
166         try {
167             Process.spawn_async(
168                 Environment.get_home_dir(),
169                 args,
170                 null,
171                 SpawnFlags.SEARCH_PATH,
172                 null,
173                 out pid);
174         } catch (SpawnError e) {
175             zavai.log.error("Running " + command + ": " + e.message);
176         }
177     }
178 }
179
180 public abstract class Applet : Gtk.VBox, Resource
181 {
182     // 'label' property: label to show in window title or button names
183     protected string _label;
184     public string label {
185         get { return this._label; }
186         set {
187             if (_label != value)
188             {
189                 _label = value;
190                 label_changed();
191             }
192         }
193     }
194     public signal void label_changed();
195
196     protected Gtk.HBox button_box;
197
198     // 'back_link' property: link to use to "go back". If null, do not show
199     // a way to go back.
200     protected AppletLink _back_link = null;
201     public Applet back_link {
202         get { return _back_link.target; }
203         set {
204 //stderr.printf("Set back link of %s to %s\n", _label, value);
205             if (value == null && _back_link != null)
206             {
207                 _back_link.target = value;
208                 button_box.remove(_back_link);
209             } else if (value != null) {
210                 if (_back_link.target == null)
211                 {
212                     _back_link.target = value;
213                     button_box.pack_end(_back_link, true, true, 0);
214                     _back_link.show();
215                 } else
216                     _back_link.target = value;
217             }
218         }
219     }
220
221     public Applet()
222     {
223         button_box = new Gtk.HBox(true, 0);
224         this.homogeneous = false;
225         this.spacing = 0;
226         pack_end(button_box, false, true, 0);
227         _back_link = new AppletStraightLink();
228         zavai.registry.register(this);
229     }
230
231     public virtual void back()
232     {
233         _back_link.activate_applet();
234     }
235
236     public virtual void back_to_main()
237     {
238         zavai.app.back_to_main();
239     }
240
241     public void shutdown()
242     {
243         stop();
244     }
245
246     public virtual void start() {}
247     public virtual void stop() {}
248 }
249
250 public class Menu : Applet
251 {
252     public Menu(string label)
253     {
254         _label = label;
255     }
256
257     public void add_applet(Applet target)
258     {
259         pack_start(new AppletPushLink(target), false, false, 0);
260     }
261
262     public void add_service_toggle(Service service, string label_start, string label_stop)
263     {
264         pack_start(new ServiceRequestLink(service, label_start, label_stop), false, false, 0);
265     }
266
267     public void add_widget(Gtk.Widget w)
268     {
269         pack_start(w, false, false, 0);
270     }
271 }
272
273 public class BigButton : Gtk.Button
274 {
275     public BigButton()
276     {
277         set_size_request(0, zavai.config.min_button_height);
278     }
279 }
280
281 public abstract class AppletLink : BigButton
282 {
283     protected Applet _target;
284     public Applet target {
285         get { return _target; }
286         set
287         {
288             if (_target != null)
289             {
290                 _target.label_changed -= on_label_changed;
291             }
292             bool was_shown = _target != null;
293             _target = value;
294             if (_target != null)
295             {
296                 set_label(_target.label);
297                 _target.label_changed += on_label_changed;
298                 if (!was_shown) show();
299             } else {
300                 if (was_shown) hide();
301             }
302         }
303     }
304
305     private void on_label_changed(Applet a)
306     {
307         set_label(a.label);
308     }
309
310     private abstract void on_clicked(Gtk.Button src);
311
312     public AppletLink(Applet? applet = null)
313     {
314         _target = null;
315         target = applet;
316
317         clicked += on_clicked;
318     }
319
320     public virtual void activate_applet()
321     {
322         on_clicked(this);
323     }
324 }
325
326 public class AppletStraightLink : AppletLink
327 {
328     private override void on_clicked(Gtk.Button src)
329     {
330 //stderr.printf("straight link: %s\n", _target);
331         if (_target != null)
332             zavai.app.show_applet(_target);
333     }
334
335     public AppletStraightLink(Applet? applet = null)
336     {
337         base(applet);
338     }
339 }
340
341 public class AppletPushLink : AppletLink
342 {
343     private override void on_clicked(Gtk.Button src)
344     {
345 //stderr.printf("push link: %s\n", _target);
346         if (_target != null)
347             zavai.app.push_applet(_target);
348     }
349
350     public AppletPushLink(Applet? applet = null)
351     {
352         base(applet);
353     }
354 }
355
356 public class ServiceRequestLink : Gtk.ToggleButton
357 {
358     protected Service service;
359     protected string label_start;
360     protected string label_stop;
361
362     private void on_toggled(Gtk.Button src)
363     {
364         if (get_active())
365             service.request("servicerequestlink");
366         else
367             service.release("servicerequestlink");
368         set_label(get_active() ? label_stop : label_start);
369     }
370
371     public ServiceRequestLink(Service service, string label_start, string label_stop)
372     {
373         this.service = service;
374         this.label_start = label_start;
375         this.label_stop = label_stop;
376         set_size_request(0, zavai.config.min_button_height);
377         toggled += on_toggled;
378
379         set_label(get_active() ? label_stop : label_start);
380     }
381 }
382
383 public class StatusIcon : Gtk.Button
384 {
385     private Gtk.Image image_widget;
386
387     public StatusIcon()
388     {
389         relief = Gtk.ReliefStyle.NONE;
390         image_widget = new Gtk.Image();
391         image = image_widget;
392     }
393
394     public void set_from_file(string file)
395     {
396         image_widget.set_from_file(file);
397     }
398
399     public void install()
400     {
401         zavai.ui.main.status.status_icons.pack_start(this, false, false, 0);
402     }
403 }
404
405
406 public zavai.Zavai app;
407 public zavai.Menu menu_main;
408 public zavai.Menu menu_gps;
409 public zavai.Menu menu_gsm;
410 public zavai.Menu menu_misc;
411
412 namespace main {
413
414 public void init()
415 {
416     zavai.app = new zavai.Zavai();
417     menu_main = new zavai.Menu("Main menu");
418
419     // Create menus
420     menu_gps = new zavai.Menu("GPS");
421     menu_main.add_applet(menu_gps);
422
423     menu_gsm = new zavai.Menu("GSM");
424     menu_main.add_applet(menu_gsm);
425
426     menu_misc = new zavai.Menu("Misc");
427     menu_main.add_applet(menu_misc);
428 }
429
430 }
431
432 }