]> mj.ucw.cz Git - teatimer.git/blob - teatimer.c
bf8d0e37b8f3fed40a28c0a26a3b8e1e40bfddb3
[teatimer.git] / teatimer.c
1 /*
2  *      Trivial Tea Timer
3  *
4  *      (c) 2002 Martin Mares <mj@ucw.cz>
5  *
6  *      GPL'ed
7  */
8
9 #include <stdio.h>
10 #include <string.h>
11 #include <time.h>
12
13 #include <gtk/gtk.h>
14
15 #define UNUSED __attribute__((unused))
16
17 static guint second_timer;
18 static unsigned char old_text[8];
19 static GtkWidget *win, *hbox1, *timebox, *togglebutton1;
20 static time_t alarm_time;
21
22 static void
23 it_tolls_for_thee(void)
24 {
25   gdk_beep();
26 }
27
28 static gint
29 on_second_timeout(gpointer data UNUSED)
30 {
31   char buf[8];
32   time_t now = time(NULL);
33   int delta = alarm_time - now;
34   char *sign = "";
35
36   if (delta < 0)
37     {
38       sign = "-";
39       delta = -delta;
40     }
41   if (delta >= 6000)
42     delta = 5999;
43   sprintf(buf, "%s%02d:%02d", sign, delta/60, delta%60);
44   gtk_entry_set_text(GTK_ENTRY(timebox), buf);
45   if (now >= alarm_time)
46     it_tolls_for_thee();
47   return 1;
48 }
49
50 static gint
51 on_timebox_key(GtkWidget *widget UNUSED, GdkEventKey *ev, gpointer user_data UNUSED)
52 {
53   if (!strcmp(ev->string, "\r"))
54     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(togglebutton1), !GTK_TOGGLE_BUTTON(togglebutton1)->active);
55   else if (!strcmp(ev->string, "\033"))
56     gtk_main_quit();
57   return FALSE;
58 }
59
60 static int
61 parse_time(char *c)
62 {
63   int t = 0;
64
65   while (*c && *c != ':')
66     {
67       if (*c >= '0' && *c <= '9')
68         t = 10*t + *c++ - '0';
69       else
70         return -1;
71     }
72   if (*c)
73     {
74       int m = 0;
75       c++;
76       while (*c)
77         {
78           if (*c >= '0' && *c <= '9')
79             m = 10*m + *c++ - '0';
80           else
81             return -1;
82         }
83       t = 60*t + m;
84     }
85   if (t >= 6000)
86     return -1;
87   return t;
88 }
89
90 static void
91 on_togglebutton1_toggled(GtkToggleButton *togglebutton, gpointer user_data UNUSED)
92 {
93   if (togglebutton->active)
94     {
95       int t;
96       strcpy(old_text, gtk_entry_get_text(GTK_ENTRY(timebox)));
97       t = parse_time(old_text);
98       if (t < 0)
99         {
100           gtk_toggle_button_set_active(togglebutton, 0);
101           return;
102         }
103       alarm_time = time(NULL) + t;
104       gtk_entry_set_editable(GTK_ENTRY(timebox), 0);
105       on_second_timeout(NULL);
106       second_timer = gtk_timeout_add(1000, on_second_timeout, NULL);
107     }
108   else
109     {
110       if (second_timer)
111         {
112           gtk_timeout_remove(second_timer);
113           second_timer = 0;
114         }
115       gtk_entry_set_text(GTK_ENTRY(timebox), old_text);
116       gtk_entry_set_editable(GTK_ENTRY(timebox), 1);
117       gtk_widget_grab_focus (timebox);
118     }
119 }
120
121 static void
122 on_window_remove(GtkContainer *container UNUSED, GtkWidget *widget UNUSED, gpointer user_data UNUSED)
123 {
124   gtk_main_quit();
125 }
126
127 static void
128 open_window(void)
129 {
130   win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
131   gtk_window_set_title (GTK_WINDOW (win), "Tea Timer");
132   gtk_window_set_policy (GTK_WINDOW (win), TRUE, TRUE, TRUE);
133
134   hbox1 = gtk_hbox_new (FALSE, 0);
135   gtk_widget_show (hbox1);
136   gtk_container_add (GTK_CONTAINER (win), hbox1);
137
138   timebox = gtk_entry_new_with_max_length (6);
139   gtk_widget_show (timebox);
140   gtk_box_pack_start (GTK_BOX (hbox1), timebox, TRUE, TRUE, 0);
141   gtk_entry_set_text (GTK_ENTRY (timebox), "00:00");
142
143   togglebutton1 = gtk_toggle_button_new_with_label ("Run");
144   gtk_widget_show (togglebutton1);
145   gtk_box_pack_start (GTK_BOX (hbox1), togglebutton1, FALSE, FALSE, 0);
146
147   gtk_signal_connect(GTK_OBJECT (win), "remove", GTK_SIGNAL_FUNC (on_window_remove), NULL);
148   gtk_signal_connect(GTK_OBJECT (timebox), "key_press_event", GTK_SIGNAL_FUNC (on_timebox_key), NULL);
149   gtk_signal_connect(GTK_OBJECT (togglebutton1), "toggled", GTK_SIGNAL_FUNC (on_togglebutton1_toggled), NULL);
150
151   gtk_widget_grab_focus (timebox);
152
153   gtk_widget_show(win);
154 }
155
156 int
157 main(int argc, char **argv)
158 {
159   gtk_set_locale();
160   gtk_init(&argc, &argv);
161   open_window();
162   if (argc > 1)
163     {
164       gtk_entry_set_text(GTK_ENTRY(timebox), argv[1]);
165       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(togglebutton1), 1);
166     }
167   gtk_main();
168   return 0;
169 }