1 | /* example-start calendar calendar.c */ |
2 | /* |
3 | * Copyright (C) 1998 Cesar Miquel, Shawn T. Amundson, Mattias Grönlund |
4 | * Copyright (C) 2000 Tony Gale |
5 | * |
6 | * This library is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU Lesser General Public License as published by |
8 | * the Free Software Foundation; either version 2.1 of the License, or |
9 | * (at your option) any later version. |
10 | * |
11 | * This library 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 Lesser General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Lesser General Public |
17 | * License along with this program. If not, see <http://www.gnu.org/licenses/>. |
18 | */ |
19 | |
20 | #include "config.h" |
21 | #include <stdio.h> |
22 | #include <string.h> |
23 | #include <gtk/gtk.h> |
24 | |
25 | #define DEF_PAD_SMALL 6 |
26 | |
27 | #define TM_YEAR_BASE 1900 |
28 | |
29 | typedef struct _CalendarData |
30 | { |
31 | GtkWidget *calendar_widget; |
32 | GtkWidget *prev2_sig; |
33 | GtkWidget *prev_sig; |
34 | GtkWidget *last_sig; |
35 | GtkWidget *month; |
36 | } CalendarData; |
37 | |
38 | enum |
39 | { |
40 | , |
41 | calendar_show_days, |
42 | calendar_month_change, |
43 | calendar_show_week, |
44 | calendar_monday_first |
45 | }; |
46 | |
47 | /* |
48 | * GtkCalendar |
49 | */ |
50 | |
51 | static char * |
52 | calendar_date_to_string (CalendarData *data, |
53 | const char *format) |
54 | { |
55 | GDateTime *date; |
56 | char *str; |
57 | |
58 | date = gtk_calendar_get_date (GTK_CALENDAR (data->calendar_widget)); |
59 | str = g_date_time_format (datetime: date, format); |
60 | |
61 | g_date_time_unref (datetime: date); |
62 | |
63 | return str; |
64 | } |
65 | |
66 | static void |
67 | calendar_set_signal_strings (char *sig_str, |
68 | CalendarData *data) |
69 | { |
70 | const char *prev_sig; |
71 | |
72 | prev_sig = gtk_label_get_text (GTK_LABEL (data->prev_sig)); |
73 | gtk_label_set_text (GTK_LABEL (data->prev2_sig), str: prev_sig); |
74 | |
75 | prev_sig = gtk_label_get_text (GTK_LABEL (data->last_sig)); |
76 | gtk_label_set_text (GTK_LABEL (data->prev_sig), str: prev_sig); |
77 | gtk_label_set_text (GTK_LABEL (data->last_sig), str: sig_str); |
78 | } |
79 | |
80 | static void |
81 | calendar_day_selected (GtkWidget *widget, |
82 | CalendarData *data) |
83 | { |
84 | char *str = calendar_date_to_string (data, format: "day-selected: %c" ); |
85 | calendar_set_signal_strings (sig_str: str, data); |
86 | g_free (mem: str); |
87 | } |
88 | |
89 | static void |
90 | calendar_prev_month (GtkWidget *widget, |
91 | CalendarData *data) |
92 | { |
93 | char *str = calendar_date_to_string (data, format: "prev-month: %c" ); |
94 | calendar_set_signal_strings (sig_str: str, data); |
95 | g_free (mem: str); |
96 | } |
97 | |
98 | static void |
99 | calendar_next_month (GtkWidget *widget, |
100 | CalendarData *data) |
101 | { |
102 | char *str = calendar_date_to_string (data, format: "next-month: %c" ); |
103 | calendar_set_signal_strings (sig_str: str, data); |
104 | g_free (mem: str); |
105 | |
106 | } |
107 | |
108 | static void |
109 | calendar_prev_year (GtkWidget *widget, |
110 | CalendarData *data) |
111 | { |
112 | char *str = calendar_date_to_string (data, format: "prev-year: %c" ); |
113 | calendar_set_signal_strings (sig_str: str, data); |
114 | g_free (mem: str); |
115 | } |
116 | |
117 | static void |
118 | calendar_next_year (GtkWidget *widget, |
119 | CalendarData *data) |
120 | { |
121 | char *str = calendar_date_to_string (data, format: "next-year: %c" ); |
122 | calendar_set_signal_strings (sig_str: str, data); |
123 | g_free (mem: str); |
124 | } |
125 | |
126 | static void |
127 | flag_toggled_cb (GtkCheckButton *button, |
128 | gpointer user_data) |
129 | { |
130 | struct { |
131 | const char *prop_name; |
132 | const char *label; |
133 | GtkWidget *calendar; |
134 | } *data = user_data; |
135 | |
136 | g_object_set (G_OBJECT (data->calendar), first_property_name: data->prop_name, |
137 | gtk_check_button_get_active (GTK_CHECK_BUTTON (button)), |
138 | NULL); |
139 | } |
140 | |
141 | static GtkWidget* |
142 | create_frame (const char *caption, |
143 | GtkWidget *child, |
144 | GtkAlign halign, |
145 | GtkAlign valign) |
146 | { |
147 | GtkWidget *frame = gtk_frame_new (label: "" ); |
148 | GtkWidget *label = gtk_frame_get_label_widget (GTK_FRAME (frame)); |
149 | |
150 | g_object_set (object: child, |
151 | first_property_name: "margin-top" , 6, |
152 | "margin-bottom" , 0, |
153 | "margin-start" , 18, |
154 | "margin-end" , 0, |
155 | "halign" , halign, |
156 | "valign" , valign, |
157 | NULL); |
158 | gtk_label_set_markup (GTK_LABEL (label), str: caption); |
159 | |
160 | gtk_frame_set_child (GTK_FRAME (frame), child); |
161 | |
162 | return frame; |
163 | } |
164 | |
165 | static void |
166 | quit_cb (GtkWidget *widget, |
167 | gpointer data) |
168 | { |
169 | gboolean *done = data; |
170 | |
171 | *done = TRUE; |
172 | |
173 | g_main_context_wakeup (NULL); |
174 | } |
175 | |
176 | static void |
177 | create_calendar(void) |
178 | { |
179 | static CalendarData calendar_data; |
180 | |
181 | GtkWidget *window, *hpaned, *vbox, *rpane, *hbox; |
182 | GtkWidget *calendar = gtk_calendar_new (); |
183 | GtkWidget *button; |
184 | GtkWidget *frame, *label, *bbox; |
185 | int i; |
186 | struct { |
187 | const char *prop_name; |
188 | const char *label; |
189 | GtkWidget *calendar; |
190 | } flags[] = { |
191 | { "show-heading" , "Show Heading" , calendar }, |
192 | { "show-day-names" , "Show Day Names" , calendar }, |
193 | { "show-week-numbers" , "Show Week Numbers" , calendar }, |
194 | }; |
195 | gboolean done = FALSE; |
196 | |
197 | window = gtk_window_new (); |
198 | gtk_window_set_hide_on_close (GTK_WINDOW (window), TRUE); |
199 | gtk_window_set_title (GTK_WINDOW (window), title: "GtkCalendar Example" ); |
200 | g_signal_connect (window, "destroy" , G_CALLBACK (quit_cb), &done); |
201 | |
202 | hpaned = gtk_paned_new (orientation: GTK_ORIENTATION_HORIZONTAL); |
203 | gtk_widget_set_vexpand (widget: hpaned, TRUE); |
204 | |
205 | /* Calendar widget */ |
206 | |
207 | calendar_data.calendar_widget = calendar; |
208 | frame = create_frame (caption: "<b>Calendar</b>" , child: calendar, halign: GTK_ALIGN_CENTER, valign: GTK_ALIGN_CENTER); |
209 | gtk_paned_set_start_child (GTK_PANED (hpaned), child: frame); |
210 | gtk_paned_set_resize_start_child (GTK_PANED (hpaned), TRUE); |
211 | gtk_paned_set_shrink_start_child (GTK_PANED (hpaned), FALSE); |
212 | |
213 | gtk_calendar_mark_day (GTK_CALENDAR (calendar), day: 19); |
214 | |
215 | g_signal_connect (calendar, "day-selected" , |
216 | G_CALLBACK (calendar_day_selected), |
217 | &calendar_data); |
218 | g_signal_connect (calendar, "prev-month" , |
219 | G_CALLBACK (calendar_prev_month), |
220 | &calendar_data); |
221 | g_signal_connect (calendar, "next-month" , |
222 | G_CALLBACK (calendar_next_month), |
223 | &calendar_data); |
224 | g_signal_connect (calendar, "prev-year" , |
225 | G_CALLBACK (calendar_prev_year), |
226 | &calendar_data); |
227 | g_signal_connect (calendar, "next-year" , |
228 | G_CALLBACK (calendar_next_year), |
229 | &calendar_data); |
230 | |
231 | rpane = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, DEF_PAD_SMALL); |
232 | gtk_paned_set_end_child (GTK_PANED (hpaned), child: rpane); |
233 | gtk_paned_set_resize_end_child (GTK_PANED (hpaned), FALSE); |
234 | gtk_paned_set_shrink_end_child (GTK_PANED (hpaned), FALSE); |
235 | |
236 | vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, DEF_PAD_SMALL); |
237 | frame = create_frame (caption: "<b>Options</b>" , child: vbox, halign: GTK_ALIGN_FILL, valign: GTK_ALIGN_CENTER); |
238 | gtk_box_append (GTK_BOX (rpane), child: frame); |
239 | |
240 | hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, DEF_PAD_SMALL); |
241 | gtk_widget_set_halign (widget: hbox, align: GTK_ALIGN_START); |
242 | gtk_widget_set_valign (widget: hbox, align: GTK_ALIGN_CENTER); |
243 | gtk_box_append (GTK_BOX (vbox), child: hbox); |
244 | |
245 | /* Build the Right frame with the flags in */ |
246 | |
247 | vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0); |
248 | gtk_box_append (GTK_BOX (rpane), child: vbox); |
249 | |
250 | for (i = 0; i < G_N_ELEMENTS (flags); i++) |
251 | { |
252 | GtkWidget *toggle = gtk_check_button_new_with_mnemonic (label: flags[i].label); |
253 | gboolean value; |
254 | |
255 | gtk_box_append (GTK_BOX (vbox), child: toggle); |
256 | |
257 | g_object_get (G_OBJECT (calendar), first_property_name: flags[i].prop_name, &value, NULL); |
258 | gtk_check_button_set_active (GTK_CHECK_BUTTON (toggle), setting: value); |
259 | |
260 | g_signal_connect (toggle, "toggled" , G_CALLBACK (flag_toggled_cb), &flags[i]); |
261 | } |
262 | |
263 | /* |
264 | * Build the Signal-event part. |
265 | */ |
266 | |
267 | vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, DEF_PAD_SMALL); |
268 | gtk_box_set_homogeneous (GTK_BOX (vbox), TRUE); |
269 | frame = create_frame (caption: "<b>Signal Events</b>" , child: vbox, halign: GTK_ALIGN_FILL, valign: GTK_ALIGN_CENTER); |
270 | |
271 | hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 3); |
272 | gtk_box_append (GTK_BOX (vbox), child: hbox); |
273 | label = gtk_label_new (str: "Signal:" ); |
274 | gtk_box_append (GTK_BOX (hbox), child: label); |
275 | calendar_data.last_sig = gtk_label_new (str: "" ); |
276 | gtk_box_append (GTK_BOX (hbox), child: calendar_data.last_sig); |
277 | |
278 | hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 3); |
279 | gtk_box_append (GTK_BOX (vbox), child: hbox); |
280 | label = gtk_label_new (str: "Previous signal:" ); |
281 | gtk_box_append (GTK_BOX (hbox), child: label); |
282 | calendar_data.prev_sig = gtk_label_new (str: "" ); |
283 | gtk_box_append (GTK_BOX (hbox), child: calendar_data.prev_sig); |
284 | |
285 | hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 3); |
286 | gtk_box_append (GTK_BOX (vbox), child: hbox); |
287 | label = gtk_label_new (str: "Second previous signal:" ); |
288 | gtk_box_append (GTK_BOX (hbox), child: label); |
289 | calendar_data.prev2_sig = gtk_label_new (str: "" ); |
290 | gtk_box_append (GTK_BOX (hbox), child: calendar_data.prev2_sig); |
291 | |
292 | /* |
293 | * Glue everything together |
294 | */ |
295 | |
296 | bbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0); |
297 | gtk_widget_set_halign (widget: bbox, align: GTK_ALIGN_END); |
298 | |
299 | button = gtk_button_new_with_label (label: "Close" ); |
300 | g_signal_connect (button, "clicked" , G_CALLBACK (quit_cb), &done); |
301 | gtk_box_append (GTK_BOX (bbox), child: button); |
302 | |
303 | vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, DEF_PAD_SMALL); |
304 | |
305 | gtk_box_append (GTK_BOX (vbox), child: hpaned); |
306 | gtk_box_append (GTK_BOX (vbox), child: gtk_separator_new (orientation: GTK_ORIENTATION_HORIZONTAL)); |
307 | gtk_box_append (GTK_BOX (vbox), child: frame); |
308 | gtk_box_append (GTK_BOX (vbox), child: gtk_separator_new (orientation: GTK_ORIENTATION_HORIZONTAL)); |
309 | gtk_box_append (GTK_BOX (vbox), child: bbox); |
310 | |
311 | gtk_window_set_child (GTK_WINDOW (window), child: vbox); |
312 | |
313 | gtk_window_set_default_widget (GTK_WINDOW (window), default_widget: button); |
314 | |
315 | gtk_window_set_default_size (GTK_WINDOW (window), width: 600, height: 0); |
316 | g_signal_connect (window, "close-request" , G_CALLBACK (quit_cb), &done); |
317 | gtk_widget_show (widget: window); |
318 | |
319 | while (!done) |
320 | g_main_context_iteration (NULL, TRUE); |
321 | } |
322 | |
323 | |
324 | int main(int argc, |
325 | char *argv[] ) |
326 | { |
327 | gtk_init (); |
328 | |
329 | if (g_getenv (variable: "GTK_RTL" )) |
330 | gtk_widget_set_default_direction (dir: GTK_TEXT_DIR_RTL); |
331 | |
332 | create_calendar(); |
333 | |
334 | return(0); |
335 | } |
336 | /* example-end */ |
337 | |