]> Pileus Git - ~andy/gtk/blob - examples/calendar/calendar.c
Deprecate widget flag: GTK_WIDGET_VISIBLE
[~andy/gtk] / examples / calendar / calendar.c
1 /*
2  * Copyright (C) 1998 Cesar Miquel, Shawn T. Amundson, Mattias Grönlund
3  * Copyright (C) 2000 Tony Gale
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19
20 #include <stdio.h>
21 #include <string.h>
22 #include <gtk/gtk.h>
23
24 #define DEF_PAD 10
25 #define DEF_PAD_SMALL 5
26
27 #define TM_YEAR_BASE 1900
28
29 typedef struct _CalendarData {
30   GtkWidget *flag_checkboxes[5];
31   gboolean  settings[5];
32   GtkWidget *font_dialog;
33   GtkWidget *window;
34   GtkWidget *prev2_sig;
35   GtkWidget *prev_sig;
36   GtkWidget *last_sig;
37   GtkWidget *month;
38 } CalendarData;
39
40 enum {
41   calendar_show_header,
42   calendar_show_days,
43   calendar_month_change,
44   calendar_show_week,
45   calendar_monday_first
46 };
47
48 /*
49  * GtkCalendar
50  */
51
52 static void calendar_date_to_string( CalendarData *data,
53                                      char         *buffer,
54                                      gint          buff_len )
55 {
56   GDate date;
57   guint year, month, day;
58
59   gtk_calendar_get_date (GTK_CALENDAR (data->window),
60                          &year, &month, &day);
61   g_date_set_dmy (&date, day, month + 1, year);
62   g_date_strftime (buffer, buff_len - 1, "%x", &date);
63
64 }
65
66 static void calendar_set_signal_strings( char         *sig_str,
67                                          CalendarData *data )
68 {
69   const gchar *prev_sig;
70
71   prev_sig = gtk_label_get_text (GTK_LABEL (data->prev_sig));
72   gtk_label_set_text (GTK_LABEL (data->prev2_sig), prev_sig);
73
74   prev_sig = gtk_label_get_text (GTK_LABEL (data->last_sig));
75   gtk_label_set_text (GTK_LABEL (data->prev_sig), prev_sig);
76   gtk_label_set_text (GTK_LABEL (data->last_sig), sig_str);
77 }
78
79 static void calendar_month_changed( GtkWidget    *widget,
80                                     CalendarData *data )
81 {
82   char buffer[256] = "month_changed: ";
83
84   calendar_date_to_string (data, buffer + 15, 256 - 15);
85   calendar_set_signal_strings (buffer, data);
86 }
87
88 static void calendar_day_selected( GtkWidget    *widget,
89                                    CalendarData *data )
90 {
91   char buffer[256] = "day_selected: ";
92
93   calendar_date_to_string (data, buffer + 14, 256 - 14);
94   calendar_set_signal_strings (buffer, data);
95 }
96
97 static void calendar_day_selected_double_click ( GtkWidget    *widget,
98                                                  CalendarData *data )
99 {
100   char buffer[256] = "day_selected_double_click: ";
101   guint day;
102
103   calendar_date_to_string (data, buffer + 27, 256 - 27);
104   calendar_set_signal_strings (buffer, data);
105
106   gtk_calendar_get_date (GTK_CALENDAR (data->window),
107                          NULL, NULL, &day);
108
109   if (GTK_CALENDAR (data->window)->marked_date[day-1] == 0) {
110     gtk_calendar_mark_day (GTK_CALENDAR (data->window), day);
111   } else {
112     gtk_calendar_unmark_day (GTK_CALENDAR (data->window), day);
113   }
114 }
115
116 static void calendar_prev_month( GtkWidget    *widget,
117                                  CalendarData *data )
118 {
119   char buffer[256] = "prev_month: ";
120
121   calendar_date_to_string (data, buffer + 12, 256 - 12);
122   calendar_set_signal_strings (buffer, data);
123 }
124
125 static void calendar_next_month( GtkWidget    *widget,
126                                  CalendarData *data )
127 {
128   char buffer[256] = "next_month: ";
129
130   calendar_date_to_string (data, buffer + 12, 256 - 12);
131   calendar_set_signal_strings (buffer, data);
132 }
133
134 static void calendar_prev_year( GtkWidget    *widget,
135                                 CalendarData *data )
136 {
137   char buffer[256] = "prev_year: ";
138
139   calendar_date_to_string (data, buffer + 11, 256 - 11);
140   calendar_set_signal_strings (buffer, data);
141 }
142
143 static void calendar_next_year( GtkWidget    *widget,
144                                 CalendarData *data )
145 {
146   char buffer[256] = "next_year: ";
147
148   calendar_date_to_string (data, buffer + 11, 256 - 11);
149   calendar_set_signal_strings (buffer, data);
150 }
151
152
153 static void calendar_set_flags( CalendarData *calendar )
154 {
155   gint i;
156   gint options = 0;
157   for (i = 0;i < 5; i++)
158     if (calendar->settings[i])
159       {
160         options = options + (1 << i);
161       }
162   if (calendar->window)
163     gtk_calendar_display_options (GTK_CALENDAR (calendar->window), options);
164 }
165
166 static void calendar_toggle_flag( GtkWidget    *toggle,
167                                   CalendarData *calendar)
168 {
169   gint i;
170   gint j;
171   j = 0;
172   for (i = 0; i < 5; i++)
173     if (calendar->flag_checkboxes[i] == toggle)
174       j = i;
175
176   calendar->settings[j] = !calendar->settings[j];
177   calendar_set_flags (calendar);
178
179 }
180
181 static void calendar_font_selection_ok( GtkWidget    *button,
182                                         CalendarData *calendar )
183 {
184   GtkRcStyle *style;
185   char *font_name;
186
187   if (calendar->window)
188     {
189       font_name = gtk_font_selection_dialog_get_font_name (GTK_FONT_SELECTION_DIALOG (calendar->font_dialog));
190       if (font_name)
191         {
192           style = gtk_rc_style_new ();
193           pango_font_description_free (style->font_desc);
194           style->font_desc = pango_font_description_from_string (font_name);
195           gtk_widget_modify_style (calendar->window, style);
196           g_free (font_name);
197         }
198     }
199
200   gtk_widget_destroy (calendar->font_dialog);
201 }
202
203 static void calendar_select_font( GtkWidget    *button,
204                                   CalendarData *calendar )
205 {
206   GtkWidget *window;
207
208   if (!calendar->font_dialog) {
209     window = gtk_font_selection_dialog_new ("Font Selection Dialog");
210     g_return_if_fail (GTK_IS_FONT_SELECTION_DIALOG (window));
211     calendar->font_dialog = window;
212
213     gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
214
215     g_signal_connect (window, "destroy",
216                       G_CALLBACK (gtk_widget_destroyed),
217                       &calendar->font_dialog);
218
219     g_signal_connect (GTK_FONT_SELECTION_DIALOG (window)->ok_button,
220                       "clicked", G_CALLBACK (calendar_font_selection_ok),
221                       calendar);
222     g_signal_connect_swapped (GTK_FONT_SELECTION_DIALOG (window)->cancel_button,
223                              "clicked", G_CALLBACK (gtk_widget_destroy),
224                              calendar->font_dialog);
225   }
226   window = calendar->font_dialog;
227   if (!gtk_widget_get_visible (window))
228     gtk_widget_show (window);
229   else
230     gtk_widget_destroy (window);
231
232 }
233
234 static void create_calendar( void )
235 {
236   GtkWidget *window;
237   GtkWidget *vbox, *vbox2, *vbox3;
238   GtkWidget *hbox;
239   GtkWidget *hbbox;
240   GtkWidget *calendar;
241   GtkWidget *toggle;
242   GtkWidget *button;
243   GtkWidget *frame;
244   GtkWidget *separator;
245   GtkWidget *label;
246   GtkWidget *bbox;
247   static CalendarData calendar_data;
248   gint i;
249
250   struct {
251     char *label;
252   } flags[] =
253     {
254       { "Show Heading" },
255       { "Show Day Names" },
256       { "No Month Change" },
257       { "Show Week Numbers" },
258       { "Week Start Monday" }
259     };
260
261
262   calendar_data.window = NULL;
263   calendar_data.font_dialog = NULL;
264
265   for (i = 0; i < 5; i++) {
266     calendar_data.settings[i] = 0;
267   }
268
269   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
270   gtk_window_set_title (GTK_WINDOW (window), "GtkCalendar Example");
271   gtk_container_set_border_width (GTK_CONTAINER (window), 5);
272   g_signal_connect (window, "destroy",
273                     G_CALLBACK (gtk_main_quit),
274                     NULL);
275   g_signal_connect (window, "delete-event",
276                     G_CALLBACK (gtk_false),
277                     NULL);
278   gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
279
280   vbox = gtk_vbox_new (FALSE, DEF_PAD);
281   gtk_container_add (GTK_CONTAINER (window), vbox);
282
283   /*
284    * The top part of the window, Calendar, flags and fontsel.
285    */
286
287   hbox = gtk_hbox_new (FALSE, DEF_PAD);
288   gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, DEF_PAD);
289   hbbox = gtk_hbutton_box_new ();
290   gtk_box_pack_start (GTK_BOX (hbox), hbbox, FALSE, FALSE, DEF_PAD);
291   gtk_button_box_set_layout (GTK_BUTTON_BOX (hbbox), GTK_BUTTONBOX_SPREAD);
292   gtk_box_set_spacing (GTK_BOX (hbbox), 5);
293
294   /* Calendar widget */
295   frame = gtk_frame_new ("Calendar");
296   gtk_box_pack_start(GTK_BOX (hbbox), frame, FALSE, TRUE, DEF_PAD);
297   calendar=gtk_calendar_new ();
298   calendar_data.window = calendar;
299   calendar_set_flags (&calendar_data);
300   gtk_calendar_mark_day (GTK_CALENDAR (calendar), 19);
301   gtk_container_add (GTK_CONTAINER (frame), calendar);
302   g_signal_connect (calendar, "month-changed",
303                     G_CALLBACK (calendar_month_changed),
304                     &calendar_data);
305   g_signal_connect (calendar, "day-selected",
306                     G_CALLBACK (calendar_day_selected),
307                     &calendar_data);
308   g_signal_connect (calendar, "day-selected-double-click",
309                     G_CALLBACK (calendar_day_selected_double_click),
310                     &calendar_data);
311   g_signal_connect (calendar, "prev-month",
312                     G_CALLBACK (calendar_prev_month),
313                     &calendar_data);
314   g_signal_connect (calendar, "next-month",
315                     G_CALLBACK (calendar_next_month),
316                     &calendar_data);
317   g_signal_connect (calendar, "prev-year",
318                     G_CALLBACK (calendar_prev_year),
319                     &calendar_data);
320   g_signal_connect (calendar, "next-year",
321                     G_CALLBACK (calendar_next_year),
322                     &calendar_data);
323
324
325   separator = gtk_vseparator_new ();
326   gtk_box_pack_start (GTK_BOX (hbox), separator, FALSE, TRUE, 0);
327
328   vbox2 = gtk_vbox_new (FALSE, DEF_PAD);
329   gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, DEF_PAD);
330
331   /* Build the Right frame with the flags in */
332
333   frame = gtk_frame_new ("Flags");
334   gtk_box_pack_start (GTK_BOX (vbox2), frame, TRUE, TRUE, DEF_PAD);
335   vbox3 = gtk_vbox_new (TRUE, DEF_PAD_SMALL);
336   gtk_container_add (GTK_CONTAINER (frame), vbox3);
337
338   for (i = 0; i < 5; i++)
339     {
340       toggle = gtk_check_button_new_with_label (flags[i].label);
341       g_signal_connect (toggle,
342                         "toggled",
343                         G_CALLBACK (calendar_toggle_flag),
344                         &calendar_data);
345       gtk_box_pack_start (GTK_BOX (vbox3), toggle, TRUE, TRUE, 0);
346       calendar_data.flag_checkboxes[i] = toggle;
347     }
348   /* Build the right font-button */
349   button = gtk_button_new_with_label ("Font...");
350   g_signal_connect (button,
351                     "clicked",
352                     G_CALLBACK (calendar_select_font),
353                     &calendar_data);
354   gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
355
356   /*
357    *  Build the Signal-event part.
358    */
359
360   frame = gtk_frame_new ("Signal events");
361   gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, DEF_PAD);
362
363   vbox2 = gtk_vbox_new (TRUE, DEF_PAD_SMALL);
364   gtk_container_add (GTK_CONTAINER (frame), vbox2);
365
366   hbox = gtk_hbox_new (FALSE, 3);
367   gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, TRUE, 0);
368   label = gtk_label_new ("Signal:");
369   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
370   calendar_data.last_sig = gtk_label_new ("");
371   gtk_box_pack_start (GTK_BOX (hbox), calendar_data.last_sig, FALSE, TRUE, 0);
372
373   hbox = gtk_hbox_new (FALSE, 3);
374   gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, TRUE, 0);
375   label = gtk_label_new ("Previous signal:");
376   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
377   calendar_data.prev_sig = gtk_label_new ("");
378   gtk_box_pack_start (GTK_BOX (hbox), calendar_data.prev_sig, FALSE, TRUE, 0);
379
380   hbox = gtk_hbox_new (FALSE, 3);
381   gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, TRUE, 0);
382   label = gtk_label_new ("Second previous signal:");
383   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
384   calendar_data.prev2_sig = gtk_label_new ("");
385   gtk_box_pack_start (GTK_BOX (hbox), calendar_data.prev2_sig, FALSE, TRUE, 0);
386
387   bbox = gtk_hbutton_box_new ();
388   gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0);
389   gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
390
391   button = gtk_button_new_with_label ("Close");
392   g_signal_connect (button, "clicked",
393                     G_CALLBACK (gtk_main_quit),
394                     NULL);
395   gtk_container_add (GTK_CONTAINER (bbox), button);
396   GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
397   gtk_widget_grab_default (button);
398
399   gtk_widget_show_all (window);
400 }
401
402
403 int main (int   argc,
404           char *argv[])
405 {
406   gtk_init (&argc, &argv);
407
408   create_calendar ();
409
410   gtk_main ();
411
412   return 0;
413 }