diff options
Diffstat (limited to 'calendar/gui/weekday-picker.c')
-rw-r--r-- | calendar/gui/weekday-picker.c | 624 |
1 files changed, 0 insertions, 624 deletions
diff --git a/calendar/gui/weekday-picker.c b/calendar/gui/weekday-picker.c deleted file mode 100644 index a37b4b7320..0000000000 --- a/calendar/gui/weekday-picker.c +++ /dev/null @@ -1,624 +0,0 @@ -/* - * Evolution calendar - Week day picker widget - * - * 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: - * Federico Mena-Quintero <federico@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <gtk/gtk.h> -#include <gdk/gdkkeysyms.h> -#include <glib/gi18n.h> -#include <libgnomecanvas/libgnomecanvas.h> -#include <e-util/e-util.h> -#include "weekday-picker.h" - -#define PADDING 2 - -#define WEEKDAY_PICKER_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), TYPE_WEEKDAY_PICKER, WeekdayPickerPrivate)) - -/* Private part of the WeekdayPicker structure */ -struct _WeekdayPickerPrivate { - /* Selected days; see weekday_picker_set_days() */ - guint8 day_mask; - - /* Blocked days; these cannot be modified */ - guint8 blocked_day_mask; - - /* Day that defines the start of the week; 0 = Sunday, ..., 6 = Saturday */ - gint week_start_day; - - /* Current keyboard focus day */ - gint focus_day; - - /* Metrics */ - gint font_ascent, font_descent; - gint max_letter_width; - - /* Components */ - GnomeCanvasItem *boxes[7]; - GnomeCanvasItem *labels[7]; -}; - -/* Signal IDs */ -enum { - CHANGED, - LAST_SIGNAL -}; - -static guint wp_signals[LAST_SIGNAL]; - -G_DEFINE_TYPE (WeekdayPicker, weekday_picker, GNOME_TYPE_CANVAS) - -static gchar * -get_day_text (gint day_index) -{ - GDateWeekday weekday; - - /* Convert from tm_wday to GDateWeekday. */ - weekday = (day_index == 0) ? G_DATE_SUNDAY : day_index; - - return g_strdup (e_get_weekday_name (weekday, TRUE)); -} - -static void -colorize_items (WeekdayPicker *wp) -{ - WeekdayPickerPrivate *priv; - GdkColor *outline, *focus_outline; - GdkColor *fill, *sel_fill; - GdkColor *text_fill, *sel_text_fill; - GtkStateType state; - GtkStyle *style; - gint i; - - priv = wp->priv; - - state = gtk_widget_get_state (GTK_WIDGET (wp)); - style = gtk_widget_get_style (GTK_WIDGET (wp)); - - outline = &style->fg[state]; - focus_outline = &style->bg[state]; - - fill = &style->base[state]; - text_fill = &style->fg[state]; - - sel_fill = &style->bg[GTK_STATE_SELECTED]; - sel_text_fill = &style->fg[GTK_STATE_SELECTED]; - - for (i = 0; i < 7; i++) { - gint day; - GdkColor *f, *t, *o; - - day = i + priv->week_start_day; - if (day >= 7) - day -= 7; - - if (priv->day_mask & (0x1 << day)) { - f = sel_fill; - t = sel_text_fill; - } else { - f = fill; - t = text_fill; - } - - if (day == priv->focus_day) - o = focus_outline; - else - o = outline; - - gnome_canvas_item_set ( - priv->boxes[i], - "fill_color_gdk", f, - "outline_color_gdk", o, - NULL); - - gnome_canvas_item_set ( - priv->labels[i], - "fill_color_gdk", t, - NULL); - } -} - -static void -configure_items (WeekdayPicker *wp) -{ - WeekdayPickerPrivate *priv; - GtkAllocation allocation; - gint width, height; - gint box_width; - gint i; - - priv = wp->priv; - - gtk_widget_get_allocation (GTK_WIDGET (wp), &allocation); - - width = allocation.width; - height = allocation.height; - - box_width = (width - 1) / 7; - - for (i = 0; i < 7; i++) { - gchar *c; - gint day; - - day = i + priv->week_start_day; - if (day >= 7) - day -= 7; - - gnome_canvas_item_set ( - priv->boxes[i], - "x1", (gdouble) (i * box_width), - "y1", (gdouble) 0, - "x2", (gdouble) ((i + 1) * box_width), - "y2", (gdouble) (height - 1), - "line_width", 0.0, - NULL); - - c = get_day_text (day); - gnome_canvas_item_set ( - priv->labels[i], - "text", c, - "x", (gdouble) (i * box_width) + PADDING, - "y", (gdouble) (1 + PADDING), - NULL); - g_free (c); - } - - colorize_items (wp); -} - -static void -weekday_picker_realize (GtkWidget *widget) -{ - WeekdayPicker *wp; - - wp = WEEKDAY_PICKER (widget); - - /* Chain up to parent's realize() method. */ - GTK_WIDGET_CLASS (weekday_picker_parent_class)->realize (widget); - - configure_items (wp); -} - -static void -weekday_picker_get_preferred_width (GtkWidget *widget, - gint *minimum_width, - gint *natural_width) -{ - WeekdayPicker *wp; - WeekdayPickerPrivate *priv; - - wp = WEEKDAY_PICKER (widget); - priv = wp->priv; - - *minimum_width = *natural_width = - (priv->max_letter_width + 2 * PADDING + 1) * 7 + 1; -} - -static void -weekday_picker_get_preferred_height (GtkWidget *widget, - gint *minimum_height, - gint *natural_height) -{ - WeekdayPicker *wp; - WeekdayPickerPrivate *priv; - - wp = WEEKDAY_PICKER (widget); - priv = wp->priv; - - *minimum_height = *natural_height = - (priv->font_ascent + priv->font_descent + 2 * PADDING + 2); -} - -static void -weekday_picker_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) -{ - GtkWidgetClass *widget_class; - WeekdayPicker *wp; - - wp = WEEKDAY_PICKER (widget); - - /* Chain up to parent's size_allocate() method. */ - widget_class = GTK_WIDGET_CLASS (weekday_picker_parent_class); - widget_class->size_allocate (widget, allocation); - - gnome_canvas_set_scroll_region ( - GNOME_CANVAS (wp), 0, 0, - allocation->width, allocation->height); - - configure_items (wp); -} - -static void -weekday_picker_style_set (GtkWidget *widget, - GtkStyle *previous_style) -{ - GtkWidgetClass *widget_class; - WeekdayPicker *wp; - WeekdayPickerPrivate *priv; - gint max_width; - gint i; - PangoFontDescription *font_desc; - PangoContext *pango_context; - PangoFontMetrics *font_metrics; - PangoLayout *layout; - - wp = WEEKDAY_PICKER (widget); - priv = wp->priv; - - /* Set up Pango prerequisites */ - font_desc = gtk_widget_get_style (widget)->font_desc; - pango_context = gtk_widget_get_pango_context (widget); - font_metrics = pango_context_get_metrics ( - pango_context, font_desc, - pango_context_get_language (pango_context)); - layout = pango_layout_new (pango_context); - - priv->font_ascent = - PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)); - priv->font_descent = - PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)); - - max_width = 0; - - for (i = 0; i < 7; i++) { - gchar *c; - gint w; - - c = get_day_text (i); - pango_layout_set_text (layout, c, strlen (c)); - pango_layout_get_pixel_size (layout, &w, NULL); - g_free (c); - - if (w > max_width) - max_width = w; - } - - priv->max_letter_width = max_width; - - configure_items (wp); - g_object_unref (layout); - pango_font_metrics_unref (font_metrics); - - /* Chain up to parent's style_set() method. */ - widget_class = GTK_WIDGET_CLASS (weekday_picker_parent_class); - widget_class->style_set (widget, previous_style); -} - -static gboolean -weekday_picker_focus (GtkWidget *widget, - GtkDirectionType direction) -{ - WeekdayPicker *wp; - WeekdayPickerPrivate *priv; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (IS_WEEKDAY_PICKER (widget), FALSE); - wp = WEEKDAY_PICKER (widget); - priv = wp->priv; - - if (!gtk_widget_get_can_focus (widget)) - return FALSE; - - if (gtk_widget_has_focus (widget)) { - priv->focus_day = -1; - colorize_items (wp); - return FALSE; - } - - priv->focus_day = priv->week_start_day; - gnome_canvas_item_grab_focus (priv->boxes[priv->focus_day]); - colorize_items (wp); - - return TRUE; -} -static void -weekday_picker_class_init (WeekdayPickerClass *class) -{ - GtkWidgetClass *widget_class; - - g_type_class_add_private (class, sizeof (WeekdayPickerPrivate)); - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->realize = weekday_picker_realize; - widget_class->get_preferred_width = weekday_picker_get_preferred_width; - widget_class->get_preferred_height = weekday_picker_get_preferred_height; - widget_class->size_allocate = weekday_picker_size_allocate; - widget_class->style_set = weekday_picker_style_set; - widget_class->focus = weekday_picker_focus; - - class->changed = NULL; - - wp_signals[CHANGED] = g_signal_new ( - "changed", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (WeekdayPickerClass, changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -day_clicked (WeekdayPicker *wp, - gint index) -{ - WeekdayPickerPrivate *priv = wp->priv; - guint8 day_mask; - - if (priv->blocked_day_mask & (0x1 << index)) - return; - - if (priv->day_mask & (0x1 << index)) - day_mask = priv->day_mask & ~(0x1 << index); - else - day_mask = priv->day_mask | (0x1 << index); - - weekday_picker_set_days (wp, day_mask); -} - -static gint -handle_key_press_event (WeekdayPicker *wp, - GdkEvent *event) -{ - WeekdayPickerPrivate *priv = wp->priv; - guint keyval = event->key.keyval; - - if (priv->focus_day == -1) - priv->focus_day = priv->week_start_day; - - switch (keyval) { - case GDK_KEY_Up: - case GDK_KEY_Right: - priv->focus_day += 1; - break; - case GDK_KEY_Down: - case GDK_KEY_Left: - priv->focus_day -= 1; - break; - case GDK_KEY_space: - case GDK_KEY_Return: - day_clicked (wp, priv->focus_day); - return TRUE; - default: - return FALSE; - } - - if (priv->focus_day > 6) - priv->focus_day = 0; - if (priv->focus_day < 0) - priv->focus_day = 6; - - colorize_items (wp); - gnome_canvas_item_grab_focus (priv->boxes[priv->focus_day]); - return TRUE; -} - -/* Event handler for the day items */ -static gint -day_event_cb (GnomeCanvasItem *item, - GdkEvent *event, - gpointer data) -{ - WeekdayPicker *wp; - WeekdayPickerPrivate *priv; - gint i; - - wp = WEEKDAY_PICKER (data); - priv = wp->priv; - - if (event->type == GDK_KEY_PRESS) - return handle_key_press_event (wp, event); - - if (!(event->type == GDK_BUTTON_PRESS && event->button.button == 1)) - return FALSE; - - /* Find which box was clicked */ - - for (i = 0; i < 7; i++) - if (priv->boxes[i] == item || priv->labels[i] == item) - break; - - g_return_val_if_fail (i != 7, TRUE); - - i += priv->week_start_day; - if (i >= 7) - i -= 7; - - priv->focus_day = i; - gnome_canvas_item_grab_focus (priv->boxes[i]); - day_clicked (wp, i); - return TRUE; -} - -/* Creates the canvas items for the weekday picker. The items are empty until - * they are configured elsewhere. - */ -static void -create_items (WeekdayPicker *wp) -{ - WeekdayPickerPrivate *priv; - GnomeCanvasGroup *parent; - gint i; - - priv = wp->priv; - - parent = gnome_canvas_root (GNOME_CANVAS (wp)); - - for (i = 0; i < 7; i++) { - priv->boxes[i] = gnome_canvas_item_new ( - parent, - GNOME_TYPE_CANVAS_RECT, - NULL); - g_signal_connect ( - priv->boxes[i], "event", - G_CALLBACK (day_event_cb), wp); - - priv->labels[i] = gnome_canvas_item_new ( - parent, - GNOME_TYPE_CANVAS_TEXT, - NULL); - g_signal_connect ( - priv->labels[i], "event", - G_CALLBACK (day_event_cb), wp); - } -} - -static void -weekday_picker_init (WeekdayPicker *wp) -{ - wp->priv = WEEKDAY_PICKER_GET_PRIVATE (wp); - - create_items (wp); - wp->priv->focus_day = -1; -} - -/** - * weekday_picker_new: - * @void: - * - * Creates a new weekday picker widget. - * - * Return value: A newly-created weekday picker. - **/ -GtkWidget * -weekday_picker_new (void) -{ - return g_object_new (TYPE_WEEKDAY_PICKER, NULL); -} - -/** - * weekday_picker_set_days: - * @wp: A weekday picker. - * @day_mask: Bitmask with the days to be selected. - * - * Sets the days that are selected in a weekday picker. In the @day_mask, - * Sunday is bit 0, Monday is bit 1, etc. - **/ -void -weekday_picker_set_days (WeekdayPicker *wp, - guint8 day_mask) -{ - g_return_if_fail (IS_WEEKDAY_PICKER (wp)); - - wp->priv->day_mask = day_mask; - colorize_items (wp); - - g_signal_emit (wp, wp_signals[CHANGED], 0); -} - -/** - * weekday_picker_get_days: - * @wp: A weekday picker. - * - * Queries the days that are selected in a weekday picker. - * - * Return value: Bit mask of selected days. Sunday is bit 0, Monday is bit 1, - * etc. - **/ -guint8 -weekday_picker_get_days (WeekdayPicker *wp) -{ - g_return_val_if_fail (IS_WEEKDAY_PICKER (wp), 0); - - return wp->priv->day_mask; -} - -/** - * weekday_picker_set_blocked_days: - * @wp: A weekday picker. - * @blocked_day_mask: Bitmask with the days to be blocked. - * - * Sets the days that the weekday picker will prevent from being modified by the - * user. The @blocked_day_mask is specified in the same way as in - * weekday_picker_set_days(). - **/ -void -weekday_picker_set_blocked_days (WeekdayPicker *wp, - guint8 blocked_day_mask) -{ - g_return_if_fail (IS_WEEKDAY_PICKER (wp)); - - wp->priv->blocked_day_mask = blocked_day_mask; -} - -/** - * weekday_picker_get_blocked_days: - * @wp: A weekday picker. - * - * Queries the set of days that the weekday picker prevents from being modified - * by the user. - * - * Return value: Bit mask of blocked days, with the same format as that returned - * by weekday_picker_get_days(). - **/ -guint -weekday_picker_get_blocked_days (WeekdayPicker *wp) -{ - g_return_val_if_fail (IS_WEEKDAY_PICKER (wp), 0); - - return wp->priv->blocked_day_mask; -} - -/** - * weekday_picker_set_week_start_day: - * @wp: A weekday picker. - * @week_start_day: Index of the day that defines the start of the week; 0 is - * Sunday, 1 is Monday, etc. - * - * Sets the day that defines the start of the week for a weekday picker. - **/ -void -weekday_picker_set_week_start_day (WeekdayPicker *wp, - gint week_start_day) -{ - g_return_if_fail (IS_WEEKDAY_PICKER (wp)); - g_return_if_fail (week_start_day >= 0 && week_start_day < 7); - - wp->priv->week_start_day = week_start_day; - - configure_items (wp); -} - -/** - * weekday_picker_get_week_start_day: - * @wp: A weekday picker. - * - * Queries the day that defines the start of the week in a weekday picker. - * - * Return value: Index of the day that defines the start of the week. See - * weekday_picker_set_week_start_day() to see how this is represented. - **/ -gint -weekday_picker_get_week_start_day (WeekdayPicker *wp) -{ - g_return_val_if_fail (IS_WEEKDAY_PICKER (wp), -1); - - return wp->priv->week_start_day; -} - |