aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/shortcut-bar/e-icon-bar-bg-item.c
diff options
context:
space:
mode:
Diffstat (limited to 'widgets/shortcut-bar/e-icon-bar-bg-item.c')
-rw-r--r--widgets/shortcut-bar/e-icon-bar-bg-item.c361
1 files changed, 361 insertions, 0 deletions
diff --git a/widgets/shortcut-bar/e-icon-bar-bg-item.c b/widgets/shortcut-bar/e-icon-bar-bg-item.c
new file mode 100644
index 0000000000..1bdb7a308d
--- /dev/null
+++ b/widgets/shortcut-bar/e-icon-bar-bg-item.c
@@ -0,0 +1,361 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * Author :
+ * Damon Chaplin <damon@gtk.org>
+ *
+ * Copyright 1999, Helix Code, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+/*
+ * EIconBarBgItem - A GnomeCanvasItem which covers the entire EIconBar.
+ * It paints the rectangles around items when the mouse moves over them, and
+ * the lines between items when dragging.
+ */
+
+#include "e-icon-bar-bg-item.h"
+#include "e-icon-bar.h"
+
+/* This is the size of the border around the icons, for the shadow. */
+#define E_ICON_BAR_LARGE_ICON_SHADOW_BORDER 2
+#define E_ICON_BAR_SMALL_ICON_SHADOW_BORDER 2
+
+/* These are for the horzontal bar when dragging. */
+#define E_ICON_BAR_BG_ITEM_BAR_HEIGHT 1
+#define E_ICON_BAR_BG_ITEM_BAR_OFFSET 2
+#define E_ICON_BAR_BG_ITEM_LARGE_ARROW_HEIGHT 8
+#define E_ICON_BAR_BG_ITEM_SMALL_ARROW_HEIGHT 4
+
+static void e_icon_bar_bg_item_class_init (EIconBarBgItemClass *class);
+static void e_icon_bar_bg_item_init (EIconBarBgItem *ibitem);
+
+static void e_icon_bar_bg_item_set_arg (GtkObject *o, GtkArg *arg,
+ guint arg_id);
+static void e_icon_bar_bg_item_update (GnomeCanvasItem *item,
+ double *affine,
+ ArtSVP *clip_path, int flags);
+static void e_icon_bar_bg_item_draw (GnomeCanvasItem *item,
+ GdkDrawable *drawable,
+ int x, int y,
+ int width, int height);
+static double e_icon_bar_bg_item_point (GnomeCanvasItem *item,
+ double x, double y,
+ int cx, int cy,
+ GnomeCanvasItem **actual_item);
+static gint e_icon_bar_bg_item_event (GnomeCanvasItem *item,
+ GdkEvent *event);
+static gint e_icon_bar_bg_item_button_press (EIconBarBgItem *ibitem,
+ GdkEvent *event);
+static gint e_icon_bar_bg_item_button_release (EIconBarBgItem *ibitem,
+ GdkEvent *event);
+static gint e_icon_bar_bg_item_motion_notify (EIconBarBgItem *ibitem,
+ GdkEvent *event);
+
+static GnomeCanvasItemClass *parent_class;
+
+/* The arguments we take */
+enum {
+ ARG_0,
+ ARG_ICON_BAR
+};
+
+
+GtkType
+e_icon_bar_bg_item_get_type (void)
+{
+ static GtkType e_icon_bar_bg_item_type = 0;
+
+ if (!e_icon_bar_bg_item_type) {
+ GtkTypeInfo e_icon_bar_bg_item_info = {
+ "EIconBarBgItem",
+ sizeof (EIconBarBgItem),
+ sizeof (EIconBarBgItemClass),
+ (GtkClassInitFunc) e_icon_bar_bg_item_class_init,
+ (GtkObjectInitFunc) e_icon_bar_bg_item_init,
+ NULL, /* reserved_1 */
+ NULL, /* reserved_2 */
+ (GtkClassInitFunc) NULL
+ };
+
+ e_icon_bar_bg_item_type = gtk_type_unique (gnome_canvas_item_get_type (), &e_icon_bar_bg_item_info);
+ }
+
+ return e_icon_bar_bg_item_type;
+}
+
+
+static void
+e_icon_bar_bg_item_class_init (EIconBarBgItemClass *class)
+{
+ GtkObjectClass *object_class;
+ GnomeCanvasItemClass *item_class;
+
+ parent_class = gtk_type_class (gnome_canvas_item_get_type());
+
+ object_class = (GtkObjectClass *) class;
+ item_class = (GnomeCanvasItemClass *) class;
+
+ gtk_object_add_arg_type ("EIconBarBgItem::icon_bar",
+ GTK_TYPE_POINTER, GTK_ARG_WRITABLE,
+ ARG_ICON_BAR);
+
+ object_class->set_arg = e_icon_bar_bg_item_set_arg;
+
+ /* GnomeCanvasItem method overrides */
+ item_class->update = e_icon_bar_bg_item_update;
+ item_class->draw = e_icon_bar_bg_item_draw;
+ item_class->point = e_icon_bar_bg_item_point;
+ item_class->event = e_icon_bar_bg_item_event;
+}
+
+
+static void
+e_icon_bar_bg_item_init (EIconBarBgItem *ibitem)
+{
+ GnomeCanvasItem *item = GNOME_CANVAS_ITEM (ibitem);
+
+ ibitem->icon_bar = NULL;
+
+ item->x1 = 0;
+ item->y1 = 0;
+ item->x2 = 0;
+ item->y2 = 0;
+}
+
+
+static void
+e_icon_bar_bg_item_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ GnomeCanvasItem *item;
+ EIconBarBgItem *ibitem;
+
+ item = GNOME_CANVAS_ITEM (o);
+ ibitem = E_ICON_BAR_BG_ITEM (o);
+
+ switch (arg_id){
+ case ARG_ICON_BAR:
+ ibitem->icon_bar = GTK_VALUE_POINTER (*arg);
+ break;
+ }
+}
+
+
+static void
+e_icon_bar_bg_item_update (GnomeCanvasItem *item,
+ double *affine,
+ ArtSVP *clip_path,
+ int flags)
+{
+ if (GNOME_CANVAS_ITEM_CLASS (parent_class)->update)
+ (* GNOME_CANVAS_ITEM_CLASS (parent_class)->update) (item, affine, clip_path, flags);
+
+ /* The grid covers the entire canvas area. */
+ item->x1 = 0;
+ item->y1 = 0;
+ item->x2 = INT_MAX;
+ item->y2 = INT_MAX;
+}
+
+
+/*
+ * DRAWING ROUTINES - functions to paint the canvas item.
+ */
+
+static void
+e_icon_bar_bg_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable,
+ int x, int y, int width, int height)
+{
+ EIconBar *icon_bar;
+ EIconBarItem *item;
+ EIconBarBgItem *ibitem;
+ GtkStyle *style;
+ GdkGC *gc;
+ GtkShadowType shadow;
+ gint item_num, border, bar_x, bar_y, bar_w, i, arrow_height;
+
+ ibitem = E_ICON_BAR_BG_ITEM (canvas_item);
+ icon_bar = ibitem->icon_bar;
+ g_return_if_fail (icon_bar != NULL);
+ style = GTK_WIDGET (icon_bar)->style;
+
+ /* Draw the highlight around the current highlight item. */
+ item_num = -1;
+ if (icon_bar->editing_item_num == -1) {
+ if (icon_bar->pressed_item_num != -1) {
+ item_num = icon_bar->pressed_item_num;
+ if (icon_bar->pressed_item_num == icon_bar->mouse_over_item_num)
+ shadow = GTK_SHADOW_IN;
+ else
+ shadow = GTK_SHADOW_OUT;
+ } else if (icon_bar->mouse_over_item_num != -1) {
+ item_num = icon_bar->mouse_over_item_num;
+ shadow = GTK_SHADOW_OUT;
+ }
+ }
+
+ if (item_num != -1) {
+ item = &g_array_index (icon_bar->items, EIconBarItem,
+ item_num);
+
+ if (icon_bar->view_type == E_ICON_BAR_LARGE_ICONS)
+ border = E_ICON_BAR_LARGE_ICON_SHADOW_BORDER;
+ else
+ border = E_ICON_BAR_SMALL_ICON_SHADOW_BORDER;
+
+ gtk_draw_shadow (style, drawable, GTK_STATE_NORMAL, shadow,
+ icon_bar->icon_x - border - x,
+ item->icon_y - border - y,
+ icon_bar->icon_w + border * 2 - 1,
+ icon_bar->icon_h + border * 2 - 1);
+ }
+
+ /* Draw the bar between items when dragging, if needed. */
+ if (icon_bar->in_drag && icon_bar->dragging_before_item_num != -1) {
+ if (icon_bar->dragging_before_item_num < icon_bar->items->len) {
+ item = &g_array_index (icon_bar->items, EIconBarItem,
+ icon_bar->dragging_before_item_num);
+ bar_y = 0;
+ } else {
+ /* We need to draw the bar after the last item. */
+ item = &g_array_index (icon_bar->items, EIconBarItem,
+ icon_bar->items->len - 1);
+ bar_y = item->item_height + icon_bar->spacing;
+ }
+
+ if (icon_bar->view_type == E_ICON_BAR_LARGE_ICONS) {
+ bar_y += item->icon_y;
+ } else {
+ bar_y += MIN (item->icon_y, item->text_y);
+ }
+ bar_y -= y + icon_bar->spacing / 2;
+
+ bar_x = E_ICON_BAR_BG_ITEM_BAR_OFFSET - x;
+ bar_w = GTK_WIDGET (icon_bar)->allocation.width - 2 * E_ICON_BAR_BG_ITEM_BAR_OFFSET - 1;
+
+ gc = GTK_WIDGET (icon_bar)->style->fg_gc[GTK_STATE_NORMAL];
+
+ /* Draw the horizontal bar. */
+ gdk_draw_rectangle (drawable, gc, TRUE,
+ bar_x, bar_y,
+ bar_w, E_ICON_BAR_BG_ITEM_BAR_HEIGHT);
+
+ if (icon_bar->view_type == E_ICON_BAR_LARGE_ICONS)
+ arrow_height = E_ICON_BAR_BG_ITEM_LARGE_ARROW_HEIGHT / 2;
+ else
+ arrow_height = E_ICON_BAR_BG_ITEM_SMALL_ARROW_HEIGHT / 2;
+
+ /* Draw the arrows at the end of the lines. We use
+ gdk_draw_line() to draw a series of vertical lines, since
+ gdk_draw_polygon() produces odd results. */
+ i = 0;
+ while (arrow_height > 0) {
+ gdk_draw_line (drawable, gc,
+ bar_x + i,
+ bar_y - arrow_height,
+ bar_x + i,
+ bar_y + arrow_height);
+ gdk_draw_line (drawable, gc,
+ bar_x + bar_w - i - 1,
+ bar_y - arrow_height,
+ bar_x + bar_w - i - 1,
+ bar_y + arrow_height);
+ arrow_height--;
+ i++;
+ }
+ }
+}
+
+
+/* This is supposed to return the nearest item the the point and the distance.
+ Since we are the only item we just return ourself and 0 for the distance.
+ This is needed so that we get button/motion events. */
+static double
+e_icon_bar_bg_item_point (GnomeCanvasItem *item, double x, double y,
+ int cx, int cy,
+ GnomeCanvasItem **actual_item)
+{
+ *actual_item = item;
+ return 0.0;
+}
+
+
+static gint
+e_icon_bar_bg_item_event (GnomeCanvasItem *item, GdkEvent *event)
+{
+ EIconBarBgItem *ibitem;
+
+ ibitem = E_ICON_BAR_BG_ITEM (item);
+
+ switch (event->type) {
+ case GDK_BUTTON_PRESS:
+ return e_icon_bar_bg_item_button_press (ibitem, event);
+ case GDK_BUTTON_RELEASE:
+ return e_icon_bar_bg_item_button_release (ibitem, event);
+ case GDK_MOTION_NOTIFY:
+ return e_icon_bar_bg_item_motion_notify (ibitem, event);
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+
+static gint
+e_icon_bar_bg_item_button_press (EIconBarBgItem *ibitem,
+ GdkEvent *event)
+{
+ gint item_num;
+
+ item_num = e_icon_bar_find_item_at_position (ibitem->icon_bar,
+ event->button.x,
+ event->button.y,
+ NULL);
+ e_icon_bar_item_pressed (ibitem->icon_bar, item_num, event);
+ return TRUE;
+}
+
+
+static gint
+e_icon_bar_bg_item_button_release (EIconBarBgItem *ibitem,
+ GdkEvent *event)
+{
+ gint item_num;
+
+ item_num = e_icon_bar_find_item_at_position (ibitem->icon_bar,
+ event->button.x,
+ event->button.y,
+ NULL);
+ e_icon_bar_item_released (ibitem->icon_bar, item_num, event);
+ return TRUE;
+}
+
+
+static gint
+e_icon_bar_bg_item_motion_notify (EIconBarBgItem *ibitem,
+ GdkEvent *event)
+{
+ gint item_num;
+
+ item_num = e_icon_bar_find_item_at_position (ibitem->icon_bar,
+ event->motion.x,
+ event->motion.y,
+ NULL);
+ e_icon_bar_item_motion (ibitem->icon_bar, item_num, event);
+ return TRUE;
+}