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