Use ousaged only for suspending
[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                 //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(string name)
92         {
93                 zavai.Applet applet = zavai.registry.geta(name);
94
95                 // Remove the current applet
96                 if (current != null)
97                 {
98                         current.stop();
99                         remove(current);
100                         current = null;
101                         current_name = null;
102                 }
103
104                 // Add the new applet
105                 current = applet;
106                 current_name = name;
107                 add(current);
108                 current.start();
109                 current.show_all();
110         }
111
112         public void push_applet(string name)
113         {
114                 // Make the function idempotent
115                 if (current_name == name)
116                         return;
117
118 //stderr.printf("push applet %s -> %s\n", current_name, name);
119                 zavai.Applet applet = zavai.registry.geta(name);
120
121                 // Remove the current applet
122                 if (current != null)
123                 {
124 //stderr.printf("push applet remove %s\n", current_name);
125                         applet.back_link = current_name;
126                         current.stop();
127                         remove(current);
128                         current = null;
129                         current_name = null;
130                 }
131
132 //stderr.printf("push applet add %s\n", name);
133                 // Add the new applet
134                 current = applet;
135                 current_name = name;
136                 add(current);
137                 current.start();
138                 current.show_all();
139         }
140
141         public void back()
142         {
143                 if (current != null)
144                         current.back();
145         }
146
147         public void back_to_main()
148         {
149                 show_applet("zavai.status");
150         }
151
152         public void shutdown()
153         {
154         }
155
156         public void run()
157         {
158                 set_size_request(300, 500);
159                 //fullscreen();
160                 show_all();
161         }
162
163         public void run_script(string command)
164         {
165                 zavai.log.info("Run program: " + command);
166                 string[] args = command.split(" ");
167                 Pid pid;
168                 try {
169                         Process.spawn_async(
170                                 Environment.get_home_dir(),
171                                 args,
172                                 null,
173                                 SpawnFlags.SEARCH_PATH,
174                                 null,
175                                 out pid);
176                 } catch (SpawnError e) {
177                         zavai.log.error("Running " + command + ": " + e.message);
178                 }
179         }
180 }
181
182 public abstract class Applet : Gtk.VBox, Resource
183 {
184         // 'label' property: label to show in window title or button names
185         protected string _label;
186         public string label {
187                 get { return this._label; }
188                 set {
189                         if (_label != value)
190                         {
191                                 _label = value;
192                                 label_changed();
193                         }
194                 }
195         }
196         public signal void label_changed();
197
198         protected Gtk.HBox button_box;
199
200         // 'back_link' property: link to use to "go back". If null, do not show
201         // a way to go back.
202         protected AppletLink _back_link = null;
203         public string back_link {
204                 get { return _back_link.target; }
205                 set {
206 //stderr.printf("Set back link of %s to %s\n", _label, value);
207                         if (value == null && _back_link != null)
208                         {
209                                 _back_link.target = value;
210                                 button_box.remove(_back_link);
211                         } else if (value != null) {
212                                 if (_back_link.target == null)
213                                 {
214                                         _back_link.target = value;
215                                         button_box.pack_end(_back_link, true, true, 0);
216                                         _back_link.show();
217                                 } else
218                                         _back_link.target = value;
219                         }
220                 }
221         }
222
223         public Applet()
224         {
225                 button_box = new Gtk.HBox(true, 0);
226                 this.homogeneous = false;
227                 this.spacing = 0;
228                 pack_end(button_box, false, true, 0);
229                 _back_link = new AppletStraightLink();
230         }
231
232         public virtual void back()
233         {
234                 _back_link.activate_applet();
235         }
236
237         public virtual void back_to_main()
238         {
239                 zavai.app.back_to_main();
240         }
241
242         public void shutdown()
243         {
244                 stop();
245         }
246
247         public virtual void start() {}
248         public virtual void stop() {}
249 }
250
251 public class Menu : Applet
252 {
253         public Menu(string label)
254         {
255                 _label = label;
256         }
257
258         public void add_applet(string target)
259         {
260                 pack_start(new AppletPushLink(target), false, false, 0);
261         }
262
263         public void add_service_toggle(string service_name, string label_start, string label_stop)
264         {
265                 pack_start(new ServiceRequestLink(service_name, label_start, label_stop), false, false, 0);
266         }
267
268         public void add_widget(Gtk.Widget w)
269         {
270                 pack_start(w, false, false, 0);
271         }
272 }
273
274 public class BigButton : Gtk.Button
275 {
276         public BigButton()
277         {
278                 set_size_request(0, zavai.config.min_button_height);
279         }
280 }
281
282 public abstract class AppletLink : BigButton
283 {
284         protected string _target;
285         public string target {
286                 get { return _target; }
287                 set
288                 {
289                         if (_target != null)
290                         {
291                                 Applet a = zavai.registry.geta(_target);
292                                 a.label_changed -= on_label_changed;
293                         }
294                         bool was_shown = _target != null;
295                         _target = value;
296                         if (_target != null)
297                         {
298                                 Applet a = zavai.registry.geta(_target);
299                                 set_label(a.label);
300                                 a.label_changed += on_label_changed;
301                                 if (!was_shown) show();
302                         } else {
303                                 if (was_shown) hide();
304                         }
305                 }
306         }
307
308         private void on_label_changed(Applet a)
309         {
310                 set_label(a.label);
311         }
312
313         private abstract void on_clicked(Gtk.Button src);
314
315         public AppletLink(string? name = null)
316         {
317                 _target = null;
318                 target = name;
319
320                 clicked += on_clicked;
321         }
322
323         public virtual void activate_applet()
324         {
325                 on_clicked(this);
326         }
327 }
328
329 public class AppletStraightLink : AppletLink
330 {
331         private override void on_clicked(Gtk.Button src)
332         {
333 //stderr.printf("straight link: %s\n", _target);
334                 if (_target != null)
335                         zavai.app.show_applet(_target);
336         }
337
338         public AppletStraightLink(string? name = null)
339         {
340                 base(name);
341         }
342 }
343
344 public class AppletPushLink : AppletLink
345 {
346         private override void on_clicked(Gtk.Button src)
347         {
348 //stderr.printf("push link: %s\n", _target);
349                 if (_target != null)
350                         zavai.app.push_applet(_target);
351         }
352
353         public AppletPushLink(string? name = null)
354         {
355                 base(name);
356         }
357 }
358
359 public class ServiceRequestLink : Gtk.ToggleButton
360 {
361         protected string service_name;
362         protected string label_start;
363         protected string label_stop;
364
365         private void on_toggled(Gtk.Button src)
366         {
367                 Service s = zavai.registry.gets(service_name);
368                 if (get_active())
369                         s.request("servicerequestlink");
370                 else
371                         s.release("servicerequestlink");
372                 set_label(get_active() ? label_stop : label_start);
373         }
374
375         public ServiceRequestLink(string service_name, string label_start, string label_stop)
376         {
377                 this.service_name = service_name;
378                 this.label_start = label_start;
379                 this.label_stop = label_stop;
380                 set_size_request(0, zavai.config.min_button_height);
381                 toggled += on_toggled;
382
383                 set_label(get_active() ? label_stop : label_start);
384         }
385 }
386
387 public class StatusIcon : Gtk.Button
388 {
389         private Gtk.Image image_widget;
390
391         public StatusIcon()
392         {
393                 relief = Gtk.ReliefStyle.NONE;
394                 image_widget = new Gtk.Image();
395                 image = image_widget;
396         }
397
398         public void set_from_file(string file)
399         {
400                 image_widget.set_from_file(file);
401         }
402
403         public void install()
404         {
405                 zavai.ui.main.status.status_icons.pack_start(this, false, false, 0);
406         }
407 }
408
409
410 zavai.Zavai app;
411
412 }