aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/misc/e-calendar-item.h
blob: 0032e12a6c50979ad18654fcf8b84e32c6bf05ad (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
/*
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) version 3.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with the program; if not, see <http://www.gnu.org/licenses/>  
 *
 *
 * Authors:
 *      Damon Chaplin <damon@ximian.com>
 *
 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 *
 */
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */

#ifndef _E_CALENDAR_ITEM_H_
#define _E_CALENDAR_ITEM_H_

#include <libgnomecanvas/gnome-canvas.h>

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/*
 * ECalendarItem - canvas item displaying a calendar.
 */

#define E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME   1
#define E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME   1

/* The number of rows & columns of days in each month. */
#define E_CALENDAR_ROWS_PER_MONTH   6
#define E_CALENDAR_COLS_PER_MONTH   7

/* Used to mark days as bold in e_calendar_item_mark_day(). */
#define E_CALENDAR_ITEM_MARK_BOLD   1

/*
 * These are the padding sizes between various pieces of the calendar.
 */

/* The minimum padding around the numbers in each cell/day. */
#define E_CALENDAR_ITEM_MIN_CELL_XPAD   4
#define E_CALENDAR_ITEM_MIN_CELL_YPAD   0

/* Vertical padding. */
#define E_CALENDAR_ITEM_YPAD_ABOVE_DAY_LETTERS      1
#define E_CALENDAR_ITEM_YPAD_BELOW_DAY_LETTERS      0
#define E_CALENDAR_ITEM_YPAD_ABOVE_CELLS        1
#define E_CALENDAR_ITEM_YPAD_BELOW_CELLS        2

/* Horizontal padding in the heading bars. */
#define E_CALENDAR_ITEM_XPAD_BEFORE_MONTH_NAME_WITH_BUTTON  16
#define E_CALENDAR_ITEM_XPAD_BEFORE_MONTH_NAME          3
#define E_CALENDAR_ITEM_XPAD_AFTER_MONTH_NAME           3
#define E_CALENDAR_ITEM_XPAD_AFTER_MONTH_NAME_WITH_BUTTON   16

/* Horizontal padding in the month displays. */
#define E_CALENDAR_ITEM_XPAD_BEFORE_WEEK_NUMBERS    4
#define E_CALENDAR_ITEM_XPAD_AFTER_WEEK_NUMBERS     2
#define E_CALENDAR_ITEM_XPAD_BEFORE_CELLS       1
#define E_CALENDAR_ITEM_XPAD_AFTER_CELLS        4


/* These index our colors array. */
typedef enum
{
    E_CALENDAR_ITEM_COLOR_TODAY_BOX,
    E_CALENDAR_ITEM_COLOR_SELECTION_FG,
    E_CALENDAR_ITEM_COLOR_SELECTION_BG_FOCUSED,
    E_CALENDAR_ITEM_COLOR_SELECTION_BG,
    E_CALENDAR_ITEM_COLOR_PREV_OR_NEXT_MONTH_FG,

    E_CALENDAR_ITEM_COLOR_LAST
} ECalendarItemColors;

typedef struct _ECalendarItem       ECalendarItem;
typedef struct _ECalendarItemClass  ECalendarItemClass;

/* The type of the callback function optionally used to get the colors to
   use for each day. */
typedef void (*ECalendarItemStyleCallback)   (ECalendarItem *calitem,
                          gint       year,
                          gint       month,
                          gint       day,
                          gint       day_style,
                          gboolean       today,
                          gboolean       prev_or_next_month,
                          gboolean       selected,
                          gboolean       has_focus,
                          gboolean       drop_target,
                          GdkColor         **bg_color,
                          GdkColor         **fg_color,
                          GdkColor         **box_color,
                          gboolean      *bold,
                          gpointer       data);

/* The type of the callback function optionally used to get the current time.
 */
typedef struct tm (*ECalendarItemGetTimeCallback) (ECalendarItem *calitem,
                           gpointer   data);


#define E_CALENDAR_ITEM(obj)     (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
        e_calendar_item_get_type (), ECalendarItem))
#define E_CALENDAR_ITEM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k),\
    e_calendar_item_get_type ()))
#define E_IS_CALENDAR_ITEM(o)    (G_TYPE_CHECK_INSTANCE_TYPE ((o), \
    e_calendar_item_get_type ()))

struct _ECalendarItem
{
    GnomeCanvasItem canvas_item;

    /* The year & month of the first calendar being displayed. */
    gint year;
    gint month; /* 0 to 11 */

    /* Points to an array of styles, one char for each day. We use 32
       chars for each month, with n + 2 months, where n is the number of
       complete months shown (since we show some days before the first
       month and after the last month grayes out).
       A value of 0 is the default, and 1 is bold. */
    guint8 *styles;

    /*
     * Options.
     */

    /* The minimum & maximum number of rows & columns of months.
       If the maximum values are -1 then there is no maximum.
       The minimum valies default to 1. The maximum values to -1. */
    gint min_rows;
    gint min_cols;
    gint max_rows;
    gint max_cols;

    /* The actual number of rows & columns of months. */
    gint rows;
    gint cols;

    /* Whether we show week nubers. */
    gboolean show_week_numbers;

    /* The first day of the week, 0 (Monday) to 6 (Sunday). */
    gint week_start_day;

    /* Whether the cells expand to fill extra space. */
    gboolean expand;

    /* The maximum number of days that can be selected. Defaults to 1. */
    gint max_days_selected;

    /* The number of days selected before we switch to selecting whole
       weeks, or -1 if we never switch. Defaults to -1. */
    gint days_to_start_week_selection;

    /* Whether the selection is moved when we move back/forward one month.
       Used for things like the EDateEdit which only want the selection to
       be changed when the user explicitly selects a day. */
    gboolean move_selection_when_moving;

    /* Whether the selection day is preserved when we  move back/forward
       one month. Used for the work week and week view. */
    gboolean preserve_day_when_moving;

    /* Whether to display the pop-up, TRUE by default */
    gboolean display_popup;

    /*
     * Internal stuff.
     */

    /* Bounds of item. */
    gdouble x1, y1, x2, y2;

    /* The minimum size of each month, based on the fonts used. */
    gint min_month_width;
    gint min_month_height;

    /* The actual size of each month, after dividing extra space. */
    gint month_width;
    gint month_height;

    /* The offset to the left edge of the first calendar. */
    gint x_offset;

    /* The padding around each calendar month. */
    gint month_lpad, month_rpad;
    gint month_tpad, month_bpad;

    /* The size of each cell. */
    gint cell_width;
    gint cell_height;

    /* The current selection. The month offsets are from 0, which is the
       top-left calendar month view. Note that -1 is used for the last days
       from the previous month. The days are real month days. */
    gboolean selecting;
    GDate *selecting_axis;
    gboolean selection_dragging_end;
    gboolean selection_from_full_week;
    gboolean selection_set;
    gint selection_start_month_offset;
    gint selection_start_day;
    gint selection_end_month_offset;
    gint selection_end_day;
    gint selection_real_start_month_offset;
    gint selection_real_start_day;

    /* Widths of the day characters. */
    gint day_widths[7];
    gint max_day_width;

    /* Widths of the digits, '0' .. '9'. */
    gint digit_widths[10];
    gint max_digit_width;

    gint week_number_digit_widths[10];
    gint max_week_number_digit_width;

    /* Fonts for drawing text. If font isn't set it uses the font from the
       canvas widget. If week_number_font isn't set it uses font. */
    PangoFontDescription *font_desc;
    PangoFontDescription *week_number_font_desc;

    ECalendarItemStyleCallback style_callback;
    gpointer style_callback_data;
    GDestroyNotify style_callback_destroy;

    ECalendarItemGetTimeCallback time_callback;
    gpointer time_callback_data;
    GDestroyNotify time_callback_destroy;

    /* Colors for drawing. */
    GdkColor colors[E_CALENDAR_ITEM_COLOR_LAST];

    /* Our idle handler for emitting signals. */
    gint signal_emission_idle_id;

    /* A flag to indicate that the selection or date range has changed.
       When set the idle function will emit the signal and reset it to
       FALSE. This is so we don't emit it several times when args are set
       etc. */
    gboolean selection_changed;
    gboolean date_range_changed;
};

struct _ECalendarItemClass
{
    GnomeCanvasItemClass parent_class;

    void (* date_range_changed) (ECalendarItem *calitem);
    void (* selection_changed)  (ECalendarItem *calitem);
    void (* selection_preview_changed)  (ECalendarItem *calitem);
};


GType    e_calendar_item_get_type       (void);

/* FIXME: months are 0-11 throughout, but 1-12 may be better. */

void     e_calendar_item_get_first_month    (ECalendarItem  *calitem,
                         gint       *year,
                         gint       *month);
void     e_calendar_item_set_first_month    (ECalendarItem  *calitem,
                         gint        year,
                         gint        month);

/* Get the maximum number of days selectable */
gint     e_calendar_item_get_max_days_sel       (ECalendarItem  *calitem);

/* Set the maximum number of days selectable */
void     e_calendar_item_set_max_days_sel       (ECalendarItem  *calitem,
                         gint            days);

/* Get the maximum number of days selectable */
gint     e_calendar_item_get_days_start_week_sel(ECalendarItem  *calitem);

/* Set the maximum number of days selectable */
void     e_calendar_item_set_days_start_week_sel(ECalendarItem  *calitem,
                         gint            days);

/* Set the maximum number of days before whole weeks are selected */
gboolean e_calendar_item_get_display_popup      (ECalendarItem  *calitem);

/* Get the maximum number of days before whole weeks are selected */
void     e_calendar_item_set_display_popup      (ECalendarItem  *calitem,
                         gboolean        display);

/* Gets the range of dates actually shown. Months are 0 to 11.
   This also includes the last days of the previous month and the first days
   of the following month, which are normally shown in gray.
   It returns FALSE if no dates are currently shown. */
gboolean e_calendar_item_get_date_range     (ECalendarItem  *calitem,
                         gint       *start_year,
                         gint       *start_month,
                         gint       *start_day,
                         gint       *end_year,
                         gint       *end_month,
                         gint       *end_day);

/* Returns the selected date range. It returns FALSE if no days are currently
   selected. */
gboolean e_calendar_item_get_selection      (ECalendarItem  *calitem,
                         GDate      *start_date,
                         GDate      *end_date);
/* Sets the selected date range, and changes the date range shown so at least
   the start of the selection is shown. If start_date is NULL it clears the
   selection. */
void     e_calendar_item_set_selection      (ECalendarItem  *calitem,
                         GDate      *start_date,
                         GDate      *end_date);

/* Marks a particular day. Passing E_CALENDAR_ITEM_MARK_BOLD as the day style
   will result in the day being shown as bold by default. The style callback
   could support more day_styles, or the style callback could determine the
   colors itself, without needing to mark days. */
void     e_calendar_item_clear_marks        (ECalendarItem  *calitem);
void     e_calendar_item_mark_day       (ECalendarItem  *calitem,
                         gint        year,
                         gint        month,
                         gint        day,
                         guint8      day_style);

/* Mark a range of days. Any days outside the currently shown range are
   ignored. */
void     e_calendar_item_mark_days      (ECalendarItem  *calitem,
                         gint        start_year,
                         gint        start_month,
                         gint        start_day,
                         gint        end_year,
                         gint        end_month,
                         gint        end_day,
                         guint8      day_style);

/* Sets the function to call to get the colors to use for a particular day. */
void     e_calendar_item_set_style_callback (ECalendarItem  *calitem,
                         ECalendarItemStyleCallback cb,
                         gpointer    data,
                         GDestroyNotify  destroy);

/* Sets a callback to use to get the current time. This is useful if the
   application needs to use its own timezone data rather than rely on the
   Unix timezone. */
void     e_calendar_item_set_get_time_callback  (ECalendarItem  *calitem,
                         ECalendarItemGetTimeCallback cb,
                         gpointer    data,
                         GDestroyNotify  destroy);
void e_calendar_item_normalize_date (ECalendarItem  *calitem,
                     gint       *year,
                     gint       *month);
gint e_calendar_item_get_week_number    (ECalendarItem *calitem,
                     gint       day,
                     gint       month,
                     gint       year);
void e_calendar_item_style_set (GtkWidget *widget, ECalendarItem *calitem);


#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* _E_CALENDAR_ITEM_H_ */