Timeout the alarm after a bit
[gregoa/zavai.git] / src / app_alarm.vala
1 /*
2  * app_alarm - zavai alarm system
3  *
4  * Copyright (C) 2010  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 alarm {
26
27 // Compute a-b in microseconds
28 static long timediff(Posix.timeval* a, Posix.timeval* b)
29 {
30     return (a->tv_sec - b->tv_sec) * 1000000 + (a->tv_usec - b->tv_usec);
31 }
32
33 public class AlarmNotifier : zavai.Resource, Gtk.Window
34 {
35     protected Gtk.VBox vbox;
36     protected bool shown;
37     protected Gtk.Label message;
38     protected Gtk.Button ack;
39     protected uint cancel_timeout;
40
41     public AlarmNotifier()
42     {
43         Object(
44             type: Gtk.WindowType.TOPLEVEL,
45             title: "Alarm"
46         );
47         shown = false;
48         destroy_with_parent = true;
49         set_transient_for(zavai.app);
50         set_modal(true);
51         set_position(Gtk.WindowPosition.CENTER_ON_PARENT);
52         set_size_request(300, 500);
53
54         vbox = new Gtk.VBox(false, 0);
55         add(vbox);
56
57         cancel_timeout = 0;
58
59         //destroy += Gtk.main_quit;
60         //set_events(get_events() | Gdk.EventMask.VISIBILITY_NOTIFY_MASK);
61         //visibility_notify_event += on_visibility;
62         set_skip_pager_hint(true);
63         set_skip_taskbar_hint(true);
64         set_type_hint(Gdk.WindowTypeHint.POPUP_MENU);
65
66         message = new Gtk.Label("no message");
67         vbox.pack_start(message, false, true, 0);
68
69         ack = new Gtk.Button.with_label("Ack");
70         ack.clicked += on_ack;
71         vbox.pack_start(ack, true, true, 0);
72
73         //vbox.show_all();
74         zavai.registry.register(this);
75     }
76
77     protected void on_ack()
78     {
79         confirm();
80     }
81
82     protected bool on_timeout()
83     {
84         cancel();
85         return false;
86     }
87
88     public void trigger(string text)
89     {
90         message.set_text(text);
91
92         if (!shown)
93         {
94             show_all();
95             show();
96             visible = true;
97             present();
98             shown = true;
99         } else {
100             // TODO: do more in case it is visible but has no visibility (is covered by others)
101             visible = !visible;
102             if (visible)
103                 present();
104         }
105
106         if (cancel_timeout != 0)
107         {
108             Source.remove(cancel_timeout);
109             cancel_timeout = 0;
110         }
111         cancel_timeout = Timeout.add(2000, on_timeout);
112     }
113
114     public void confirm()
115     {
116         visible = false;
117         if (cancel_timeout != 0)
118         {
119             Source.remove(cancel_timeout);
120             cancel_timeout = 0;
121         }
122     }
123
124     public void cancel()
125     {
126         visible = false;
127         if (cancel_timeout != 0)
128         {
129             Source.remove(cancel_timeout);
130             cancel_timeout = 0;
131         }
132     }
133
134     public void shutdown() {}
135 }
136
137 public AlarmNotifier notifier;
138
139 public void init()
140 {
141     notifier = new AlarmNotifier();
142 }
143
144 }
145 }
146 }