Use ousaged only for suspending
[gregoa/zavai.git] / src / app_main.vala
1 /*
2  * app_main - zavai main status display
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 namespace ui {
25 namespace main {
26
27 /*
28 public class StatusBar : Gtk.HBox
29 {
30     void StatusBar()
31     {
32     }
33 }
34 */
35
36 public class Clock : Gtk.VBox
37 {
38     protected Gtk.Label l_date;
39     protected Gtk.Button l_date_button;
40     protected Gtk.Label l_time;
41     protected Gtk.Label l_deadline;
42     protected time_t last_time;
43     protected zavai.clock.SourceType last_time_type;
44     protected time_t last_deadline;
45     protected string last_deadline_label;
46
47     construct
48     {
49         last_time = time_t();
50         last_time_type = zavai.clock.SourceType.SYSTEM;
51         last_deadline = 0;
52         last_deadline_label = "";
53
54         l_date = new Gtk.Label("--");
55         l_date.modify_font(Pango.FontDescription.from_string("Sans 40"));
56         l_date_button = new Gtk.Button();
57         l_date_button.set_image(l_date);
58         l_date_button.relief = Gtk.ReliefStyle.NONE;
59         l_date_button.clicked += on_date_clicked;
60         pack_start(l_date_button, false, false, 0);
61         l_time = new Gtk.Label("--:--");
62         l_time.modify_font(Pango.FontDescription.from_string("Sans 60"));
63         pack_start(l_time, false, false, 0);
64         l_deadline = new Gtk.Label("");
65         l_deadline.modify_font(Pango.FontDescription.from_string("Sans 30"));
66         l_deadline.set_justify(Gtk.Justification.CENTER);
67         pack_start(l_deadline, false, false, 0);
68
69         zavai.clock.clock.minute_changed += on_minute_changed;
70         zavai.clock.clock.schedule_changed += on_schedule_changed;
71
72         zavai.clock.clock.request("ui.main.clock");
73     }
74
75     private void on_date_clicked(Gtk.Button b)
76     {
77             zavai.app.push_applet("ui.calendar");
78     }
79
80     private void on_schedule_changed()
81     {
82         zavai.clock.Alarm a = zavai.clock.clock.next_alarm();
83         if (a == null)
84         {
85             last_deadline = 0;
86             last_deadline_label = "";
87         }
88         else
89         {
90             last_deadline = a.deadline;
91             last_deadline_label = a.label;
92         }
93         on_minute_changed((long)last_time, last_time_type);
94     }
95
96     private void on_minute_changed(long ts, zavai.clock.SourceType type)
97     {
98         last_time = (time_t)ts;
99         last_time_type = type;
100
101         string typetag = "unknown";
102         switch (type)
103         {
104             case zavai.clock.SourceType.GPS:
105                 typetag = "gps";
106                 break;
107             case zavai.clock.SourceType.SYSTEM:
108                 typetag = "sys";
109                 break;
110         }
111                 
112         var t = Time.local((time_t)ts);
113         l_date.set_text(t.format("%a %d %b"));
114         l_time.set_text("%2d:%02d (%s)".printf(t.hour, t.minute, typetag));
115
116         if (last_deadline == 0)
117             l_deadline.set_text("");
118         else
119         {
120             int remaining = (int)(last_deadline - last_time);
121             int hours = remaining / 3600;
122             int minutes = (remaining % 3600) / 60;
123             if (hours == 0 && minutes == 0)
124                 l_deadline.set_text(last_deadline_label + "\nanytime now");
125             else
126                 l_deadline.set_text("%s\nin %02dh %02dm".printf(last_deadline_label, hours, minutes));
127         }
128     }
129 }
130
131 public class Status : Applet
132 {
133     public Gtk.HBox status_icons;
134     public Clock clock;
135     public AppletPushLink menu;
136
137         public Status(string label)
138         {
139                 _label = label;
140         status_icons = new Gtk.HBox(false, 0);
141         clock = new Clock();
142         menu = new AppletPushLink("menu.main");
143
144                 pack_start(status_icons, false, false, 0);
145                 pack_start(clock, false, false, 0);
146                 pack_end(menu, false, false, 0);
147         }
148 }
149
150 public class IncDec : Gtk.HBox
151 {
152     protected Gtk.Button b_decmore;
153     protected Gtk.Button b_dec;
154     protected Gtk.Button b_inc;
155     protected Gtk.Button b_incmore;
156     static const int BH = 50;
157     static const int BW = 50;
158
159     public signal void tweaked(IncDec id, int amount);
160
161     public IncDec()
162     {
163         homogeneous = true;
164         b_decmore = new Gtk.Button.with_label("«");
165                 b_decmore.set_size_request(BW, BH);
166         b_dec = new Gtk.Button.with_label("<");
167                 b_dec.set_size_request(BW, BH);
168         b_inc = new Gtk.Button.with_label(">");
169                 b_inc.set_size_request(BW, BH);
170         b_incmore = new Gtk.Button.with_label("»");
171                 b_incmore.set_size_request(BW, BH);
172         pack_start(b_decmore, false, true, 0);
173         pack_start(b_dec, false, true, 0);
174         pack_start(b_inc, false, true, 0);
175         pack_start(b_incmore, false, true, 0);
176         b_decmore.clicked += on_clicked;
177         b_dec.clicked += on_clicked;
178         b_inc.clicked += on_clicked;
179         b_incmore.clicked += on_clicked;
180     }
181
182     protected void on_clicked(Gtk.Button b)
183     {
184         if (b == b_decmore)
185             tweaked(this, -10);
186         else if (b == b_dec)
187             tweaked(this, -1);
188         else if (b == b_inc)
189             tweaked(this, 1);
190         else if (b == b_incmore)
191             tweaked(this, 10);
192     }
193 }
194
195 public abstract class AddDeadline : Applet
196 {
197     protected Gtk.ComboBoxEntry dl_label;
198     protected Gtk.Button dl_submit;
199
200     public AddDeadline()
201     {
202         dl_label = new Gtk.ComboBoxEntry.text();
203         dl_label.append_text("Pasta");
204         dl_label.append_text("Talk");
205         dl_label.append_text("Leave");
206         dl_label.changed += on_label_changed;
207
208         var hbox = new Gtk.HBox(false, 0);
209         hbox.pack_start(new Gtk.Label("Label: "), false, false, 0);
210         hbox.pack_start(dl_label, true, true, 0);
211         pack_start(hbox, false, false, 0);
212
213         dl_submit = new Gtk.Button.with_label("Activate");
214         dl_submit.set_sensitive(false);
215         dl_submit.clicked += on_submit;
216         button_box.pack_start(dl_submit, true, true, 0);
217     }
218
219         public override void start()
220     {
221         ((Gtk.Entry)dl_label.get_child()).set_text("");
222         update();
223     }
224
225     protected virtual void update()
226     {
227         dl_submit.set_sensitive(((Gtk.Entry)dl_label.get_child()).get_text() == "" ? false : true);
228     }
229
230     protected abstract time_t get_deadline();
231
232     protected void on_label_changed(Gtk.ComboBox e)
233     {
234         update();
235     }
236
237     protected void on_submit(Gtk.Button b)
238     {
239         string label = ((Gtk.Entry)dl_label.get_child()).get_text();
240         zavai.log.info("Scheduling deadline " + label);
241         zavai.clock.Alarm a = new zavai.clock.Alarm(get_deadline(), label);
242         a.trigger += zavai.audio.audio.notify_alarm;
243         zavai.clock.clock.schedule(a);
244         back();
245     }
246 }
247
248 public class AddAbsoluteDeadline : AddDeadline
249 {
250     protected Gtk.Label dl_day;
251     protected IncDec dl_day_tweak;
252     protected Gtk.Label dl_hour;
253     protected IncDec dl_hour_tweak;
254     protected Gtk.Label dl_min;
255     protected IncDec dl_min_tweak;
256     protected time_t dl_time;
257
258     public AddAbsoluteDeadline()
259     {
260         _label = "Add absolute deadline";
261         dl_time = 0;
262
263         dl_day = new Gtk.Label("");
264         dl_day.set_justify(Gtk.Justification.RIGHT);
265         dl_day_tweak = new IncDec();
266         dl_day_tweak.tweaked += on_tweak;
267         var hbox = new Gtk.HBox(false, 0);
268         hbox.pack_start(new Gtk.Label("Day: "), false, false, 0);
269         hbox.pack_start(dl_day, true, true, 0);
270         hbox.pack_start(dl_day_tweak, false, false, 0);
271         pack_start(hbox, false, false, 0);
272
273         dl_hour = new Gtk.Label("");
274         dl_hour.set_justify(Gtk.Justification.RIGHT);
275         dl_hour_tweak = new IncDec();
276         dl_hour_tweak.tweaked += on_tweak;
277         hbox = new Gtk.HBox(false, 0);
278         hbox.pack_start(new Gtk.Label("Hour: "), false, false, 0);
279         hbox.pack_start(dl_hour, true, true, 0);
280         hbox.pack_start(dl_hour_tweak, false, false, 0);
281         pack_start(hbox, false, false, 0);
282
283         dl_min = new Gtk.Label("");
284         dl_min.set_justify(Gtk.Justification.RIGHT);
285         dl_min_tweak = new IncDec();
286         dl_min_tweak.tweaked += on_tweak;
287         hbox = new Gtk.HBox(false, 0);
288         hbox.pack_start(new Gtk.Label("Minute: "), false, false, 0);
289         hbox.pack_start(dl_min, true, true, 0);
290         hbox.pack_start(dl_min_tweak, false, false, 0);
291         pack_start(hbox, false, false, 0);
292     }
293
294         public override void start()
295     {
296         dl_time = time_t();
297         base.start();
298     }
299
300     protected override void update()
301     {
302         Time t = Time.local(dl_time);
303         dl_day.set_text(t.format("%a %d %b"));
304         dl_hour.set_text(t.format("%H"));
305         dl_min.set_text(t.format("%M"));
306         base.update();
307     }
308
309     protected override time_t get_deadline()
310     {
311         return dl_time;
312     }
313
314     protected void on_tweak(IncDec id, int amount)
315     {
316         time_t old = dl_time;
317         if (id == dl_day_tweak)
318             dl_time += amount * 3600 * 24;
319         else if (id == dl_hour_tweak)
320             dl_time += amount * 3600;
321         else if (id == dl_min_tweak)
322             dl_time += amount * 60;
323         time_t now = time_t();
324         if (dl_time < now)
325             dl_time = old;
326         update();
327     }
328 }
329
330 public class AddRelativeDeadline : AddDeadline
331 {
332     protected Gtk.Label dl_hour;
333     protected IncDec dl_hour_tweak;
334     protected Gtk.Label dl_min;
335     protected IncDec dl_min_tweak;
336     protected int dl_time;
337
338     public AddRelativeDeadline()
339     {
340         _label = "Add relative deadline";
341         dl_time = 0;
342
343         dl_hour = new Gtk.Label("");
344         dl_hour.set_justify(Gtk.Justification.RIGHT);
345         dl_hour_tweak = new IncDec();
346         dl_hour_tweak.tweaked += on_tweak;
347         var hbox = new Gtk.HBox(false, 0);
348         hbox.pack_start(new Gtk.Label("Hour: "), false, false, 0);
349         hbox.pack_start(dl_hour, true, true, 0);
350         hbox.pack_start(dl_hour_tweak, false, false, 0);
351         pack_start(hbox, false, false, 0);
352
353         dl_min = new Gtk.Label("");
354         dl_min.set_justify(Gtk.Justification.RIGHT);
355         dl_min_tweak = new IncDec();
356         dl_min_tweak.tweaked += on_tweak;
357         hbox = new Gtk.HBox(false, 0);
358         hbox.pack_start(new Gtk.Label("Minute: "), false, false, 0);
359         hbox.pack_start(dl_min, true, true, 0);
360         hbox.pack_start(dl_min_tweak, false, false, 0);
361         pack_start(hbox, false, false, 0);
362     }
363
364         public override void start()
365     {
366         dl_time = 0;
367         base.start();
368     }
369
370     protected override void update()
371     {
372         dl_hour.set_text("%2d".printf(dl_time/60));
373         dl_min.set_text("%2d".printf(dl_time%60));
374         base.update();
375     }
376
377     protected void on_tweak(IncDec id, int amount)
378     {
379         int old = dl_time;
380         if (id == dl_hour_tweak)
381             dl_time += amount * 60;
382         else if (id == dl_min_tweak)
383             dl_time += amount;
384         if (dl_time < 0)
385             dl_time = old;
386         update();
387     }
388
389     protected override time_t get_deadline()
390     {
391         return time_t() + dl_time * 60;
392     }
393 }
394
395 /*
396 public class AddDailyDeadline : Applet
397 {
398     public AddDailyDeadline()
399     {
400         _label = "Add daily deadline";
401     }
402 }
403 */
404
405 Status status;
406 AddAbsoluteDeadline aad;
407 AddRelativeDeadline ard;
408 //AddDailyDeadline add;
409
410 public void init()
411 {
412     status = new Status("Zavai");
413     zavai.registry.register_applet("zavai.status", status);
414
415     aad = new AddAbsoluteDeadline();
416     zavai.registry.register_applet("clock.addabsolute", aad);
417     ard = new AddRelativeDeadline();
418     zavai.registry.register_applet("clock.addrelative", ard);
419     /*
420     add = new AddDailyDeadline();
421     zavai.registry.register_applet("clock.adddaily", add);
422     */
423
424     var menu_misc = zavai.registry.getmenu("menu.misc");
425         menu_misc.add_applet("clock.addabsolute");
426         menu_misc.add_applet("clock.addrelative");
427         //menu_misc.add_applet("clock.adddaily");
428 }
429
430 }
431 }
432 }