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