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