diff options
Diffstat (limited to 'widgets/shortcut-bar')
-rw-r--r-- | widgets/shortcut-bar/.cvsignore | 7 | ||||
-rw-r--r-- | widgets/shortcut-bar/LICENSE | 1 | ||||
-rw-r--r-- | widgets/shortcut-bar/Makefile.am | 30 | ||||
-rw-r--r-- | widgets/shortcut-bar/e-clipped-label.c | 361 | ||||
-rw-r--r-- | widgets/shortcut-bar/e-clipped-label.h | 90 | ||||
-rw-r--r-- | widgets/shortcut-bar/e-group-bar.c | 1498 | ||||
-rw-r--r-- | widgets/shortcut-bar/e-group-bar.h | 171 | ||||
-rw-r--r-- | widgets/shortcut-bar/e-icon-bar-bg-item.c | 361 | ||||
-rw-r--r-- | widgets/shortcut-bar/e-icon-bar-bg-item.h | 72 | ||||
-rw-r--r-- | widgets/shortcut-bar/e-icon-bar-text-item.c | 1696 | ||||
-rw-r--r-- | widgets/shortcut-bar/e-icon-bar-text-item.h | 158 | ||||
-rw-r--r-- | widgets/shortcut-bar/e-icon-bar.c | 1450 | ||||
-rw-r--r-- | widgets/shortcut-bar/e-icon-bar.h | 221 | ||||
-rw-r--r-- | widgets/shortcut-bar/e-shortcut-bar.c | 563 | ||||
-rw-r--r-- | widgets/shortcut-bar/e-shortcut-bar.h | 114 | ||||
-rw-r--r-- | widgets/shortcut-bar/e-vscrolled-bar.c | 652 | ||||
-rw-r--r-- | widgets/shortcut-bar/e-vscrolled-bar.h | 97 | ||||
-rw-r--r-- | widgets/shortcut-bar/test-shortcut-bar.c | 445 |
18 files changed, 0 insertions, 7987 deletions
diff --git a/widgets/shortcut-bar/.cvsignore b/widgets/shortcut-bar/.cvsignore deleted file mode 100644 index 41439d256d..0000000000 --- a/widgets/shortcut-bar/.cvsignore +++ /dev/null @@ -1,7 +0,0 @@ -*.o -libshortcut-bar.a -Makefile -Makefile.in -.deps -.libs -test-shortcut-bar diff --git a/widgets/shortcut-bar/LICENSE b/widgets/shortcut-bar/LICENSE deleted file mode 100644 index f58649ad9b..0000000000 --- a/widgets/shortcut-bar/LICENSE +++ /dev/null @@ -1 +0,0 @@ -This code is licensed under the terms of the GNU GPL
\ No newline at end of file diff --git a/widgets/shortcut-bar/Makefile.am b/widgets/shortcut-bar/Makefile.am deleted file mode 100644 index c60c57e872..0000000000 --- a/widgets/shortcut-bar/Makefile.am +++ /dev/null @@ -1,30 +0,0 @@ - -noinst_LIBRARIES = libshortcut-bar.a -noinst_PROGRAMS = test-shortcut-bar - -INCLUDES = \ - -DEVOLUTION_VERSION=\""$(VERSION)"\" \ - $(EXTRA_GNOME_CFLAGS) - -libshortcut_bar_a_SOURCES = \ - e-clipped-label.c \ - e-clipped-label.h \ - e-group-bar.c \ - e-group-bar.h \ - e-icon-bar-bg-item.c \ - e-icon-bar-bg-item.h \ - e-icon-bar-text-item.c \ - e-icon-bar-text-item.h \ - e-icon-bar.c \ - e-icon-bar.h \ - e-shortcut-bar.c \ - e-shortcut-bar.h \ - e-vscrolled-bar.c \ - e-vscrolled-bar.h - -test_shortcut_bar_SOURCES = \ - test-shortcut-bar.c - -test_shortcut_bar_LDADD = \ - ./libshortcut-bar.a \ - $(EXTRA_GNOME_LIBS) \ diff --git a/widgets/shortcut-bar/e-clipped-label.c b/widgets/shortcut-bar/e-clipped-label.c deleted file mode 100644 index 0b595f6063..0000000000 --- a/widgets/shortcut-bar/e-clipped-label.c +++ /dev/null @@ -1,361 +0,0 @@ -/* -*- 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 - */ - -/* - * This is similar to GtkLabel but clips itself and displays '...' if it - * can't fit inside its allocated area. The intended use is for inside buttons - * that are a fixed size. The GtkLabel would normally display only the middle - * part of the text, which doesn't look very good. This only supports one line - * of text (so no wrapping/justification), without underlined characters. - */ - -#include <math.h> - -#include <gdk/gdki18n.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> - -#include "e-clipped-label.h" - - -static void e_clipped_label_class_init (EClippedLabelClass *class); -static void e_clipped_label_init (EClippedLabel *label); -static void e_clipped_label_size_request (GtkWidget *widget, - GtkRequisition *requisition); -static void e_clipped_label_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static gint e_clipped_label_expose (GtkWidget *widget, - GdkEventExpose *event); -static void e_clipped_label_recalc_chars_displayed (EClippedLabel *label); - - -static GtkMiscClass *parent_class; - -/* This is the string to draw when the label is clipped, e.g. '...'. */ -static gchar *e_clipped_label_ellipsis; - -/* Flags used in chars_displayed field. Must be negative. */ -#define E_CLIPPED_LABEL_NEED_RECALC -1 -#define E_CLIPPED_LABEL_SHOW_ENTIRE_LABEL -2 - - -GtkType -e_clipped_label_get_type (void) -{ - static GtkType e_clipped_label_type = 0; - - if (!e_clipped_label_type){ - GtkTypeInfo e_clipped_label_info = { - "EClippedLabel", - sizeof (EClippedLabel), - sizeof (EClippedLabelClass), - (GtkClassInitFunc) e_clipped_label_class_init, - (GtkObjectInitFunc) e_clipped_label_init, - NULL, /* reserved 1 */ - NULL, /* reserved 2 */ - (GtkClassInitFunc) NULL - }; - - parent_class = gtk_type_class (GTK_TYPE_MISC); - e_clipped_label_type = gtk_type_unique (GTK_TYPE_MISC, - &e_clipped_label_info); - } - - return e_clipped_label_type; -} - - -static void -e_clipped_label_class_init (EClippedLabelClass *class) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - - object_class = (GtkObjectClass *) class; - widget_class = (GtkWidgetClass *) class; - - /* Method override */ - widget_class->size_request = e_clipped_label_size_request; - widget_class->size_allocate = e_clipped_label_size_allocate; - widget_class->expose_event = e_clipped_label_expose; - - e_clipped_label_ellipsis = _("..."); -} - - -static void -e_clipped_label_init (EClippedLabel *label) -{ - GTK_WIDGET_SET_FLAGS (label, GTK_NO_WINDOW); - - label->label = NULL; - label->label_wc = NULL; - label->chars_displayed = E_CLIPPED_LABEL_NEED_RECALC; -} - - -/** - * e_clipped_label_new: - * - * @text: The label text. - * @Returns: A new #EClippedLabel. - * - * Creates a new #EClippedLabel with the given text. - **/ -GtkWidget * -e_clipped_label_new (const gchar *text) -{ - GtkWidget *label; - - label = GTK_WIDGET (gtk_type_new (e_clipped_label_get_type ())); - - if (text && *text) - e_clipped_label_set_text (E_CLIPPED_LABEL (label), text); - - return label; -} - - -static void -e_clipped_label_size_request (GtkWidget *widget, - GtkRequisition *requisition) -{ - EClippedLabel *label; - GdkFont *font; - - g_return_if_fail (E_IS_CLIPPED_LABEL (widget)); - g_return_if_fail (requisition != NULL); - - label = E_CLIPPED_LABEL (widget); - font = widget->style->font; - - requisition->width = 0; - requisition->height = font->ascent + font->descent - + 2 * GTK_MISC (widget)->ypad; -} - - -static void -e_clipped_label_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) -{ - EClippedLabel *label; - - label = E_CLIPPED_LABEL (widget); - - widget->allocation = *allocation; - - /* Flag that we need to recalculate how many characters to display. */ - label->chars_displayed = E_CLIPPED_LABEL_NEED_RECALC; -} - - -static gint -e_clipped_label_expose (GtkWidget *widget, - GdkEventExpose *event) -{ - EClippedLabel *label; - GtkMisc *misc; - gint x, y; - GdkFont *font; - gchar *tmp_str, tmp_ch; - - g_return_val_if_fail (E_IS_CLIPPED_LABEL (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - label = E_CLIPPED_LABEL (widget); - misc = GTK_MISC (widget); - font = widget->style->font; - - /* If the label isn't visible or has no text, just return. */ - if (!GTK_WIDGET_VISIBLE (widget) || !GTK_WIDGET_MAPPED (widget) - || !label->label || (*label->label == '\0')) - return TRUE; - - /* Recalculate the number of characters displayed, if necessary. */ - if (label->chars_displayed == E_CLIPPED_LABEL_NEED_RECALC) - e_clipped_label_recalc_chars_displayed (label); - - /* - * GC Clipping - */ - gdk_gc_set_clip_rectangle (widget->style->white_gc, - &event->area); - gdk_gc_set_clip_rectangle (widget->style->fg_gc[widget->state], - &event->area); - - y = floor (widget->allocation.y + (gint)misc->ypad - + (((gint)widget->allocation.height - 2 * (gint)misc->ypad - - (gint)font->ascent - font->descent) - * misc->yalign) + 0.5) + font->ascent; - - if (label->chars_displayed == E_CLIPPED_LABEL_SHOW_ENTIRE_LABEL) { - x = floor (widget->allocation.x + (gint)misc->xpad - + (((gint)widget->allocation.width - - (gint)label->label_width - 2 * (gint)misc->xpad) - * misc->xalign) + 0.5); - - gtk_paint_string (widget->style, widget->window, widget->state, - &event->area, widget, "label", - x, y, label->label); - } else { - x = widget->allocation.x + (gint)misc->xpad; - - tmp_ch = label->label_wc[label->chars_displayed]; - label->label_wc[label->chars_displayed] = '\0'; - tmp_str = gdk_wcstombs (label->label_wc); - if (tmp_str) { - gtk_paint_string (widget->style, widget->window, - widget->state, &event->area, - widget, "label", - x, y, tmp_str); - g_free (tmp_str); - } - label->label_wc[label->chars_displayed] = tmp_ch; - - x = widget->allocation.x + (gint)misc->xpad - + label->ellipsis_x; - gtk_paint_string (widget->style, widget->window, widget->state, - &event->area, widget, "label", - x, y, e_clipped_label_ellipsis); - } - - gdk_gc_set_clip_mask (widget->style->white_gc, NULL); - gdk_gc_set_clip_mask (widget->style->fg_gc[widget->state], NULL); - - return TRUE; -} - - -/** - * e_clipped_label_get_text: - * - * @label: An #EClippedLabel. - * @Return: The label text. - * - * Returns the label text, or NULL. - **/ -gchar* -e_clipped_label_get_text (EClippedLabel *label) -{ - g_return_val_if_fail (E_IS_CLIPPED_LABEL (label), NULL); - - return label->label; -} - - -/** - * e_clipped_label_set_text: - * - * @label: An #EClippedLabel. - * @text: The new label text. - * - * Sets the label text. - **/ -void -e_clipped_label_set_text (EClippedLabel *label, - const gchar *text) -{ - gint len; - - g_return_if_fail (E_IS_CLIPPED_LABEL (label)); - - if (label->label != text || !label->label || !text - || strcmp (label->label, text)) { - g_free (label->label); - g_free (label->label_wc); - label->label = NULL; - label->label_wc = NULL; - - if (text) { - label->label = g_strdup (text); - len = strlen (text); - label->label_wc = g_new (GdkWChar, len + 1); - label->wc_len = gdk_mbstowcs (label->label_wc, - label->label, len + 1); - label->label_wc[label->wc_len] = '\0'; - } - - /* Reset the number of characters displayed, so it is - recalculated when needed. */ - label->chars_displayed = E_CLIPPED_LABEL_NEED_RECALC; - - /* We don't queue a resize, since the label should not affect - the widget size, but we queue a draw. */ - gtk_widget_queue_draw (GTK_WIDGET (label)); - } -} - - -static void -e_clipped_label_recalc_chars_displayed (EClippedLabel *label) -{ - GdkFont *font; - gint max_width, width, ch, last_width; - - font = GTK_WIDGET (label)->style->font; - - max_width = GTK_WIDGET (label)->allocation.width - - 2 * GTK_MISC (label)->xpad; - - if (!label->label) { - label->chars_displayed = 0; - return; - } - - /* See if the entire label fits in the allocated width. */ - label->label_width = gdk_string_width (font, label->label); - if (label->label_width <= max_width) { - label->chars_displayed = E_CLIPPED_LABEL_SHOW_ENTIRE_LABEL; - return; - } - - /* Calculate the width of the ellipsis string. */ - max_width -= gdk_string_measure (font, e_clipped_label_ellipsis); - - if (max_width <= 0) { - label->chars_displayed = 0; - label->ellipsis_x = 0; - return; - } - - /* Step through the wide-char label, adding on the widths of the - characters, until we can't fit any more in. */ - width = last_width = 0; - for (ch = 0; ch < label->wc_len; ch++) { - width += gdk_char_width_wc (font, label->label_wc[ch]); - - if (width > max_width) { - label->chars_displayed = ch; - label->ellipsis_x = last_width; - return; - } - - last_width = width; - } - - g_warning ("Clipped label width not exceeded as expected"); - label->chars_displayed = E_CLIPPED_LABEL_SHOW_ENTIRE_LABEL; -} - diff --git a/widgets/shortcut-bar/e-clipped-label.h b/widgets/shortcut-bar/e-clipped-label.h deleted file mode 100644 index b94d261c11..0000000000 --- a/widgets/shortcut-bar/e-clipped-label.h +++ /dev/null @@ -1,90 +0,0 @@ -/* -*- 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 - */ - -/* - * This is similar to GtkLabel but clips itself and displays '...' if it - * can't fit inside its allocated area. The intended use is for inside buttons - * that are a fixed size. The GtkLabel would normally display only the middle - * part of the text, which doesn't look very good. This only supports one line - * of text (so no wrapping/justification), without underlined characters. - */ -#ifndef _E_CLIPPED_LABEL_H_ -#define _E_CLIPPED_LABEL_H_ - -#include <gtk/gtkmisc.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#define E_CLIPPED_LABEL(obj) GTK_CHECK_CAST (obj, e_clipped_label_get_type (), EClippedLabel) -#define E_CLIPPED_LABEL_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_clipped_label_get_type (), EClippedLabelClass) -#define E_IS_CLIPPED_LABEL(obj) GTK_CHECK_TYPE (obj, e_clipped_label_get_type ()) - - -typedef struct _EClippedLabel EClippedLabel; -typedef struct _EClippedLabelClass EClippedLabelClass; - -struct _EClippedLabel -{ - GtkMisc misc; - - gchar *label; - GdkWChar *label_wc; - - /* This is the number of wide characters in the label. */ - gint wc_len; - - /* This is the width of the entire label string, in pixels. */ - gint label_width; - - /* This is the number of characters we can fit in, or - E_CLIPPED_LABEL_NEED_RECALC if it needs to be recalculated, or - E_CLIPPED_LABEL_SHOW_ENTIRE_LABEL to show the entire label. */ - gint chars_displayed; - - /* This is the x position to display the ellipsis string, e.g. '...', - relative to the start of the label. */ - gint ellipsis_x; -}; - -struct _EClippedLabelClass -{ - GtkMiscClass parent_class; -}; - - -GtkType e_clipped_label_get_type (void); -GtkWidget* e_clipped_label_new (const gchar *text); - -gchar* e_clipped_label_get_text (EClippedLabel *label); -void e_clipped_label_set_text (EClippedLabel *label, - const gchar *text); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_CLIPPED_LABEL_H_ */ diff --git a/widgets/shortcut-bar/e-group-bar.c b/widgets/shortcut-bar/e-group-bar.c deleted file mode 100644 index 603aa6f78f..0000000000 --- a/widgets/shortcut-bar/e-group-bar.c +++ /dev/null @@ -1,1498 +0,0 @@ -/* -*- 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 - */ - -/* - * ShortcutBar displays a vertical bar with a number of Groups, each of which - * contains any number of icons. It is used on the left of the main application - * window so users can easily access items such as folders and files. - */ - -#include <math.h> - -#include <gnome.h> - -#include "e-group-bar.h" - -#define E_GROUP_BAR_SCROLL_TIMEOUT 10 -#define E_GROUP_BAR_MIN_STEP_SIZE 4 - -#define E_GROUP_BAR_AUTO_SHOW_TIMEOUT 300 - - -static void e_group_bar_class_init (EGroupBarClass *class); -static void e_group_bar_init (EGroupBar *group_bar); -static void e_group_bar_destroy (GtkObject *object); -static void e_group_bar_realize (GtkWidget *widget); -static void e_group_bar_unrealize (GtkWidget *widget); -static void e_group_bar_map (GtkWidget *widget); -static void e_group_bar_unmap (GtkWidget *widget); -static void e_group_bar_size_request (GtkWidget *widget, - GtkRequisition *requisition); -static void e_group_bar_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static gint e_group_bar_expose (GtkWidget *widget, - GdkEventExpose *event); -static void e_group_bar_draw (GtkWidget *widget, - GdkRectangle *area); -static void e_group_bar_add (GtkContainer *container, - GtkWidget *widget); -static void e_group_bar_remove (GtkContainer *container, - GtkWidget *widget); -static void e_group_bar_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data); - -static void e_group_bar_create_group_button_window (EGroupBar *group_bar, - gint group_num); -static void e_group_bar_create_group_child_window (EGroupBar *group_bar, - gint group_num); -static gint e_group_bar_get_group_button_position (EGroupBar *group_bar, - gint group_num); -static gint e_group_bar_sum_button_heights (EGroupBar *group_bar, - gint first, - gint last); -static gint e_group_bar_get_child_height (EGroupBar *group_bar); -static gint e_group_bar_get_group_child_position (EGroupBar *group_bar, - gint group_num); - -static void e_group_bar_on_button_clicked (GtkWidget *group_button, - EGroupBar *group_bar); -static gint e_group_bar_find_button (EGroupBar *group_bar, - GtkWidget *group_button); -static void e_group_bar_start_animation (EGroupBar *group_bar, - gint group_num); -static gboolean e_group_bar_timeout_handler (gpointer data); -static gint e_group_bar_get_increment (EGroupBar *group_bar, - gint window_y, - gint window_target_y); -static gboolean e_group_bar_on_button_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time, - EGroupBar *group_bar); -static void e_group_bar_on_button_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time, - EGroupBar *group_bar); -static gboolean e_group_bar_auto_show (gpointer data); -static void e_group_bar_stop_all_animation (EGroupBar *group_bar); - - -static GtkContainerClass *parent_class; - - -GtkType -e_group_bar_get_type (void) -{ - static GtkType e_group_bar_type = 0; - - if (!e_group_bar_type){ - GtkTypeInfo e_group_bar_info = { - "EGroupBar", - sizeof (EGroupBar), - sizeof (EGroupBarClass), - (GtkClassInitFunc) e_group_bar_class_init, - (GtkObjectInitFunc) e_group_bar_init, - NULL, /* reserved 1 */ - NULL, /* reserved 2 */ - (GtkClassInitFunc) NULL - }; - - parent_class = gtk_type_class (GTK_TYPE_CONTAINER); - e_group_bar_type = gtk_type_unique (GTK_TYPE_CONTAINER, - &e_group_bar_info); - } - - return e_group_bar_type; -} - - -static void -e_group_bar_class_init (EGroupBarClass *class) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - GtkContainerClass *container_class; - - object_class = (GtkObjectClass *) class; - widget_class = (GtkWidgetClass *) class; - container_class = (GtkContainerClass *) class; - - /* Method override */ - object_class->destroy = e_group_bar_destroy; - - widget_class->realize = e_group_bar_realize; - widget_class->unrealize = e_group_bar_unrealize; - widget_class->map = e_group_bar_map; - widget_class->unmap = e_group_bar_unmap; - widget_class->size_request = e_group_bar_size_request; - widget_class->size_allocate = e_group_bar_size_allocate; - widget_class->expose_event = e_group_bar_expose; - widget_class->draw = e_group_bar_draw; - - container_class->add = e_group_bar_add; - container_class->remove = e_group_bar_remove; - container_class->forall = e_group_bar_forall; -} - - -static void -e_group_bar_init (EGroupBar *group_bar) -{ - - GTK_WIDGET_UNSET_FLAGS (group_bar, GTK_NO_WINDOW); - - /* We don't want child resizes to propagate up to the parent. */ - gtk_container_set_resize_mode (GTK_CONTAINER (group_bar), - GTK_RESIZE_QUEUE); - - group_bar->children = g_array_new (FALSE, FALSE, - sizeof (EGroupBarChild)); - - group_bar->current_group_num = -1; - group_bar->buttons_homogeneous = TRUE; - group_bar->max_button_height = 0; - group_bar->animation_timeout_id = 0; -} - - -/** - * e_group_bar_new: - * @Returns: a new #EGroupBar. - * - * Creates a new #EGroupBar. - **/ -GtkWidget * -e_group_bar_new (void) -{ - GtkWidget *group_bar; - - group_bar = GTK_WIDGET (gtk_type_new (e_group_bar_get_type ())); - - return group_bar; -} - - -static void -e_group_bar_destroy (GtkObject *object) -{ - EGroupBar *group_bar; - - group_bar = E_GROUP_BAR (object); - - e_group_bar_stop_all_animation (group_bar); - - /* The parent GtkContainer class will automatically destroy all the - child widgets, but it calls gtk_container_foreach() so we must not - destroy our children array until after. */ - GTK_OBJECT_CLASS (parent_class)->destroy (object); - - g_array_free (group_bar->children, TRUE); -} - - -static void -e_group_bar_realize (GtkWidget *widget) -{ - EGroupBar *group_bar; - EGroupBarChild *group; - GdkWindowAttr attributes; - gint attributes_mask; - gint border_width, group_num; - - g_return_if_fail (widget != NULL); - g_return_if_fail (E_IS_GROUP_BAR (widget)); - - group_bar = E_GROUP_BAR (widget); - GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); - - border_width = GTK_CONTAINER (group_bar)->border_width; - - attributes.window_type = GDK_WINDOW_CHILD; - attributes.x = widget->allocation.x + border_width; - attributes.y = widget->allocation.y + border_width; - attributes.width = widget->allocation.width - 2 * border_width; - attributes.height = widget->allocation.height - 2 * border_width; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gtk_widget_get_visual (widget); - attributes.colormap = gtk_widget_get_colormap (widget); - attributes.event_mask = gtk_widget_get_events (widget); - attributes.event_mask |= (GDK_EXPOSURE_MASK); - - attributes_mask = GDK_WA_X | GDK_WA_Y - | GDK_WA_VISUAL | GDK_WA_COLORMAP; - - widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), - &attributes, attributes_mask); - gdk_window_set_user_data (widget->window, widget); - - widget->style = gtk_style_attach (widget->style, widget->window); - gtk_style_set_background (widget->style, widget->window, - GTK_STATE_NORMAL); - - gdk_window_set_back_pixmap (widget->window, NULL, TRUE); - - /* Create windows for all the buttons & group canvases. */ - for (group_num = 0; - group_num < group_bar->children->len; - group_num++) { - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - e_group_bar_create_group_button_window (group_bar, group_num); - e_group_bar_create_group_child_window (group_bar, group_num); - } -} - - -static void -e_group_bar_unrealize (GtkWidget *widget) -{ - EGroupBar *group_bar; - EGroupBarChild *group; - gint group_num; - - g_return_if_fail (widget != NULL); - g_return_if_fail (E_IS_GROUP_BAR (widget)); - - group_bar = E_GROUP_BAR (widget); - - /* Destroy the windows for all the buttons & group canvases. */ - for (group_num = 0; - group_num < group_bar->children->len; - group_num++) { - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - - if (group->button_window) { - gdk_window_set_user_data (group->button_window, NULL); - gdk_window_destroy (group->button_window); - group->button_window = NULL; - } - if (group->child_window) { - gdk_window_set_user_data (group->child_window, NULL); - gdk_window_destroy (group->child_window); - group->child_window = NULL; - } - } - - if (GTK_WIDGET_CLASS (parent_class)->unrealize) - (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); -} - - -static void -e_group_bar_map (GtkWidget *widget) -{ - EGroupBar *group_bar; - EGroupBarChild *group; - gint group_num; - - g_return_if_fail (widget != NULL); - g_return_if_fail (E_IS_GROUP_BAR (widget)); - - group_bar = E_GROUP_BAR (widget); - - GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED); - - /* We do this in reverse order, and lower all the child windows, so - the stacking order ends up correct. */ - for (group_num = group_bar->children->len - 1; - group_num >= 0; - group_num--) { - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - - if (group->button_window) { - gdk_window_show (group->button_window); - } - - if (group->button - && GTK_WIDGET_VISIBLE (group->button) - && !GTK_WIDGET_MAPPED (group->button)) { - gtk_widget_map (group->button); - } - - if (group->child_window) { - gdk_window_show (group->child_window); - gdk_window_lower (group->child_window); - } - - if (group->child - && GTK_WIDGET_VISIBLE (group->child) - && !GTK_WIDGET_MAPPED (group->child)) - gtk_widget_map (group->child); - } - - gdk_window_show (widget->window); -} - - -static void -e_group_bar_unmap (GtkWidget *widget) -{ - EGroupBar *group_bar; - EGroupBarChild *group; - gint group_num; - - g_return_if_fail (widget != NULL); - g_return_if_fail (E_IS_GROUP_BAR (widget)); - - group_bar = E_GROUP_BAR (widget); - - GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED); - - for (group_num = 0; - group_num < group_bar->children->len; - group_num++) { - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - - if (group->button_window) { - gdk_window_hide (group->button_window); - } - - if (group->button - && GTK_WIDGET_MAPPED (group->button)) - gtk_widget_unmap (group->button); - - if (group->child_window) { - gdk_window_hide (group->child_window); - } - - if (group->child - && GTK_WIDGET_MAPPED (group->child)) - gtk_widget_unmap (group->child); - } - - gdk_window_hide (widget->window); -} - - -static void -e_group_bar_size_request (GtkWidget *widget, - GtkRequisition *requisition) -{ - EGroupBar *group_bar; - EGroupBarChild *group; - gint group_num, max_child_height; - GtkRequisition child_requisition; - - g_return_if_fail (widget != NULL); - g_return_if_fail (E_IS_GROUP_BAR (widget)); - g_return_if_fail (requisition != NULL); - - group_bar = E_GROUP_BAR (widget); - - /* We set the requisition width to the largest requested width of the - child widgets. The requisition height is set to the sum of all the - button heights plus the height of the largest child. */ - requisition->width = 0; - requisition->height = 0; - - /* We have to call size_request on all children, even though we don't - use the results, since some widgets like GtkLabel depend on it. */ - group_bar->max_button_height = 0; - max_child_height = 0; - for (group_num = 0; - group_num < group_bar->children->len; - group_num++) { - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - - if (group->button) { - gtk_widget_size_request (group->button, - &child_requisition); - group->button_height = child_requisition.height; - } else { - group->button_height = 0; - } - - group_bar->max_button_height = MAX (group_bar->max_button_height, group->button_height); - requisition->height += child_requisition.height; - - if (group->child) { - gtk_widget_size_request (group->child, - &child_requisition); - max_child_height = MAX (max_child_height, - child_requisition.height); - requisition->width = MAX (requisition->width, - child_requisition.width); - } - } - - requisition->height += max_child_height; - - /* Add on the standard container border widths. */ - requisition->width += GTK_CONTAINER (widget)->border_width * 2; - requisition->height += GTK_CONTAINER (widget)->border_width * 2; -} - - -static void -e_group_bar_size_allocate (GtkWidget *widget, GtkAllocation *allocation) -{ - EGroupBar *group_bar; - EGroupBarChild *group; - gint group_num, border_width, width, height, child_height, y; - GtkAllocation button_allocation, child_allocation; - - group_bar = E_GROUP_BAR (widget); - - /* All child & button windows and widgets use the same width as the - group bar minus the border width. */ - border_width = GTK_CONTAINER (widget)->border_width; - width = allocation->width - border_width * 2; - height = allocation->height - border_width * 2; - - widget->allocation = *allocation; - if (GTK_WIDGET_REALIZED (widget)) - gdk_window_move_resize (widget->window, - allocation->x + border_width, - allocation->y + border_width, - width, height); - - /* All the child widgets use the same height. */ - child_height = e_group_bar_get_child_height (group_bar); - - /* The buttons are always in the top-left of the button windows, and - all have the same width. The height is calculated for each group. */ - button_allocation.x = 0; - button_allocation.y = 0; - button_allocation.width = width; - - /* The child widgets are always in the top-left of the child windows, - and all have the same width and height. */ - child_allocation.x = 0; - child_allocation.y = 0; - child_allocation.width = width; - child_allocation.height = child_height; - - /* Step through the groups, placing the windows as necessary, and - allocating the areas for the child widgets. Note that if a button - or child window is in the middle of an animation, we just resize it - and update the target position, and let the animation continue. */ - for (group_num = 0; - group_num < group_bar->children->len; - group_num++) { - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - - /* Calculate the y position of the button, which depends on - the currently selected group and the button heights. */ - y = e_group_bar_get_group_button_position (group_bar, group_num); - button_allocation.height = group_bar->buttons_homogeneous ? group_bar->max_button_height : group->button_height; - - if (GTK_WIDGET_REALIZED (group->button)) { - if (group->button_window_in_animation) { - gdk_window_resize (group->button_window, - width, button_allocation.height); - group->button_window_target_y = y; - } else { - gdk_window_move_resize (group->button_window, - 0, y, width, button_allocation.height); - } - } - gtk_widget_size_allocate (group->button, &button_allocation); - - if (GTK_WIDGET_REALIZED (group->child)) { - if (group->child_window_in_animation) { - gdk_window_resize (group->child_window, - width, child_height); - group->child_window_target_y = y + button_allocation.height; - } else { - gdk_window_move_resize (group->child_window, - 0, y + button_allocation.height, - width, child_height); - } - } - gtk_widget_size_allocate (group->child, &child_allocation); - } -} - - -static gint -e_group_bar_expose (GtkWidget *widget, - GdkEventExpose *event) -{ - EGroupBar *group_bar; - EGroupBarChild *group; - GdkEventExpose child_event; - gint group_num; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (E_IS_GROUP_BAR (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - if (GTK_WIDGET_DRAWABLE (widget)) { - group_bar = E_GROUP_BAR (widget); - - child_event = *event; - - for (group_num = 0; - group_num < group_bar->children->len; - group_num++) { - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - - if (event->window == group->button_window - && GTK_WIDGET_DRAWABLE (group->button) - && GTK_WIDGET_NO_WINDOW (group->button) - && gtk_widget_intersect (group->button, &event->area, &child_event.area)) - gtk_widget_event (group->button, (GdkEvent*) &child_event); - - if (event->window == group->child_window - && GTK_WIDGET_DRAWABLE (group->child) - && GTK_WIDGET_NO_WINDOW (group->child) - && gtk_widget_intersect (group->child, &event->area, &child_event.area)) - gtk_widget_event (group->child, (GdkEvent*) &child_event); - } - } - - return FALSE; -} - - -static void -e_group_bar_draw (GtkWidget *widget, - GdkRectangle *area) -{ - EGroupBar *group_bar; - EGroupBarChild *group; - gint group_num; -#if 0 - GdkRectangle child_area; -#endif - g_return_if_fail (widget != NULL); - g_return_if_fail (E_IS_GROUP_BAR (widget)); - - g_print ("In e_group_bar_draw %i,%i %ix%i\n", area->x, area->y, - area->width, area->height); - - if (GTK_WIDGET_DRAWABLE (widget)) { - group_bar = E_GROUP_BAR (widget); - - for (group_num = 0; - group_num < group_bar->children->len; - group_num++) { - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - /* FIXME */ -#if 0 - if (GTK_WIDGET_DRAWABLE (child->widget) && - gtk_widget_intersect (child->widget, area, &child_area)) - gtk_widget_draw (child->widget, &child_area); -#endif - } - } -} - - -static void -e_group_bar_add (GtkContainer *container, - GtkWidget *widget) -{ - EGroupBar *group_bar; - GtkWidget *button; - gchar buffer[32]; - - g_return_if_fail (container != NULL); - g_return_if_fail (E_IS_GROUP_BAR (container)); - g_return_if_fail (widget != NULL); - - g_snprintf (buffer, sizeof (buffer), _("Group %i"), - group_bar->children->len + 1); - button = gtk_button_new_with_label (buffer); - gtk_widget_show (button); - - e_group_bar_add_group (group_bar, widget, button, -1); -} - - -static void -e_group_bar_remove (GtkContainer *container, - GtkWidget *widget) -{ - EGroupBar *group_bar; - gint group_num; - - g_return_if_fail (container != NULL); - g_return_if_fail (E_IS_GROUP_BAR (container)); - g_return_if_fail (widget != NULL); - - group_bar = E_GROUP_BAR (container); - - group_num = e_group_bar_get_group_num (group_bar, widget); - e_group_bar_remove_group (group_bar, group_num); -} - - -static void -e_group_bar_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data) -{ - EGroupBar *group_bar; - EGroupBarChild *group; - gint group_num; - GList *tmp_list; - - g_return_if_fail (container != NULL); - g_return_if_fail (E_IS_GROUP_BAR (container)); - g_return_if_fail (callback != NULL); - - group_bar = E_GROUP_BAR (container); - - /* Note that drag-and-drop does not check the Z-order of widgets, so - we have to iterate through them from top to bottom, or it will - not work properly. We also have to use temporary lists so widgets - can be safely destroyed while iterating. */ - - if (include_internals) { - tmp_list = NULL; - for (group_num = group_bar->children->len - 1; - group_num >= 0; - group_num--) { - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - - if (group->button) - tmp_list = g_list_prepend (tmp_list, - group->button); - } - - g_list_foreach (tmp_list, (GFunc) callback, callback_data); - g_list_free (tmp_list); - } - - tmp_list = NULL; - for (group_num = 0; - group_num < group_bar->children->len; - group_num++) { - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - - if (group->child) - tmp_list = g_list_prepend (tmp_list, group->child); - } - g_list_foreach (tmp_list, (GFunc) callback, callback_data); - g_list_free (tmp_list); -} - - -static void -e_group_bar_create_group_button_window (EGroupBar *group_bar, - gint group_num) -{ - EGroupBarChild *group; - GtkWidget *widget; - GdkWindowAttr attributes; - gint attributes_mask; - gint y, height, border_width; - - widget = GTK_WIDGET (group_bar); - - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - y = e_group_bar_get_group_button_position (group_bar, group_num); - height = group_bar->buttons_homogeneous ? group_bar->max_button_height - : group->button_height; - border_width = GTK_CONTAINER (group_bar)->border_width; - - attributes.window_type = GDK_WINDOW_CHILD; - attributes.x = 0; - attributes.y = y; - attributes.width = widget->allocation.width - 2 * border_width; - attributes.height = height; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gtk_widget_get_visual (widget); - attributes.colormap = gtk_widget_get_colormap (widget); - attributes.event_mask = gtk_widget_get_events (widget); - attributes.event_mask |= (GDK_EXPOSURE_MASK); - - attributes_mask = GDK_WA_X | GDK_WA_Y - | GDK_WA_VISUAL | GDK_WA_COLORMAP; - - group->button_window = gdk_window_new (widget->window, &attributes, - attributes_mask); - gdk_window_set_user_data (group->button_window, widget); - - gtk_widget_set_parent_window (group->button, - group->button_window); - gdk_window_set_back_pixmap (group->button_window, NULL, TRUE); -} - - -static void -e_group_bar_create_group_child_window (EGroupBar *group_bar, - gint group_num) -{ - EGroupBarChild *group; - GtkWidget *widget; - GdkWindowAttr attributes; - gint attributes_mask; - gint y, height, border_width; - - widget = GTK_WIDGET (group_bar); - - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - y = e_group_bar_get_group_button_position (group_bar, group_num); - y += group_bar->buttons_homogeneous ? group_bar->max_button_height - : group->button_height; - height = e_group_bar_get_child_height (group_bar); - border_width = GTK_CONTAINER (group_bar)->border_width; - - attributes.window_type = GDK_WINDOW_CHILD; - attributes.x = 0; - attributes.y = y; - attributes.width = widget->allocation.width - 2 * border_width; - attributes.height = height; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gtk_widget_get_visual (widget); - attributes.colormap = gtk_widget_get_colormap (widget); - attributes.event_mask = gtk_widget_get_events (widget); - attributes.event_mask |= (GDK_EXPOSURE_MASK); - - attributes_mask = GDK_WA_X | GDK_WA_Y - | GDK_WA_VISUAL | GDK_WA_COLORMAP; - - group->child_window = gdk_window_new (widget->window, &attributes, - attributes_mask); - gdk_window_set_user_data (group->child_window, widget); - - gtk_widget_set_parent_window (GTK_WIDGET (group->child), - group->child_window); - gdk_window_set_back_pixmap (group->child_window, NULL, TRUE); -} - - -/* This returns the y position of a group's button within the EGroupBar window. - */ -static gint -e_group_bar_get_group_button_position (EGroupBar *group_bar, - gint group_num) -{ - gint border_width, window_height, y; - - border_width = GTK_CONTAINER (group_bar)->border_width; - window_height = GTK_WIDGET (group_bar)->allocation.height - 2 * border_width; - - if (group_num <= group_bar->current_group_num) - y = e_group_bar_sum_button_heights (group_bar, 0, group_num - 1); - else - y = window_height - e_group_bar_sum_button_heights (group_bar, group_num, group_bar->children->len - 1); - - return y; -} - - -/* This returns the sum of all the buttons from first to last inclusive. */ -static gint -e_group_bar_sum_button_heights (EGroupBar *group_bar, gint first, gint last) -{ - EGroupBarChild *group; - gint height, group_num; - - height = 0; - - if (group_bar->buttons_homogeneous) - return (last - first + 1) * group_bar->max_button_height; - - for (group_num = first; group_num <= last; group_num++) { - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - height += group->button_height; - } - - return height; -} - - -static gint -e_group_bar_get_group_child_position (EGroupBar *group_bar, - gint group_num) -{ - EGroupBarChild *group; - gint y; - - y = e_group_bar_get_group_button_position (group_bar, group_num); - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - y += group_bar->buttons_homogeneous ? group_bar->max_button_height - : group->button_height; - - return y; -} - - -static gint -e_group_bar_get_child_height (EGroupBar *group_bar) -{ - EGroupBarChild *group; - gint group_num; - - /* Start with the allocated height of the EGroupBar, less the border.*/ - group_bar->child_height = GTK_WIDGET (group_bar)->allocation.height; - group_bar->child_height -= 2 * GTK_CONTAINER (group_bar)->border_width; - - /* Now subtract the heights of all the buttons. */ - if (group_bar->buttons_homogeneous) { - group_bar->child_height -= group_bar->children->len * group_bar->max_button_height; - } else { - for (group_num = 0; - group_num < group_bar->children->len; - group_num++) { - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - group_bar->child_height -= group->button_height; - } - } - - return group_bar->child_height; -} - - -/* - * Insertion, reordering and deletion of items. - */ - -/** - * e_group_bar_add_group: - * @group_bar: an #EGroupBar. - * @child: the child widget to add. - * @button: the button used to show the child widget. - * @position: the new group's position, or -1 to place it last. - * @Returns: the position of the new group. - * - * Adds a new group to a #EGroupBar at the given position. - **/ -gint -e_group_bar_add_group (EGroupBar *group_bar, - GtkWidget *child, - GtkWidget *button, - gint position) -{ - EGroupBarChild *group, empty_group, *tmp_group; - gint group_num, tmp_group_num; - - g_return_val_if_fail (group_bar != NULL, -1); - g_return_val_if_fail (E_IS_GROUP_BAR (group_bar), -1); - g_return_val_if_fail (child != NULL, -1); - g_return_val_if_fail (button != NULL, -1); - g_return_val_if_fail (GTK_IS_BUTTON (button), -1); - - /* Append an empty group to the children array and get a pointer to - it, so we can use it like a normal group. */ - group_num = group_bar->children->len; - g_array_append_val (group_bar->children, empty_group); - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - - /* Initialize the group. */ - group->button = button; - group->button_window = NULL; - group->child = child; - group->child_window = NULL; - group->button_window_in_animation = FALSE; - group->child_window_in_animation = FALSE; - group->button_window_target_y = 0; - group->child_window_target_y = 0; - - /* If we don't have a current group, set it to the first one. */ - if (group_bar->current_group_num == -1) - group_bar->current_group_num = 0; - - /* If the EGroupBar widget is realize, we need to create the child - windows to put the button & child in. */ - if (GTK_WIDGET_REALIZED (group_bar)) { - e_group_bar_create_group_button_window (group_bar, group_num); - e_group_bar_create_group_child_window (group_bar, group_num); - - /* We need to lower all the child windows of the previous - groups, in reverse order, to keep the stacking order - correct. */ - for (tmp_group_num = group_num - 1; - tmp_group_num >= 0; - tmp_group_num--) { - tmp_group = &g_array_index (group_bar->children, - EGroupBarChild, - tmp_group_num); - gdk_window_lower (group->child_window); - } - } - - gtk_widget_set_parent (group->button, GTK_WIDGET (group_bar)); - gtk_widget_set_parent (group->child, GTK_WIDGET (group_bar)); - - if (GTK_WIDGET_REALIZED (group_bar)) { - gtk_widget_realize (group->button); - gtk_widget_realize (group->child); - } - - if (GTK_WIDGET_VISIBLE (group_bar) - && GTK_WIDGET_MAPPED (group_bar)) { - if (group->button - && GTK_WIDGET_VISIBLE (group->button) - && !GTK_WIDGET_MAPPED (group->button)) { - gtk_widget_map (group->button); - gtk_widget_queue_resize (group->button); - } - if (group->child - && GTK_WIDGET_VISIBLE (group->child) - && !GTK_WIDGET_MAPPED (group->child)) { - gtk_widget_map (group->child); - gtk_widget_queue_resize (group->child); - } - } - - gtk_signal_connect (GTK_OBJECT (group->button), "clicked", - GTK_SIGNAL_FUNC (e_group_bar_on_button_clicked), - group_bar); - - gtk_signal_connect (GTK_OBJECT (group->button), "drag_motion", - GTK_SIGNAL_FUNC (e_group_bar_on_button_drag_motion), - group_bar); - gtk_signal_connect (GTK_OBJECT (group->button), "drag_leave", - GTK_SIGNAL_FUNC (e_group_bar_on_button_drag_leave), - group_bar); - - return group_num; -} - - -/** - * e_group_bar_reorder_group: - * @group_bar: an #EGroupBar. - * @group_num: the index of the group to move. - * @new_position: the new position of the group. - * - * Moves a group to a new position within the #EGroupBar. - **/ -void -e_group_bar_reorder_group (EGroupBar *group_bar, - gint group_num, - gint new_position) -{ - g_return_if_fail (E_IS_GROUP_BAR (group_bar)); - -} - - -/** - * e_group_bar_remove_group: - * @group_bar: an #EGroupBar. - * @group_num: the index of the group to remove. - * - * Removes a group from an #EGroupBar. - **/ -void -e_group_bar_remove_group (EGroupBar *group_bar, - gint group_num) -{ - EGroupBarChild *group; - - g_return_if_fail (E_IS_GROUP_BAR (group_bar)); - g_return_if_fail (group_num >= 0); - g_return_if_fail (group_num < group_bar->children->len); - - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - - /* Stop any animation. */ - e_group_bar_stop_all_animation (group_bar); - - gtk_widget_unparent (group->child); - if (group->button) - gtk_widget_unparent (group->button); - - if (group->button_window) { - gdk_window_set_user_data (group->button_window, NULL); - gdk_window_destroy (group->button_window); - } - if (group->child_window) { - gdk_window_set_user_data (group->child_window, NULL); - gdk_window_destroy (group->child_window); - } - - g_array_remove_index (group_bar->children, group_num); - - /* Make sure the current group is valid. */ - if (group_bar->current_group_num >= group_bar->children->len) - group_bar->current_group_num = group_bar->children->len - 1; - - gtk_widget_queue_resize (GTK_WIDGET (group_bar)); -} - - -/* - * Getting & setting the current group. - */ - -/** - * e_group_bar_get_current_group_num: - * @group_bar: an #EGroupBar. - * @Returns: the index of the group currently displayed. - * - * Returns the index of the group currently displayed. - **/ -gint -e_group_bar_get_current_group_num (EGroupBar *group_bar) -{ - g_return_val_if_fail (E_IS_GROUP_BAR (group_bar), -1); - - return group_bar->current_group_num; -} - - -/** - * e_group_bar_set_current_group_num: - * @group_bar: an #EGroupBar. - * @Returns: the index of the group to display. - * - * Sets the group to display. - **/ -/* FIXME: animate option? May want to set group without animation. */ -void -e_group_bar_set_current_group_num (EGroupBar *group_bar, - gint group_num) -{ - g_return_if_fail (E_IS_GROUP_BAR (group_bar)); - - /* If that already is the current group, just return. */ - if (group_bar->current_group_num == group_num) - return; - - /* FIXME: Set the target positions of the old current group and the - new current group, map the new group's child window, and create the - animation timeout, if we haven't already got one. */ - - group_bar->current_group_num = group_num; - -} - - -/* - * Getting groups and group numbers. - */ - -/** - * e_group_bar_get_nth_group: - * @group_bar: an #EGroupBar. - * @group_num: the index of the group to get. - * @Returns: the child widget at the given index. - * - * Returns the child widget at the given index. - **/ -GtkWidget* -e_group_bar_get_nth_group (EGroupBar *group_bar, - gint group_num) -{ - EGroupBarChild *group; - - g_return_val_if_fail (E_IS_GROUP_BAR (group_bar), NULL); - g_return_val_if_fail (group_num >= 0, NULL); - g_return_val_if_fail (group_num < group_bar->children->len, NULL); - - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - return group->child; -} - - -/** - * e_group_bar_get_group_num: - * @group_bar: an #EGroupBar. - * @child: the child widget to find. - * @Returns: the index of the group containing the given widget. - * - * Returns the index of the group containing the given child widget. - **/ -gint -e_group_bar_get_group_num (EGroupBar *group_bar, - GtkWidget *child) -{ - EGroupBarChild *group; - gint group_num; - - g_return_val_if_fail (E_IS_GROUP_BAR (group_bar), -1); - g_return_val_if_fail (child != NULL, -1); - - for (group_num = 0; - group_num < group_bar->children->len; - group_num++) { - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - - if (group->child == child) - return group_num; - } - - return -1; -} - - -/** - * e_group_bar_set_group_button_label: - * @group_bar: an #EGroupBar. - * @group_num: the index of the group. - * @label: the label widget to place in the group's button. - * - * Sets the label widget for the given group's button, replacing any existing - * widget in the button. - **/ -void -e_group_bar_set_group_button_label (EGroupBar *group_bar, - gint group_num, - GtkWidget *label) -{ - EGroupBarChild *group; - GtkWidget *button_child; - - g_return_if_fail (E_IS_GROUP_BAR (group_bar)); - g_return_if_fail (group_num >= 0); - g_return_if_fail (group_num < group_bar->children->len); - - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - - button_child = GTK_BIN (group->button)->child; - if (button_child) { - gtk_container_remove (GTK_CONTAINER (group->button), - button_child); - } - - if (label) - gtk_container_add (GTK_CONTAINER (group->button), label); -} - - -/* - * Getting & setting the EGroupBar options. - */ - -/** - * e_group_bar_get_buttons_homogeneous: - * @group_bar: an #EGroupBar. - * @Returns: TRUE if the buttons are homoegeneous. - * - * Returns TRUE if the buttons are homogeneous (i.e. all have the same height). - **/ -gboolean -e_group_bar_get_buttons_homogeneous (EGroupBar *group_bar) -{ - g_return_val_if_fail (E_IS_GROUP_BAR (group_bar), TRUE); - - return group_bar->buttons_homogeneous; -} - - -/** - * e_group_bar_set_buttons_homogeneous: - * @group_bar: an #EGroupBar. - * @homogeneous: TRUE if the buttons should be homoegeneous. - * - * Specifies whether the buttons should be homogeneous. When set to TRUE all - * the group buttons will be set to the same height (equal to the largest - * requested height). When set to FALSE the buttons will use their own - * individual requested heights. - **/ -void -e_group_bar_set_buttons_homogeneous (EGroupBar *group_bar, - gboolean homogeneous) -{ - g_return_if_fail (E_IS_GROUP_BAR (group_bar)); - - /* Just return if the setting hasn't changed. */ - if (group_bar->buttons_homogeneous == homogeneous) - return; - - group_bar->buttons_homogeneous = homogeneous; - - /* Update the position & sizes of the buttons. */ - gtk_widget_queue_resize (GTK_WIDGET (group_bar)); -} - - -static void -e_group_bar_on_button_clicked (GtkWidget *group_button, - EGroupBar *group_bar) -{ - gint group_num; - - /* Determine which group button was clicked. */ - group_num = e_group_bar_find_button (group_bar, group_button); - - if (group_num != -1) - e_group_bar_start_animation (group_bar, group_num); -} - - -/* This returns the group containing the given button, or -1 if not found. */ -static gint -e_group_bar_find_button (EGroupBar *group_bar, - GtkWidget *group_button) -{ - EGroupBarChild *group; - gint group_num; - - /* Determine which group button was clicked. */ - for (group_num = 0; - group_num < group_bar->children->len; - group_num++) { - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - if (group->button == group_button) - return group_num; - } - - return -1; -} - - -static void -e_group_bar_start_animation (EGroupBar *group_bar, - gint group_num) -{ - EGroupBarChild *group, *old_group; - gint old_group_num, step; - - old_group_num = group_bar->current_group_num; - - /* Return if it is already the current group. */ - if (old_group_num == group_num) - return; - - group_bar->current_group_num = group_num; - - /* Calculate the target y position of the new current group button - and child, and map the child. */ - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - group->button_window_target_y = e_group_bar_get_group_button_position (group_bar, group_num); - group->button_window_in_animation = TRUE; - - group->child_window_target_y = e_group_bar_get_group_child_position (group_bar, group_num); - group->child_window_in_animation = TRUE; - - /* Calculate the target y position of the current group button and - child. */ - old_group = &g_array_index (group_bar->children, - EGroupBarChild, old_group_num); - old_group->button_window_target_y = e_group_bar_get_group_button_position (group_bar, old_group_num); - old_group->button_window_in_animation = TRUE; - - old_group->child_window_target_y = e_group_bar_get_group_child_position (group_bar, old_group_num); - old_group->child_window_in_animation = TRUE; - - /* We also need to animate the buttons in between the old group and the - new group. */ - step = (old_group_num < group_num) ? 1 : -1; - old_group_num += step; - while (old_group_num != group_num) { - old_group = &g_array_index (group_bar->children, - EGroupBarChild, old_group_num); - old_group->button_window_target_y = e_group_bar_get_group_button_position (group_bar, old_group_num); - old_group->button_window_in_animation = TRUE; - - old_group->child_window_target_y = e_group_bar_get_group_child_position (group_bar, old_group_num); - old_group->child_window_in_animation = TRUE; - - old_group_num += step; - } - - /* Add a timeout handler if we haven't already got one. */ - if (group_bar->animation_timeout_id == 0) { - group_bar->animation_timeout_id = g_timeout_add (E_GROUP_BAR_SCROLL_TIMEOUT, e_group_bar_timeout_handler, group_bar); - } -} - - -static gboolean -e_group_bar_timeout_handler (gpointer data) -{ - EGroupBar *group_bar; - EGroupBarChild *group; - gint group_num, button_window_y, child_window_y; - gboolean finished = TRUE; - - g_return_val_if_fail (E_IS_GROUP_BAR (data), FALSE); - - group_bar = E_GROUP_BAR (data); - - GDK_THREADS_ENTER (); - - for (group_num = 0; - group_num < group_bar->children->len; - group_num++) { - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - - if (group->button_window_in_animation) { - gdk_window_get_position (group->button_window, NULL, - &button_window_y); - button_window_y += e_group_bar_get_increment (group_bar, button_window_y, group->button_window_target_y); - if (button_window_y == group->button_window_target_y) - group->button_window_in_animation = FALSE; - else - finished = FALSE; - gdk_window_move (group->button_window, - 0, button_window_y); - } - if (group->child_window_in_animation) { - gdk_window_get_position (group->child_window, NULL, - &child_window_y); - child_window_y += e_group_bar_get_increment (group_bar, child_window_y, group->child_window_target_y); - if (child_window_y == group->child_window_target_y) - group->child_window_in_animation = FALSE; - else - finished = FALSE; - gdk_window_move (group->child_window, - 0, child_window_y); - } - - } - - if (finished) - group_bar->animation_timeout_id = 0; - - GDK_THREADS_LEAVE (); - - return !finished; -} - - -static gint -e_group_bar_get_increment (EGroupBar *group_bar, - gint window_y, - gint window_target_y) -{ - gdouble percentage; - gint distance, total_distance, step; - - total_distance = group_bar->child_height; - distance = MIN (abs (window_target_y - window_y), total_distance); - - /* Convert the distance into an angle between -PI/2 and PI/2, so we can - then do a cosine of it. */ - percentage = cos (M_PI * ((gdouble)distance / (gdouble)total_distance) - M_PI / 2); - - /* Now multiply by our maximum step size to get the step size. */ - step = percentage * total_distance / 6; - - /* Add it to the minimum step size, but don't go too far. */ - step = step + E_GROUP_BAR_MIN_STEP_SIZE; - step = MIN (step, distance); - - if (window_target_y > window_y) - return step; - else - return -step; -} - - -static gboolean -e_group_bar_on_button_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time, - EGroupBar *group_bar) -{ - gint group_num; - - if (!group_bar->auto_show_timeout_id) { - group_num = e_group_bar_find_button (group_bar, widget); - if (group_num != -1) { - group_bar->auto_show_timeout_id = gtk_timeout_add (E_GROUP_BAR_AUTO_SHOW_TIMEOUT, e_group_bar_auto_show, group_bar); - group_bar->auto_show_group_num = group_num; - } - } - return TRUE; -} - - -static void -e_group_bar_on_button_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time, - EGroupBar *group_bar) -{ - if (group_bar->auto_show_timeout_id) { - gtk_timeout_remove (group_bar->auto_show_timeout_id); - group_bar->auto_show_timeout_id = 0; - } -} - - -static gboolean -e_group_bar_auto_show (gpointer data) -{ - EGroupBar *group_bar; - - g_return_val_if_fail (E_IS_GROUP_BAR (data), FALSE); - - group_bar = E_GROUP_BAR (data); - - GDK_THREADS_ENTER (); - - e_group_bar_start_animation (group_bar, - group_bar->auto_show_group_num); - - group_bar->auto_show_timeout_id = 0; - - GDK_THREADS_LEAVE (); - - return FALSE; -} - - -/* This removes all timeouts and sets all 'in_animation' flags to FALSE. */ -static void -e_group_bar_stop_all_animation (EGroupBar *group_bar) -{ - EGroupBarChild *group; - gint group_num; - - if (group_bar->animation_timeout_id) { - g_source_remove (group_bar->animation_timeout_id); - group_bar->animation_timeout_id = 0; - } - if (group_bar->auto_show_timeout_id) { - g_source_remove (group_bar->auto_show_timeout_id); - group_bar->auto_show_timeout_id = 0; - } - - for (group_num = 0; - group_num < group_bar->children->len; - group_num++) { - group = &g_array_index (group_bar->children, - EGroupBarChild, group_num); - group->button_window_in_animation = FALSE; - group->child_window_in_animation = FALSE; - } -} - diff --git a/widgets/shortcut-bar/e-group-bar.h b/widgets/shortcut-bar/e-group-bar.h deleted file mode 100644 index 9a6f83b461..0000000000 --- a/widgets/shortcut-bar/e-group-bar.h +++ /dev/null @@ -1,171 +0,0 @@ -/* -*- 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 - */ -#ifndef _E_GROUP_BAR_H_ -#define _E_GROUP_BAR_H_ - -#include <gtk/gtkcontainer.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * EGroupBar displays a vertical bar with a number of Groups, which are viewed - * one at a time by selecting the Group's button. When a different Group is - * selected, it slides into view, and the old Group slides out. - * It is typically used on the left of the main application window so users - * can easily access particular features. - * - * It is implemented like GtkNotebook, i.e. the main widgets are the children - * of the EGroupBar and the button widgets are treated specially like the - * GtkNotebook tab labels. - */ - -/* This contains information on one item. */ -typedef struct _EGroupBarChild EGroupBarChild; -struct _EGroupBarChild -{ - /* This is the button used to select the group, and the window we use - to move it around easily. */ - GtkWidget *button; - GdkWindow *button_window; - gint button_height; - - /* This is the child widget, which can be any widget added by the - application, and the window we use to move it around easily. */ - GtkWidget *child; - GdkWindow *child_window; - - /* These are TRUE if we are currently animating the windows. */ - gboolean button_window_in_animation; - gboolean child_window_in_animation; - - /* These are the target y positions that the windows should eventually - move to, used for animation. If we get a size_allocate we just - update these and the animation can continue as normal. - When a child window reaches its target position, it is unmapped if - if it is not the current group (i.e. it has slid off screen). */ - gint button_window_target_y; - gint child_window_target_y; -}; - - -#define E_GROUP_BAR(obj) GTK_CHECK_CAST (obj, e_group_bar_get_type (), EGroupBar) -#define E_GROUP_BAR_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_group_bar_get_type (), EGroupBarClass) -#define E_IS_GROUP_BAR(obj) GTK_CHECK_TYPE (obj, e_group_bar_get_type ()) - - -typedef struct _EGroupBar EGroupBar; -typedef struct _EGroupBarClass EGroupBarClass; - -struct _EGroupBar -{ - GtkContainer container; - - /* This is an array of EGroupBarChild elements. */ - GArray *children; - - /* This is the group currently shown. */ - gint current_group_num; - - /* This is TRUE if all the buttons are allocated the same height. */ - gboolean buttons_homogeneous; - - /* This is the biggest requested height of all the buttons, which we - use for all buttons when buttons_homogeneous is set. */ - gint max_button_height; - - /* This is the height of all the child windows & widgets. */ - gint child_height; - - /* The id of the source function for animation timeouts. If this is - not 0 then we are in the middle of an animation. */ - guint animation_timeout_id; - - /* The id of the source function for automatically showing groups when - the user drags over the group button, and the group to show. */ - guint auto_show_timeout_id; - gint auto_show_group_num; -}; - -struct _EGroupBarClass -{ - GtkContainerClass parent_class; -}; - - -GtkType e_group_bar_get_type (void); -GtkWidget* e_group_bar_new (void); - -/* - * Insertion, reordering and deletion of items. - */ - -/* Adds a new group at the given position. If position is -1 it adds it as - the last group. It returns the group number. */ -gint e_group_bar_add_group (EGroupBar *group_bar, - GtkWidget *child, - GtkWidget *button, - gint position); -void e_group_bar_reorder_group (EGroupBar *group_bar, - gint group_num, - gint new_position); -void e_group_bar_remove_group (EGroupBar *group_bar, - gint group_num); - -/* - * Getting & setting the current group. - */ -gint e_group_bar_get_current_group_num (EGroupBar *group_bar); -void e_group_bar_set_current_group_num (EGroupBar *group_bar, - gint group_num); - -/* - * Getting groups and group numbers. - */ -GtkWidget* e_group_bar_get_nth_group (EGroupBar *group_bar, - gint group_num); -gint e_group_bar_get_group_num (EGroupBar *group_bar, - GtkWidget *child); - -/* - * Setting the group button label. - */ -void e_group_bar_set_group_button_label (EGroupBar *group_bar, - gint group_num, - GtkWidget *label); - -/* - * Getting & setting the EGroupBar options. - */ -gboolean e_group_bar_get_buttons_homogeneous (EGroupBar *group_bar); -void e_group_bar_set_buttons_homogeneous (EGroupBar *group_bar, - gboolean homogeneous); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_GROUP_BAR_H_ */ diff --git a/widgets/shortcut-bar/e-icon-bar-bg-item.c b/widgets/shortcut-bar/e-icon-bar-bg-item.c deleted file mode 100644 index 1bdb7a308d..0000000000 --- a/widgets/shortcut-bar/e-icon-bar-bg-item.c +++ /dev/null @@ -1,361 +0,0 @@ -/* -*- 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; -} diff --git a/widgets/shortcut-bar/e-icon-bar-bg-item.h b/widgets/shortcut-bar/e-icon-bar-bg-item.h deleted file mode 100644 index ae25e987d7..0000000000 --- a/widgets/shortcut-bar/e-icon-bar-bg-item.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- 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. - */ - -#ifndef _E_ICON_BAR_BG_ITEM_H_ -#define _E_ICON_BAR_BG_ITEM_H_ - -#include <libgnomeui/gnome-canvas.h> - -#include "e-icon-bar.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -#define E_ICON_BAR_BG_ITEM(obj) (GTK_CHECK_CAST((obj), e_icon_bar_bg_item_get_type (), EIconBarBgItem)) -#define E_ICON_BAR_BG_ITEM_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), e_icon_bar_bg_item_get_type (), EIconBarBgItemClass)) -#define E_IS_ICON_BAR_BG_ITEM(o) (GTK_CHECK_TYPE((o), e_icon_bar_bg_item_get_type ())) - - -typedef struct _EIconBarBgItem EIconBarBgItem; -typedef struct _EIconBarBgItemClass EIconBarBgItemClass; - -struct _EIconBarBgItem -{ - GnomeCanvasItem canvas_item; - - /* The parent EIconBar widget. */ - EIconBar *icon_bar; -}; - - -struct _EIconBarBgItemClass -{ - GnomeCanvasItemClass parent_class; -}; - -GtkType e_icon_bar_bg_item_get_type (void); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_ICON_BAR_BG_ITEM_H_ */ diff --git a/widgets/shortcut-bar/e-icon-bar-text-item.c b/widgets/shortcut-bar/e-icon-bar-text-item.c deleted file mode 100644 index 5548c630b3..0000000000 --- a/widgets/shortcut-bar/e-icon-bar-text-item.c +++ /dev/null @@ -1,1696 +0,0 @@ -/* -*- 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 - */ - -/* - * Based on gnome-icon-text-item: an editable text block with word wrapping - * for the GNOME canvas. - * - * Copyright (C) 1998, 1999 The Free Software Foundation - * - * Authors: Miguel de Icaza <miguel@gnu.org> - * Federico Mena <federico@gimp.org> - */ - -/* - * EIconBarTextItem - An editable canvas text item for the EIconBar. - */ - -#include <math.h> -#include <gdk/gdkkeysyms.h> -#include <gtk/gtkmain.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkwindow.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> - -#include "e-icon-bar-text-item.h" - - -/* Margins used to display the information */ -#define MARGIN_X 2 -#define MARGIN_Y 2 - -/* Default fontset to be used if the user specified fontset is not found */ -#define DEFAULT_FONT_NAME "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*," \ - "-*-*-medium-r-normal--10-*-*-*-*-*-*-*,*" - -/* Separators for text layout */ -#define DEFAULT_SEPARATORS " \t-.[]#" - -/* This is the string to draw when the text is clipped, e.g. '...'. */ -static gchar *e_icon_bar_text_item_ellipsis; - -/* Aliases to minimize screen use in my laptop */ -#define ITI(x) E_ICON_BAR_TEXT_ITEM (x) -#define ITI_CLASS(x) E_ICON_BAR_TEXT_ITEM_CLASS (x) -#define IS_ITI(x) E_IS_ICON_BAR_TEXT_ITEM (x) - - -typedef EIconBarTextItem Iti; - -/* Private part of the EIconBarTextItem structure */ -typedef struct { - /* Font */ - GdkFont *font; - - /* Hack: create an offscreen window and place an entry inside it */ - GtkEntry *entry; - GtkWidget *entry_top; - - /* Whether the user pressed the mouse while the item was unselected */ - guint unselected_click : 1; - - /* Whether we need to update the position */ - guint need_pos_update : 1; - - /* Whether we need to update the font */ - guint need_font_update : 1; - - /* Whether we need to update the text */ - guint need_text_update : 1; - - /* Whether we need to update because the editing/selected state changed */ - guint need_state_update : 1; -} ItiPrivate; - -typedef struct _EIconBarTextItemInfoRow EIconBarTextItemInfoRow; - -struct _EIconBarTextItemInfoRow { - gchar *text; - gint width; - GdkWChar *text_wc; /* text in wide characters */ - gint text_length; /* number of characters */ -}; - -struct _EIconBarTextItemInfo { - GList *rows; - GdkFont *font; - gint width; - gint height; - gint baseline_skip; -}; - -static GnomeCanvasItemClass *parent_class; - -enum { - ARG_0, - ARG_XALIGN, - ARG_JUSTIFY, - ARG_MAX_LINES, - ARG_SHOW_ELLIPSIS -}; - -enum { - TEXT_CHANGED, - HEIGHT_CHANGED, - WIDTH_CHANGED, - EDITING_STARTED, - EDITING_STOPPED, - SELECTION_STARTED, - SELECTION_STOPPED, - LAST_SIGNAL -}; - -static guint iti_signals [LAST_SIGNAL] = { 0 }; - -static GdkFont *default_font; - -static void e_icon_bar_text_item_free_info (EIconBarTextItemInfo *ti); -static EIconBarTextItemInfo *e_icon_bar_text_item_layout_text (EIconBarTextItem *iti, GdkFont *font, const gchar *text, const gchar *separators, gint max_width, gboolean confine); -static void e_icon_bar_text_item_paint_text (EIconBarTextItem *iti, - EIconBarTextItemInfo *ti, - GdkDrawable *drawable, - GdkGC *gc, - gint x, - gint y, - GtkJustification just); - - -/* Stops the editing state of an icon text item */ -static void -iti_stop_editing (Iti *iti) -{ - ItiPrivate *priv; - - priv = iti->priv; - - iti->editing = FALSE; - - gtk_widget_destroy (priv->entry_top); - priv->entry = NULL; - priv->entry_top = NULL; - - priv->need_state_update = TRUE; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti)); - - gtk_signal_emit (GTK_OBJECT (iti), iti_signals[EDITING_STOPPED]); -} - -/* Lays out the text in an icon item */ -static void -layout_text (Iti *iti) -{ - ItiPrivate *priv; - char *text; - int old_width, old_height; - int width, height; - - priv = iti->priv; - - /* Save old size */ - - if (iti->ti) { - old_width = iti->ti->width + 2 * MARGIN_X; - old_height = iti->ti->height + 2 * MARGIN_Y; - - e_icon_bar_text_item_free_info (iti->ti); - } else { - old_width = 2 * MARGIN_X; - old_height = 2 * MARGIN_Y; - } - - /* Change the text layout */ - - if (iti->editing) - text = gtk_entry_get_text (priv->entry); - else - text = iti->text; - - iti->ti = e_icon_bar_text_item_layout_text (iti, priv->font, - text, - DEFAULT_SEPARATORS, - iti->width - 2 * MARGIN_X, - TRUE); - - /* Check the sizes and see if we need to emit any signals */ - - width = iti->ti->width + 2 * MARGIN_X; - height = iti->ti->height + 2 * MARGIN_Y; - - if (width != old_width) - gtk_signal_emit (GTK_OBJECT (iti), iti_signals[WIDTH_CHANGED]); - - if (height != old_height) - gtk_signal_emit (GTK_OBJECT (iti), iti_signals[HEIGHT_CHANGED]); -} - -/* Accepts the text in the off-screen entry of an icon text item */ -static void -iti_edition_accept (Iti *iti) -{ - ItiPrivate *priv; - gboolean accept; - - priv = iti->priv; - accept = TRUE; - - gtk_signal_emit (GTK_OBJECT (iti), iti_signals [TEXT_CHANGED], &accept); - - if (iti->editing){ - if (accept) { - if (iti->is_text_allocated) - g_free (iti->text); - - iti->text = g_strdup (gtk_entry_get_text (priv->entry)); - iti->is_text_allocated = 1; - } - - iti_stop_editing (iti); - } - - priv->need_text_update = TRUE; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti)); -} - -/* Callback used when the off-screen entry of an icon text item is activated. - * When this happens, we have to accept edition. - */ -static void -iti_entry_activate (GtkWidget *entry, Iti *iti) -{ - iti_edition_accept (iti); -} - -/* Starts the editing state of an icon text item */ -static void -iti_start_editing (Iti *iti) -{ - ItiPrivate *priv; - - priv = iti->priv; - - if (iti->editing) - return; - - /* Trick: The actual edition of the entry takes place in a GtkEntry - * which is placed offscreen. That way we get all of the advantages - * from GtkEntry without duplicating code. Yes, this is a hack. - */ - priv->entry = (GtkEntry *) gtk_entry_new (); - gtk_entry_set_text (priv->entry, iti->text); - gtk_signal_connect (GTK_OBJECT (priv->entry), "activate", - GTK_SIGNAL_FUNC (iti_entry_activate), iti); - - priv->entry_top = gtk_window_new (GTK_WINDOW_POPUP); - gtk_container_add (GTK_CONTAINER (priv->entry_top), GTK_WIDGET (priv->entry)); - gtk_widget_set_uposition (priv->entry_top, 20000, 20000); - gtk_widget_show_all (priv->entry_top); - - gtk_editable_select_region (GTK_EDITABLE (priv->entry), 0, -1); - - iti->editing = TRUE; - - priv->need_text_update = TRUE; - priv->need_state_update = TRUE; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti)); - - gtk_signal_emit (GTK_OBJECT (iti), iti_signals[EDITING_STARTED]); -} - -/* Destroy method handler for the icon text item */ -static void -iti_destroy (GtkObject *object) -{ - Iti *iti; - ItiPrivate *priv; - GnomeCanvasItem *item; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_ITI (object)); - - iti = ITI (object); - priv = iti->priv; - item = GNOME_CANVAS_ITEM (object); - - /* FIXME: stop selection and editing */ - - /* Queue redraw of bounding box */ - - gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2); - - /* Free everything */ - - if (iti->fontname) - g_free (iti->fontname); - - if (iti->text && iti->is_text_allocated) - g_free (iti->text); - - if (iti->ti) - e_icon_bar_text_item_free_info (iti->ti); - - if (priv->font) - gdk_font_unref (priv->font); - - if (priv->entry_top) - gtk_widget_destroy (priv->entry_top); - - g_free (priv); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -/* set_arg handler for the icon text item */ -static void -iti_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - Iti *iti; - GnomeCanvasItem *item; - ItiPrivate *priv; - gfloat xalign; - gint max_lines; - gboolean show_ellipsis; - GtkJustification justification; - - iti = ITI (object); - item = GNOME_CANVAS_ITEM (object); - priv = iti->priv; - - switch (arg_id) { - case ARG_XALIGN: - xalign = GTK_VALUE_FLOAT (*arg); - if (iti->xalign != xalign) { - iti->xalign = xalign; - priv->need_pos_update = TRUE; - gnome_canvas_item_request_update (item); - } - break; - case ARG_JUSTIFY: - justification = GTK_VALUE_ENUM (*arg); - if (iti->justification != justification) { - iti->justification = justification; - priv->need_text_update = TRUE; - gnome_canvas_item_request_update (item); - } - break; - case ARG_MAX_LINES: - max_lines = GTK_VALUE_INT (*arg); - if (iti->max_lines != max_lines) { - iti->max_lines = max_lines; - priv->need_text_update = TRUE; - gnome_canvas_item_request_update (item); - } - break; - case ARG_SHOW_ELLIPSIS: - show_ellipsis = GTK_VALUE_BOOL (*arg); - if (iti->show_ellipsis != show_ellipsis) { - iti->show_ellipsis = show_ellipsis; - priv->need_text_update = TRUE; - gnome_canvas_item_request_update (item); - } - break; - default: - break; - } -} - -static void -iti_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - Iti *iti; - ItiPrivate *priv; - - iti = ITI (object); - priv = iti->priv; - - switch (arg_id) { - case ARG_XALIGN: - GTK_VALUE_FLOAT (*arg) = iti->xalign; - break; - case ARG_JUSTIFY: - GTK_VALUE_ENUM (*arg) = iti->justification; - break; - case ARG_MAX_LINES: - GTK_VALUE_INT (*arg) = iti->max_lines; - break; - case ARG_SHOW_ELLIPSIS: - GTK_VALUE_BOOL (*arg) = iti->show_ellipsis; - break; - default: - arg->type = GTK_TYPE_INVALID; - break; - } -} - -/* Loads the default font for icon text items if necessary */ -static GdkFont * -get_default_font (void) -{ - if (!default_font) { - /* FIXME: this is never unref-ed */ - default_font = gdk_fontset_load (DEFAULT_FONT_NAME); - g_assert (default_font != NULL); - } - - return gdk_font_ref (default_font); -} - -/* Recomputes the bounding box of an icon text item */ -static void -recompute_bounding_box (Iti *iti) -{ - GnomeCanvasItem *item; - double affine[6]; - ArtPoint p, q; - int x1, y1, x2, y2; - int width, height; - - item = GNOME_CANVAS_ITEM (iti); - - /* Compute width, height, position */ - - width = iti->ti->width + 2 * MARGIN_X; - height = iti->ti->height + 2 * MARGIN_Y; - - x1 = iti->x + (iti->width - width) * iti->xalign; - y1 = iti->y; - x2 = x1 + width; - y2 = y1 + height; - - /* Translate to world coordinates */ - - gnome_canvas_item_i2w_affine (item, affine); - - p.x = x1; - p.y = y1; - art_affine_point (&q, &p, affine); - item->x1 = q.x; - item->y1 = q.y; - - p.x = x2; - p.y = y2; - art_affine_point (&q, &p, affine); - item->x2 = q.x; - item->y2 = q.y; -} - -/* Update method for the icon text item */ -static void -iti_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags) -{ - Iti *iti; - ItiPrivate *priv; - - iti = ITI (item); - priv = iti->priv; - - if (parent_class->update) - (* parent_class->update) (item, affine, clip_path, flags); - - /* If necessary, queue a redraw of the old bounding box */ - - if ((flags & GNOME_CANVAS_UPDATE_VISIBILITY) - || (flags & GNOME_CANVAS_UPDATE_AFFINE) - || priv->need_pos_update - || priv->need_font_update - || priv->need_text_update) - gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2); - - if (priv->need_text_update) - layout_text (iti); - - /* Compute new bounds */ - - if (priv->need_pos_update - || priv->need_font_update - || priv->need_text_update) - recompute_bounding_box (iti); - - /* Queue redraw */ - - gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2); - - priv->need_pos_update = FALSE; - priv->need_font_update = FALSE; - priv->need_text_update = FALSE; - priv->need_state_update = FALSE; -} - -/* Draw the icon text item's text when it is being edited */ -static void -iti_paint_text (Iti *iti, GdkDrawable *drawable, int x, int y) -{ - ItiPrivate *priv; - EIconBarTextItemInfoRow *row; - EIconBarTextItemInfo *ti; - GtkStyle *style; - GdkGC *fg_gc, *bg_gc; - GdkGC *gc, *bgc, *sgc, *bsgc; - GList *item; - int xpos, len; - - priv = iti->priv; - style = GTK_WIDGET (GNOME_CANVAS_ITEM (iti)->canvas)->style; - - ti = iti->ti; - len = 0; - y += ti->font->ascent; - - /* - * Pointers to all of the GCs we use - */ - gc = style->black_gc; - bgc = style->white_gc; - sgc = style->fg_gc [GTK_STATE_SELECTED]; - bsgc = style->bg_gc [GTK_STATE_SELECTED]; - - for (item = ti->rows; item; item = item->next, len += (row ? row->text_length : 0)) { - GdkWChar *text_wc; - int text_length; - int cursor, offset, i; - int sel_start, sel_end; - - row = item->data; - - if (!row) { - y += ti->baseline_skip; - continue; - } - - text_wc = row->text_wc; - text_length = row->text_length; - - switch (iti->justification) { - case GTK_JUSTIFY_LEFT: - xpos = 0; - break; - - case GTK_JUSTIFY_RIGHT: - xpos = ti->width - row->width; - break; - - case GTK_JUSTIFY_CENTER: - xpos = (ti->width - row->width) / 2; - break; - - default: - /* Anyone care to implement GTK_JUSTIFY_FILL? */ - g_warning ("Justification type %d not supported. Using left-justification.", - (int) iti->justification); - xpos = 0; - } - - sel_start = GTK_EDITABLE (priv->entry)->selection_start_pos - len; - sel_end = GTK_EDITABLE (priv->entry)->selection_end_pos - len; - offset = 0; - cursor = GTK_EDITABLE (priv->entry)->current_pos - len; - - for (i = 0; *text_wc; text_wc++, i++) { - int size, px; - - size = gdk_text_width_wc (ti->font, text_wc, 1); - - if (i >= sel_start && i < sel_end) { - fg_gc = sgc; - bg_gc = bsgc; - } else { - fg_gc = gc; - bg_gc = bgc; - } - - px = x + xpos + offset; - gdk_draw_rectangle (drawable, - bg_gc, - TRUE, - px, - y - ti->font->ascent, - size, ti->baseline_skip); - - gdk_draw_text_wc (drawable, - ti->font, - fg_gc, - px, y, - text_wc, 1); - - if (cursor == i) - gdk_draw_line (drawable, - gc, - px - 1, - y - ti->font->ascent, - px - 1, - y + ti->font->descent - 1); - - offset += size; - } - - if (cursor == i) { - int px = x + xpos + offset; - - gdk_draw_line (drawable, - gc, - px - 1, - y - ti->font->ascent, - px - 1, - y + ti->font->descent - 1); - } - - y += ti->baseline_skip; - } -} - -/* Draw method handler for the icon text item */ -static void -iti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height) -{ - Iti *iti; - GtkStyle *style; - int w, h; - int xofs, yofs; - - iti = ITI (item); - - if (iti->ti) { - w = iti->ti->width + 2 * MARGIN_X; - h = iti->ti->height + 2 * MARGIN_Y; - } else { - w = 2 * MARGIN_X; - h = 2 * MARGIN_Y; - } - - xofs = item->x1 - x; - yofs = item->y1 - y; - - style = GTK_WIDGET (item->canvas)->style; - - if (iti->selected && !iti->editing) - gdk_draw_rectangle (drawable, - style->bg_gc[GTK_STATE_SELECTED], - TRUE, - xofs, yofs, - w, h); - - if (iti->editing) { - gdk_draw_rectangle (drawable, - style->white_gc, - TRUE, - xofs + 1, yofs + 1, - w - 2, h - 2); - gdk_draw_rectangle (drawable, - style->black_gc, - FALSE, - xofs, yofs, - w - 1, h - 1); - - iti_paint_text (iti, drawable, xofs + MARGIN_X, yofs + MARGIN_Y); - } else - e_icon_bar_text_item_paint_text (iti, iti->ti, - drawable, - style->fg_gc[(iti->selected - ? GTK_STATE_SELECTED - : GTK_STATE_NORMAL)], - xofs + MARGIN_X, - yofs + MARGIN_Y, - iti->justification); -} - -/* Point method handler for the icon text item */ -static double -iti_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, GnomeCanvasItem **actual_item) -{ - double dx, dy; - - *actual_item = item; - - if (cx < item->x1) - dx = item->x1 - cx; - else if (cx > item->x2) - dx = cx - item->x2; - else - dx = 0.0; - - if (cy < item->y1) - dy = item->y1 - cy; - else if (cy > item->y2) - dy = cy - item->y2; - else - dy = 0.0; - - return sqrt (dx * dx + dy * dy); -} - -/* Given X, Y, a mouse position, return a valid index inside the edited text */ -static int -iti_idx_from_x_y (Iti *iti, int x, int y) -{ - ItiPrivate *priv; - EIconBarTextItemInfoRow *row; - int lines; - int line, col, i, idx; - GList *l; - - priv = iti->priv; - - if (iti->ti->rows == NULL) - return 0; - - lines = g_list_length (iti->ti->rows); - line = y / iti->ti->baseline_skip; - - if (line < 0) - line = 0; - else if (lines < line + 1) - line = lines - 1; - - /* Compute the base index for this line */ - for (l = iti->ti->rows, idx = i = 0; i < line; l = l->next, i++) { - row = l->data; - idx += row->text_length; - } - - row = g_list_nth (iti->ti->rows, line)->data; - col = 0; - if (row != NULL) { - int first_char; - int last_char; - - first_char = (iti->ti->width - row->width) / 2; - last_char = first_char + row->width; - - if (x < first_char) { - /* nothing */ - } else if (x > last_char) { - col = row->text_length; - } else { - GdkWChar *s = row->text_wc; - int pos = first_char; - - while (pos < last_char) { - pos += gdk_text_width_wc (iti->ti->font, s, 1); - if (pos > x) - break; - col++; - s++; - } - } - } - - idx += col; - - g_assert (idx <= priv->entry->text_size); - - return idx; -} - -/* Starts the selection state in the icon text item */ -static void -iti_start_selecting (Iti *iti, int idx, guint32 event_time) -{ - ItiPrivate *priv; - GtkEditable *e; - GdkCursor *ibeam; - - priv = iti->priv; - e = GTK_EDITABLE (priv->entry); - - gtk_editable_select_region (e, idx, idx); - gtk_editable_set_position (e, idx); - ibeam = gdk_cursor_new (GDK_XTERM); - gnome_canvas_item_grab (GNOME_CANVAS_ITEM (iti), - GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_MASK, - ibeam, event_time); - gdk_cursor_destroy (ibeam); - - gtk_editable_select_region (e, idx, idx); - e->current_pos = e->selection_start_pos; - e->has_selection = TRUE; - iti->selecting = TRUE; - - priv->need_state_update = TRUE; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti)); - - gtk_signal_emit (GTK_OBJECT (iti), iti_signals[SELECTION_STARTED]); -} - -/* Stops the selection state in the icon text item */ -static void -iti_stop_selecting (Iti *iti, guint32 event_time) -{ - ItiPrivate *priv; - GnomeCanvasItem *item; - GtkEditable *e; - - priv = iti->priv; - item = GNOME_CANVAS_ITEM (iti); - e = GTK_EDITABLE (priv->entry); - - gnome_canvas_item_ungrab (item, event_time); - e->has_selection = FALSE; - iti->selecting = FALSE; - - priv->need_state_update = TRUE; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti)); - gtk_signal_emit (GTK_OBJECT (iti), iti_signals[SELECTION_STOPPED]); -} - -/* Handles selection range changes on the icon text item */ -static void -iti_selection_motion (Iti *iti, int idx) -{ - ItiPrivate *priv; - GtkEditable *e; - - priv = iti->priv; - e = GTK_EDITABLE (priv->entry); - - if (idx < e->current_pos) { - e->selection_start_pos = idx; - e->selection_end_pos = e->current_pos; - } else { - e->selection_start_pos = e->current_pos; - e->selection_end_pos = idx; - } - - priv->need_state_update = TRUE; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti)); -} - -/* Event handler for icon text items */ -static gint -iti_event (GnomeCanvasItem *item, GdkEvent *event) -{ - Iti *iti; - ItiPrivate *priv; - int idx; - double x, y; - - iti = ITI (item); - priv = iti->priv; - - switch (event->type) { - case GDK_KEY_PRESS: - if (!iti->editing) - break; - - if (event->key.keyval == GDK_Escape) - iti_stop_editing (iti); - else - gtk_widget_event (GTK_WIDGET (priv->entry), event); - - priv->need_text_update = TRUE; - gnome_canvas_item_request_update (item); - return TRUE; - - case GDK_BUTTON_PRESS: - if (!iti->editing) - break; - - if (iti->editing && event->button.button == 1) { - x = event->button.x - (item->x1 + MARGIN_X); - y = event->button.y - (item->y1 + MARGIN_Y); - idx = iti_idx_from_x_y (iti, x, y); - - iti_start_selecting (iti, idx, event->button.time); - } - - return TRUE; - - case GDK_MOTION_NOTIFY: - if (!iti->selecting) - break; - - x = event->motion.x - (item->x1 + MARGIN_X); - y = event->motion.y - (item->y1 + MARGIN_Y); - idx = iti_idx_from_x_y (iti, x, y); - iti_selection_motion (iti, idx); - return TRUE; - - case GDK_BUTTON_RELEASE: - if (iti->selecting && event->button.button == 1) - iti_stop_selecting (iti, event->button.time); - else - break; - - return TRUE; - - default: - break; - } - - return FALSE; -} - -/* Bounds method handler for the icon text item */ -static void -iti_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2) -{ - Iti *iti; - ItiPrivate *priv; - int width, height; - - iti = ITI (item); - priv = iti->priv; - - if (priv->need_text_update) { - layout_text (iti); - priv->need_text_update = FALSE; - } - - if (iti->ti) { - width = iti->ti->width + 2 * MARGIN_X; - height = iti->ti->height + 2 * MARGIN_Y; - } else { - width = 2 * MARGIN_X; - height = 2 * MARGIN_Y; - } - - *x1 = iti->x + (iti->width - width) * iti->xalign; - *y1 = iti->y; - *x2 = *x1 + width; - *y2 = *y1 + height; -} - -/* Class initialization function for the icon text item */ -static void -iti_class_init (EIconBarTextItemClass *text_item_class) -{ - GtkObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - object_class = (GtkObjectClass *) text_item_class; - item_class = (GnomeCanvasItemClass *) text_item_class; - - parent_class = gtk_type_class (gnome_canvas_item_get_type ()); - - gtk_object_add_arg_type ("EIconBarTextItem::xalign", GTK_TYPE_FLOAT, GTK_ARG_READWRITE, ARG_XALIGN); - gtk_object_add_arg_type ("EIconBarTextItem::justify", GTK_TYPE_JUSTIFICATION, GTK_ARG_READWRITE, ARG_JUSTIFY); - gtk_object_add_arg_type ("EIconBarTextItem::max_lines", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_MAX_LINES); - gtk_object_add_arg_type ("EIconBarTextItem::show_ellipsis", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_SHOW_ELLIPSIS); - - iti_signals [TEXT_CHANGED] = - gtk_signal_new ( - "text_changed", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (EIconBarTextItemClass, text_changed), - gtk_marshal_BOOL__NONE, - GTK_TYPE_BOOL, 0); - - iti_signals [HEIGHT_CHANGED] = - gtk_signal_new ( - "height_changed", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (EIconBarTextItemClass, height_changed), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - iti_signals [WIDTH_CHANGED] = - gtk_signal_new ( - "width_changed", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (EIconBarTextItemClass, width_changed), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - iti_signals[EDITING_STARTED] = - gtk_signal_new ( - "editing_started", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (EIconBarTextItemClass, editing_started), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - iti_signals[EDITING_STOPPED] = - gtk_signal_new ( - "editing_stopped", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (EIconBarTextItemClass, editing_stopped), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - iti_signals[SELECTION_STARTED] = - gtk_signal_new ( - "selection_started", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (EIconBarTextItemClass, selection_started), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - iti_signals[SELECTION_STOPPED] = - gtk_signal_new ( - "selection_stopped", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (EIconBarTextItemClass, selection_stopped), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - gtk_object_class_add_signals (object_class, iti_signals, LAST_SIGNAL); - - object_class->destroy = iti_destroy; - object_class->get_arg = iti_get_arg; - object_class->set_arg = iti_set_arg; - - item_class->update = iti_update; - item_class->draw = iti_draw; - item_class->point = iti_point; - item_class->bounds = iti_bounds; - item_class->event = iti_event; - - e_icon_bar_text_item_ellipsis = _("..."); -} - -/* Object initialization function for the icon text item */ -static void -iti_init (EIconBarTextItem *iti) -{ - ItiPrivate *priv; - - priv = g_new0 (ItiPrivate, 1); - iti->priv = priv; - - iti->xalign = 0.5; - iti->justification = GTK_JUSTIFY_CENTER; - iti->max_lines = -1; - iti->show_ellipsis = TRUE; -} - -/** - * e_icon_bar_text_item_configure: - * @iti: An #EIconBarTextItem. - * @x: X position in which to place the item. - * @y: Y position in which to place the item. - * @width: Maximum width allowed for this item, to be used for word wrapping. - * @fontname: Name of the fontset that should be used to display the text. - * @text: Text that is going to be displayed. - * @is_static: Whether @text points to a static string or not. - * - * This routine is used to configure an #EIconBarTextItem. - * - * @x and @y specify the coordinates where the item is placed in the canvas. - * The @x coordinate should be the leftmost position that the item can - * assume at any one time, that is, the left margin of the column in which the - * icon is to be placed. The @y coordinate specifies the top of the item. - * - * @width is the maximum width allowed for this icon text item. The coordinates - * define the upper-left corner of an item with maximum width; this may - * actually be outside the bounding box of the item if the text is narrower - * than the maximum width. - * - * If @is_static is true, it means that there is no need for the item to - * allocate memory for the string (it is a guarantee that the text is allocated - * by the caller and it will not be deallocated during the lifetime of this - * item). This is an optimization to reduce memory usage for large icon sets. - */ -void -e_icon_bar_text_item_configure (EIconBarTextItem *iti, int x, int y, - int width, const char *fontname, - const char *text, - gboolean is_static) -{ - ItiPrivate *priv; - - g_return_if_fail (iti != NULL); - g_return_if_fail (IS_ITI (iti)); - g_return_if_fail (width > 2 * MARGIN_X); - g_return_if_fail (text != NULL); - - priv = iti->priv; - - iti->x = x; - iti->y = y; - iti->width = width; - - if (iti->text && iti->is_text_allocated) - g_free (iti->text); - - iti->is_text_allocated = !is_static; - - /* This cast is to shut up the compiler */ - if (is_static) - iti->text = (char *) text; - else - iti->text = g_strdup (text); - - if (iti->fontname) - g_free (iti->fontname); - - iti->fontname = g_strdup (fontname ? fontname : DEFAULT_FONT_NAME); - - if (priv->font) - gdk_font_unref (priv->font); - - priv->font = NULL; - if (fontname) - priv->font = gdk_fontset_load (iti->fontname); - if (!priv->font) - priv->font = get_default_font (); - - /* Request update */ - - priv->need_pos_update = TRUE; - priv->need_font_update = TRUE; - priv->need_text_update = TRUE; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti)); -} - -/** - * e_icon_bar_text_item_set_width: - * @iti: An #EIconBarTextItem. - * @width: Maximum width allowed for this item, to be used for word wrapping. - * - * This routine is used to set the maximum width of an #EIconBarTextItem. - */ -void -e_icon_bar_text_item_set_width (EIconBarTextItem *iti, int width) -{ - ItiPrivate *priv; - - g_return_if_fail (iti != NULL); - g_return_if_fail (IS_ITI (iti)); - g_return_if_fail (width > 2 * MARGIN_X); - - priv = iti->priv; - - if (iti->width == width) - return; - - iti->width = width; - - /* Request update */ - priv->need_text_update = TRUE; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti)); -} - -/** - * e_icon_bar_text_item_setxy: - * @iti: An #EIconBarTextItem. - * @x: X position. - * @y: Y position. - * - * Sets the coordinates at which the #EIconBarTextItem should be placed. - * - * See also: e_icon_bar_text_item_configure(). - */ -void -e_icon_bar_text_item_setxy (EIconBarTextItem *iti, int x, int y) -{ - ItiPrivate *priv; - - g_return_if_fail (iti != NULL); - g_return_if_fail (IS_ITI (iti)); - - priv = iti->priv; - - iti->x = x; - iti->y = y; - - priv->need_pos_update = TRUE; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti)); -} - -/** - * e_icon_bar_text_item_select: - * @iti: An #EIconBarTextItem. - * @sel: Whether the item should be displayed as selected. - * - * This function is used to control whether an icon text item is displayed as - * selected or not. Mouse events are ignored by the item when it is unselected; - * when the user clicks on a selected icon text item, it will start the text - * editing process. - */ -void -e_icon_bar_text_item_select (EIconBarTextItem *iti, int sel) -{ - ItiPrivate *priv; - - g_return_if_fail (iti != NULL); - g_return_if_fail (IS_ITI (iti)); - - priv = iti->priv; - - if (!iti->selected == !sel) - return; - - iti->selected = sel ? TRUE : FALSE; - - if (!iti->selected && iti->editing) - iti_edition_accept (iti); - - priv->need_state_update = TRUE; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti)); -} - -/** - * e_icon_bar_text_item_get_text: - * @iti: An #EIconBarTextItem. - * - * Returns the current text. The client should not free this string, as it is - * internal to the #EIconBarTextItem. - */ -char * -e_icon_bar_text_item_get_text (EIconBarTextItem *iti) -{ - ItiPrivate *priv; - - g_return_val_if_fail (iti != NULL, NULL); - g_return_val_if_fail (IS_ITI (iti), NULL); - - priv = iti->priv; - - if (iti->editing) - return gtk_entry_get_text (priv->entry); - else - return iti->text; -} - - -/** - * e_icon_bar_text_item_set_text: - * @iti: An #EIconBarTextItem. - * @text: Text that is going to be displayed. - * @is_static: Whether @text points to a static string or not. - * - * If @is_static is true, it means that there is no need for the item to - * allocate memory for the string (it is a guarantee that the text is allocated - * by the caller and it will not be deallocated during the lifetime of this - * item). This is an optimization to reduce memory usage for large icon sets. - */ -void -e_icon_bar_text_item_set_text (EIconBarTextItem *iti, const char *text, - gboolean is_static) -{ - ItiPrivate *priv; - - g_return_if_fail (iti != NULL); - g_return_if_fail (IS_ITI (iti)); - g_return_if_fail (text != NULL); - - priv = iti->priv; - - if (iti->text && iti->is_text_allocated) - g_free (iti->text); - - iti->is_text_allocated = !is_static; - - /* This cast is to shut up the compiler */ - if (is_static) - iti->text = (char *) text; - else - iti->text = g_strdup (text); - - /* Request update */ - - priv->need_text_update = TRUE; - gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti)); -} - - -/** - * e_icon_bar_text_item_start_editing: - * @iti: An #EIconBarTextItem. - * - * Starts the editing state of an #EIconBarTextItem. - **/ -void -e_icon_bar_text_item_start_editing (EIconBarTextItem *iti) -{ - g_return_if_fail (iti != NULL); - g_return_if_fail (IS_ITI (iti)); - - if (iti->editing) - return; - - iti->selected = TRUE; /* Ensure that we are selected */ - gnome_canvas_item_grab_focus (GNOME_CANVAS_ITEM (iti)); - iti_start_editing (iti); -} - -/** - * e_icon_bar_text_item_stop_editing: - * @iti: An #EIconBarTextItem. - * @accept: Whether to accept the current text or to discard it. - * - * Terminates the editing state of an icon text item. The @accept argument - * controls whether the item's current text should be accepted or discarded. - * If it is discarded, then the icon's original text will be restored. - **/ -void -e_icon_bar_text_item_stop_editing (EIconBarTextItem *iti, - gboolean accept) -{ - g_return_if_fail (iti != NULL); - g_return_if_fail (IS_ITI (iti)); - - if (!iti->editing) - return; - - if (accept) - iti_edition_accept (iti); - else - iti_stop_editing (iti); -} - - -/** - * e_icon_bar_text_item_get_type: - * - * Registers the &EIconBarTextItem class if necessary, and returns the type ID - * associated to it. - * - * Return value: the type ID of the #EIconBarTextItem class. - **/ -GtkType -e_icon_bar_text_item_get_type (void) -{ - static GtkType iti_type = 0; - - if (!iti_type) { - static const GtkTypeInfo iti_info = { - "EIconBarTextItem", - sizeof (EIconBarTextItem), - sizeof (EIconBarTextItemClass), - (GtkClassInitFunc) iti_class_init, - (GtkObjectInitFunc) iti_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - iti_type = gtk_type_unique (gnome_canvas_item_get_type (), &iti_info); - } - - return iti_type; -} - - -static void -free_row (gpointer data, gpointer user_data) -{ - EIconBarTextItemInfoRow *row; - - if (data) { - row = data; - g_free (row->text); - g_free (row->text_wc); - g_free (row); - } -} - -/* - * e_icon_bar_text_item_free_info: - * @ti: An icon text info structure. - * - * Frees a &EIconBarTextItemInfo structure. You should call this instead of - * freeing the structure yourself. - */ -static void -e_icon_bar_text_item_free_info (EIconBarTextItemInfo *ti) -{ - g_list_foreach (ti->rows, free_row, NULL); - g_list_free (ti->rows); - g_free (ti); -} - -/* - * e_icon_bar_text_item_layout_text: - * @font: Name of the font that will be used to render the text. - * @text: Text to be formatted. - * @separators: Separators used for word wrapping, can be NULL. - * @max_width: Width in pixels to be used for word wrapping. - * @confine: Whether it is mandatory to wrap at @max_width. - * - * Creates a new &EIconBarTextItemInfo structure by wrapping the specified - * text. If non-NULL, the @separators argument defines a set of characters - * to be used as word delimiters for performing word wrapping. If it is - * NULL, then only spaces will be used as word delimiters. - * - * The @max_width argument is used to specify the width at which word - * wrapping will be performed. If there is a very long word that does not - * fit in a single line, the @confine argument can be used to specify - * whether the word should be unconditionally split to fit or whether - * the maximum width should be increased as necessary. - * - * Return value: A newly-created &EIconBarTextItemInfo structure. - */ -static EIconBarTextItemInfo * -e_icon_bar_text_item_layout_text (EIconBarTextItem *iti, GdkFont *font, - const gchar *text, const gchar *separators, - gint max_width, gboolean confine) -{ - EIconBarTextItemInfo *ti; - EIconBarTextItemInfoRow *row; - GdkWChar *row_end; - GdkWChar *s, *word_start, *word_end, *old_word_end; - GdkWChar *sub_text; - int i, w_len, w; - GdkWChar *text_wc, *text_iter, *separators_wc; - int text_len_wc, separators_len_wc; - gboolean restrict_lines; - int lines; - - g_return_val_if_fail (font != NULL, NULL); - g_return_val_if_fail (text != NULL, NULL); - - if (!separators) - separators = " "; - - text_wc = g_new (GdkWChar, strlen (text) + 1); - text_len_wc = gdk_mbstowcs (text_wc, text, strlen (text)); - if (text_len_wc < 0) text_len_wc = 0; - text_wc[text_len_wc] = 0; - - separators_wc = g_new (GdkWChar, strlen (separators) + 1); - separators_len_wc = gdk_mbstowcs (separators_wc, separators, strlen (separators)); - if (separators_len_wc < 0) separators_len_wc = 0; - separators_wc[separators_len_wc] = 0; - - ti = g_new (EIconBarTextItemInfo, 1); - - ti->rows = NULL; - ti->font = font; - ti->width = 0; - ti->height = 0; - ti->baseline_skip = font->ascent + font->descent; - - word_end = NULL; - - if (!iti->editing && iti->max_lines != -1) - restrict_lines = TRUE; - else - restrict_lines = FALSE; - - text_iter = text_wc; - lines = 0; - while (*text_iter) { - /* If we are restricting the height, and this is the last line, - and we are displaying the ellipsis, then subtract the width - of the ellipsis from our max_width. */ - if (restrict_lines && lines == iti->max_lines - 1 - && iti->show_ellipsis) { - max_width -= gdk_string_measure (font, e_icon_bar_text_item_ellipsis); - } - - for (row_end = text_iter; *row_end != 0 && *row_end != '\n'; row_end++); - - /* Accumulate words from this row until they don't fit in the max_width */ - - s = text_iter; - - while (s < row_end) { - word_start = s; - old_word_end = word_end; - for (word_end = word_start; *word_end; word_end++) { - GdkWChar *p; - for (p = separators_wc; *p; p++) { - if (*word_end == *p) - goto found; - } - } - found: - if (word_end < row_end) - word_end++; - - if (gdk_text_width_wc (font, text_iter, word_end - text_iter) > max_width) { - if (word_start == text_iter - || (restrict_lines - && lines == iti->max_lines - 1)) { - if (confine) { - /* We must force-split the word. Look for a proper - * place to do it. - */ - - w_len = word_end - text_iter; - - for (i = 1; i < w_len; i++) { - w = gdk_text_width_wc (font, text_iter, i); - if (w > max_width) { - if (i == 1) - /* Shit, not even a single character fits */ - max_width = w; - else - break; - } - } - - /* Create sub-row with the chars that fit */ - - sub_text = g_new (GdkWChar, i); - memcpy (sub_text, text_iter, (i - 1) * sizeof (GdkWChar)); - sub_text[i - 1] = 0; - - row = g_new (EIconBarTextItemInfoRow, 1); - row->text_wc = sub_text; - row->text_length = i - 1; - row->width = gdk_text_width_wc (font, sub_text, i - 1); - row->text = gdk_wcstombs(sub_text); - if (row->text == NULL) - row->text = g_strdup(""); - - ti->rows = g_list_append (ti->rows, row); - - if (row->width > ti->width) - ti->width = row->width; - - ti->height += ti->baseline_skip; - - /* Bump the text pointer */ - - text_iter += i - 1; - s = text_iter; - - lines++; - if (restrict_lines - && lines >= iti->max_lines) - break; - - continue; - } else - max_width = gdk_text_width_wc (font, word_start, word_end - word_start); - - continue; /* Retry split */ - } else { - word_end = old_word_end; /* Restore to region that does fit */ - break; /* Stop the loop because we found something that doesn't fit */ - } - } - - s = word_end; - } - - if (restrict_lines && lines >= iti->max_lines) - break; - - /* Append row */ - - if (text_iter == row_end) { - /* We are on a newline, so append an empty row */ - - ti->rows = g_list_append (ti->rows, NULL); - ti->height += ti->baseline_skip; - - /* Next! */ - - text_iter = row_end + 1; - - lines++; - if (restrict_lines && lines >= iti->max_lines) - break; - - } else { - /* Create subrow and append it to the list */ - - int sub_len; - sub_len = word_end - text_iter; - - sub_text = g_new (GdkWChar, sub_len + 1); - memcpy (sub_text, text_iter, sub_len * sizeof (GdkWChar)); - sub_text[sub_len] = 0; - - row = g_new (EIconBarTextItemInfoRow, 1); - row->text_wc = sub_text; - row->text_length = sub_len; - row->width = gdk_text_width_wc (font, sub_text, sub_len); - row->text = gdk_wcstombs(sub_text); - if (row->text == NULL) - row->text = g_strdup(""); - - ti->rows = g_list_append (ti->rows, row); - - if (row->width > ti->width) - ti->width = row->width; - - ti->height += ti->baseline_skip; - - /* Next! */ - - text_iter = word_end; - - lines++; - if (restrict_lines && lines >= iti->max_lines) - break; - } - } - - /* Check if we've had to clip the text. */ - iti->is_clipped = *text_iter ? TRUE : FALSE; - - g_free (text_wc); - g_free (separators_wc); - return ti; -} - -/* - * e_icon_bar_text_item_paint_text: - * @ti: An icon text info structure. - * @drawable: Target drawable. - * @gc: GC used to render the string. - * @x: Left coordinate for text. - * @y: Upper coordinate for text. - * @just: Justification for text. - * - * Paints the formatted text in the icon text info structure onto a drawable. - * This is just a sample implementation; applications can choose to use other - * rendering functions. - */ -static void -e_icon_bar_text_item_paint_text (EIconBarTextItem *iti, - EIconBarTextItemInfo *ti, - GdkDrawable *drawable, GdkGC *gc, - gint x, gint y, GtkJustification just) -{ - GList *item; - EIconBarTextItemInfoRow *row; - int xpos, line, width; - gboolean show_ellipsis; - - g_return_if_fail (ti != NULL); - g_return_if_fail (drawable != NULL); - g_return_if_fail (gc != NULL); - - y += ti->font->ascent; - - for (item = ti->rows, line = 1; item; item = item->next, line++) { - - if (item->data) { - row = item->data; - width = row->width; - } - - /* If this is the last line, and the text has been clipped, - and show_ellipsis is TRUE, display '...' */ - if (line == iti->max_lines && iti->is_clipped) { - show_ellipsis = TRUE; - width += gdk_string_measure (ti->font, e_icon_bar_text_item_ellipsis); - } else { - show_ellipsis = FALSE; - } - - switch (just) { - case GTK_JUSTIFY_LEFT: - xpos = 0; - break; - - case GTK_JUSTIFY_RIGHT: - xpos = ti->width - width; - break; - - case GTK_JUSTIFY_CENTER: - xpos = (ti->width - width) / 2; - break; - - default: - /* Anyone care to implement GTK_JUSTIFY_FILL? */ - g_warning ("Justification type %d not supported. Using left-justification.", - (int) just); - xpos = 0; - } - - if (item->data) - gdk_draw_text_wc (drawable, ti->font, gc, x + xpos, y, row->text_wc, row->text_length); - - if (show_ellipsis) - gdk_draw_string (drawable, ti->font, gc, - x + xpos + row->width, y, - e_icon_bar_text_item_ellipsis); - - y += ti->baseline_skip; - } -} diff --git a/widgets/shortcut-bar/e-icon-bar-text-item.h b/widgets/shortcut-bar/e-icon-bar-text-item.h deleted file mode 100644 index 7c0380c87b..0000000000 --- a/widgets/shortcut-bar/e-icon-bar-text-item.h +++ /dev/null @@ -1,158 +0,0 @@ -/* -*- 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 - */ - -/* - * Based on gnome-icon-text-item: an editable text block with word wrapping - * for the GNOME canvas. - * - * Copyright (C) 1998, 1999 The Free Software Foundation - * - * Authors: Miguel de Icaza <miguel@gnu.org> - * Federico Mena <federico@gimp.org> - */ - -/* - * EIconBarTextItem - An editable canvas text item for the EIconBar. - */ - -#ifndef _E_ICON_BAR_TEXT_ITEM_H_ -#define _E_ICON_BAR_TEXT_ITEM_H_ - -#include <gtk/gtkentry.h> -#include <libgnomeui/gnome-canvas.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -#define E_ICON_BAR_TEXT_ITEM(obj) (GTK_CHECK_CAST((obj), \ - e_icon_bar_text_item_get_type (), EIconBarTextItem)) -#define E_ICON_BAR_TEXT_ITEM_CLASS(k) (GTK_CHECK_CLASS_CAST ((k),\ - e_icon_bar_text_item_get_type ())) -#define E_IS_ICON_BAR_TEXT_ITEM(o) (GTK_CHECK_TYPE((o), \ - e_icon_bar_text_item_get_type ())) - -typedef struct _EIconBarTextItemInfo EIconBarTextItemInfo; - -typedef struct { - GnomeCanvasItem canvas_item; - - /* Size and maximum allowed width */ - int x, y; - int width; - - /* Font name */ - char *fontname; - - /* Private data */ - gpointer priv; /* was GtkEntry *entry */ - - /* Actual text */ - char *text; - - /* Text layout information */ - EIconBarTextItemInfo *ti; - - /* Whether the text is being edited */ - unsigned int editing : 1; - - /* Whether the text item is selected */ - unsigned int selected : 1; - - /* Whether the user is select-dragging a block of text */ - unsigned int selecting : 1; - - /* Whether the text is editable */ - unsigned int is_editable : 1; - - /* Whether the text is allocated by us (FALSE if allocated by the client) */ - unsigned int is_text_allocated : 1; - - - /* The horizontal alignment of the text (default 0.5). */ - gfloat xalign; - - /* The justification of the text (default is centered). */ - GtkJustification justification; - - /* The max number of lines of text shown, or -1 for all (default). */ - gint max_lines; - - /* If '...' is displayed if the text doesn't all fit (default TRUE). */ - gboolean show_ellipsis; - - /* This is TRUE if we couldn't fit all the text in. */ - gboolean is_clipped; -} EIconBarTextItem; - -typedef struct { - GnomeCanvasItemClass parent_class; - - /* Signals we emit */ - int (* text_changed) (EIconBarTextItem *iti); - void (* height_changed) (EIconBarTextItem *iti); - void (* width_changed) (EIconBarTextItem *iti); - void (* editing_started) (EIconBarTextItem *iti); - void (* editing_stopped) (EIconBarTextItem *iti); - void (* selection_started) (EIconBarTextItem *iti); - void (* selection_stopped) (EIconBarTextItem *iti); -} EIconBarTextItemClass; - -GtkType e_icon_bar_text_item_get_type (void); - -void e_icon_bar_text_item_configure (EIconBarTextItem *iti, - int x, - int y, - int width, - const char *fontname, - const char *text, - gboolean is_static); - -void e_icon_bar_text_item_set_width (EIconBarTextItem *iti, - int width); - -void e_icon_bar_text_item_setxy (EIconBarTextItem *iti, - int x, - int y); - -void e_icon_bar_text_item_select (EIconBarTextItem *iti, - int sel); - -char* e_icon_bar_text_item_get_text (EIconBarTextItem *iti); -void e_icon_bar_text_item_set_text (EIconBarTextItem *iti, - const char *text, - gboolean is_static); - -void e_icon_bar_text_item_start_editing (EIconBarTextItem *iti); -void e_icon_bar_text_item_stop_editing (EIconBarTextItem *iti, - gboolean accept); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_ICON_BAR_TEXT_ITEM_H_ */ - diff --git a/widgets/shortcut-bar/e-icon-bar.c b/widgets/shortcut-bar/e-icon-bar.c deleted file mode 100644 index 6bb32ed2a2..0000000000 --- a/widgets/shortcut-bar/e-icon-bar.c +++ /dev/null @@ -1,1450 +0,0 @@ -/* -*- 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 - */ - -/* - * EIconBar is a subclass of GnomeCanvas for displaying a vertical column of - * icons and descriptions. It provides 2 views - large icons and small icons. - */ - -#include <gtk/gtkmain.h> -#include <gtk/gtksignal.h> -#include <libgnomeui/gnome-canvas-image.h> - -#include "e-icon-bar.h" -#include "e-icon-bar-bg-item.h" -#include "e-icon-bar-text-item.h" - -/* These are the offsets of the icons & text in both views. Note that the - shadow around icons is drawn in the space between items (as is the - horizontal bar when dragging). */ -#define E_ICON_BAR_LARGE_ICON_SPACING 8 /* Spacing between items. */ -#define E_ICON_BAR_LARGE_ICON_WIDTH 48 -#define E_ICON_BAR_LARGE_ICON_HEIGHT 48 -#define E_ICON_BAR_LARGE_ICON_TEXT_X 4 -#define E_ICON_BAR_LARGE_ICON_TEXT_Y (E_ICON_BAR_LARGE_ICON_HEIGHT + 4) - -#define E_ICON_BAR_SMALL_ICON_SPACING 4 /* Spacing between items. */ -#define E_ICON_BAR_SMALL_ICON_WIDTH 24 -#define E_ICON_BAR_SMALL_ICON_HEIGHT 24 -#define E_ICON_BAR_SMALL_ICON_X 4 -#define E_ICON_BAR_SMALL_ICON_TEXT_X (E_ICON_BAR_SMALL_ICON_WIDTH + 4) - -/* The space we leave at the top or bottom of the bar when position an item - while it is being edited. This is used since the EIconBar may be in a - EScrolledBar which may show buttons at the top or bottom. */ -#define E_ICON_BAR_V_SPACE 22 - -/* The number of pixels the mouse has to be moved with the button down before - we start a drag. */ -#define E_ICON_BAR_DRAG_START_OFFSET 4 - -/* This is the area at the top & bottom of the bar where we auto-scroll if the - mouse goes into during a drag-and-drop operation. */ -#define E_ICON_BAR_DRAG_AUTO_SCROLL_OFFSET 16 - -/* This is the time between each auto-scroll, when dragging. */ -#define E_ICON_BAR_SCROLL_TIMEOUT 30 - -/* This is the number of timeouts we skip before we start scrolling. */ -#define E_ICON_BAR_SCROLL_DELAY 12 - - -static void e_icon_bar_class_init (EIconBarClass *class); -static void e_icon_bar_init (EIconBar *icon_bar); -static void e_icon_bar_destroy (GtkObject *object); -static void e_icon_bar_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static gint e_icon_bar_leave_notify_event (GtkWidget *widget, - GdkEventCrossing *event); -static gint e_icon_bar_focus_in (GtkWidget *widget, - GdkEventFocus *event); -static gint e_icon_bar_focus_out (GtkWidget *widget, - GdkEventFocus *event); -static gint e_icon_bar_key_event (GtkWidget *widget, GdkEventKey *event); - -static gint e_icon_bar_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time); -static void e_icon_bar_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time); -static void e_icon_bar_set_dragging_before_item (EIconBar *icon_bar, - gint before_item); -static gboolean e_icon_bar_timeout_handler (gpointer data); - -static void e_icon_bar_recalc_common_positions (EIconBar *icon_bar); -static gint e_icon_bar_recalc_item_positions (EIconBar *icon_bar); -static void e_icon_bar_on_text_height_changed (GnomeCanvasItem *text_item, - EIconBar *icon_bar); -static gint e_icon_bar_find_item (EIconBar *icon_bar, - GnomeCanvasItem *text_item); -static gboolean e_icon_bar_on_item_event (GnomeCanvasItem *item, - GdkEvent *event, - EIconBar *icon_bar); - -static gboolean e_icon_bar_large_icons_intersects (EIconBar *icon_bar, - EIconBarItem *item, - gint x, - gint y); -static gboolean e_icon_bar_large_icons_is_before (EIconBar *icon_bar, - EIconBarItem *item, - gint x, - gint y); -static gboolean e_icon_bar_small_icons_intersects (EIconBar *icon_bar, - EIconBarItem *item, - gint x, - gint y); -static gboolean e_icon_bar_small_icons_is_before (EIconBar *icon_bar, - EIconBarItem *item, - gint x, - gint y); -static void e_icon_bar_on_text_item_editing_started (EIconBarTextItem *text_item, - EIconBar *icon_bar); -static void e_icon_bar_on_text_item_editing_stopped (EIconBarTextItem *text_item, - EIconBar *icon_bar); -static void e_icon_bar_ensure_edited_item_visible (EIconBar *icon_bar); -static void e_icon_bar_update_highlight (EIconBar *icon_bar); - -enum -{ - ITEM_SELECTED, - ITEM_DRAGGED, - LAST_SIGNAL -}; - -static guint e_icon_bar_signals[LAST_SIGNAL] = {0}; - -static GnomeCanvasClass *parent_class; - - -GtkType -e_icon_bar_get_type (void) -{ - static GtkType e_icon_bar_type = 0; - - if (!e_icon_bar_type){ - GtkTypeInfo e_icon_bar_info = { - "EIconBar", - sizeof (EIconBar), - sizeof (EIconBarClass), - (GtkClassInitFunc) e_icon_bar_class_init, - (GtkObjectInitFunc) e_icon_bar_init, - NULL, /* reserved 1 */ - NULL, /* reserved 2 */ - (GtkClassInitFunc) NULL - }; - - parent_class = gtk_type_class (gnome_canvas_get_type ()); - e_icon_bar_type = gtk_type_unique (gnome_canvas_get_type (), - &e_icon_bar_info); - } - - return e_icon_bar_type; -} - - -static void -e_icon_bar_class_init (EIconBarClass *class) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - - object_class = (GtkObjectClass *) class; - widget_class = (GtkWidgetClass *) class; - - e_icon_bar_signals[ITEM_SELECTED] = - gtk_signal_new ("item_selected", - GTK_RUN_LAST | GTK_RUN_ACTION, - object_class->type, - GTK_SIGNAL_OFFSET (EIconBarClass, - selected_item), - gtk_marshal_NONE__POINTER_INT, - GTK_TYPE_NONE, 2, GTK_TYPE_GDK_EVENT, - GTK_TYPE_INT); - e_icon_bar_signals[ITEM_DRAGGED] = - gtk_signal_new ("item_dragged", - GTK_RUN_LAST | GTK_RUN_ACTION, - object_class->type, - GTK_SIGNAL_OFFSET (EIconBarClass, - dragged_item), - gtk_marshal_NONE__POINTER_INT, - GTK_TYPE_NONE, 2, GTK_TYPE_GDK_EVENT, - GTK_TYPE_INT); - - gtk_object_class_add_signals (object_class, e_icon_bar_signals, - LAST_SIGNAL); - - /* Method override */ - object_class->destroy = e_icon_bar_destroy; - - widget_class->size_allocate = e_icon_bar_size_allocate; - widget_class->leave_notify_event = e_icon_bar_leave_notify_event; - widget_class->focus_in_event = e_icon_bar_focus_in; - widget_class->focus_out_event = e_icon_bar_focus_out; - widget_class->key_press_event = e_icon_bar_key_event; - widget_class->key_release_event = e_icon_bar_key_event; - widget_class->drag_motion = e_icon_bar_drag_motion; - widget_class->drag_leave = e_icon_bar_drag_leave; - - class->selected_item = NULL; -} - - -static void -e_icon_bar_init (EIconBar *icon_bar) -{ - icon_bar->view_type = E_ICON_BAR_LARGE_ICONS; - icon_bar->items = g_array_new (FALSE, FALSE, sizeof (EIconBarItem)); - icon_bar->pressed_item_num = -1; - icon_bar->mouse_over_item_num = -1; - icon_bar->editing_item_num = -1; - icon_bar->in_drag = FALSE; - icon_bar->dragging_before_item_num = -1; - icon_bar->icon_x = 0; - icon_bar->icon_w = 0; - icon_bar->icon_h = 0; - icon_bar->text_x = 0; - icon_bar->text_w = 5; - icon_bar->auto_scroll_timeout_id = 0; - - /* Create the background item in the canvas, which handles selections - and drag-and-drop. */ - gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (icon_bar)->root), - e_icon_bar_bg_item_get_type (), - "EIconBarBgItem::icon_bar", icon_bar, - NULL); -} - - -/** - * e_icon_bar_new: - * @Returns: A new #EIconBar. - * - * Creates a new #EIconBar. - **/ -GtkWidget * -e_icon_bar_new (void) -{ - GtkWidget *icon_bar; - - icon_bar = GTK_WIDGET (gtk_type_new (e_icon_bar_get_type ())); - - return icon_bar; -} - - -static void -e_icon_bar_destroy (GtkObject *object) -{ - EIconBar *icon_bar; - - icon_bar = E_ICON_BAR (object); - - GTK_OBJECT_CLASS (parent_class)->destroy (object); - - g_array_free (icon_bar->items, TRUE); - - if (icon_bar->auto_scroll_timeout_id != 0) { - gtk_timeout_remove (icon_bar->auto_scroll_timeout_id); - icon_bar->auto_scroll_timeout_id = 0; - } -} - - -static void -e_icon_bar_size_allocate (GtkWidget *widget, GtkAllocation *allocation) -{ - EIconBar *icon_bar; - gint canvas_width, canvas_height, height; - - icon_bar = E_ICON_BAR (widget); - - GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation); - - canvas_width = GTK_WIDGET (icon_bar)->allocation.width; - canvas_height = GTK_WIDGET (icon_bar)->allocation.height; - - /* Reset the y position and widths of all the items to the width of - the canvas, and reset the button labels, so they fit. */ - e_icon_bar_recalc_common_positions (icon_bar); - height = e_icon_bar_recalc_item_positions (icon_bar); - - gnome_canvas_set_scroll_region (GNOME_CANVAS (widget), - 0, 0, canvas_width, - MAX (height, canvas_height - 1)); - - /* If we are editing an item, make sure it is visible. */ - e_icon_bar_ensure_edited_item_visible (icon_bar); - - GTK_LAYOUT (widget)->vadjustment->step_increment = 16; - - e_icon_bar_update_highlight (icon_bar); -} - - -/* This sets all the item positions which are the same for all items in the - group. */ -static void -e_icon_bar_recalc_common_positions (EIconBar *icon_bar) -{ - gint canvas_width; - - canvas_width = GTK_WIDGET (icon_bar)->allocation.width; - - if (icon_bar->view_type == E_ICON_BAR_LARGE_ICONS) { - icon_bar->icon_x = (canvas_width - E_ICON_BAR_LARGE_ICON_WIDTH) / 2; - icon_bar->icon_w = E_ICON_BAR_LARGE_ICON_WIDTH; - icon_bar->icon_h = E_ICON_BAR_LARGE_ICON_HEIGHT; - - icon_bar->text_x = E_ICON_BAR_LARGE_ICON_TEXT_X; - icon_bar->text_w = MAX (canvas_width - (E_ICON_BAR_LARGE_ICON_TEXT_X * 2), 5); - - icon_bar->spacing = E_ICON_BAR_LARGE_ICON_SPACING; - } else { - icon_bar->icon_x = E_ICON_BAR_SMALL_ICON_X; - icon_bar->icon_w = E_ICON_BAR_SMALL_ICON_WIDTH; - icon_bar->icon_h = E_ICON_BAR_SMALL_ICON_HEIGHT; - - icon_bar->text_x = E_ICON_BAR_SMALL_ICON_TEXT_X; - icon_bar->text_w = MAX (canvas_width - E_ICON_BAR_SMALL_ICON_TEXT_X, 5); - - icon_bar->spacing = E_ICON_BAR_SMALL_ICON_SPACING; - } -} - - -/* This recalculates the positions of all the items, according to the current - view type and the height of the text items. */ -static gint -e_icon_bar_recalc_item_positions (EIconBar *icon_bar) -{ - EIconBarItem *item; - gint y, item_num; - gdouble x1, y1, x2, y2, xalign; - GtkJustification justify; - gint max_lines; - - if (icon_bar->view_type == E_ICON_BAR_LARGE_ICONS) { - xalign = 0.5; - justify = GTK_JUSTIFY_CENTER; - max_lines = 2; - } else { - xalign = 0.0; - justify = GTK_JUSTIFY_LEFT; - max_lines = 1; - } - - /* Now step through the items, setting the y positions. */ - y = icon_bar->spacing; - for (item_num = 0; item_num < icon_bar->items->len; item_num++) { - item = &g_array_index (icon_bar->items, - EIconBarItem, item_num); - - e_icon_bar_text_item_set_width (E_ICON_BAR_TEXT_ITEM (item->text), - icon_bar->text_w); - - /* Get the text item's height. */ - gnome_canvas_item_get_bounds (item->text, &x1, &y1, &x2, &y2); - item->text_width = x2 - x1; - item->text_height = y2 - y1; - - if (icon_bar->view_type == E_ICON_BAR_LARGE_ICONS) { - item->icon_y = y; - item->text_y = y + E_ICON_BAR_LARGE_ICON_TEXT_Y; - - item->item_height = E_ICON_BAR_LARGE_ICON_TEXT_Y - + item->text_height; - } else { - item->item_height = MAX (item->text_height, E_ICON_BAR_SMALL_ICON_HEIGHT); - item->icon_y = y + (item->item_height - E_ICON_BAR_SMALL_ICON_HEIGHT) / 2; - item->text_y = y + (item->item_height - item->text_height) / 2; - } - - e_icon_bar_text_item_setxy (E_ICON_BAR_TEXT_ITEM (item->text), - icon_bar->text_x, item->text_y); - - /* We need to get the bounds again, in case it has moved. */ - gnome_canvas_item_get_bounds (item->text, &x1, &y1, &x2, &y2); - item->text_x = x1; - - gnome_canvas_item_set (item->text, - "EIconBarTextItem::xalign", xalign, - "EIconBarTextItem::justify", justify, - "EIconBarTextItem::max_lines", max_lines, - NULL); - - gnome_canvas_item_set (item->image, - "GnomeCanvasImage::x", (gdouble)icon_bar->icon_x, - "GnomeCanvasImage::y", (gdouble)item->icon_y, - "GnomeCanvasImage::width", (gdouble)icon_bar->icon_w, - "GnomeCanvasImage::height", (gdouble)icon_bar->icon_h, - NULL); - - y += item->item_height + icon_bar->spacing; - } - - return y; -} - - -static gint -e_icon_bar_leave_notify_event (GtkWidget *widget, GdkEventCrossing *event) -{ - EIconBar *icon_bar; - - icon_bar = E_ICON_BAR (widget); - - GTK_WIDGET_CLASS (parent_class)->leave_notify_event (widget, event); - - /* Make sure no items are highlighted. */ - e_icon_bar_item_motion (icon_bar, -1, NULL); - - return FALSE; -} - - -static gint -e_icon_bar_focus_in (GtkWidget *widget, - GdkEventFocus *event) -{ - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (E_IS_ICON_BAR (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - GTK_WIDGET_CLASS (parent_class)->focus_in_event (widget, event); - GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS); - return FALSE; -} - - -static gint -e_icon_bar_focus_out (GtkWidget *widget, - GdkEventFocus *event) -{ - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (E_IS_ICON_BAR (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - GTK_WIDGET_CLASS (parent_class)->focus_out_event (widget, event); - GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS); - return FALSE; -} - - -/* Key event handler for the canvas. - FIXME: GnomeCanvas bug workaround - I needed to override this to stop the - canvas ignoring key events from other windows. */ -static gint -e_icon_bar_key_event (GtkWidget *widget, GdkEventKey *event) -{ - GnomeCanvas *canvas; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (E_IS_ICON_BAR (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - canvas = GNOME_CANVAS (widget); - - if (event->window != canvas->layout.bin_window) { - /* We change the window in the event struct so the canvas - doesn't ignore the event. Note that windows are ref-counted - in the event struct. */ - if (event->window) - gdk_window_unref (event->window); - event->window = canvas->layout.bin_window; - gdk_window_ref (event->window); - } - - /* These both call the same function at present, but we'll do it - properly just in case that changes. */ - if (event->type == GDK_KEY_PRESS) - return (*GTK_WIDGET_CLASS (parent_class)->key_press_event)(widget, event); - else - return (*GTK_WIDGET_CLASS (parent_class)->key_release_event)(widget, event); -} - - -/** - * e_icon_bar_set_view_type: - * @icon_bar: An #EIconBar. - * @view_type: The new view type, %E_ICON_BAR_LARGE_ICONS or - * %E_ICON_BAR_SMALL_ICONS. - * - * Sets the view type of the #EIconBar. - **/ -void -e_icon_bar_set_view_type (EIconBar *icon_bar, - EIconBarViewType view_type) -{ - g_return_if_fail (E_IS_ICON_BAR (icon_bar)); - - if (icon_bar->view_type == view_type) - return; - - icon_bar->view_type = view_type; - - /* Queue a resize of the canvas, so everything is put in the right - positions based on the new view type. */ - gtk_widget_queue_resize (GTK_WIDGET (icon_bar)); -} - - -/** - * e_icon_bar_add_item: - * @icon_bar: An #EIconBar. - * @image: the new item's icon. - * @text: the new item's text. - * @position: the position to place the new item, or -1 to place it last. - * - * Adds an item to the #EIconBar at the given position. - **/ -gint -e_icon_bar_add_item (EIconBar *icon_bar, - GdkImlibImage *image, - gchar *text, - gint position) -{ - EIconBarItem item; - gfloat xalign; - GtkJustification justify; - gint max_lines, retval; - - g_return_val_if_fail (E_IS_ICON_BAR (icon_bar), -1); - g_return_val_if_fail (text != NULL, -1); - g_return_val_if_fail (position >= -1, -1); - g_return_val_if_fail (position <= (gint)icon_bar->items->len, -1); - - if (icon_bar->view_type == E_ICON_BAR_LARGE_ICONS) { - xalign = 0.5; - justify = GTK_JUSTIFY_CENTER; - max_lines = 2; - } else { - xalign = 0.0; - justify = GTK_JUSTIFY_LEFT; - max_lines = 1; - } - - item.text = gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (icon_bar)->root), - e_icon_bar_text_item_get_type (), - "EIconBarTextItem::xalign", xalign, - "EIconBarTextItem::justify", justify, - "EIconBarTextItem::max_lines", max_lines, - NULL); - e_icon_bar_text_item_configure (E_ICON_BAR_TEXT_ITEM (item.text), - icon_bar->text_x, 0, - icon_bar->text_w, NULL, - text, FALSE); - gtk_signal_connect (GTK_OBJECT (item.text), "height_changed", - GTK_SIGNAL_FUNC (e_icon_bar_on_text_height_changed), icon_bar); - gtk_signal_connect (GTK_OBJECT (item.text), "event", - GTK_SIGNAL_FUNC (e_icon_bar_on_item_event), - icon_bar); - gtk_signal_connect (GTK_OBJECT (item.text), "editing_started", - GTK_SIGNAL_FUNC (e_icon_bar_on_text_item_editing_started), - icon_bar); - gtk_signal_connect (GTK_OBJECT (item.text), "editing_stopped", - GTK_SIGNAL_FUNC (e_icon_bar_on_text_item_editing_stopped), - icon_bar); - - item.image = gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (icon_bar)->root), - gnome_canvas_image_get_type (), - "GnomeCanvasImage::image", image, - "GnomeCanvasImage::anchor", GTK_ANCHOR_NORTH_WEST, - "GnomeCanvasImage::width", (gdouble) icon_bar->icon_w, - "GnomeCanvasImage::height", (gdouble) icon_bar->icon_h, - NULL); - gtk_signal_connect (GTK_OBJECT (item.image), "event", - GTK_SIGNAL_FUNC (e_icon_bar_on_item_event), - icon_bar); - - item.data = NULL; - item.destroy = NULL; - - if (position == -1) { - g_array_append_val (icon_bar->items, item); - retval = icon_bar->items->len - 1; - } else { - g_array_insert_val (icon_bar->items, position, item); - retval = position; - - /* FIXME: Should possibly update other indices. */ - if (icon_bar->dragged_item_num >= position) - icon_bar->dragged_item_num++; - } - - gtk_widget_queue_resize (GTK_WIDGET (icon_bar)); - - return retval; -} - - -/** - * e_icon_bar_reorder_item: - * @icon_bar: An #EIconBar. - * @item_num: The index of the item to move. - * @new_position: The new position of the item, which is used after the item - * has been removed from its current position. If @new_position is -1, the item - * is placed last. - * - * Moves an item to a new position within the #EIconBar. - **/ -void -e_icon_bar_reorder_item (EIconBar *icon_bar, - gint item_num, - gint new_position) -{ - EIconBarItem tmp_item; - - g_return_if_fail (E_IS_ICON_BAR (icon_bar)); - g_return_if_fail (item_num >= 0); - g_return_if_fail (item_num < icon_bar->items->len); - g_return_if_fail (new_position >= -1); - g_return_if_fail (new_position < icon_bar->items->len); - - tmp_item = g_array_index (icon_bar->items, EIconBarItem, item_num); - g_array_remove_index (icon_bar->items, item_num); - - if (new_position == -1) - g_array_append_val (icon_bar->items, tmp_item); - else - g_array_insert_val (icon_bar->items, new_position, tmp_item); - - gtk_widget_queue_resize (GTK_WIDGET (icon_bar)); -} - - -/** - * e_icon_bar_remove_item: - * @icon_bar: An #EIconBar. - * @item_num: The index of the item to remove. - * - * Removes an item from the #EIconBar. - **/ -void -e_icon_bar_remove_item (EIconBar *icon_bar, - gint item_num) -{ - EIconBarItem *item; - - g_return_if_fail (E_IS_ICON_BAR (icon_bar)); - g_return_if_fail (item_num >= 0); - g_return_if_fail (item_num < icon_bar->items->len); - - item = &g_array_index (icon_bar->items, EIconBarItem, item_num); - - if (item->destroy) - item->destroy (item->data); - - gtk_object_destroy (GTK_OBJECT (item->text)); - gtk_object_destroy (GTK_OBJECT (item->image)); - - g_array_remove_index (icon_bar->items, item_num); - - gtk_widget_queue_resize (GTK_WIDGET (icon_bar)); -} - - -/** - * e_icon_bar_get_item_image: - * @icon_bar: An #EIconBar. - * @item_num: The index of the item. - * @Returns: The icon of the given item. - * - * Returns the icon used for the given item. - **/ -GdkImlibImage* -e_icon_bar_get_item_image (EIconBar *icon_bar, - gint item_num) -{ - EIconBarItem *item; - GdkImlibImage *image; - - g_return_val_if_fail (E_IS_ICON_BAR (icon_bar), NULL); - g_return_val_if_fail (item_num >= 0, NULL); - g_return_val_if_fail (item_num < icon_bar->items->len, NULL); - - item = &g_array_index (icon_bar->items, EIconBarItem, item_num); - gtk_object_get (GTK_OBJECT (item->image), - "GnomeCanvasImage::image", image, - NULL); - return image; -} - - -/** - * e_icon_bar_set_item_image: - * @icon_bar: An #EIconBar. - * @item_num: The index of the item. - * @image: The new icon to use for the given item. - * - * Sets the icon to use for the given item. - **/ -void -e_icon_bar_set_item_image (EIconBar *icon_bar, - gint item_num, - GdkImlibImage *image) -{ - EIconBarItem *item; - - g_return_if_fail (E_IS_ICON_BAR (icon_bar)); - g_return_if_fail (item_num >= 0); - g_return_if_fail (item_num < icon_bar->items->len); - - item = &g_array_index (icon_bar->items, EIconBarItem, item_num); - gnome_canvas_item_set (item->image, - "GnomeCanvasImage::image", image, - NULL); -} - - -/** - * e_icon_bar_get_item_text: - * @icon_bar: An #EIconBar. - * @item_num: The index of the item. - * @Returns: The text of the given item. - * - * Returns the text of the given item. - **/ -gchar* -e_icon_bar_get_item_text (EIconBar *icon_bar, - gint item_num) -{ - EIconBarItem *item; - - g_return_val_if_fail (E_IS_ICON_BAR (icon_bar), NULL); - g_return_val_if_fail (item_num >= 0, NULL); - g_return_val_if_fail (item_num < icon_bar->items->len, NULL); - - item = &g_array_index (icon_bar->items, EIconBarItem, item_num); - return e_icon_bar_text_item_get_text (E_ICON_BAR_TEXT_ITEM (item->text)); -} - - -/** - * e_icon_bar_set_item_text: - * @icon_bar: An #EIconBar. - * @item_num: The index of the item. - * @text: The new text for the given item. - * - * Sets the text of the given item. - **/ -void -e_icon_bar_set_item_text (EIconBar *icon_bar, - gint item_num, - gchar *text) -{ - EIconBarItem *item; - - g_return_if_fail (E_IS_ICON_BAR (icon_bar)); - g_return_if_fail (item_num >= 0); - g_return_if_fail (item_num < icon_bar->items->len); - - item = &g_array_index (icon_bar->items, EIconBarItem, item_num); - e_icon_bar_text_item_set_text (E_ICON_BAR_TEXT_ITEM (item->text), - text, FALSE); -} - - -/** - * e_icon_bar_get_item_data: - * @icon_bar: An #EIconBar. - * @item_num: The index of the item. - * @Returns: The user data associated with the given item. - * - * Returns the user data associated with the given item. - **/ -gpointer -e_icon_bar_get_item_data (EIconBar *icon_bar, - gint item_num) -{ - EIconBarItem *item; - - g_return_val_if_fail (E_IS_ICON_BAR (icon_bar), NULL); - g_return_val_if_fail (item_num >= 0, NULL); - g_return_val_if_fail (item_num < icon_bar->items->len, NULL); - - item = &g_array_index (icon_bar->items, EIconBarItem, item_num); - return item->data; -} - - -/** - * e_icon_bar_set_item_data: - * @icon_bar: An #EIconBar. - * @item_num: The index of the item. - * @data: The user data to set for the given item. - * - * Sets the user data of the given item. - **/ -void -e_icon_bar_set_item_data (EIconBar *icon_bar, - gint item_num, - gpointer data) -{ - e_icon_bar_set_item_data_full (icon_bar, item_num, data, NULL); -} - - -/** - * e_icon_bar_set_item_data_full: - * @icon_bar: An #EIconBar. - * @item_num: The index of the item. - * @data: The user data to set for the given item. - * @destroy: The function to free @data when the item is destroyed. - * - * Sets the user data of the given item, and the function to free the data - * when the item is destroyed. - **/ -void -e_icon_bar_set_item_data_full (EIconBar *icon_bar, - gint item_num, - gpointer data, - GtkDestroyNotify destroy) -{ - EIconBarItem *item; - - g_return_if_fail (E_IS_ICON_BAR (icon_bar)); - g_return_if_fail (item_num >= 0); - g_return_if_fail (item_num < icon_bar->items->len); - - item = &g_array_index (icon_bar->items, EIconBarItem, item_num); - - if (item->destroy) - item->destroy (item->data); - - item->data = data; - item->destroy = destroy; -} - - -static void -e_icon_bar_on_text_height_changed (GnomeCanvasItem *text_item, - EIconBar *icon_bar) -{ - gtk_widget_queue_resize (GTK_WIDGET (icon_bar)); -} - - -/* This returns the index of the given item, or -1 if it isn't found. */ -static gint -e_icon_bar_find_item (EIconBar *icon_bar, - GnomeCanvasItem *canvas_item) -{ - EIconBarItem *item; - gint item_num; - - for (item_num = 0; item_num < icon_bar->items->len; item_num++) { - item = &g_array_index (icon_bar->items, - EIconBarItem, item_num); - - if (item->text == canvas_item || item->image == canvas_item) { - return item_num; - } - } - - return -1; -} - - -/* When an item has a grab, it will get all events, so we need to use the - position to find the real item. */ -static gboolean -e_icon_bar_on_item_event (GnomeCanvasItem *item, - GdkEvent *event, - EIconBar *icon_bar) -{ - gint item_num; - - switch (event->type) { - case GDK_BUTTON_PRESS: - item_num = e_icon_bar_find_item_at_position (icon_bar, - event->button.x, - event->button.y, - NULL); - e_icon_bar_item_pressed (icon_bar, item_num, event); - return TRUE; - case GDK_BUTTON_RELEASE: - item_num = e_icon_bar_find_item_at_position (icon_bar, - event->button.x, - event->button.y, - NULL); - e_icon_bar_item_released (icon_bar, item_num, event); - return TRUE; - case GDK_MOTION_NOTIFY: - item_num = e_icon_bar_find_item_at_position (icon_bar, - event->motion.x, - event->motion.y, - NULL); - e_icon_bar_item_motion (icon_bar, item_num, event); - return TRUE; - default: - break; - } - - return FALSE; -} - - -void -e_icon_bar_item_pressed (EIconBar *icon_bar, - gint item_num, - GdkEvent *event) -{ - EIconBarItem *item; - gint button; - - /* If we are editing an item, and a different item (or anywhere outside - an item) is clicked, stop the edit. If the item being edited is - clicked we just return, since the user may be selecting text. */ - if (icon_bar->editing_item_num != -1) { - if (icon_bar->editing_item_num == item_num) { - item = &g_array_index (icon_bar->items, EIconBarItem, - icon_bar->editing_item_num); - if (!GTK_WIDGET_HAS_FOCUS (item->text->canvas) - || item->text->canvas->focused_item != item->text) - gnome_canvas_item_grab_focus (item->text); - } else { - e_icon_bar_stop_editing_item (icon_bar, TRUE); - } - - return; - } - - button = event->button.button; - - if (button == 1 && item_num != -1) { - icon_bar->pressed_item_num = item_num; - icon_bar->pressed_x = event->button.x; - icon_bar->pressed_y = event->button.y; - gtk_widget_queue_draw (GTK_WIDGET (icon_bar)); - } else if (button == 3) { - gtk_signal_emit (GTK_OBJECT (icon_bar), - e_icon_bar_signals[ITEM_SELECTED], - event, item_num); - } -} - - -void -e_icon_bar_item_released (EIconBar *icon_bar, - gint item_num, - GdkEvent *event) -{ - gint button; - - /* If we are editing an item, just return. */ - if (icon_bar->editing_item_num != -1) - return; - - button = event->button.button; - - if (button == 1) { - if (icon_bar->pressed_item_num == icon_bar->mouse_over_item_num) { - gtk_signal_emit (GTK_OBJECT (icon_bar), - e_icon_bar_signals[ITEM_SELECTED], - event, item_num); - } - - icon_bar->pressed_item_num = -1; - gtk_widget_queue_draw (GTK_WIDGET (icon_bar)); - } -} - - -void -e_icon_bar_item_motion (EIconBar *icon_bar, - gint item_num, - GdkEvent *event) -{ - gboolean need_redraw = TRUE; - - if (event && event->motion.state & GDK_BUTTON1_MASK - && icon_bar->pressed_item_num != -1) { - if (abs (event->motion.x - icon_bar->pressed_x) > E_ICON_BAR_DRAG_START_OFFSET - || abs (event->motion.y - icon_bar->pressed_y) > E_ICON_BAR_DRAG_START_OFFSET) { - icon_bar->dragged_item_num = icon_bar->pressed_item_num; - gtk_signal_emit (GTK_OBJECT (icon_bar), - e_icon_bar_signals[ITEM_DRAGGED], - event, icon_bar->dragged_item_num); - - /* Don't show the button as pressed while dragging. */ - icon_bar->pressed_item_num = -1; - gtk_widget_queue_draw (GTK_WIDGET (icon_bar)); - } - - return; - } - - if (icon_bar->mouse_over_item_num == item_num) - return; - - /* If we are editing an item, items aren't highlighted so we don't - need a redraw. Also if an item is pressed, we only need a redraw if - item_num or the old mouse_over_item_num is the pressed item. */ - if (icon_bar->editing_item_num != -1) { - need_redraw = FALSE; - } else if (icon_bar->pressed_item_num != -1) { - if (icon_bar->pressed_item_num != item_num - && icon_bar->pressed_item_num != icon_bar->mouse_over_item_num) - need_redraw = FALSE; - } - - icon_bar->mouse_over_item_num = item_num; - - if (need_redraw) - gtk_widget_queue_draw (GTK_WIDGET (icon_bar)); -} - - -/* This returns the index of the item at the given position on the EIconBar, - or -1 if no item is found. If before_item is not NULL, it returns the - item which the mouse is before, or -1 (for dragging). */ -gint -e_icon_bar_find_item_at_position (EIconBar *icon_bar, - gint x, - gint y, - gint *before_item) -{ - EIconBarItem *item; - gint item_num; - - if (before_item) - *before_item = -1; - - for (item_num = 0; item_num < icon_bar->items->len; item_num++) { - item = &g_array_index (icon_bar->items, - EIconBarItem, item_num); - - if (icon_bar->view_type == E_ICON_BAR_LARGE_ICONS) { - if (e_icon_bar_large_icons_intersects (icon_bar, item, - x, y)) - return item_num; - - if (before_item - && e_icon_bar_large_icons_is_before (icon_bar, - item, x, y)) { - *before_item = item_num; - return -1; - } - } else { - if (e_icon_bar_small_icons_intersects (icon_bar, item, - x, y)) - return item_num; - - if (before_item - && e_icon_bar_small_icons_is_before (icon_bar, - item, x, y)) { - *before_item = item_num; - return -1; - } - - } - - } - - /* If the mouse is below all the items, but inside the items' width, - and before_item is not NULL, we set it to the number of items, so - the dropped item would be added at the end. Note that this assumes - that the item variable points to the last item in the EIconBar. */ - if (before_item) { - if (icon_bar->view_type == E_ICON_BAR_LARGE_ICONS) { - if (x < icon_bar->text_x - || x >= icon_bar->text_x + icon_bar->text_w) - return -1; - - if (item == NULL - || y > item->icon_y + item->item_height) - *before_item = icon_bar->items->len; - } else { - if (x < icon_bar->icon_x - || x >= icon_bar->text_x + icon_bar->text_w) - return -1; - - if (item == NULL) { - *before_item = icon_bar->items->len; - } else { - gint max_y; - max_y = MAX (item->icon_y + icon_bar->icon_h, - item->text_y + item->text_height); - if (y > max_y) - *before_item = icon_bar->items->len; - } - } - } - - return -1; -} - - -static gboolean -e_icon_bar_large_icons_intersects (EIconBar *icon_bar, - EIconBarItem *item, - gint x, - gint y) -{ - if (y < item->icon_y || y >= item->text_y + item->text_height) - return FALSE; - - if (y < item->icon_y + icon_bar->icon_h) { - if (x < icon_bar->icon_x - || x >= icon_bar->icon_x + icon_bar->icon_w) - return FALSE; - } else { - if (x < item->text_x - || x >= item->text_x + item->text_width) - return FALSE; - } - - return TRUE; -} - - -static gboolean -e_icon_bar_large_icons_is_before (EIconBar *icon_bar, - EIconBarItem *item, - gint x, - gint y) -{ - if (y < item->icon_y - icon_bar->spacing - || y >= item->icon_y) - return FALSE; - - if (x < icon_bar->text_x || x >= icon_bar->text_x + icon_bar->text_w) - return FALSE; - - return TRUE; -} - - -static gboolean -e_icon_bar_small_icons_intersects (EIconBar *icon_bar, - EIconBarItem *item, - gint x, - gint y) -{ - gint min_y, max_y; - - min_y = MIN (item->icon_y, item->text_y); - max_y = MAX (item->icon_y + icon_bar->icon_h, - item->text_y + item->text_height); - - if (y < min_y || y >= max_y) - return FALSE; - - if (x < icon_bar->icon_x || x >= item->text_x + item->text_width) - return FALSE; - - return TRUE; -} - - -static gboolean -e_icon_bar_small_icons_is_before (EIconBar *icon_bar, - EIconBarItem *item, - gint x, - gint y) -{ - gint min_y, max_y; - - max_y = MIN (item->icon_y, item->text_y); - min_y = max_y - icon_bar->spacing; - - if (y < min_y || y >= max_y) - return FALSE; - - if (x < icon_bar->icon_x || x >= icon_bar->text_x + icon_bar->text_w) - return FALSE; - - return TRUE; -} - - -/** - * e_icon_bar_start_editing_item: - * @icon_bar: An #EIconBar. - * @item_num: The index of the item. - * - * Turns the item into an editable text field so the user can rename it. - * Editing is stopped automatically when the user hits 'Return' or clicks - * outside the item. It can also be stopped explicitly by calling - * e_icon_bar_stop_editing_item(). - **/ -void -e_icon_bar_start_editing_item (EIconBar *icon_bar, - gint item_num) -{ - EIconBarItem *item; - - g_return_if_fail (E_IS_ICON_BAR (icon_bar)); - g_return_if_fail (item_num >= 0); - g_return_if_fail (item_num < icon_bar->items->len); - - item = &g_array_index (icon_bar->items, - EIconBarItem, item_num); - - e_icon_bar_text_item_start_editing (E_ICON_BAR_TEXT_ITEM (item->text)); -} - - -/** - * e_icon_bar_stop_editing_item: - * @icon_bar: An #EIconBar. - * @accept: TRUE if the changes should be accepted, FALSE if the text should be - * changed back to its state before the editing started. - * - * Stops the editing of the items, if any were being edited. - **/ -void -e_icon_bar_stop_editing_item (EIconBar *icon_bar, - gboolean accept) -{ - EIconBarItem *item; - - g_return_if_fail (E_IS_ICON_BAR (icon_bar)); - - if (icon_bar->editing_item_num != -1) { - item = &g_array_index (icon_bar->items, EIconBarItem, - icon_bar->editing_item_num); - e_icon_bar_text_item_stop_editing (E_ICON_BAR_TEXT_ITEM (item->text), accept); - } -} - - -static void -e_icon_bar_on_text_item_editing_started (EIconBarTextItem *text_item, - EIconBar *icon_bar) -{ - gint item_num; - - item_num = e_icon_bar_find_item (icon_bar, - GNOME_CANVAS_ITEM (text_item)); - g_return_if_fail (item_num != -1); - - /* Turn off any highlighted item. */ - e_icon_bar_item_motion (icon_bar, -1, NULL); - - icon_bar->editing_item_num = item_num; - - e_icon_bar_ensure_edited_item_visible (icon_bar); -} - - -static void -e_icon_bar_on_text_item_editing_stopped (EIconBarTextItem *text_item, - EIconBar *icon_bar) -{ - gint item_num; - - item_num = e_icon_bar_find_item (icon_bar, - GNOME_CANVAS_ITEM (text_item)); - g_return_if_fail (item_num != -1); - - e_icon_bar_text_item_select (text_item, FALSE); - - icon_bar->editing_item_num = -1; - - e_icon_bar_update_highlight (icon_bar); -} - - -static void -e_icon_bar_ensure_edited_item_visible (EIconBar *icon_bar) -{ - EIconBarItem *item; - gint scroll_x, scroll_y, min_scroll_y, max_scroll_y, new_scroll_y; - - if (icon_bar->editing_item_num == -1) - return; - - item = &g_array_index (icon_bar->items, - EIconBarItem, icon_bar->editing_item_num); - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (icon_bar), - &scroll_x, &scroll_y); - - /* The minimum scroll y position is with the text right on the bottom - of the display. */ - min_scroll_y = item->text_y + item->text_height + E_ICON_BAR_V_SPACE - - GTK_WIDGET (icon_bar)->allocation.height; - /* The maximum scroll y position is with the text at the top. */ - max_scroll_y = item->text_y - E_ICON_BAR_V_SPACE; - - new_scroll_y = MAX (scroll_y, min_scroll_y); - new_scroll_y = MIN (new_scroll_y, max_scroll_y); - - if (new_scroll_y != scroll_y) - gnome_canvas_scroll_to (GNOME_CANVAS (icon_bar), - scroll_x, new_scroll_y); -} - - -/* This gets the mouse position and updates the highlight if necessary. - It is called after items are added/deleted/scrolled/edited. */ -static void -e_icon_bar_update_highlight (EIconBar *icon_bar) -{ - GtkWidget *widget; - gint x, y, item_num; - - widget = GTK_WIDGET (icon_bar); - - if (!widget->window) - return; - - gdk_window_get_pointer (widget->window, &x, &y, NULL); - - if (x < 0 || y < 0 - || x > widget->allocation.width || y > widget->allocation.height) - return; - - item_num = e_icon_bar_find_item_at_position (icon_bar, x, y, NULL); - e_icon_bar_item_motion (icon_bar, item_num, NULL); -} - - -static gint -e_icon_bar_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time) -{ - EIconBar *icon_bar; - gint item_num, before_item, scroll_x, scroll_y; - - g_return_val_if_fail (E_IS_ICON_BAR (widget), FALSE); - - icon_bar = E_ICON_BAR (widget); - - icon_bar->in_drag = TRUE; - - /* Check if the mouse is over or between items, and if so highlight. */ - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (icon_bar), - &scroll_x, &scroll_y); - item_num = e_icon_bar_find_item_at_position (icon_bar, - x + scroll_x, - y + scroll_y, - &before_item); - e_icon_bar_item_motion (icon_bar, item_num, NULL); - e_icon_bar_set_dragging_before_item (icon_bar, before_item); - - /* Check if the mouse is at the top or bottom of the bar, and if it is - scroll up/down. */ - if (y < E_ICON_BAR_DRAG_AUTO_SCROLL_OFFSET) - icon_bar->scrolling_up = TRUE; - else if (y >= widget->allocation.height - E_ICON_BAR_DRAG_AUTO_SCROLL_OFFSET) - icon_bar->scrolling_up = FALSE; - else { - if (icon_bar->auto_scroll_timeout_id != 0) { - gtk_timeout_remove (icon_bar->auto_scroll_timeout_id); - icon_bar->auto_scroll_timeout_id = 0; - } - return FALSE; - } - - if (icon_bar->auto_scroll_timeout_id == 0) { - icon_bar->auto_scroll_timeout_id = g_timeout_add (E_ICON_BAR_SCROLL_TIMEOUT, e_icon_bar_timeout_handler, icon_bar); - icon_bar->auto_scroll_delay = E_ICON_BAR_SCROLL_DELAY; - } - - return FALSE; -} - - -static void -e_icon_bar_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time) -{ - EIconBar *icon_bar; - - g_return_if_fail (E_IS_ICON_BAR (widget)); - - icon_bar = E_ICON_BAR (widget); - - icon_bar->in_drag = FALSE; - - if (icon_bar->auto_scroll_timeout_id != 0) { - gtk_timeout_remove (icon_bar->auto_scroll_timeout_id); - icon_bar->auto_scroll_timeout_id = 0; - } - - if (icon_bar->mouse_over_item_num != -1) { - icon_bar->mouse_over_item_num = -1; - gtk_widget_queue_draw (GTK_WIDGET (icon_bar)); - } -} - - -static void -e_icon_bar_set_dragging_before_item (EIconBar *icon_bar, - gint before_item) -{ - if (icon_bar->dragging_before_item_num == before_item) - return; - - icon_bar->dragging_before_item_num = before_item; - - gtk_widget_queue_draw (GTK_WIDGET (icon_bar)); -} - - -static gboolean -e_icon_bar_timeout_handler (gpointer data) -{ - EIconBar *icon_bar; - gint scroll_x, scroll_y, new_scroll_y; - GtkAdjustment *adj; - - g_return_val_if_fail (E_IS_ICON_BAR (data), FALSE); - - icon_bar = E_ICON_BAR (data); - - GDK_THREADS_ENTER (); - - if (icon_bar->auto_scroll_delay > 0) { - icon_bar->auto_scroll_delay--; - GDK_THREADS_LEAVE (); - return TRUE; - } - - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (icon_bar), - &scroll_x, &scroll_y); - - adj = GTK_LAYOUT (icon_bar)->vadjustment; - - if (icon_bar->scrolling_up) - new_scroll_y = MAX (scroll_y - adj->step_increment, 0); - else - new_scroll_y = MIN (scroll_y + adj->step_increment, - adj->upper - adj->page_size); - - if (new_scroll_y != scroll_y) - gnome_canvas_scroll_to (GNOME_CANVAS (icon_bar), - scroll_x, new_scroll_y); - - GDK_THREADS_LEAVE (); - return TRUE; -} diff --git a/widgets/shortcut-bar/e-icon-bar.h b/widgets/shortcut-bar/e-icon-bar.h deleted file mode 100644 index 74b7507384..0000000000 --- a/widgets/shortcut-bar/e-icon-bar.h +++ /dev/null @@ -1,221 +0,0 @@ -/* -*- 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 - */ -#ifndef _E_ICON_BAR_H_ -#define _E_ICON_BAR_H_ - -#include <gdk_imlib.h> -#include <libgnomeui/gnome-canvas.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * EIconBar is a subclass of GnomeCanvas for displaying a vertical column of - * icons and descriptions. It provides 2 views - large icons and small icons. - */ - - -/* This contains information on one item. */ -typedef struct _EIconBarItem EIconBarItem; -struct _EIconBarItem -{ - GnomeCanvasItem *text; - GnomeCanvasItem *image; - - /* This is user data attached to the item, e.g. a URL. */ - gpointer data; - GtkDestroyNotify destroy; - - /* This is the height of the item. */ - gint item_height; - - /* This is the actual x, width and height of the text, rather than - the maximum allowed area. */ - gint text_x; - gint text_width; - gint text_height; - - gint icon_y, text_y; -}; - - -/* These are the view types. Defaults to LARGE_ICONS. */ -typedef enum -{ - E_ICON_BAR_LARGE_ICONS, - E_ICON_BAR_SMALL_ICONS -} EIconBarViewType; - - -#define E_ICON_BAR(obj) GTK_CHECK_CAST (obj, e_icon_bar_get_type (), EIconBar) -#define E_ICON_BAR_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_icon_bar_get_type (), EIconBarClass) -#define E_IS_ICON_BAR(obj) GTK_CHECK_TYPE (obj, e_icon_bar_get_type ()) - - -typedef struct _EIconBar EIconBar; -typedef struct _EIconBarClass EIconBarClass; - -struct _EIconBar -{ - GnomeCanvas canvas; - - /* This specifies if we are using large icons or small icons. */ - EIconBarViewType view_type; - - /* This is an array of EIconBarItem elements. */ - GArray *items; - - /* This is the index of the item which has been pressed, or -1. - It will be shown as pressed in while the mouse is over it. */ - gint pressed_item_num; - - /* This is the coordinates of where the button was pressed. If the - mouse moves a certain distance with the button still pressed, we - start a drag. */ - gint pressed_x; - gint pressed_y; - - /* This is the index of the item the mouse is currently over, or -1. - It will be highlighted unless one of the items is pressed. */ - gint mouse_over_item_num; - - /* This is the item that we are currently editing, or -1. */ - gint editing_item_num; - - /* This is the index of the item which is being dragged, or -1. - If the drag results in a move it will be deleted. */ - gint dragged_item_num; - - /* This is TRUE if we are dragging over this EIconBar. */ - gboolean in_drag; - - /* This is used in drag-and-drop to indicate the item which the mouse - is currently before, e.g. if it is 1 then a dropped item would be - inserted between items 0 and 1. It ranges from 0 to the number of - items, or is -1 when the mouse is not dragging between items. */ - gint dragging_before_item_num; - - /* These are the common positions of all the items in the EIconBar. */ - gint icon_x, icon_w, icon_h, text_x, text_w, spacing; - - /* This is the source id of our auto-scroll timeout handler, used when - in the middle of drag-and-drop operations. */ - gint auto_scroll_timeout_id; - gint auto_scroll_delay; - gboolean scrolling_up; -}; - -struct _EIconBarClass -{ - GnomeCanvasClass parent_class; - - void (*selected_item) (EIconBar *icon_bar, - GdkEvent *event, - gint item_num); - void (*dragged_item) (EIconBar *icon_bar, - GdkEvent *event, - gint item_num); -}; - - -GtkType e_icon_bar_get_type (void); -GtkWidget* e_icon_bar_new (void); - -/* Sets the view type. */ -void e_icon_bar_set_view_type (EIconBar *icon_bar, - EIconBarViewType view_type); - -/* Adds a new item to a group at the given position. If position is -1 it is - added at the end. It returns the index of the item. */ -gint e_icon_bar_add_item (EIconBar *icon_bar, - GdkImlibImage *image, - gchar *text, - gint position); - -/* Reorders an item. Note that position refers to the new position to add the - item after removing it from its current position. If position is -1 it is - moved to the end of the bar. */ -void e_icon_bar_reorder_item (EIconBar *icon_bar, - gint item_num, - gint new_position); -void e_icon_bar_remove_item (EIconBar *icon_bar, - gint item_num); - -GdkImlibImage* e_icon_bar_get_item_image (EIconBar *icon_bar, - gint item_num); -void e_icon_bar_set_item_image (EIconBar *icon_bar, - gint item_num, - GdkImlibImage *image); - -gchar* e_icon_bar_get_item_text (EIconBar *icon_bar, - gint item_num); -void e_icon_bar_set_item_text (EIconBar *icon_bar, - gint item_num, - gchar *text); - -gpointer e_icon_bar_get_item_data (EIconBar *icon_bar, - gint item_num); -void e_icon_bar_set_item_data (EIconBar *icon_bar, - gint item_num, - gpointer data); -void e_icon_bar_set_item_data_full (EIconBar *icon_bar, - gint item_num, - gpointer data, - GtkDestroyNotify destroy); - -void e_icon_bar_start_editing_item (EIconBar *icon_bar, - gint item_num); -void e_icon_bar_stop_editing_item (EIconBar *icon_bar, - gboolean accept); - - - -/* - * INTERNAL FUNCTIONS - for use by EIconBarBgItem. - */ - -/* This returns the index of the item at the given position on the EIconBar, - or -1 if no item is found. If before_item is not NULL, it returns the - item which the mouse is before, or -1 (this is used for dragging). */ -gint e_icon_bar_find_item_at_position (EIconBar *icon_bar, - gint x, - gint y, - gint *before_item); - -void e_icon_bar_item_pressed (EIconBar *icon_bar, - gint item_num, - GdkEvent *event); -void e_icon_bar_item_released (EIconBar *icon_bar, - gint item_num, - GdkEvent *event); -void e_icon_bar_item_motion (EIconBar *icon_bar, - gint item_num, - GdkEvent *event); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_ICON_BAR_H_ */ diff --git a/widgets/shortcut-bar/e-shortcut-bar.c b/widgets/shortcut-bar/e-shortcut-bar.c deleted file mode 100644 index 7ad00feb78..0000000000 --- a/widgets/shortcut-bar/e-shortcut-bar.c +++ /dev/null @@ -1,563 +0,0 @@ -/* -*- 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 - */ - -/* - * ShortcutBar displays a vertical bar with a number of Groups, each of which - * contains any number of icons. It is used on the left of the main application - * window so users can easily access items such as folders and files. - */ - -#include <string.h> -#include <gnome.h> - -#include "e-shortcut-bar.h" -#include "e-clipped-label.h" -#include "e-vscrolled-bar.h" - -/* Drag and Drop stuff. */ -enum { - TARGET_SHORTCUT -}; -static GtkTargetEntry target_table[] = { - { "E-SHORTCUT", 0, TARGET_SHORTCUT } -}; -static guint n_targets = sizeof(target_table) / sizeof(target_table[0]); - -typedef struct _EShortcutBarBuiltinType EShortcutBarBuiltinType; -struct _EShortcutBarBuiltinType { - gchar *name; - gchar *filename; - GdkImlibImage *image; -}; - -EShortcutBarBuiltinType e_shortcut_bar_builtin_types[] = { - { "folder:", "gnome-word.png", NULL }, - { "calendar:", "gnome-calendar.png", NULL }, - { "todo:", "gnome-cromagnon.png", NULL }, - { "contacts:", "gnome-ccthemes.png", NULL } -}; -static gint e_shortcut_bar_num_builtin_types = sizeof (e_shortcut_bar_builtin_types) / sizeof (EShortcutBarBuiltinType); - -gboolean e_shortcut_bar_default_type_image_loaded = FALSE; -GdkImlibImage *e_shortcut_bar_default_type_image = NULL; -gchar *e_shortcut_bar_default_type_filename = "gnome-balsa2.png"; - -static void e_shortcut_bar_class_init (EShortcutBarClass *class); -static void e_shortcut_bar_init (EShortcutBar *shortcut_bar); -static void e_shortcut_bar_destroy (GtkObject *object); -static void e_shortcut_bar_set_canvas_style (EShortcutBar *shortcut_bar, - GtkWidget *canvas); -static void e_shortcut_bar_item_selected (EIconBar *icon_bar, - GdkEvent *event, - gint item_num, - EShortcutBar *shortcut_bar); -static void e_shortcut_bar_item_dragged (EIconBar *icon_bar, - GdkEvent *event, - gint item_num, - EShortcutBar *shortcut_bar); -static void e_shortcut_bar_on_drag_data_get (GtkWidget *widget, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint time, - EShortcutBar *shortcut_bar); -static void e_shortcut_bar_on_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *data, - guint info, - guint time, - EShortcutBar *shortcut_bar); -static void e_shortcut_bar_on_drag_data_delete (GtkWidget *widget, - GdkDragContext *context, - EShortcutBar *shortcut_bar); -static void e_shortcut_bar_stop_editing (GtkWidget *button, - EShortcutBar *shortcut_bar); -static GdkImlibImage* e_shortcut_bar_get_image_from_url (EShortcutBar *shortcut_bar, - gchar *item_url); -static GdkImlibImage* e_shortcut_bar_load_image (gchar *filename); - - -enum -{ - ITEM_SELECTED, - LAST_SIGNAL -}; - -static guint e_shortcut_bar_signals[LAST_SIGNAL] = {0}; - -static EGroupBarClass *parent_class; - - -GtkType -e_shortcut_bar_get_type (void) -{ - static GtkType e_shortcut_bar_type = 0; - - if (!e_shortcut_bar_type){ - GtkTypeInfo e_shortcut_bar_info = { - "EShortcutBar", - sizeof (EShortcutBar), - sizeof (EShortcutBarClass), - (GtkClassInitFunc) e_shortcut_bar_class_init, - (GtkObjectInitFunc) e_shortcut_bar_init, - NULL, /* reserved 1 */ - NULL, /* reserved 2 */ - (GtkClassInitFunc) NULL - }; - - parent_class = gtk_type_class (e_group_bar_get_type ()); - e_shortcut_bar_type = gtk_type_unique (e_group_bar_get_type (), - &e_shortcut_bar_info); - } - - return e_shortcut_bar_type; -} - - -static void -e_shortcut_bar_class_init (EShortcutBarClass *class) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - - object_class = (GtkObjectClass *) class; - widget_class = (GtkWidgetClass *) class; - - e_shortcut_bar_signals[ITEM_SELECTED] = - gtk_signal_new ("item_selected", - GTK_RUN_LAST | GTK_RUN_ACTION, - object_class->type, - GTK_SIGNAL_OFFSET (EShortcutBarClass, - selected_item), - gtk_marshal_NONE__POINTER_INT_INT, - GTK_TYPE_NONE, 3, GTK_TYPE_GDK_EVENT, - GTK_TYPE_INT, GTK_TYPE_INT); - - gtk_object_class_add_signals (object_class, e_shortcut_bar_signals, - LAST_SIGNAL); - - /* Method override */ - object_class->destroy = e_shortcut_bar_destroy; -} - - -static void -e_shortcut_bar_init (EShortcutBar *shortcut_bar) -{ - shortcut_bar->groups = g_array_new (FALSE, FALSE, - sizeof (EShortcutBarGroup)); -} - - -GtkWidget * -e_shortcut_bar_new (void) -{ - GtkWidget *shortcut_bar; - - shortcut_bar = GTK_WIDGET (gtk_type_new (e_shortcut_bar_get_type ())); - - return shortcut_bar; -} - - -static void -e_shortcut_bar_destroy (GtkObject *object) -{ - EShortcutBar *shortcut_bar; - - shortcut_bar = E_SHORTCUT_BAR (object); - - GTK_OBJECT_CLASS (parent_class)->destroy (object); - - g_array_free (shortcut_bar->groups, TRUE); -} - - -gint -e_shortcut_bar_add_group (EShortcutBar *shortcut_bar, gchar *group_name) -{ - EShortcutBarGroup *group, tmp_group; - gint group_num; - GtkWidget *button, *label; - - g_return_val_if_fail (E_IS_SHORTCUT_BAR (shortcut_bar), -1); - g_return_val_if_fail (group_name != NULL, -1); - - group_num = shortcut_bar->groups->len; - g_array_append_val (shortcut_bar->groups, tmp_group); - - group = &g_array_index (shortcut_bar->groups, - EShortcutBarGroup, group_num); - - group->vscrolled_bar = e_vscrolled_bar_new (NULL); - gtk_widget_show (group->vscrolled_bar); - gtk_signal_connect (GTK_OBJECT (E_VSCROLLED_BAR (group->vscrolled_bar)->up_button), "pressed", GTK_SIGNAL_FUNC (e_shortcut_bar_stop_editing), shortcut_bar); - gtk_signal_connect (GTK_OBJECT (E_VSCROLLED_BAR (group->vscrolled_bar)->down_button), "pressed", GTK_SIGNAL_FUNC (e_shortcut_bar_stop_editing), shortcut_bar); - - group->icon_bar = e_icon_bar_new (); - gtk_widget_show (group->icon_bar); - gtk_container_add (GTK_CONTAINER (group->vscrolled_bar), - group->icon_bar); - gtk_signal_connect (GTK_OBJECT (group->icon_bar), "item_selected", - GTK_SIGNAL_FUNC (e_shortcut_bar_item_selected), - shortcut_bar); - gtk_signal_connect (GTK_OBJECT (group->icon_bar), "item_dragged", - GTK_SIGNAL_FUNC (e_shortcut_bar_item_dragged), - shortcut_bar); - gtk_signal_connect (GTK_OBJECT (group->icon_bar), "drag_data_get", - GTK_SIGNAL_FUNC (e_shortcut_bar_on_drag_data_get), - shortcut_bar); - gtk_signal_connect (GTK_OBJECT (group->icon_bar), "drag_data_received", - GTK_SIGNAL_FUNC (e_shortcut_bar_on_drag_data_received), - shortcut_bar); - gtk_signal_connect (GTK_OBJECT (group->icon_bar), "drag_data_delete", - GTK_SIGNAL_FUNC (e_shortcut_bar_on_drag_data_delete), - shortcut_bar); - - e_shortcut_bar_set_canvas_style (shortcut_bar, group->icon_bar); - - button = gtk_button_new (); - label = e_clipped_label_new (group_name); - gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); - gtk_widget_show (label); - gtk_container_add (GTK_CONTAINER (button), label); - gtk_widget_show (button); - gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (e_shortcut_bar_stop_editing), - shortcut_bar); - - gtk_drag_dest_set (GTK_WIDGET (group->icon_bar), - GTK_DEST_DEFAULT_ALL, - target_table, n_targets, - GDK_ACTION_COPY | GDK_ACTION_MOVE); - gtk_drag_dest_set (GTK_WIDGET (button), - GTK_DEST_DEFAULT_ALL, - target_table, n_targets, - GDK_ACTION_COPY | GDK_ACTION_MOVE); - - e_group_bar_add_group (E_GROUP_BAR (shortcut_bar), - group->vscrolled_bar, button, -1); - - - return group_num; -} - - -void -e_shortcut_bar_remove_group (EShortcutBar *shortcut_bar, - gint group_num) -{ - e_group_bar_remove_group (E_GROUP_BAR (shortcut_bar), group_num); - g_array_remove_index (shortcut_bar->groups, group_num); -} - - -gint -e_shortcut_bar_add_item (EShortcutBar *shortcut_bar, gint group_num, - gchar *item_url, gchar *item_name) -{ - EShortcutBarGroup *group; - GdkImlibImage *image; - gint item_num; - - g_return_val_if_fail (E_IS_SHORTCUT_BAR (shortcut_bar), -1); - g_return_val_if_fail (group_num >= 0, -1); - g_return_val_if_fail (group_num < shortcut_bar->groups->len, -1); - g_return_val_if_fail (item_url != NULL, -1); - g_return_val_if_fail (item_name != NULL, -1); - - image = e_shortcut_bar_get_image_from_url (shortcut_bar, item_url); - - group = &g_array_index (shortcut_bar->groups, - EShortcutBarGroup, group_num); - - item_num = e_icon_bar_add_item (E_ICON_BAR (group->icon_bar), - image, item_name, -1); - e_icon_bar_set_item_data_full (E_ICON_BAR (group->icon_bar), item_num, - g_strdup (item_url), g_free); - return item_num; -} - - -void -e_shortcut_bar_remove_item (EShortcutBar *shortcut_bar, - gint group_num, - gint item_num) -{ - EShortcutBarGroup *group; - - g_return_if_fail (E_IS_SHORTCUT_BAR (shortcut_bar)); - g_return_if_fail (group_num >= 0); - g_return_if_fail (group_num < shortcut_bar->groups->len); - - group = &g_array_index (shortcut_bar->groups, - EShortcutBarGroup, group_num); - - e_icon_bar_remove_item (E_ICON_BAR (group->icon_bar), item_num); -} - - -static void -e_shortcut_bar_set_canvas_style (EShortcutBar *shortcut_bar, - GtkWidget *canvas) -{ - GtkRcStyle *rc_style; - - rc_style = gtk_rc_style_new (); - - rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_FG | GTK_RC_BG; - rc_style->fg[GTK_STATE_NORMAL].red = 65535; - rc_style->fg[GTK_STATE_NORMAL].green = 65535; - rc_style->fg[GTK_STATE_NORMAL].blue = 65535; - - rc_style->bg[GTK_STATE_NORMAL].red = 32512; - rc_style->bg[GTK_STATE_NORMAL].green = 32512; - rc_style->bg[GTK_STATE_NORMAL].blue = 32512; - - gtk_widget_modify_style (GTK_WIDGET (canvas), rc_style); - gtk_rc_style_unref (rc_style); -} - - -void -e_shortcut_bar_set_view_type (EShortcutBar *shortcut_bar, - gint group_num, - EIconBarViewType view_type) -{ - EShortcutBarGroup *group; - - g_return_if_fail (E_IS_SHORTCUT_BAR (shortcut_bar)); - g_return_if_fail (group_num >= 0); - g_return_if_fail (group_num < shortcut_bar->groups->len); - - group = &g_array_index (shortcut_bar->groups, - EShortcutBarGroup, group_num); - - e_icon_bar_set_view_type (E_ICON_BAR (group->icon_bar), view_type); -} - - -static void -e_shortcut_bar_item_selected (EIconBar *icon_bar, - GdkEvent *event, - gint item_num, - EShortcutBar *shortcut_bar) -{ - gint group_num; - - group_num = e_group_bar_get_group_num (E_GROUP_BAR (shortcut_bar), - GTK_WIDGET (icon_bar)->parent); - - gtk_signal_emit (GTK_OBJECT (shortcut_bar), - e_shortcut_bar_signals[ITEM_SELECTED], - event, group_num, item_num); -} - - -static void -e_shortcut_bar_item_dragged (EIconBar *icon_bar, - GdkEvent *event, - gint item_num, - EShortcutBar *shortcut_bar) -{ - GtkTargetList *target_list; - gint group_num; - - group_num = e_group_bar_get_group_num (E_GROUP_BAR (shortcut_bar), - GTK_WIDGET (icon_bar)->parent); - - /* FIXME: free somewhere - drag_end? */ - shortcut_bar->dragged_url = g_strdup (e_icon_bar_get_item_data (icon_bar, item_num)); - shortcut_bar->dragged_name = g_strdup (e_icon_bar_get_item_text (icon_bar, item_num)); - - target_list = gtk_target_list_new (target_table, n_targets); - gtk_drag_begin (GTK_WIDGET (icon_bar), target_list, - GDK_ACTION_COPY | GDK_ACTION_MOVE, - 1, event); - gtk_target_list_unref (target_list); -} - - -static void -e_shortcut_bar_on_drag_data_get (GtkWidget *widget, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint time, - EShortcutBar *shortcut_bar) -{ - gchar *data; - - if (info == TARGET_SHORTCUT) { - data = g_strdup_printf ("%s%c%s", shortcut_bar->dragged_name, - '\0', shortcut_bar->dragged_url); - gtk_selection_data_set (selection_data, selection_data->target, - 8, data, - strlen (shortcut_bar->dragged_name) - + strlen (shortcut_bar->dragged_url) - + 2); - g_free (data); - } -} - - -static void -e_shortcut_bar_on_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *data, - guint info, - guint time, - EShortcutBar *shortcut_bar) -{ - EShortcutBarGroup *group; - gchar *item_name, *item_url; - EIconBar *icon_bar; - GdkImlibImage *image; - gint group_num, item_num; - - icon_bar = E_ICON_BAR (widget); - - if ((data->length >= 0) && (data->format == 8) - && icon_bar->dragging_before_item_num != -1) { - item_name = data->data; - item_url = item_name + strlen (item_name) + 1; - - image = e_shortcut_bar_get_image_from_url (shortcut_bar, - item_url); - - group_num = e_group_bar_get_group_num (E_GROUP_BAR (shortcut_bar), - GTK_WIDGET (icon_bar)->parent); - group = &g_array_index (shortcut_bar->groups, - EShortcutBarGroup, group_num); - - item_num = e_icon_bar_add_item (E_ICON_BAR (group->icon_bar), image, item_name, icon_bar->dragging_before_item_num); - e_icon_bar_set_item_data_full (E_ICON_BAR (group->icon_bar), - item_num, g_strdup (item_url), - g_free); - - gtk_drag_finish (context, TRUE, TRUE, time); - return; - } - - gtk_drag_finish (context, FALSE, FALSE, time); -} - - -static void -e_shortcut_bar_on_drag_data_delete (GtkWidget *widget, - GdkDragContext *context, - EShortcutBar *shortcut_bar) -{ - EIconBar *icon_bar; - - icon_bar = E_ICON_BAR (widget); - - e_icon_bar_remove_item (icon_bar, icon_bar->dragged_item_num); -} - - -void -e_shortcut_bar_start_editing_item (EShortcutBar *shortcut_bar, - gint group_num, - gint item_num) -{ - EShortcutBarGroup *group; - - g_return_if_fail (E_IS_SHORTCUT_BAR (shortcut_bar)); - g_return_if_fail (group_num >= 0); - g_return_if_fail (group_num < shortcut_bar->groups->len); - - group = &g_array_index (shortcut_bar->groups, - EShortcutBarGroup, group_num); - - e_icon_bar_start_editing_item (E_ICON_BAR (group->icon_bar), item_num); -} - - -/* We stop editing any item when a scroll button is pressed. */ -static void -e_shortcut_bar_stop_editing (GtkWidget *button, - EShortcutBar *shortcut_bar) -{ - EShortcutBarGroup *group; - gint group_num; - - for (group_num = 0; - group_num < shortcut_bar->groups->len; - group_num++) { - group = &g_array_index (shortcut_bar->groups, - EShortcutBarGroup, group_num); - e_icon_bar_stop_editing_item (E_ICON_BAR (group->icon_bar), - TRUE); - } -} - - -static GdkImlibImage* -e_shortcut_bar_get_image_from_url (EShortcutBar *shortcut_bar, - gchar *item_url) -{ - gchar *method_terminator; - gint method_len, i; - - method_terminator = strchr (item_url, ':'); - if (method_terminator) { - method_len = method_terminator - item_url + 1; - - /* Check if it is a builtin type. */ - for (i = 0; i < e_shortcut_bar_num_builtin_types; i++) { - if (!strncmp (item_url, e_shortcut_bar_builtin_types[i].name, method_len)) { - if (!e_shortcut_bar_builtin_types[i].image) - e_shortcut_bar_builtin_types[i].image = e_shortcut_bar_load_image (e_shortcut_bar_builtin_types[i].filename); - return e_shortcut_bar_builtin_types[i].image; - } - } - } - - if (!e_shortcut_bar_default_type_image_loaded) { - e_shortcut_bar_default_type_image_loaded = TRUE; - e_shortcut_bar_default_type_image = e_shortcut_bar_load_image (e_shortcut_bar_default_type_filename); - } - return e_shortcut_bar_default_type_image; -} - - -static GdkImlibImage* -e_shortcut_bar_load_image (gchar *filename) -{ - gchar *pathname; - GdkImlibImage *image = NULL; - - pathname = gnome_pixmap_file (filename); - if (pathname) - image = gdk_imlib_load_image (pathname); - else - g_warning ("Couldn't find pixmap: %s", filename); - - return image; -} diff --git a/widgets/shortcut-bar/e-shortcut-bar.h b/widgets/shortcut-bar/e-shortcut-bar.h deleted file mode 100644 index 1bbdfb6754..0000000000 --- a/widgets/shortcut-bar/e-shortcut-bar.h +++ /dev/null @@ -1,114 +0,0 @@ -/* -*- 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 - */ -#ifndef _E_SHORTCUT_BAR_H_ -#define _E_SHORTCUT_BAR_H_ - -#include "e-group-bar.h" -#include "e-icon-bar.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * EShortcutBar displays a vertical bar with a number of Groups, each of which - * contains any number of icons. It is used on the left of the main application - * window so users can easily access items such as folders and files. - */ - - -/* This contains information on one group. */ -typedef struct _EShortcutBarGroup EShortcutBarGroup; -struct _EShortcutBarGroup -{ - /* This is the EVScrolledBar which scrolls the group. */ - GtkWidget *vscrolled_bar; - - /* This is the icon bar containing the child items. */ - GtkWidget *icon_bar; -}; - - -#define E_SHORTCUT_BAR(obj) GTK_CHECK_CAST (obj, e_shortcut_bar_get_type (), EShortcutBar) -#define E_SHORTCUT_BAR_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_shortcut_bar_get_type (), EShortcutBarClass) -#define E_IS_SHORTCUT_BAR(obj) GTK_CHECK_TYPE (obj, e_shortcut_bar_get_type ()) - - -typedef struct _EShortcutBar EShortcutBar; -typedef struct _EShortcutBarClass EShortcutBarClass; - -struct _EShortcutBar -{ - EGroupBar group_bar; - - /* This is an array of EShortcutBarGroup elements. */ - GArray *groups; - - gchar *dragged_url; - gchar *dragged_name; -}; - -struct _EShortcutBarClass -{ - EGroupBarClass parent_class; - - void (*selected_item) (EShortcutBar *shortcut_bar, - GdkEvent *event, - gint group_num, - gint item_num); -}; - - -GtkType e_shortcut_bar_get_type (void); -GtkWidget* e_shortcut_bar_new (void); - -/* Adds a new group, returning the index. */ -gint e_shortcut_bar_add_group (EShortcutBar *shortcut_bar, - gchar *group_name); -void e_shortcut_bar_remove_group (EShortcutBar *shortcut_bar, - gint group_num); - -/* Sets the view type for the group. */ -void e_shortcut_bar_set_view_type (EShortcutBar *shortcut_bar, - gint group_num, - EIconBarViewType view_type); - -/* Adds a new item to a group, returning the index within the group. */ -gint e_shortcut_bar_add_item (EShortcutBar *shortcut_bar, - gint group_num, - gchar *item_url, - gchar *item_name); - -void e_shortcut_bar_start_editing_item (EShortcutBar *shortcut_bar, - gint group_num, - gint item_num); -void e_shortcut_bar_remove_item (EShortcutBar *shortcut_bar, - gint group_num, - gint item_num); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_SHORTCUT_BAR_H_ */ diff --git a/widgets/shortcut-bar/e-vscrolled-bar.c b/widgets/shortcut-bar/e-vscrolled-bar.c deleted file mode 100644 index 5d5f0ab2e2..0000000000 --- a/widgets/shortcut-bar/e-vscrolled-bar.c +++ /dev/null @@ -1,652 +0,0 @@ -/* -*- 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 - */ - -/* - * EVScrolledBar is like GtkScrolledWindow but only scrolls the child widget - * vertically. It is intended for scrolling narrow vertical bars. - */ - -#include <gtk/gtkarrow.h> -#include <gtk/gtkbutton.h> -#include <gtk/gtksignal.h> - -#include "e-vscrolled-bar.h" - -/* These are the offsets of the up & down buttons from the right and top/bottom - of the widget. */ -#define E_VSCROLLED_BAR_BUTTON_X_OFFSET 2 -#define E_VSCROLLED_BAR_BUTTON_Y_OFFSET 2 - -/* This is the time between scrolls. */ -#define E_VSCROLLED_BAR_SCROLL_TIMEOUT 20 - -static void e_vscrolled_bar_class_init (EVScrolledBarClass *class); -static void e_vscrolled_bar_init (EVScrolledBar *vscrolled_bar); -static void e_vscrolled_bar_destroy (GtkObject *object); -static void e_vscrolled_bar_finalize (GtkObject *object); -static void e_vscrolled_bar_map (GtkWidget *widget); -static void e_vscrolled_bar_unmap (GtkWidget *widget); -static void e_vscrolled_bar_size_request (GtkWidget *widget, - GtkRequisition *requisition); -static void e_vscrolled_bar_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static void e_vscrolled_bar_draw (GtkWidget *widget, - GdkRectangle *area); -static void e_vscrolled_bar_add (GtkContainer *container, - GtkWidget *child); -static void e_vscrolled_bar_remove (GtkContainer *container, - GtkWidget *child); -static void e_vscrolled_bar_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data); -static void e_vscrolled_bar_adjustment_changed (GtkAdjustment *adjustment, - gpointer data); -static void e_vscrolled_bar_button_pressed (GtkWidget *button, - EVScrolledBar *vscrolled_bar); -static void e_vscrolled_bar_button_released (GtkWidget *button, - EVScrolledBar *vscrolled_bar); -static void e_vscrolled_bar_button_clicked (GtkWidget *button, - EVScrolledBar *vscrolled_bar); -static gboolean e_vscrolled_bar_timeout_handler (gpointer data); - - -static GtkBinClass *parent_class; - - -GtkType -e_vscrolled_bar_get_type (void) -{ - static GtkType e_vscrolled_bar_type = 0; - - if (!e_vscrolled_bar_type) { - GtkTypeInfo e_vscrolled_bar_info = { - "EVScrolledBar", - sizeof (EVScrolledBar), - sizeof (EVScrolledBarClass), - (GtkClassInitFunc) e_vscrolled_bar_class_init, - (GtkObjectInitFunc) e_vscrolled_bar_init, - NULL, /* reserved 1 */ - NULL, /* reserved 2 */ - (GtkClassInitFunc) NULL - }; - - parent_class = gtk_type_class (GTK_TYPE_BIN); - e_vscrolled_bar_type = gtk_type_unique (GTK_TYPE_BIN, - &e_vscrolled_bar_info); - } - - return e_vscrolled_bar_type; -} - - -static void -e_vscrolled_bar_class_init (EVScrolledBarClass *class) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - GtkContainerClass *container_class; - - object_class = (GtkObjectClass *) class; - widget_class = (GtkWidgetClass *) class; - container_class = (GtkContainerClass *) class; - - /* Method override */ - object_class->destroy = e_vscrolled_bar_destroy; - object_class->finalize = e_vscrolled_bar_finalize; - - widget_class->map = e_vscrolled_bar_map; - widget_class->unmap = e_vscrolled_bar_unmap; - widget_class->size_request = e_vscrolled_bar_size_request; - widget_class->size_allocate = e_vscrolled_bar_size_allocate; - widget_class->draw = e_vscrolled_bar_draw; - - container_class->add = e_vscrolled_bar_add; - container_class->remove = e_vscrolled_bar_remove; - container_class->forall = e_vscrolled_bar_forall; -} - - -static void -e_vscrolled_bar_init (EVScrolledBar *vscrolled_bar) -{ - GtkWidget *arrow; - - GTK_WIDGET_SET_FLAGS (vscrolled_bar, GTK_NO_WINDOW); - - gtk_container_set_resize_mode (GTK_CONTAINER (vscrolled_bar), - GTK_RESIZE_QUEUE); - - gtk_widget_push_composite_child (); - - vscrolled_bar->up_button = gtk_button_new (); - gtk_widget_set_composite_name (vscrolled_bar->up_button, - "up_button"); - gtk_widget_set_parent (vscrolled_bar->up_button, - GTK_WIDGET (vscrolled_bar)); - arrow = gtk_arrow_new (GTK_ARROW_UP, GTK_SHADOW_OUT); - gtk_misc_set_padding (GTK_MISC (arrow), 1, 1); - gtk_widget_show (arrow); - gtk_container_add (GTK_CONTAINER (vscrolled_bar->up_button), arrow); - gtk_signal_connect_after (GTK_OBJECT (vscrolled_bar->up_button), "pressed", GTK_SIGNAL_FUNC (e_vscrolled_bar_button_pressed), vscrolled_bar); - gtk_signal_connect_after (GTK_OBJECT (vscrolled_bar->up_button), "released", GTK_SIGNAL_FUNC (e_vscrolled_bar_button_released), vscrolled_bar); - gtk_signal_connect (GTK_OBJECT (vscrolled_bar->up_button), "clicked", GTK_SIGNAL_FUNC (e_vscrolled_bar_button_clicked), vscrolled_bar); - - vscrolled_bar->down_button = gtk_button_new (); - gtk_widget_set_composite_name (vscrolled_bar->up_button, - "down_button"); - gtk_widget_set_parent (vscrolled_bar->down_button, - GTK_WIDGET (vscrolled_bar)); - arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT); - gtk_misc_set_padding (GTK_MISC (arrow), 1, 1); - gtk_widget_show (arrow); - gtk_container_add (GTK_CONTAINER (vscrolled_bar->down_button), arrow); - gtk_signal_connect_after (GTK_OBJECT (vscrolled_bar->down_button), "pressed", GTK_SIGNAL_FUNC (e_vscrolled_bar_button_pressed), vscrolled_bar); - gtk_signal_connect_after (GTK_OBJECT (vscrolled_bar->down_button), "released", GTK_SIGNAL_FUNC (e_vscrolled_bar_button_released), vscrolled_bar); - gtk_signal_connect (GTK_OBJECT (vscrolled_bar->down_button), "clicked", GTK_SIGNAL_FUNC (e_vscrolled_bar_button_clicked), vscrolled_bar); - - gtk_widget_pop_composite_child (); - - vscrolled_bar->adjustment = NULL; - vscrolled_bar->timeout_id = 0; - vscrolled_bar->scrolling_up = FALSE; - vscrolled_bar->min_distance = -1.0; - vscrolled_bar->button_pressed = FALSE; -} - - -/** - * e_vscrolled_bar_new: - * - * @adjustment: The #GtkAdjustment to use for scrolling, or NULL. - * @Return: A new #EVScrolledBar. - * - * Creates a new #EVScrolledBar with the given adjustment. - **/ -GtkWidget * -e_vscrolled_bar_new (GtkAdjustment *adjustment) -{ - GtkWidget *vscrolled_bar; - - vscrolled_bar = GTK_WIDGET (gtk_type_new (e_vscrolled_bar_get_type ())); - e_vscrolled_bar_set_adjustment (E_VSCROLLED_BAR (vscrolled_bar), - adjustment); - - return vscrolled_bar; -} - - -static void -e_vscrolled_bar_destroy (GtkObject *object) -{ - EVScrolledBar *vscrolled_bar; - - vscrolled_bar = E_VSCROLLED_BAR (object); - - if (vscrolled_bar->timeout_id) { - g_source_remove (vscrolled_bar->timeout_id); - vscrolled_bar->timeout_id = 0; - } - - gtk_widget_unparent (vscrolled_bar->up_button); - gtk_widget_unparent (vscrolled_bar->down_button); - - GTK_OBJECT_CLASS (parent_class)->destroy (object); -} - - -static void -e_vscrolled_bar_finalize (GtkObject *object) -{ - EVScrolledBar *vscrolled_bar; - - vscrolled_bar = E_VSCROLLED_BAR (object); - - gtk_object_unref (GTK_OBJECT (vscrolled_bar->adjustment)); - - GTK_OBJECT_CLASS (parent_class)->finalize (object); -} - - -static void -e_vscrolled_bar_map (GtkWidget *widget) -{ - EVScrolledBar *vscrolled_bar; - - g_return_if_fail (widget != NULL); - g_return_if_fail (E_IS_VSCROLLED_BAR (widget)); - - vscrolled_bar = E_VSCROLLED_BAR (widget); - - /* chain parent class handler to map self and child */ - GTK_WIDGET_CLASS (parent_class)->map (widget); - - if (GTK_WIDGET_VISIBLE (vscrolled_bar->up_button) && - !GTK_WIDGET_MAPPED (vscrolled_bar->up_button)) - gtk_widget_map (vscrolled_bar->up_button); - - if (GTK_WIDGET_VISIBLE (vscrolled_bar->down_button) && - !GTK_WIDGET_MAPPED (vscrolled_bar->down_button)) - gtk_widget_map (vscrolled_bar->down_button); -} - - -static void -e_vscrolled_bar_unmap (GtkWidget *widget) -{ - EVScrolledBar *vscrolled_bar; - - g_return_if_fail (widget != NULL); - g_return_if_fail (E_IS_VSCROLLED_BAR (widget)); - - vscrolled_bar = E_VSCROLLED_BAR (widget); - - /* chain parent class handler to unmap self and child */ - GTK_WIDGET_CLASS (parent_class)->unmap (widget); - - if (GTK_WIDGET_MAPPED (vscrolled_bar->up_button)) - gtk_widget_unmap (vscrolled_bar->up_button); - - if (GTK_WIDGET_MAPPED (vscrolled_bar->down_button)) - gtk_widget_unmap (vscrolled_bar->down_button); -} - - -static void -e_vscrolled_bar_size_request (GtkWidget *widget, - GtkRequisition *requisition) -{ - EVScrolledBar *vscrolled_bar; - GtkBin *bin; - GtkRequisition child_requisition; - - g_return_if_fail (widget != NULL); - g_return_if_fail (E_IS_VSCROLLED_BAR (widget)); - g_return_if_fail (requisition != NULL); - - vscrolled_bar = E_VSCROLLED_BAR (widget); - bin = GTK_BIN (widget); - - requisition->width = 0; - requisition->height = 0; - - /* We just return the requisition of the child widget, plus the - border width. */ - if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) { - gtk_widget_size_request (bin->child, &child_requisition); - *requisition = child_requisition; - } - - /* We remember the requested heights of the up & down buttons. */ - gtk_widget_size_request (vscrolled_bar->up_button, - &child_requisition); - vscrolled_bar->up_button_width = child_requisition.width; - vscrolled_bar->up_button_height = child_requisition.height; - - gtk_widget_size_request (vscrolled_bar->down_button, - &child_requisition); - vscrolled_bar->down_button_width = child_requisition.width; - vscrolled_bar->down_button_height = child_requisition.height; - - /* Add on the standard container border widths. */ - requisition->width += GTK_CONTAINER (widget)->border_width * 2; - requisition->height += GTK_CONTAINER (widget)->border_width * 2; -} - - -static void -e_vscrolled_bar_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) -{ - EVScrolledBar *vscrolled_bar; - GtkBin *bin; - GtkAllocation button_allocation, child_allocation; - gint border_width; - - g_return_if_fail (widget != NULL); - g_return_if_fail (E_IS_VSCROLLED_BAR (widget)); - g_return_if_fail (allocation != NULL); - - vscrolled_bar = E_VSCROLLED_BAR (widget); - bin = GTK_BIN (widget); - - widget->allocation = *allocation; - - border_width = GTK_CONTAINER (widget)->border_width; - - child_allocation.x = border_width; - child_allocation.y = border_width; - child_allocation.width = allocation->width - 2 * border_width; - child_allocation.height = allocation->height - 2 * border_width; - gtk_widget_size_allocate (bin->child, &child_allocation); - - button_allocation.x = allocation->width - border_width - - vscrolled_bar->up_button_width - - E_VSCROLLED_BAR_BUTTON_X_OFFSET; - button_allocation.y = border_width + E_VSCROLLED_BAR_BUTTON_Y_OFFSET; - button_allocation.width = vscrolled_bar->up_button_width; - button_allocation.height = vscrolled_bar->up_button_height; - gtk_widget_size_allocate (vscrolled_bar->up_button, - &button_allocation); - - button_allocation.x = allocation->width - border_width - - vscrolled_bar->down_button_width - - E_VSCROLLED_BAR_BUTTON_X_OFFSET; - button_allocation.y = allocation->height - border_width - - vscrolled_bar->down_button_height - - E_VSCROLLED_BAR_BUTTON_Y_OFFSET; - button_allocation.width = vscrolled_bar->down_button_width; - button_allocation.height = vscrolled_bar->down_button_height; - gtk_widget_size_allocate (vscrolled_bar->down_button, - &button_allocation); -} - - -static void -e_vscrolled_bar_draw (GtkWidget *widget, - GdkRectangle *area) -{ - EVScrolledBar *vscrolled_bar; - GtkBin *bin; - GdkRectangle child_area; - - g_return_if_fail (widget != NULL); - g_return_if_fail (E_IS_VSCROLLED_BAR (widget)); - g_return_if_fail (area != NULL); - - vscrolled_bar = E_VSCROLLED_BAR (widget); - bin = GTK_BIN (widget); - - if (bin->child && GTK_WIDGET_VISIBLE (bin->child) && - gtk_widget_intersect (bin->child, area, &child_area)) - gtk_widget_draw (bin->child, &child_area); - - if (GTK_WIDGET_VISIBLE (vscrolled_bar->up_button) && - gtk_widget_intersect (vscrolled_bar->up_button, area, &child_area)) - gtk_widget_draw (vscrolled_bar->up_button, &child_area); - - if (GTK_WIDGET_VISIBLE (vscrolled_bar->down_button) && - gtk_widget_intersect (vscrolled_bar->down_button, area, &child_area)) - gtk_widget_draw (vscrolled_bar->down_button, &child_area); -} - - -static void -e_vscrolled_bar_add (GtkContainer *container, - GtkWidget *child) -{ - EVScrolledBar *vscrolled_bar; - GtkBin *bin; - - g_return_if_fail (container != NULL); - g_return_if_fail (E_IS_VSCROLLED_BAR (container)); - - vscrolled_bar = E_VSCROLLED_BAR (container); - bin = GTK_BIN (container); - - g_return_if_fail (bin->child == NULL); - - bin->child = child; - gtk_widget_set_parent (child, GTK_WIDGET (bin)); - - gtk_widget_set_scroll_adjustments (child, NULL, - vscrolled_bar->adjustment); - - if (GTK_WIDGET_REALIZED (child->parent)) - gtk_widget_realize (child); - - if (GTK_WIDGET_VISIBLE (child->parent) && GTK_WIDGET_VISIBLE (child)) { - if (GTK_WIDGET_MAPPED (child->parent)) - gtk_widget_map (child); - - gtk_widget_queue_resize (child); - } -} - - -static void -e_vscrolled_bar_remove (GtkContainer *container, - GtkWidget *child) -{ - g_return_if_fail (container != NULL); - g_return_if_fail (E_IS_VSCROLLED_BAR (container)); - g_return_if_fail (child != NULL); - g_return_if_fail (GTK_BIN (container)->child == child); - - gtk_widget_set_scroll_adjustments (child, NULL, NULL); - - /* chain parent class handler to remove child */ - GTK_CONTAINER_CLASS (parent_class)->remove (container, child); -} - - -static void -e_vscrolled_bar_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data) -{ - g_return_if_fail (container != NULL); - g_return_if_fail (E_IS_VSCROLLED_BAR (container)); - g_return_if_fail (callback != NULL); - - GTK_CONTAINER_CLASS (parent_class)->forall (container, - include_internals, - callback, - callback_data); - if (include_internals) { - EVScrolledBar *vscrolled_bar; - - vscrolled_bar = E_VSCROLLED_BAR (container); - - if (vscrolled_bar->up_button) - callback (vscrolled_bar->up_button, callback_data); - if (vscrolled_bar->down_button) - callback (vscrolled_bar->down_button, callback_data); - } -} - - -/** - * e_vscrolled_bar_get_adjustment: - * - * @vscrolled_bar: An #EVScrolledBar. - * @Return: The #GtkAdjustment used for scrolling @vscrolled_bar. - * - * Returns the #GtkAdjustment used for scrolling the #EVscrolledBar. - **/ -GtkAdjustment* -e_vscrolled_bar_get_adjustment (EVScrolledBar *vscrolled_bar) -{ - g_return_val_if_fail (vscrolled_bar != NULL, NULL); - g_return_val_if_fail (E_IS_VSCROLLED_BAR (vscrolled_bar), NULL); - - return vscrolled_bar->adjustment; -} - - -/** - * e_vscrolled_bar_set_adjustment: - * - * @vscrolled_bar: An #EVScrolledBar. - * @adjustment: The #GtkAdjustment to use for scrolling @vscrolled_bar. - * - * Sets the #GtkAdjustment to use for scrolling the #EVscrolledBar. - **/ -void -e_vscrolled_bar_set_adjustment (EVScrolledBar *vscrolled_bar, - GtkAdjustment *adjustment) -{ - g_return_if_fail (vscrolled_bar != NULL); - g_return_if_fail (E_IS_VSCROLLED_BAR (vscrolled_bar)); - - if (adjustment) - g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); - else - adjustment = (GtkAdjustment*) gtk_object_new (GTK_TYPE_ADJUSTMENT, NULL); - - if (vscrolled_bar->adjustment == adjustment) - return; - - if (vscrolled_bar->adjustment) { - gtk_signal_disconnect_by_func (GTK_OBJECT (vscrolled_bar->adjustment), - GTK_SIGNAL_FUNC (e_vscrolled_bar_adjustment_changed), - vscrolled_bar); - gtk_object_unref (GTK_OBJECT (vscrolled_bar->adjustment)); - } - - vscrolled_bar->adjustment = adjustment; - gtk_object_ref (GTK_OBJECT (vscrolled_bar->adjustment)); - gtk_object_sink (GTK_OBJECT (vscrolled_bar->adjustment)); - - /* I've used connect_after here to avoid a problem when using a - GnomeCanvas as the child widget. When just using connect it would - leave a blank space when one of the buttons is hidden. We want - the GtkLayout to handle the scrolling before we hide any buttons. */ - gtk_signal_connect_after (GTK_OBJECT (adjustment), "changed", - GTK_SIGNAL_FUNC (e_vscrolled_bar_adjustment_changed), - vscrolled_bar); - gtk_signal_connect_after (GTK_OBJECT (adjustment), "value_changed", - GTK_SIGNAL_FUNC (e_vscrolled_bar_adjustment_changed), - vscrolled_bar); - - e_vscrolled_bar_adjustment_changed (adjustment, vscrolled_bar); - - if (GTK_BIN (vscrolled_bar)->child) - gtk_widget_set_scroll_adjustments (GTK_BIN (vscrolled_bar)->child, NULL, adjustment); -} - - -static void -e_vscrolled_bar_adjustment_changed (GtkAdjustment *adjustment, - gpointer data) -{ - EVScrolledBar *vscrolled_bar; - - g_return_if_fail (adjustment != NULL); - g_return_if_fail (data != NULL); - - vscrolled_bar = E_VSCROLLED_BAR (data); - - /* If the adjustment value is not 0, show the up button. */ - if (adjustment->value != 0) - gtk_widget_show (vscrolled_bar->up_button); - else - gtk_widget_hide (vscrolled_bar->up_button); - - /* If the adjustment value is less than the maximum value, show the - down button. */ - if (adjustment->value < adjustment->upper - adjustment->page_size) - gtk_widget_show (vscrolled_bar->down_button); - else - gtk_widget_hide (vscrolled_bar->down_button); -} - - -static void -e_vscrolled_bar_button_pressed (GtkWidget *button, - EVScrolledBar *vscrolled_bar) -{ - if (vscrolled_bar->timeout_id != 0) - g_source_remove (vscrolled_bar->timeout_id); - - vscrolled_bar->timeout_id = g_timeout_add (E_VSCROLLED_BAR_SCROLL_TIMEOUT, e_vscrolled_bar_timeout_handler, vscrolled_bar); - vscrolled_bar->scrolling_up = (button == vscrolled_bar->up_button) ? TRUE : FALSE; - vscrolled_bar->min_distance = vscrolled_bar->adjustment->page_size / 4; - vscrolled_bar->button_pressed = TRUE; - - e_vscrolled_bar_timeout_handler (vscrolled_bar); -} - - -static void -e_vscrolled_bar_button_released (GtkWidget *button, - EVScrolledBar *vscrolled_bar) -{ - vscrolled_bar->button_pressed = FALSE; -} - - -/* This will be called when the user hits the space key to activate the button. - It will also be called just before button_released() is called, but since - we already handle that we simply return if the button is pressed. */ -static void -e_vscrolled_bar_button_clicked (GtkWidget *button, - EVScrolledBar *vscrolled_bar) -{ - if (vscrolled_bar->button_pressed) - return; - - /* We act as if the button is pressed and released immediately. */ - e_vscrolled_bar_button_pressed (button, vscrolled_bar); - vscrolled_bar->button_pressed = FALSE; -} - - -static gboolean -e_vscrolled_bar_timeout_handler (gpointer data) -{ - EVScrolledBar *vscrolled_bar; - GtkAdjustment *adjustment; - gfloat new_value; - gboolean retval = TRUE; - - vscrolled_bar = E_VSCROLLED_BAR (data); - adjustment = vscrolled_bar->adjustment; - - GDK_THREADS_ENTER (); - - /* Check if the user has released the button and we have already - scrolled the minimum distance. */ - if (vscrolled_bar->button_pressed == FALSE - && vscrolled_bar->min_distance <= 0) { - GDK_THREADS_LEAVE (); - return FALSE; - } - - vscrolled_bar->min_distance -= adjustment->step_increment; - - if (vscrolled_bar->scrolling_up) { - new_value = adjustment->value - adjustment->step_increment; - if (new_value <= adjustment->lower) { - new_value = adjustment->lower; - retval = FALSE; - } - } else { - new_value = adjustment->value + adjustment->step_increment; - if (new_value >= adjustment->upper - adjustment->page_size) { - new_value = adjustment->upper - adjustment->page_size; - retval = FALSE; - } - } - - if (adjustment->value != new_value) { - adjustment->value = new_value; - gtk_signal_emit_by_name (GTK_OBJECT (adjustment), - "value_changed"); - } - - GDK_THREADS_LEAVE (); - return retval; -} diff --git a/widgets/shortcut-bar/e-vscrolled-bar.h b/widgets/shortcut-bar/e-vscrolled-bar.h deleted file mode 100644 index d3273e6685..0000000000 --- a/widgets/shortcut-bar/e-vscrolled-bar.h +++ /dev/null @@ -1,97 +0,0 @@ -/* -*- 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 - */ -#ifndef _E_VSCROLLED_BAR_H_ -#define _E_VSCROLLED_BAR_H_ - -#include <gtk/gtkbin.h> -#include <gtk/gtkadjustment.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * EVScrolledBar is like GtkScrolledWindow but only scrolls the child widget - * vertically. It is intended for scrolling narrow vertical bars. - */ - - -#define E_VSCROLLED_BAR(obj) GTK_CHECK_CAST (obj, e_vscrolled_bar_get_type (), EVScrolledBar) -#define E_VSCROLLED_BAR_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_vscrolled_bar_get_type (), EVScrolledBarClass) -#define E_IS_VSCROLLED_BAR(obj) GTK_CHECK_TYPE (obj, e_vscrolled_bar_get_type ()) - - -typedef struct _EVScrolledBar EVScrolledBar; -typedef struct _EVScrolledBarClass EVScrolledBarClass; - -struct _EVScrolledBar -{ - GtkBin bin; - - GtkWidget *up_button; - GtkWidget *down_button; - - GtkAdjustment *adjustment; - - gint up_button_width; - gint up_button_height; - gint down_button_width; - gint down_button_height; - - /* The GTK+ event source ID of our timeout handler. */ - gint timeout_id; - - /* TRUE if we are scrolling up, FALSE if scrolling down. */ - gboolean scrolling_up; - - /* The minimum distance left to scroll. If the user just clicks a - button we scroll a minimum amount. This is reduced after each - scroll. */ - gfloat min_distance; - - /* TRUE if the button is still pressed. When the up/down button is - released, this gets set to FALSE, and we scroll until the minimum - distance falls below 0. */ - gboolean button_pressed; -}; - -struct _EVScrolledBarClass -{ - GtkBinClass parent_class; -}; - - -GtkType e_vscrolled_bar_get_type (void); -GtkWidget* e_vscrolled_bar_new (GtkAdjustment *adjustment); - -GtkAdjustment* e_vscrolled_bar_get_adjustment (EVScrolledBar *vscrolled_bar); -void e_vscrolled_bar_set_adjustment (EVScrolledBar *vscrolled_bar, - GtkAdjustment *adjustment); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_VSCROLLED_BAR_H_ */ diff --git a/widgets/shortcut-bar/test-shortcut-bar.c b/widgets/shortcut-bar/test-shortcut-bar.c deleted file mode 100644 index 186bf3ed8a..0000000000 --- a/widgets/shortcut-bar/test-shortcut-bar.c +++ /dev/null @@ -1,445 +0,0 @@ -/* -*- 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 - */ - -/* - * This tests the ShortcutBar widget. - */ - -#include <gnome.h> - -#include "e-shortcut-bar.h" - -#define NUM_SHORTCUT_TYPES 5 -gchar *shortcut_types[] = { - "folder:", "file:", "calendar:", "todo:", "contacts:" -}; - -GtkWidget *main_label; - -static void quit (GtkWidget *window, GdkEvent *event, gpointer data); -static void add_test_groups (EShortcutBar *shortcut_bar); -static void add_test_group (EShortcutBar *shortcut_bar, gint i, - gchar *group_name); -static gint get_random_int (gint max); - -static void on_shortcut_bar_item_selected (EShortcutBar *shortcut_bar, - GdkEvent *event, - gint group_num, - gint item_num); -static void show_standard_popup (EShortcutBar *shortcut_bar, - GdkEvent *event, - gint group_num); -static void show_context_popup (EShortcutBar *shortcut_bar, - GdkEvent *event, - gint group_num, - gint item_num); - -static void set_large_icons (GtkWidget *menuitem, - EShortcutBar *shortcut_bar); -static void set_small_icons (GtkWidget *menuitem, - EShortcutBar *shortcut_bar); -static void remove_group (GtkWidget *menuitem, - EShortcutBar *shortcut_bar); - -static void rename_item (GtkWidget *menuitem, - EShortcutBar *shortcut_bar); -static void remove_item (GtkWidget *menuitem, - EShortcutBar *shortcut_bar); - -int -main (int argc, char *argv[]) -{ - GtkWidget *window, *hpaned, *shortcut_bar; - - gnome_init ("test-shortcut-bar", "0.1", argc, argv); - - gtk_widget_push_visual (gdk_imlib_get_visual ()); - gtk_widget_push_colormap (gdk_imlib_get_colormap ()); - - window = gnome_app_new ("TestShortcutBar", "TestShortCutBar"); - gtk_window_set_default_size (GTK_WINDOW (window), 600, 400); - gtk_window_set_policy (GTK_WINDOW (window), FALSE, TRUE, FALSE); - - gtk_signal_connect (GTK_OBJECT (window), "delete-event", - GTK_SIGNAL_FUNC (quit), NULL); - - hpaned = gtk_hpaned_new (); - gnome_app_set_contents (GNOME_APP (window), hpaned); - gtk_widget_show (hpaned); - - shortcut_bar = e_shortcut_bar_new (); - gtk_paned_pack1 (GTK_PANED (hpaned), shortcut_bar, FALSE, TRUE); - gtk_widget_show (shortcut_bar); - -#if 0 - gtk_container_set_border_width (GTK_CONTAINER (shortcut_bar), 4); -#endif - - gtk_paned_set_position (GTK_PANED (hpaned), 100); - /*gtk_paned_set_gutter_size (GTK_PANED (hpaned), 12);*/ - - main_label = gtk_label_new ("Main Application Window Goes Here"); - gtk_paned_pack2 (GTK_PANED (hpaned), main_label, TRUE, TRUE); - gtk_widget_show (main_label); - - - gtk_widget_pop_visual (); - gtk_widget_pop_colormap (); - - add_test_groups (E_SHORTCUT_BAR (shortcut_bar)); - - gtk_signal_connect (GTK_OBJECT (shortcut_bar), "item_selected", - GTK_SIGNAL_FUNC (on_shortcut_bar_item_selected), - NULL); - - gtk_widget_show (window); - gtk_main (); - return 0; -} - - -static void -quit (GtkWidget *window, GdkEvent *event, gpointer data) -{ - gtk_widget_destroy (window); - gtk_exit (0); -} - - -static void -add_test_groups (EShortcutBar *shortcut_bar) -{ - add_test_group (shortcut_bar, 1, "Shortcuts"); - add_test_group (shortcut_bar, 2, "My Shortcuts"); - add_test_group (shortcut_bar, 3, "Longer Shortcuts"); - add_test_group (shortcut_bar, 4, "Very Long Shortcuts"); - add_test_group (shortcut_bar, 5, "Incredibly Long Shortcuts"); -} - - -static void -add_test_group (EShortcutBar *shortcut_bar, gint i, gchar *group_name) -{ - gint group_num, item_num, num_items; - gchar buffer[128]; - gint shortcut_type, j; - - group_num = e_shortcut_bar_add_group (E_SHORTCUT_BAR (shortcut_bar), - group_name); - - if (group_num % 2) - e_shortcut_bar_set_view_type (E_SHORTCUT_BAR (shortcut_bar), - group_num, - E_ICON_BAR_SMALL_ICONS); - - num_items = get_random_int (5) + 3; - for (j = 1; j <= num_items; j++) { - if (j == 1) - sprintf (buffer, "A very long shortcut with proper words so I can test the wrapping and ellipsis behaviour"); - else if (j == 2) - sprintf (buffer, "A very long shortcut with averylongworkinthemiddlesoIcantestthewrappingandellipsisbehaviour"); - else - sprintf (buffer, "Item %i:%i\n", i, j); - - shortcut_type = get_random_int (NUM_SHORTCUT_TYPES); - item_num = e_shortcut_bar_add_item (E_SHORTCUT_BAR (shortcut_bar), group_num, shortcut_types[shortcut_type], buffer); - } -} - - -/* Returns a random integer between 0 and max - 1. */ -static gint -get_random_int (gint max) -{ - gint random_num; - - random_num = (int) (max * (rand () / (RAND_MAX + 1.0))); -#if 0 - g_print ("Random num (%i): %i\n", max, random_num); -#endif - return random_num; -} - - -static void -on_shortcut_bar_item_selected (EShortcutBar *shortcut_bar, - GdkEvent *event, gint group_num, gint item_num) -{ - gchar buffer[256]; - - if (event->button.button == 1) { - sprintf (buffer, "Item Selected - %i:%i", - group_num + 1, item_num + 1); - gtk_label_set_text (GTK_LABEL (main_label), buffer); - } else if (event->button.button == 3) { - if (item_num == -1) - show_standard_popup (shortcut_bar, event, group_num); - else - show_context_popup (shortcut_bar, event, group_num, - item_num); - } -} - - -static void -show_standard_popup (EShortcutBar *shortcut_bar, - GdkEvent *event, - gint group_num) -{ - GtkWidget *menu, *menuitem; - - /* We don't have any commands if there aren't any groups yet. */ - if (group_num == -1) - return; - - menu = gtk_menu_new (); - - menuitem = gtk_menu_item_new_with_label ("Large Icons"); - gtk_widget_show (menuitem); - gtk_menu_append (GTK_MENU (menu), menuitem); - gtk_signal_connect (GTK_OBJECT (menuitem), "activate", - GTK_SIGNAL_FUNC (set_large_icons), shortcut_bar); - - menuitem = gtk_menu_item_new_with_label ("Small Icons"); - gtk_widget_show (menuitem); - gtk_menu_append (GTK_MENU (menu), menuitem); - gtk_signal_connect (GTK_OBJECT (menuitem), "activate", - GTK_SIGNAL_FUNC (set_small_icons), shortcut_bar); - - menuitem = gtk_menu_item_new (); - gtk_widget_set_sensitive (menuitem, FALSE); - gtk_widget_show (menuitem); - gtk_menu_append (GTK_MENU (menu), menuitem); - - menuitem = gtk_menu_item_new_with_label ("Add New Group"); - gtk_widget_set_sensitive (menuitem, FALSE); - gtk_widget_show (menuitem); - gtk_menu_append (GTK_MENU (menu), menuitem); - - menuitem = gtk_menu_item_new_with_label ("Remove Group"); - gtk_widget_show (menuitem); - gtk_menu_append (GTK_MENU (menu), menuitem); - gtk_signal_connect (GTK_OBJECT (menuitem), "activate", - GTK_SIGNAL_FUNC (remove_group), shortcut_bar); - - menuitem = gtk_menu_item_new_with_label ("Rename Group"); - gtk_widget_set_sensitive (menuitem, FALSE); - gtk_widget_show (menuitem); - gtk_menu_append (GTK_MENU (menu), menuitem); - - menuitem = gtk_menu_item_new (); - gtk_widget_set_sensitive (menuitem, FALSE); - gtk_widget_show (menuitem); - gtk_menu_append (GTK_MENU (menu), menuitem); - - menuitem = gtk_menu_item_new_with_label ("Add Shortcut..."); - gtk_widget_set_sensitive (menuitem, FALSE); - gtk_widget_show (menuitem); - gtk_menu_append (GTK_MENU (menu), menuitem); - - menuitem = gtk_menu_item_new (); - gtk_widget_set_sensitive (menuitem, FALSE); - gtk_widget_show (menuitem); - gtk_menu_append (GTK_MENU (menu), menuitem); - - menuitem = gtk_menu_item_new_with_label ("Hide Shortcut Bar"); - gtk_widget_set_sensitive (menuitem, FALSE); - gtk_widget_show (menuitem); - gtk_menu_append (GTK_MENU (menu), menuitem); - - /* Save the group num so we can get it in the callbacks. */ - gtk_object_set_data (GTK_OBJECT (menu), "group_num", - GINT_TO_POINTER (group_num)); - - /* FIXME: Destroy menu when finished with it somehow? */ - gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, - event->button.button, event->button.time); -} - - -static void -set_large_icons (GtkWidget *menuitem, - EShortcutBar *shortcut_bar) -{ - GtkWidget *menu; - gint group_num; - - menu = menuitem->parent; - g_return_if_fail (GTK_IS_MENU (menu)); - - group_num = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (menu), - "group_num")); - - e_shortcut_bar_set_view_type (shortcut_bar, group_num, - E_ICON_BAR_LARGE_ICONS); -} - - -static void -set_small_icons (GtkWidget *menuitem, - EShortcutBar *shortcut_bar) -{ - GtkWidget *menu; - gint group_num; - - menu = menuitem->parent; - g_return_if_fail (GTK_IS_MENU (menu)); - - group_num = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (menu), - "group_num")); - - e_shortcut_bar_set_view_type (shortcut_bar, group_num, - E_ICON_BAR_SMALL_ICONS); -} - - -static void -remove_group (GtkWidget *menuitem, - EShortcutBar *shortcut_bar) -{ - GtkWidget *menu; - gint group_num; - - menu = menuitem->parent; - g_return_if_fail (GTK_IS_MENU (menu)); - - group_num = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (menu), - "group_num")); - - e_shortcut_bar_remove_group (shortcut_bar, group_num); -} - - -static void -show_context_popup (EShortcutBar *shortcut_bar, - GdkEvent *event, - gint group_num, - gint item_num) -{ - GtkWidget *menu, *menuitem, *label, *pixmap; - - menu = gtk_menu_new (); - - menuitem = gtk_pixmap_menu_item_new (); - label = gtk_label_new ("Open Folder"); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_widget_show (label); - gtk_container_add (GTK_CONTAINER (menuitem), label); - gtk_widget_set_sensitive (menuitem, FALSE); - gtk_widget_show (menuitem); - gtk_menu_append (GTK_MENU (menu), menuitem); - pixmap = gnome_stock_pixmap_widget (menu, GNOME_STOCK_MENU_OPEN); - if (pixmap) { - gtk_widget_show(pixmap); - gtk_pixmap_menu_item_set_pixmap (GTK_PIXMAP_MENU_ITEM (menuitem), pixmap); - } - - menuitem = gtk_menu_item_new_with_label ("Open in New Window"); - gtk_widget_set_sensitive (menuitem, FALSE); - gtk_widget_show (menuitem); - gtk_menu_append (GTK_MENU (menu), menuitem); - - menuitem = gtk_menu_item_new_with_label ("Advanced Find"); - gtk_widget_set_sensitive (menuitem, FALSE); - gtk_widget_show (menuitem); - gtk_menu_append (GTK_MENU (menu), menuitem); - - menuitem = gtk_menu_item_new (); - gtk_widget_set_sensitive (menuitem, FALSE); - gtk_widget_show (menuitem); - gtk_menu_append (GTK_MENU (menu), menuitem); - - menuitem = gtk_menu_item_new_with_label ("Remove from Shortcut Bar"); - gtk_widget_show (menuitem); - gtk_menu_append (GTK_MENU (menu), menuitem); - gtk_signal_connect (GTK_OBJECT (menuitem), "activate", - GTK_SIGNAL_FUNC (remove_item), shortcut_bar); - - menuitem = gtk_menu_item_new_with_label ("Rename Shortcut"); - gtk_widget_show (menuitem); - gtk_menu_append (GTK_MENU (menu), menuitem); - gtk_signal_connect (GTK_OBJECT (menuitem), "activate", - GTK_SIGNAL_FUNC (rename_item), shortcut_bar); - - menuitem = gtk_menu_item_new (); - gtk_widget_set_sensitive (menuitem, FALSE); - gtk_widget_show (menuitem); - gtk_menu_append (GTK_MENU (menu), menuitem); - - menuitem = gtk_menu_item_new_with_label ("Properties"); - gtk_widget_set_sensitive (menuitem, FALSE); - gtk_widget_show (menuitem); - gtk_menu_append (GTK_MENU (menu), menuitem); - - - /* Save the group & item nums so we can get them in the callbacks. */ - gtk_object_set_data (GTK_OBJECT (menu), "group_num", - GINT_TO_POINTER (group_num)); - gtk_object_set_data (GTK_OBJECT (menu), "item_num", - GINT_TO_POINTER (item_num)); - - /* FIXME: Destroy menu when finished with it somehow? */ - gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, - event->button.button, event->button.time); -} - - -static void -rename_item (GtkWidget *menuitem, - EShortcutBar *shortcut_bar) -{ - GtkWidget *menu; - gint group_num, item_num; - - menu = menuitem->parent; - g_return_if_fail (GTK_IS_MENU (menu)); - - group_num = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (menu), - "group_num")); - item_num = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (menu), - "item_num")); - - e_shortcut_bar_start_editing_item (shortcut_bar, group_num, item_num); -} - - -static void -remove_item (GtkWidget *menuitem, - EShortcutBar *shortcut_bar) -{ - GtkWidget *menu; - gint group_num, item_num; - - menu = menuitem->parent; - g_return_if_fail (GTK_IS_MENU (menu)); - - group_num = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (menu), - "group_num")); - item_num = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (menu), - "item_num")); - - e_shortcut_bar_remove_item (shortcut_bar, group_num, item_num); -} - - |