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