diff options
Diffstat (limited to 'widgets/e-reflow')
-rw-r--r-- | widgets/e-reflow/e-reflow-sorted.c | 185 | ||||
-rw-r--r-- | widgets/e-reflow/e-reflow-sorted.h | 87 | ||||
-rw-r--r-- | widgets/e-reflow/e-reflow.c | 36 | ||||
-rw-r--r-- | widgets/e-reflow/e-reflow.h | 16 |
4 files changed, 309 insertions, 15 deletions
diff --git a/widgets/e-reflow/e-reflow-sorted.c b/widgets/e-reflow/e-reflow-sorted.c new file mode 100644 index 0000000000..696efe454a --- /dev/null +++ b/widgets/e-reflow/e-reflow-sorted.c @@ -0,0 +1,185 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * e-reflow-sorted.c + * Copyright (C) 2000 Helix Code, Inc. + * Author: Chris Lahey <clahey@helixcode.com> + * + * This library 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 library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <gnome.h> +#include <math.h> +#include "e-reflow-sorted.h" +#include "e-canvas-utils.h" +#include "e-canvas.h" +#include "e-util.h" +#include <glib.h> +static void e_reflow_sorted_init (EReflowSorted *card); +static void e_reflow_sorted_class_init (EReflowSortedClass *klass); +static void e_reflow_sorted_set_arg (GtkObject *o, GtkArg *arg, guint arg_id); +static void e_reflow_sorted_get_arg (GtkObject *object, GtkArg *arg, guint arg_id); +static void e_reflow_sorted_add_item(EReflow *e_reflow, GnomeCanvasItem *item); + +static EReflowClass *parent_class = NULL; + +/* The arguments we take */ +enum { + ARG_0, + ARG_COMPARE_FUNC, + ARG_STRING_FUNC +}; + +GtkType +e_reflow_sorted_get_type (void) +{ + static GtkType reflow_type = 0; + + if (!reflow_type) + { + static const GtkTypeInfo reflow_info = + { + "EReflowSorted", + sizeof (EReflowSorted), + sizeof (EReflowSortedClass), + (GtkClassInitFunc) e_reflow_sorted_class_init, + (GtkObjectInitFunc) e_reflow_sorted_init, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL, + }; + + reflow_type = gtk_type_unique (e_reflow_get_type (), &reflow_info); + } + + return reflow_type; +} + +static void +e_reflow_sorted_class_init (EReflowSortedClass *klass) +{ + GtkObjectClass *object_class; + EReflowClass *reflow_class; + + object_class = (GtkObjectClass*) klass; + reflow_class = E_REFLOW_CLASS (klass); + + parent_class = gtk_type_class (e_reflow_get_type ()); + + gtk_object_add_arg_type ("EReflowSorted::compare_func", GTK_TYPE_POINTER, + GTK_ARG_READWRITE, ARG_COMPARE_FUNC); + gtk_object_add_arg_type ("EReflowSorted::string_func", GTK_TYPE_POINTER, + GTK_ARG_READWRITE, ARG_STRING_FUNC); + + reflow_class->add_item = e_reflow_sorted_add_item; + + object_class->set_arg = e_reflow_sorted_set_arg; + object_class->get_arg = e_reflow_sorted_get_arg; +} + +static void +e_reflow_sorted_init (EReflowSorted *reflow) +{ + reflow->compare_func = NULL; + reflow->string_func = NULL; +} + +static void +e_reflow_sorted_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) +{ + GnomeCanvasItem *item; + EReflowSorted *e_reflow_sorted; + + item = GNOME_CANVAS_ITEM (o); + e_reflow_sorted = E_REFLOW_SORTED (o); + + switch (arg_id){ + case ARG_COMPARE_FUNC: + e_reflow_sorted->compare_func = GTK_VALUE_POINTER (*arg); + break; + case ARG_STRING_FUNC: + e_reflow_sorted->string_func = GTK_VALUE_POINTER (*arg); + break; + } +} + +static void +e_reflow_sorted_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) +{ + EReflowSorted *e_reflow_sorted; + + e_reflow_sorted = E_REFLOW_SORTED (object); + + switch (arg_id) { + case ARG_COMPARE_FUNC: + GTK_VALUE_POINTER (*arg) = e_reflow_sorted->compare_func; + break; + case ARG_STRING_FUNC: + GTK_VALUE_POINTER (*arg) = e_reflow_sorted->string_func; + break; + default: + arg->type = GTK_TYPE_INVALID; + break; + } +} + +void +e_reflow_sorted_remove_item(EReflowSorted *e_reflow_sorted, const gchar *id) +{ + if (e_reflow_sorted->string_func) { + EReflow *reflow = E_REFLOW(e_reflow_sorted); + GList *list; + for (list = reflow->items; list; list = g_list_next(list)) { + GnomeCanvasItem *item = list->data; + char *string = e_reflow_sorted->string_func (item); + if (string && !strcmp(string, id)) { + reflow->items = g_list_remove_link(reflow->items, list); + g_list_free_1(list); + gtk_object_destroy(GTK_OBJECT(item)); + if ( GTK_OBJECT_FLAGS( e_reflow_sorted ) & GNOME_CANVAS_ITEM_REALIZED ) { + e_canvas_item_request_reflow(item); + } + return; + } + } + } +} + +void +e_reflow_sorted_replace_item(EReflowSorted *e_reflow_sorted, GnomeCanvasItem *item) +{ + if (e_reflow_sorted->string_func) { + char *string = e_reflow_sorted->string_func (item); + e_reflow_sorted_remove_item(e_reflow_sorted, string); + e_reflow_sorted_add_item(E_REFLOW(e_reflow_sorted), item); + } +} + + +static void +e_reflow_sorted_add_item(EReflow *reflow, GnomeCanvasItem *item) +{ + EReflowSorted *e_reflow_sorted = E_REFLOW_SORTED(reflow); + if ( e_reflow_sorted->compare_func ) { + reflow->items = g_list_insert_sorted(reflow->items, item, e_reflow_sorted->compare_func); + + if ( GTK_OBJECT_FLAGS( e_reflow_sorted ) & GNOME_CANVAS_ITEM_REALIZED ) { + gnome_canvas_item_set(item, + "width", (double) reflow->column_width, + NULL); + e_canvas_item_request_reflow(item); + } + } +} diff --git a/widgets/e-reflow/e-reflow-sorted.h b/widgets/e-reflow/e-reflow-sorted.h new file mode 100644 index 0000000000..4ffec7579b --- /dev/null +++ b/widgets/e-reflow/e-reflow-sorted.h @@ -0,0 +1,87 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* e-reflow-sorted.h + * Copyright (C) 2000 Helix Code, Inc. + * Author: Chris Lahey <clahey@helixcode.com> + * + * This library 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 library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef __E_REFLOW_SORTED_H__ +#define __E_REFLOW_SORTED_H__ + +#include <e-reflow.h> + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + +/* EReflowSorted - A canvas item container. + * + * The following arguments are available: + * + * name type read/write description + * -------------------------------------------------------------------------------- + * compare_func GCompareFunc RW compare function + * string_func EReflowStringFunc RW string function + * + * From EReflow: + * minimum_width double RW minimum width of the reflow. width >= minimum_width + * width double R width of the reflow + * height double RW height of the reflow + */ + +#define E_REFLOW_SORTED_TYPE (e_reflow_sorted_get_type ()) +#define E_REFLOW_SORTED(obj) (GTK_CHECK_CAST ((obj), E_REFLOW_SORTED_TYPE, EReflowSorted)) +#define E_REFLOW_SORTED_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_REFLOW_SORTED_TYPE, EReflowSortedClass)) +#define E_IS_REFLOW_SORTED(obj) (GTK_CHECK_TYPE ((obj), E_REFLOW_SORTED_TYPE)) +#define E_IS_REFLOW_SORTED_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_REFLOW_SORTED_TYPE)) + +typedef char * (* EReflowStringFunc) (GnomeCanvasItem *); + +typedef struct _EReflowSorted EReflowSorted; +typedef struct _EReflowSortedClass EReflowSortedClass; + +/* FIXME: Try reimplementing this as a hash table with key as string + and change EReflow to use a GTree. */ +struct _EReflowSorted +{ + EReflow parent; + + /* item specific fields */ + GCompareFunc compare_func; + EReflowStringFunc string_func; +}; + +struct _EReflowSortedClass +{ + EReflowClass parent_class; +}; + +/* + * To be added to a reflow, an item must have the argument "width" as + * a Read/Write argument and "height" as a Read Only argument. It + * should also do an ECanvas parent reflow request if its size + * changes. + */ +void e_reflow_sorted_remove_item (EReflowSorted *sorted, const char *id); +void e_reflow_sorted_replace_item (EReflowSorted *sorted, GnomeCanvasItem *item); +GtkType e_reflow_sorted_get_type (void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __E_REFLOW_SORTED_H__ */ diff --git a/widgets/e-reflow/e-reflow.c b/widgets/e-reflow/e-reflow.c index 4af46bd4a4..0ff8c0f4ea 100644 --- a/widgets/e-reflow/e-reflow.c +++ b/widgets/e-reflow/e-reflow.c @@ -26,10 +26,11 @@ #include "e-canvas-utils.h" #include "e-canvas.h" #include "e-util.h" -static void e_reflow_init (EReflow *card); +static void e_reflow_init (EReflow *reflow); static void e_reflow_class_init (EReflowClass *klass); static void e_reflow_set_arg (GtkObject *o, GtkArg *arg, guint arg_id); static void e_reflow_get_arg (GtkObject *object, GtkArg *arg, guint arg_id); +static void e_reflow_destroy (GtkObject *object); static gboolean e_reflow_event (GnomeCanvasItem *item, GdkEvent *event); static void e_reflow_realize (GnomeCanvasItem *item); static void e_reflow_unrealize (GnomeCanvasItem *item); @@ -38,6 +39,7 @@ static void e_reflow_draw (GnomeCanvasItem *item, GdkDrawable *drawable, static void e_reflow_update (GnomeCanvasItem *item, double affine[6], ArtSVP *clip_path, gint flags); static double e_reflow_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, GnomeCanvasItem **actual_item); static void e_reflow_reflow (GnomeCanvasItem *item, int flags); +static void e_reflow_real_add_item(EReflow *e_reflow, GnomeCanvasItem *item); static void e_reflow_resize_children (GnomeCanvasItem *item); @@ -97,10 +99,12 @@ e_reflow_class_init (EReflowClass *klass) GTK_ARG_READABLE, ARG_WIDTH); gtk_object_add_arg_type ("EReflow::height", GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_HEIGHT); + + klass->add_item = e_reflow_real_add_item; - object_class->set_arg = e_reflow_set_arg; - object_class->get_arg = e_reflow_get_arg; - /* object_class->destroy = e_reflow_destroy; */ + object_class->set_arg = e_reflow_set_arg; + object_class->get_arg = e_reflow_get_arg; + object_class->destroy = e_reflow_destroy; /* GnomeCanvasItem method overrides */ item_class->event = e_reflow_event; @@ -114,7 +118,6 @@ e_reflow_class_init (EReflowClass *klass) static void e_reflow_init (EReflow *reflow) { - /* reflow->card = NULL;*/ reflow->items = NULL; reflow->columns = NULL; reflow->column_width = 150; @@ -181,6 +184,14 @@ e_reflow_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) } static void +e_reflow_destroy (GtkObject *object) +{ + EReflow *reflow = E_REFLOW(object); + + g_list_free(reflow->items); +} + +static void e_reflow_realize (GnomeCanvasItem *item) { EReflow *e_reflow; @@ -228,9 +239,11 @@ e_reflow_unrealize (GnomeCanvasItem *item) gdk_cursor_destroy (e_reflow->arrow_cursor); gdk_cursor_destroy (e_reflow->default_cursor); + e_reflow->arrow_cursor = NULL; + e_reflow->default_cursor = NULL; - g_list_free (e_reflow->items); g_list_free (e_reflow->columns); + e_reflow->columns = NULL; if (GNOME_CANVAS_ITEM_CLASS(parent_class)->unrealize) (* GNOME_CANVAS_ITEM_CLASS(parent_class)->unrealize) (item); @@ -428,8 +441,8 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event) return 0; } -void -e_reflow_add_item(EReflow *e_reflow, GnomeCanvasItem *item) +static void +e_reflow_real_add_item(EReflow *e_reflow, GnomeCanvasItem *item) { e_reflow->items = g_list_append(e_reflow->items, item); if ( GTK_OBJECT_FLAGS( e_reflow ) & GNOME_CANVAS_ITEM_REALIZED ) { @@ -747,3 +760,10 @@ e_reflow_reflow( GnomeCanvasItem *item, int flags ) e_canvas_item_request_parent_reflow(item); } } + +void +e_reflow_add_item(EReflow *e_reflow, GnomeCanvasItem *item) +{ + if (E_REFLOW_CLASS(GTK_OBJECT(e_reflow)->klass)->add_item) + (E_REFLOW_CLASS(GTK_OBJECT(e_reflow)->klass)->add_item) (e_reflow, item); +} diff --git a/widgets/e-reflow/e-reflow.h b/widgets/e-reflow/e-reflow.h index 3a731474cb..54de59ba55 100644 --- a/widgets/e-reflow/e-reflow.h +++ b/widgets/e-reflow/e-reflow.h @@ -54,10 +54,8 @@ struct _EReflow GnomeCanvasGroup parent; /* item specific fields */ - /* EBook *book; */ - GList *items; /* Of type GnomeCanvasItem */ - GList *columns; /* Of type GList pointing to type GnomeCanvasItem (points into items) */ + GList *columns; /* Of type GList of type GnomeCanvasItem (points into items) */ gint column_count; /* Number of columnns */ double minimum_width; @@ -87,12 +85,16 @@ struct _EReflowClass { GnomeCanvasGroupClass parent_class; - void (* resize) (EReflow *reflow); + /* Virtual methods. */ + void (* add_item) (EReflow *reflow, GnomeCanvasItem *item); }; -/* To be added to a reflow, an item must have the arguments "x", "y", - and "width" as Read/Write arguments and "height" as a Read Only - argument. It must also have a "resize" signal. */ +/* + * To be added to a reflow, an item must have the argument "width" as + * a Read/Write argument and "height" as a Read Only argument. It + * should also do an ECanvas parent reflow request if its size + * changes. + */ void e_reflow_add_item(EReflow *e_reflow, GnomeCanvasItem *item); GtkType e_reflow_get_type (void); |