aboutsummaryrefslogtreecommitdiffstats
path: root/widgets
diff options
context:
space:
mode:
authorChristopher James Lahey <clahey@helixcode.com>2000-03-11 08:32:15 +0800
committerChris Lahey <clahey@src.gnome.org>2000-03-11 08:32:15 +0800
commit0a908b7fe481dd3bf216021fd8e04489f5f2aa66 (patch)
treecd22b484c729a21684ef46b6c99483847c43dae2 /widgets
parent8c65f8861bd16321eeafac1d827d1fb4a557247c (diff)
downloadgsoc2013-evolution-0a908b7fe481dd3bf216021fd8e04489f5f2aa66.tar.gz
gsoc2013-evolution-0a908b7fe481dd3bf216021fd8e04489f5f2aa66.tar.zst
gsoc2013-evolution-0a908b7fe481dd3bf216021fd8e04489f5f2aa66.zip
Designed a new system for doing hierarchical displays in the canvas. Adds
2000-03-10 Christopher James Lahey <clahey@helixcode.com> * e-util/e-canvas.c, e-util/e-canvas.h: Designed a new system for doing hierarchical displays in the canvas. Adds an extra idle loop to the canvas system. * widgets/e-minicard/e-minicard.c, widgets/e-minicard/e-minicard-label.c, widgets/e-minicard/e-minicard-label.h, widgets/e-minicard/e-reflow.c, widgets/e-minicard/test-reflow.c, widgets/e-text/e-text.c, widgets/e-text/e-text.h: Adapted to use the new e-canvas reflow system. svn path=/trunk/; revision=2096
Diffstat (limited to 'widgets')
-rw-r--r--widgets/e-minicard/e-minicard-label.c86
-rw-r--r--widgets/e-minicard/e-minicard-label.h2
-rw-r--r--widgets/e-minicard/e-minicard.c93
-rw-r--r--widgets/e-minicard/e-reflow.c102
-rw-r--r--widgets/e-minicard/test-reflow.c8
-rw-r--r--widgets/e-reflow/e-reflow.c102
-rw-r--r--widgets/e-text/e-text.c211
-rw-r--r--widgets/e-text/e-text.h6
-rw-r--r--widgets/misc/e-canvas.c117
-rw-r--r--widgets/misc/e-canvas.h9
-rw-r--r--widgets/misc/e-reflow.c102
-rw-r--r--widgets/text/e-text.c211
-rw-r--r--widgets/text/e-text.h6
13 files changed, 608 insertions, 447 deletions
diff --git a/widgets/e-minicard/e-minicard-label.c b/widgets/e-minicard/e-minicard-label.c
index 3f6a80a890..25f7f939fc 100644
--- a/widgets/e-minicard/e-minicard-label.c
+++ b/widgets/e-minicard/e-minicard-label.c
@@ -33,19 +33,12 @@ static void e_minicard_label_get_arg (GtkObject *object, GtkArg *arg, guint arg_
static gboolean e_minicard_label_event (GnomeCanvasItem *item, GdkEvent *event);
static void e_minicard_label_realize (GnomeCanvasItem *item);
static void e_minicard_label_unrealize (GnomeCanvasItem *item);
+static void e_minicard_label_reflow(GnomeCanvasItem *item, int flags);
-static void update_label( EMinicardLabel *minicard_label );
-static void resize( GtkObject *object, gpointer data );
+static void e_minicard_label_resize_children( EMinicardLabel *e_minicard_label );
static GnomeCanvasGroupClass *parent_class = NULL;
-enum {
- E_MINICARD_LABEL_RESIZE,
- E_MINICARD_LABEL_LAST_SIGNAL
-};
-
-static guint e_minicard_label_signals[E_MINICARD_LABEL_LAST_SIGNAL] = { 0 };
-
/* The arguments we take */
enum {
ARG_0,
@@ -92,17 +85,6 @@ e_minicard_label_class_init (EMinicardLabelClass *klass)
parent_class = gtk_type_class (gnome_canvas_group_get_type ());
- e_minicard_label_signals[E_MINICARD_LABEL_RESIZE] =
- gtk_signal_new ("resize",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EMinicardLabelClass, resize),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
-
- gtk_object_class_add_signals (object_class, e_minicard_label_signals, E_MINICARD_LABEL_LAST_SIGNAL);
-
gtk_object_add_arg_type ("EMinicardLabel::width", GTK_TYPE_DOUBLE,
GTK_ARG_READWRITE, ARG_WIDTH);
gtk_object_add_arg_type ("EMinicardLabel::height", GTK_TYPE_DOUBLE,
@@ -113,8 +95,6 @@ e_minicard_label_class_init (EMinicardLabelClass *klass)
GTK_ARG_READWRITE, ARG_FIELD);
gtk_object_add_arg_type ("EMinicardLabel::fieldname", GTK_TYPE_STRING,
GTK_ARG_READWRITE, ARG_FIELDNAME);
-
- klass->resize = NULL;
object_class->set_arg = e_minicard_label_set_arg;
object_class->get_arg = e_minicard_label_get_arg;
@@ -136,6 +116,8 @@ e_minicard_label_init (EMinicardLabel *minicard_label)
minicard_label->field = NULL;
minicard_label->fieldname_text = NULL;
minicard_label->field_text = NULL;
+
+ e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM(minicard_label), e_minicard_label_reflow);
}
static void
@@ -150,8 +132,8 @@ e_minicard_label_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
switch (arg_id){
case ARG_WIDTH:
e_minicard_label->width = GTK_VALUE_DOUBLE (*arg);
- update_label( e_minicard_label );
- gnome_canvas_item_request_update (item);
+ e_minicard_label_resize_children(e_minicard_label);
+ e_canvas_item_request_reflow (item);
break;
case ARG_HAS_FOCUS:
if (e_minicard_label->field && (GTK_VALUE_ENUM(*arg) != E_FOCUS_NONE))
@@ -241,7 +223,6 @@ e_minicard_label_realize (GnomeCanvasItem *item)
e_text_get_type(),
"anchor", GTK_ANCHOR_NW,
"clip_width", (double) ( e_minicard_label->width / 2 - 4 ),
- "clip_height", (double) 1,
"clip", TRUE,
"use_ellipsis", TRUE,
"font_gdk", font,
@@ -255,17 +236,12 @@ e_minicard_label_realize (GnomeCanvasItem *item)
NULL );
g_free( e_minicard_label->fieldname_text );
}
- gtk_signal_connect(GTK_OBJECT(e_minicard_label->fieldname),
- "resize",
- GTK_SIGNAL_FUNC(resize),
- (gpointer) e_minicard_label);
e_minicard_label->field =
gnome_canvas_item_new( group,
e_text_get_type(),
"anchor", GTK_ANCHOR_NW,
"clip_width", (double) ( ( e_minicard_label->width + 1 ) / 2 - 4 ),
- "clip_height", (double) 1,
"clip", TRUE,
"use_ellipsis", TRUE,
"font_gdk", font,
@@ -281,12 +257,7 @@ e_minicard_label_realize (GnomeCanvasItem *item)
g_free( e_minicard_label->field_text );
}
- gtk_signal_connect(GTK_OBJECT(e_minicard_label->field),
- "resize",
- GTK_SIGNAL_FUNC(resize),
- (gpointer) e_minicard_label);
-
- update_label (e_minicard_label);
+ e_canvas_item_request_reflow(item);
if (!item->canvas->aa)
{
@@ -344,10 +315,11 @@ e_minicard_label_event (GnomeCanvasItem *item, GdkEvent *event)
case GDK_MOTION_NOTIFY:
case GDK_ENTER_NOTIFY:
case GDK_LEAVE_NOTIFY: {
+ gboolean return_val;
+#if 0
GnomeCanvasItem *field;
ArtPoint p;
double inv[6], affine[6];
- gboolean return_val;
field = e_minicard_label->field;
art_affine_identity (affine);
@@ -389,7 +361,7 @@ e_minicard_label_event (GnomeCanvasItem *item, GdkEvent *event)
default:
break;
}
-
+#endif
gtk_signal_emit_by_name(GTK_OBJECT(e_minicard_label->field), "event", event, &return_val);
return return_val;
break;
@@ -405,8 +377,22 @@ e_minicard_label_event (GnomeCanvasItem *item, GdkEvent *event)
}
static void
-update_label( EMinicardLabel *e_minicard_label )
+e_minicard_label_resize_children(EMinicardLabel *e_minicard_label)
{
+ if ( GTK_OBJECT_FLAGS( e_minicard_label ) & GNOME_CANVAS_ITEM_REALIZED ) {
+ gnome_canvas_item_set( e_minicard_label->fieldname,
+ "clip_width", (double) ( e_minicard_label->width / 2 - 4 ),
+ NULL );
+ gnome_canvas_item_set( e_minicard_label->field,
+ "clip_width", (double) ( ( e_minicard_label->width + 1 ) / 2 - 4 ),
+ NULL );
+ }
+}
+
+static void
+e_minicard_label_reflow(GnomeCanvasItem *item, int flags)
+{
+ EMinicardLabel *e_minicard_label = E_MINICARD_LABEL(item);
if ( GTK_OBJECT_FLAGS( e_minicard_label ) & GNOME_CANVAS_ITEM_REALIZED )
{
gint old_height;
@@ -416,9 +402,6 @@ update_label( EMinicardLabel *e_minicard_label )
gtk_object_get(GTK_OBJECT(e_minicard_label->fieldname),
"text_height", &text_height,
NULL);
- gnome_canvas_item_set(e_minicard_label->fieldname,
- "clip_height", (double) text_height,
- NULL);
e_minicard_label->height = text_height;
@@ -426,9 +409,6 @@ update_label( EMinicardLabel *e_minicard_label )
gtk_object_get(GTK_OBJECT(e_minicard_label->field),
"text_height", &text_height,
NULL);
- gnome_canvas_item_set(e_minicard_label->field,
- "clip_height", (double) text_height,
- NULL);
if (e_minicard_label->height < text_height)
e_minicard_label->height = text_height;
@@ -438,24 +418,10 @@ update_label( EMinicardLabel *e_minicard_label )
"x2", (double) e_minicard_label->width - 1,
"y2", (double) e_minicard_label->height - 1,
NULL );
- gnome_canvas_item_set( e_minicard_label->fieldname,
- "clip_width", (double) ( e_minicard_label->width / 2 - 4 ),
- NULL );
- gnome_canvas_item_set( e_minicard_label->field,
- "clip_width", (double) ( ( e_minicard_label->width + 1 ) / 2 - 4 ),
- NULL );
e_canvas_item_move_absolute(e_minicard_label->field, ( e_minicard_label->width / 2 + 2), 1);
if (old_height != e_minicard_label->height)
- gtk_signal_emit_by_name (GTK_OBJECT (e_minicard_label), "resize");
+ e_canvas_item_request_parent_reflow(item);
}
}
-
-
-static void
-resize( GtkObject *object, gpointer data )
-{
- update_label(E_MINICARD_LABEL(data));
-}
-
diff --git a/widgets/e-minicard/e-minicard-label.h b/widgets/e-minicard/e-minicard-label.h
index 3311e3c9af..b439c53f9d 100644
--- a/widgets/e-minicard/e-minicard-label.h
+++ b/widgets/e-minicard/e-minicard-label.h
@@ -69,8 +69,6 @@ struct _EMinicardLabel
struct _EMinicardLabelClass
{
GnomeCanvasGroupClass parent_class;
-
- void (* resize) (EMinicardLabel *text);
};
diff --git a/widgets/e-minicard/e-minicard.c b/widgets/e-minicard/e-minicard.c
index b8d25f5dc6..79668b6507 100644
--- a/widgets/e-minicard/e-minicard.c
+++ b/widgets/e-minicard/e-minicard.c
@@ -34,19 +34,12 @@ static void e_minicard_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
static gboolean e_minicard_event (GnomeCanvasItem *item, GdkEvent *event);
static void e_minicard_realize (GnomeCanvasItem *item);
static void e_minicard_unrealize (GnomeCanvasItem *item);
+static void e_minicard_reflow ( GnomeCanvasItem *item, int flags );
-static void _update_card ( EMinicard *minicard );
-static void _resize( GtkObject *object, gpointer data );
+static void e_minicard_resize_children( EMinicard *e_minicard );
static GnomeCanvasGroupClass *parent_class = NULL;
-enum {
- E_MINICARD_RESIZE,
- E_MINICARD_LAST_SIGNAL
-};
-
-static guint e_minicard_signals[E_MINICARD_LAST_SIGNAL] = { 0 };
-
/* The arguments we take */
enum {
ARG_0,
@@ -92,17 +85,6 @@ e_minicard_class_init (EMinicardClass *klass)
parent_class = gtk_type_class (gnome_canvas_group_get_type ());
- e_minicard_signals[E_MINICARD_RESIZE] =
- gtk_signal_new ("resize",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EMinicardClass, resize),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
-
- gtk_object_class_add_signals (object_class, e_minicard_signals, E_MINICARD_LAST_SIGNAL);
-
gtk_object_add_arg_type ("EMinicard::width", GTK_TYPE_DOUBLE,
GTK_ARG_READWRITE, ARG_WIDTH);
gtk_object_add_arg_type ("EMinicard::height", GTK_TYPE_DOUBLE,
@@ -131,6 +113,8 @@ e_minicard_init (EMinicard *minicard)
minicard->width = 10;
minicard->height = 10;
minicard->has_focus = FALSE;
+
+ e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM(minicard), e_minicard_reflow);
}
static void
@@ -146,8 +130,8 @@ e_minicard_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
case ARG_WIDTH:
if (e_minicard->width != GTK_VALUE_DOUBLE (*arg)) {
e_minicard->width = GTK_VALUE_DOUBLE (*arg);
- _update_card(e_minicard);
- gnome_canvas_item_request_update (item);
+ e_minicard_resize_children(e_minicard);
+ e_canvas_item_request_reflow(item);
}
break;
case ARG_HAS_FOCUS:
@@ -237,7 +221,7 @@ e_minicard_realize (GnomeCanvasItem *item)
gnome_canvas_item_new( group,
e_text_get_type(),
"anchor", GTK_ANCHOR_NW,
- "clip_width", (double) ( e_minicard->width - 12 ),
+ "width", (double) ( e_minicard->width - 12 ),
"clip", TRUE,
"use_ellipsis", TRUE,
"font", "lucidasans-bold-10",
@@ -246,10 +230,6 @@ e_minicard_realize (GnomeCanvasItem *item)
NULL );
e_canvas_item_move_absolute(e_minicard->header_text, 6, 6);
- gtk_signal_connect(GTK_OBJECT(e_minicard->header_text),
- "resize",
- GTK_SIGNAL_FUNC(_resize),
- (gpointer) e_minicard);
if ( rand() % 2 ) {
new_item = gnome_canvas_item_new( group,
e_minicard_label_get_type(),
@@ -259,11 +239,6 @@ e_minicard_realize (GnomeCanvasItem *item)
NULL );
e_minicard->fields = g_list_append( e_minicard->fields, new_item);
e_canvas_item_move_absolute(new_item, 2, e_minicard->height);
-
- gtk_signal_connect(GTK_OBJECT(new_item),
- "resize",
- GTK_SIGNAL_FUNC(_resize),
- (gpointer) e_minicard);
}
if (rand() % 2) {
@@ -275,11 +250,6 @@ e_minicard_realize (GnomeCanvasItem *item)
NULL );
e_minicard->fields = g_list_append( e_minicard->fields, new_item);
e_canvas_item_move_absolute(new_item, 2, e_minicard->height);
-
- gtk_signal_connect(GTK_OBJECT(new_item),
- "resize",
- GTK_SIGNAL_FUNC(_resize),
- (gpointer) e_minicard);
}
if (rand() % 2) {
@@ -291,13 +261,8 @@ e_minicard_realize (GnomeCanvasItem *item)
NULL );
e_minicard->fields = g_list_append( e_minicard->fields, new_item);
e_canvas_item_move_absolute(new_item, 2, e_minicard->height);
-
- gtk_signal_connect(GTK_OBJECT(new_item),
- "resize",
- GTK_SIGNAL_FUNC(_resize),
- (gpointer) e_minicard);
}
- _update_card( e_minicard );
+ e_canvas_item_request_reflow(item);
if (!item->canvas->aa) {
}
@@ -402,8 +367,26 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
}
static void
-_update_card( EMinicard *e_minicard )
+e_minicard_resize_children( EMinicard *e_minicard )
+{
+ if ( GTK_OBJECT_FLAGS( e_minicard ) & GNOME_CANVAS_ITEM_REALIZED ) {
+ GList *list;
+
+ gnome_canvas_item_set( e_minicard->header_text,
+ "width", (double) e_minicard->width - 12,
+ NULL );
+ for ( list = e_minicard->fields; list; list = g_list_next( list ) ) {
+ gnome_canvas_item_set( GNOME_CANVAS_ITEM( list->data ),
+ "width", (double) e_minicard->width - 4.0,
+ NULL );
+ }
+ }
+}
+
+static void
+e_minicard_reflow( GnomeCanvasItem *item, int flags )
{
+ EMinicard *e_minicard = E_MINICARD(item);
if ( GTK_OBJECT_FLAGS( e_minicard ) & GNOME_CANVAS_ITEM_REALIZED ) {
GList *list;
gdouble text_height;
@@ -421,10 +404,6 @@ _update_card( EMinicard *e_minicard )
"y2", text_height + 9.0,
NULL );
- gnome_canvas_item_set( e_minicard->header_text,
- "clip_height", (double)text_height,
- NULL );
-
for(list = e_minicard->fields; list; list = g_list_next(list)) {
gtk_object_get (GTK_OBJECT(list->data),
"height", &text_height,
@@ -445,22 +424,8 @@ _update_card( EMinicard *e_minicard )
gnome_canvas_item_set( e_minicard->header_rect,
"x2", (double) e_minicard->width - 3.0,
NULL );
- gnome_canvas_item_set( e_minicard->header_text,
- "clip_width", (double) e_minicard->width - 12,
- NULL );
- for ( list = e_minicard->fields; list; list = g_list_next( list ) ) {
- gnome_canvas_item_set( GNOME_CANVAS_ITEM( list->data ),
- "width", (double) e_minicard->width - 4.0,
- NULL );
if (old_height != e_minicard->height)
- gtk_signal_emit_by_name (GTK_OBJECT (e_minicard), "resize");
- }
- }
-}
-
-static void
-_resize( GtkObject *object, gpointer data )
-{
- _update_card(E_MINICARD(data));
+ e_canvas_item_request_parent_reflow(item);
+ }
}
diff --git a/widgets/e-minicard/e-reflow.c b/widgets/e-minicard/e-reflow.c
index 984e972f0c..4af46bd4a4 100644
--- a/widgets/e-minicard/e-reflow.c
+++ b/widgets/e-minicard/e-reflow.c
@@ -24,6 +24,7 @@
#include <math.h>
#include "e-reflow.h"
#include "e-canvas-utils.h"
+#include "e-canvas.h"
#include "e-util.h"
static void e_reflow_init (EReflow *card);
static void e_reflow_class_init (EReflowClass *klass);
@@ -36,10 +37,9 @@ static void e_reflow_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
int x, int y, int width, int height);
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 _update_reflow ( EReflow *reflow );
-static void _resize( GtkObject *object, gpointer data );
-static void _queue_reflow(EReflow *e_reflow);
+static void e_reflow_resize_children (GnomeCanvasItem *item);
#define E_REFLOW_DIVIDER_WIDTH 2
#define E_REFLOW_BORDER_WIDTH 7
@@ -47,13 +47,6 @@ static void _queue_reflow(EReflow *e_reflow);
static GnomeCanvasGroupClass *parent_class = NULL;
-enum {
- E_REFLOW_RESIZE,
- E_REFLOW_LAST_SIGNAL
-};
-
-static guint e_reflow_signals[E_REFLOW_LAST_SIGNAL] = { 0 };
-
/* The arguments we take */
enum {
ARG_0,
@@ -98,16 +91,6 @@ e_reflow_class_init (EReflowClass *klass)
parent_class = gtk_type_class (gnome_canvas_group_get_type ());
- e_reflow_signals[E_REFLOW_RESIZE] =
- gtk_signal_new ("resize",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EReflowClass, resize),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- gtk_object_class_add_signals (object_class, e_reflow_signals, E_REFLOW_LAST_SIGNAL);
-
gtk_object_add_arg_type ("EReflow::minimum_width", GTK_TYPE_DOUBLE,
GTK_ARG_READWRITE, ARG_MINIMUM_WIDTH);
gtk_object_add_arg_type ("EReflow::width", GTK_TYPE_DOUBLE,
@@ -149,6 +132,8 @@ e_reflow_init (EReflow *reflow)
reflow->default_cursor_shown = TRUE;
reflow->arrow_cursor = NULL;
reflow->default_cursor = NULL;
+
+ e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM(reflow), e_reflow_reflow);
}
static void
@@ -163,11 +148,11 @@ e_reflow_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
switch (arg_id){
case ARG_HEIGHT:
e_reflow->height = GTK_VALUE_DOUBLE (*arg);
- _queue_reflow(e_reflow);
+ e_canvas_item_request_reflow(item);
break;
case ARG_MINIMUM_WIDTH:
e_reflow->minimum_width = GTK_VALUE_DOUBLE (*arg);
- _queue_reflow(e_reflow);
+ e_canvas_item_request_reflow(item);
break;
}
}
@@ -214,17 +199,13 @@ e_reflow_realize (GnomeCanvasItem *item)
for(list = e_reflow->items; list; list = g_list_next(list)) {
GnomeCanvasItem *item = GNOME_CANVAS_ITEM(list->data);
- gtk_signal_connect(GTK_OBJECT(item),
- "resize",
- GTK_SIGNAL_FUNC(_resize),
- (gpointer) e_reflow);
gnome_canvas_item_set(item,
"width", (double) e_reflow->column_width,
NULL);
}
- _queue_reflow( e_reflow );
-
+ e_canvas_item_request_reflow(item);
+
adjustment = gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas));
adjustment->step_increment = (e_reflow->column_width + E_REFLOW_FULL_GUTTER) / 2;
adjustment->page_increment = adjustment->page_size - adjustment->step_increment;
@@ -365,11 +346,11 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event)
adjustment->step_increment = (e_reflow->column_width + E_REFLOW_FULL_GUTTER) / 2;
adjustment->page_increment = adjustment->page_size - adjustment->step_increment;
gtk_adjustment_changed(adjustment);
- _queue_reflow(e_reflow);
- } else {
- e_reflow->need_column_resize = TRUE;
- gnome_canvas_item_request_update(item);
+ e_reflow_resize_children(item);
+ e_canvas_item_request_reflow(item);
}
+ e_reflow->need_column_resize = TRUE;
+ gnome_canvas_item_request_update(item);
gnome_canvas_item_ungrab (item, button->time);
return TRUE;
}
@@ -452,14 +433,10 @@ e_reflow_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 ) {
- gtk_signal_connect(GTK_OBJECT(item),
- "resize",
- GTK_SIGNAL_FUNC(_resize),
- (gpointer) e_reflow);
gnome_canvas_item_set(item,
"width", (double) e_reflow->column_width,
NULL);
- _queue_reflow(e_reflow);
+ e_canvas_item_request_reflow(item);
}
}
@@ -621,6 +598,21 @@ e_reflow_update (GnomeCanvasItem *item, double affine[6], ArtSVP *clip_path, gin
}
}
+static void
+e_reflow_resize_children (GnomeCanvasItem *item)
+{
+ GList *list;
+ EReflow *e_reflow;
+
+ e_reflow = E_REFLOW (item);
+ for ( list = e_reflow->items; list; list = list->next ) {
+ GnomeCanvasItem *child = GNOME_CANVAS_ITEM(list->data);
+ gnome_canvas_item_set(child,
+ "width", (double) e_reflow->column_width,
+ NULL);
+ }
+}
+
static double
e_reflow_point (GnomeCanvasItem *item,
double x, double y, int cx, int cy,
@@ -696,8 +688,9 @@ _reflow( EReflow *e_reflow )
}
static void
-_update_reflow( EReflow *e_reflow )
+e_reflow_reflow( GnomeCanvasItem *item, int flags )
{
+ EReflow *e_reflow = E_REFLOW(item);
if ( GTK_OBJECT_FLAGS( e_reflow ) & GNOME_CANVAS_ITEM_REALIZED ) {
gdouble old_width;
@@ -719,9 +712,6 @@ _update_reflow( EReflow *e_reflow )
running_height = E_REFLOW_BORDER_WIDTH;
list = e_reflow->items;
- gtk_object_set (GTK_OBJECT(list->data),
- "width", e_reflow->column_width,
- NULL);
gtk_object_get (GTK_OBJECT(list->data),
"height", &item_height,
NULL);
@@ -733,9 +723,6 @@ _update_reflow( EReflow *e_reflow )
list = g_list_next(list);
for( ; list; list = g_list_next(list)) {
- gtk_object_set (GTK_OBJECT(list->data),
- "width", e_reflow->column_width,
- NULL);
gtk_object_get (GTK_OBJECT(list->data),
"height", &item_height,
NULL);
@@ -757,31 +744,6 @@ _update_reflow( EReflow *e_reflow )
if ( e_reflow->width < e_reflow->minimum_width )
e_reflow->width = e_reflow->minimum_width;
if (old_width != e_reflow->width)
- gtk_signal_emit_by_name (GTK_OBJECT (e_reflow), "resize");
+ e_canvas_item_request_parent_reflow(item);
}
}
-
-
-static gboolean
-_idle_reflow(gpointer data)
-{
- EReflow *e_reflow = E_REFLOW(data);
- _update_reflow(e_reflow);
- e_reflow->need_height_update = TRUE;
- gnome_canvas_item_request_update(GNOME_CANVAS_ITEM(e_reflow));
- e_reflow->idle = 0;
- return FALSE;
-}
-
-static void
-_queue_reflow(EReflow *e_reflow)
-{
- if (e_reflow->idle == 0)
- e_reflow->idle = g_idle_add(_idle_reflow, e_reflow);
-}
-
-static void
-_resize( GtkObject *object, gpointer data )
-{
- _queue_reflow(E_REFLOW(data));
-}
diff --git a/widgets/e-minicard/test-reflow.c b/widgets/e-minicard/test-reflow.c
index 319a3f5626..8cedbaac28 100644
--- a/widgets/e-minicard/test-reflow.c
+++ b/widgets/e-minicard/test-reflow.c
@@ -55,14 +55,14 @@ static void allocate_callback(GtkWidget *canvas, GtkAllocation *allocation, gpoi
NULL );
}
-static void resize(GnomeCanvasItem *item, gpointer data)
+static void resize(GnomeCanvas *canvas, gpointer data)
{
double width;
gtk_object_get(GTK_OBJECT(reflow),
- "width", &width,
+ "width", &width,
NULL);
width = MAX(width, last_alloc.width);
- gnome_canvas_set_scroll_region(item->canvas , 0, 0, width, last_alloc.height );
+ gnome_canvas_set_scroll_region(canvas , 0, 0, width, last_alloc.height );
gnome_canvas_item_set( rect,
"x2", (double) width,
"y2", (double) last_alloc.height,
@@ -121,7 +121,7 @@ int main( int argc, char *argv[] )
"height", (double) 100,
"minimum_width", (double) 100,
NULL );
- gtk_signal_connect( GTK_OBJECT( reflow ), "resize",
+ gtk_signal_connect( GTK_OBJECT( canvas ), "reflow",
GTK_SIGNAL_FUNC( resize ),
( gpointer ) app);
for ( i = 0; i < 200; i++ )
diff --git a/widgets/e-reflow/e-reflow.c b/widgets/e-reflow/e-reflow.c
index 984e972f0c..4af46bd4a4 100644
--- a/widgets/e-reflow/e-reflow.c
+++ b/widgets/e-reflow/e-reflow.c
@@ -24,6 +24,7 @@
#include <math.h>
#include "e-reflow.h"
#include "e-canvas-utils.h"
+#include "e-canvas.h"
#include "e-util.h"
static void e_reflow_init (EReflow *card);
static void e_reflow_class_init (EReflowClass *klass);
@@ -36,10 +37,9 @@ static void e_reflow_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
int x, int y, int width, int height);
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 _update_reflow ( EReflow *reflow );
-static void _resize( GtkObject *object, gpointer data );
-static void _queue_reflow(EReflow *e_reflow);
+static void e_reflow_resize_children (GnomeCanvasItem *item);
#define E_REFLOW_DIVIDER_WIDTH 2
#define E_REFLOW_BORDER_WIDTH 7
@@ -47,13 +47,6 @@ static void _queue_reflow(EReflow *e_reflow);
static GnomeCanvasGroupClass *parent_class = NULL;
-enum {
- E_REFLOW_RESIZE,
- E_REFLOW_LAST_SIGNAL
-};
-
-static guint e_reflow_signals[E_REFLOW_LAST_SIGNAL] = { 0 };
-
/* The arguments we take */
enum {
ARG_0,
@@ -98,16 +91,6 @@ e_reflow_class_init (EReflowClass *klass)
parent_class = gtk_type_class (gnome_canvas_group_get_type ());
- e_reflow_signals[E_REFLOW_RESIZE] =
- gtk_signal_new ("resize",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EReflowClass, resize),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- gtk_object_class_add_signals (object_class, e_reflow_signals, E_REFLOW_LAST_SIGNAL);
-
gtk_object_add_arg_type ("EReflow::minimum_width", GTK_TYPE_DOUBLE,
GTK_ARG_READWRITE, ARG_MINIMUM_WIDTH);
gtk_object_add_arg_type ("EReflow::width", GTK_TYPE_DOUBLE,
@@ -149,6 +132,8 @@ e_reflow_init (EReflow *reflow)
reflow->default_cursor_shown = TRUE;
reflow->arrow_cursor = NULL;
reflow->default_cursor = NULL;
+
+ e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM(reflow), e_reflow_reflow);
}
static void
@@ -163,11 +148,11 @@ e_reflow_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
switch (arg_id){
case ARG_HEIGHT:
e_reflow->height = GTK_VALUE_DOUBLE (*arg);
- _queue_reflow(e_reflow);
+ e_canvas_item_request_reflow(item);
break;
case ARG_MINIMUM_WIDTH:
e_reflow->minimum_width = GTK_VALUE_DOUBLE (*arg);
- _queue_reflow(e_reflow);
+ e_canvas_item_request_reflow(item);
break;
}
}
@@ -214,17 +199,13 @@ e_reflow_realize (GnomeCanvasItem *item)
for(list = e_reflow->items; list; list = g_list_next(list)) {
GnomeCanvasItem *item = GNOME_CANVAS_ITEM(list->data);
- gtk_signal_connect(GTK_OBJECT(item),
- "resize",
- GTK_SIGNAL_FUNC(_resize),
- (gpointer) e_reflow);
gnome_canvas_item_set(item,
"width", (double) e_reflow->column_width,
NULL);
}
- _queue_reflow( e_reflow );
-
+ e_canvas_item_request_reflow(item);
+
adjustment = gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas));
adjustment->step_increment = (e_reflow->column_width + E_REFLOW_FULL_GUTTER) / 2;
adjustment->page_increment = adjustment->page_size - adjustment->step_increment;
@@ -365,11 +346,11 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event)
adjustment->step_increment = (e_reflow->column_width + E_REFLOW_FULL_GUTTER) / 2;
adjustment->page_increment = adjustment->page_size - adjustment->step_increment;
gtk_adjustment_changed(adjustment);
- _queue_reflow(e_reflow);
- } else {
- e_reflow->need_column_resize = TRUE;
- gnome_canvas_item_request_update(item);
+ e_reflow_resize_children(item);
+ e_canvas_item_request_reflow(item);
}
+ e_reflow->need_column_resize = TRUE;
+ gnome_canvas_item_request_update(item);
gnome_canvas_item_ungrab (item, button->time);
return TRUE;
}
@@ -452,14 +433,10 @@ e_reflow_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 ) {
- gtk_signal_connect(GTK_OBJECT(item),
- "resize",
- GTK_SIGNAL_FUNC(_resize),
- (gpointer) e_reflow);
gnome_canvas_item_set(item,
"width", (double) e_reflow->column_width,
NULL);
- _queue_reflow(e_reflow);
+ e_canvas_item_request_reflow(item);
}
}
@@ -621,6 +598,21 @@ e_reflow_update (GnomeCanvasItem *item, double affine[6], ArtSVP *clip_path, gin
}
}
+static void
+e_reflow_resize_children (GnomeCanvasItem *item)
+{
+ GList *list;
+ EReflow *e_reflow;
+
+ e_reflow = E_REFLOW (item);
+ for ( list = e_reflow->items; list; list = list->next ) {
+ GnomeCanvasItem *child = GNOME_CANVAS_ITEM(list->data);
+ gnome_canvas_item_set(child,
+ "width", (double) e_reflow->column_width,
+ NULL);
+ }
+}
+
static double
e_reflow_point (GnomeCanvasItem *item,
double x, double y, int cx, int cy,
@@ -696,8 +688,9 @@ _reflow( EReflow *e_reflow )
}
static void
-_update_reflow( EReflow *e_reflow )
+e_reflow_reflow( GnomeCanvasItem *item, int flags )
{
+ EReflow *e_reflow = E_REFLOW(item);
if ( GTK_OBJECT_FLAGS( e_reflow ) & GNOME_CANVAS_ITEM_REALIZED ) {
gdouble old_width;
@@ -719,9 +712,6 @@ _update_reflow( EReflow *e_reflow )
running_height = E_REFLOW_BORDER_WIDTH;
list = e_reflow->items;
- gtk_object_set (GTK_OBJECT(list->data),
- "width", e_reflow->column_width,
- NULL);
gtk_object_get (GTK_OBJECT(list->data),
"height", &item_height,
NULL);
@@ -733,9 +723,6 @@ _update_reflow( EReflow *e_reflow )
list = g_list_next(list);
for( ; list; list = g_list_next(list)) {
- gtk_object_set (GTK_OBJECT(list->data),
- "width", e_reflow->column_width,
- NULL);
gtk_object_get (GTK_OBJECT(list->data),
"height", &item_height,
NULL);
@@ -757,31 +744,6 @@ _update_reflow( EReflow *e_reflow )
if ( e_reflow->width < e_reflow->minimum_width )
e_reflow->width = e_reflow->minimum_width;
if (old_width != e_reflow->width)
- gtk_signal_emit_by_name (GTK_OBJECT (e_reflow), "resize");
+ e_canvas_item_request_parent_reflow(item);
}
}
-
-
-static gboolean
-_idle_reflow(gpointer data)
-{
- EReflow *e_reflow = E_REFLOW(data);
- _update_reflow(e_reflow);
- e_reflow->need_height_update = TRUE;
- gnome_canvas_item_request_update(GNOME_CANVAS_ITEM(e_reflow));
- e_reflow->idle = 0;
- return FALSE;
-}
-
-static void
-_queue_reflow(EReflow *e_reflow)
-{
- if (e_reflow->idle == 0)
- e_reflow->idle = g_idle_add(_idle_reflow, e_reflow);
-}
-
-static void
-_resize( GtkObject *object, gpointer data )
-{
- _queue_reflow(E_REFLOW(data));
-}
diff --git a/widgets/e-text/e-text.c b/widgets/e-text/e-text.c
index d9448fe783..ca41dc1d96 100644
--- a/widgets/e-text/e-text.c
+++ b/widgets/e-text/e-text.c
@@ -25,6 +25,7 @@
#include <libart_lgpl/art_rgb.h>
#include <libart_lgpl/art_rgb_bitmap_affine.h>
#include <gtk/gtkinvisible.h>
+#include "e-util/e-canvas.h"
#include "e-text-event-processor-emacs-like.h"
@@ -75,7 +76,9 @@ enum {
ARG_ELLIPSIS,
ARG_LINE_WRAP,
ARG_BREAK_CHARACTERS,
- ARG_MAX_LINES
+ ARG_MAX_LINES,
+ ARG_WIDTH,
+ ARG_HEIGHT
};
@@ -95,6 +98,7 @@ static void e_text_destroy (GtkObject *object);
static void e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);
static void e_text_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+static void e_text_reflow (GnomeCanvasItem *item, int flags);
static void e_text_update (GnomeCanvasItem *item, double *affine,
ArtSVP *clip_path, int flags);
static void e_text_realize (GnomeCanvasItem *item);
@@ -250,6 +254,10 @@ e_text_class_init (ETextClass *klass)
GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_BREAK_CHARACTERS);
gtk_object_add_arg_type ("EText::max_lines",
GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_MAX_LINES);
+ gtk_object_add_arg_type ("EText::width",
+ GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_WIDTH);
+ gtk_object_add_arg_type ("EText::height",
+ GTK_TYPE_DOUBLE, GTK_ARG_READABLE, ARG_HEIGHT);
if (!clipboard_atom)
clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
@@ -325,6 +333,8 @@ e_text_init (EText *text)
text->line_wrap = FALSE;
text->break_characters = NULL;
text->max_lines = -1;
+
+ e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM(text), e_text_reflow);
}
/* Destroy handler for the text item */
@@ -460,43 +470,14 @@ get_bounds_item_relative (EText *text, double *px1, double *py1, double *px2, do
}
}
-
-static gboolean
-idle_resize(gpointer data)
-{
- EText *text = E_TEXT(data);
- gtk_signal_emit_by_name (GTK_OBJECT (text), "resize");
- return FALSE;
-}
-
-static void
-queue_resize_signal(EText *text)
-{
- if (text->idle == 0)
- text->idle = g_idle_add(idle_resize, text);
-}
-
static void
get_bounds (EText *text, double *px1, double *py1, double *px2, double *py2)
{
GnomeCanvasItem *item;
double wx, wy;
- int old_height;
item = GNOME_CANVAS_ITEM (text);
- /* Calculate text dimensions */
-
- old_height = text->height;
-
- if (text->text && text->font)
- text->height = (text->font->ascent + text->font->descent) * text->num_lines;
- else
- text->height = 0;
-
- if (old_height != text->height)
- queue_resize_signal(text);
-
/* Get canvas pixel coordinates for text position */
wx = text->x;
@@ -573,6 +554,27 @@ get_bounds (EText *text, double *px1, double *py1, double *px2, double *py2)
}
static void
+calc_height (EText *text)
+{
+ GnomeCanvasItem *item;
+ int old_height;
+
+ item = GNOME_CANVAS_ITEM (text);
+
+ /* Calculate text dimensions */
+
+ old_height = text->height;
+
+ if (text->text && text->font)
+ text->height = (text->font->ascent + text->font->descent) * text->num_lines;
+ else
+ text->height = 0;
+
+ if (old_height != text->height)
+ e_canvas_item_request_parent_reflow(item);
+}
+
+static void
calc_ellipsis (EText *text)
{
if (text->font)
@@ -635,6 +637,16 @@ calc_line_widths (EText *text)
}
}
+static void
+e_text_free_lines(EText *text)
+{
+ if (text->lines)
+ g_free (text->lines);
+
+ text->lines = NULL;
+ text->num_lines = 0;
+}
+
#define IS_BREAKCHAR(text,c) ((text)->break_characters && strchr ((text)->break_characters, (c)))
/* Splits the text of the text item into lines */
static void
@@ -649,11 +661,8 @@ split_into_lines (EText *text)
char *linestart;
/* Free old array of lines */
+ e_text_free_lines(text);
- if (text->lines)
- g_free (text->lines);
-
- text->lines = NULL;
text->num_lines = 0;
if (!text->text)
@@ -850,6 +859,9 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
GdkColor *pcolor;
gboolean color_changed;
int have_pixel;
+
+ gboolean needs_update = 0;
+ gboolean needs_reflow = 0;
item = GNOME_CANVAS_ITEM (object);
text = E_TEXT (object);
@@ -863,17 +875,21 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
g_free (text->text);
text->text = g_strdup (GTK_VALUE_STRING (*arg));
+ e_text_free_lines(text);
text->needs_split_into_lines = 1;
+ needs_reflow = 1;
break;
case ARG_X:
text->x = GTK_VALUE_DOUBLE (*arg);
text->needs_recalc_bounds = 1;
+ needs_update = 1;
break;
case ARG_Y:
text->y = GTK_VALUE_DOUBLE (*arg);
text->needs_recalc_bounds = 1;
+ needs_update = 1;
break;
case ARG_FONT:
@@ -894,6 +910,7 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
text->needs_split_into_lines = 1;
else
text->needs_calc_line_widths = 1;
+ needs_reflow = 1;
break;
case ARG_FONTSET:
@@ -914,6 +931,7 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
text->needs_split_into_lines = 1;
else
text->needs_calc_line_widths = 1;
+ needs_reflow = 1;
break;
case ARG_FONT_GDK:
@@ -934,16 +952,19 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
text->needs_split_into_lines = 1;
else
text->needs_calc_line_widths = 1;
+ needs_reflow = 1;
break;
case ARG_ANCHOR:
text->anchor = GTK_VALUE_ENUM (*arg);
text->needs_recalc_bounds = 1;
+ needs_update = 1;
break;
case ARG_JUSTIFICATION:
text->justification = GTK_VALUE_ENUM (*arg);
text->needs_redraw = 1;
+ needs_update = 1;
break;
case ARG_CLIP_WIDTH:
@@ -953,11 +974,13 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
text->needs_split_into_lines = 1;
else
text->needs_calc_line_widths = 1;
+ needs_reflow = 1;
break;
case ARG_CLIP_HEIGHT:
text->clip_height = fabs (GTK_VALUE_DOUBLE (*arg));
text->needs_recalc_bounds = 1;
+ needs_reflow = 1;
break;
case ARG_CLIP:
@@ -967,16 +990,19 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
text->needs_split_into_lines = 1;
else
text->needs_calc_line_widths = 1;
+ needs_reflow = 1;
break;
case ARG_X_OFFSET:
text->xofs = GTK_VALUE_DOUBLE (*arg);
text->needs_recalc_bounds = 1;
+ needs_update = 1;
break;
case ARG_Y_OFFSET:
text->yofs = GTK_VALUE_DOUBLE (*arg);
text->needs_recalc_bounds = 1;
+ needs_update = 1;
break;
case ARG_FILL_COLOR:
@@ -989,6 +1015,7 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
0xff);
color_changed = TRUE;
text->needs_redraw = 1;
+ needs_update = 1;
break;
case ARG_FILL_COLOR_GDK:
@@ -1005,27 +1032,32 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
0xff);
color_changed = TRUE;
text->needs_redraw = 1;
+ needs_update = 1;
break;
case ARG_FILL_COLOR_RGBA:
text->rgba = GTK_VALUE_UINT (*arg);
color_changed = TRUE;
text->needs_redraw = 1;
+ needs_update = 1;
break;
case ARG_FILL_STIPPLE:
set_stipple (text, GTK_VALUE_BOXED (*arg), FALSE);
text->needs_redraw = 1;
+ needs_update = 1;
break;
case ARG_EDITABLE:
text->editable = GTK_VALUE_BOOL (*arg);
text->needs_redraw = 1;
+ needs_update = 1;
break;
case ARG_USE_ELLIPSIS:
text->use_ellipsis = GTK_VALUE_BOOL (*arg);
text->needs_calc_line_widths = 1;
+ needs_reflow = 1;
break;
case ARG_ELLIPSIS:
@@ -1035,11 +1067,13 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
text->ellipsis = g_strdup (GTK_VALUE_STRING (*arg));
calc_ellipsis (text);
text->needs_calc_line_widths = 1;
+ needs_reflow = 1;
break;
case ARG_LINE_WRAP:
text->line_wrap = GTK_VALUE_BOOL (*arg);
text->needs_split_into_lines = 1;
+ needs_reflow = 1;
break;
case ARG_BREAK_CHARACTERS:
@@ -1050,11 +1084,23 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
if ( GTK_VALUE_STRING (*arg) )
text->break_characters = g_strdup( GTK_VALUE_STRING (*arg) );
text->needs_split_into_lines = 1;
+ needs_reflow = 1;
break;
case ARG_MAX_LINES:
text->max_lines = GTK_VALUE_INT (*arg);
text->needs_split_into_lines = 1;
+ needs_reflow = 1;
+ break;
+
+ case ARG_WIDTH:
+ text->clip_width = fabs (GTK_VALUE_DOUBLE (*arg));
+ calc_ellipsis (text);
+ if ( text->line_wrap )
+ text->needs_split_into_lines = 1;
+ else
+ text->needs_calc_line_widths = 1;
+ needs_reflow = 1;
break;
default:
@@ -1072,7 +1118,10 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
}
- gnome_canvas_item_request_update (item);
+ if ( needs_reflow )
+ e_canvas_item_request_reflow (item);
+ if ( needs_update )
+ gnome_canvas_item_request_update (item);
}
/* Get_arg handler for the text item */
@@ -1176,6 +1225,14 @@ e_text_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
GTK_VALUE_INT (*arg) = text->max_lines;
break;
+ case ARG_WIDTH:
+ GTK_VALUE_DOUBLE (*arg) = text->clip_width;
+ break;
+
+ case ARG_HEIGHT:
+ GTK_VALUE_DOUBLE (*arg) = text->max_width / text->item.canvas->pixels_per_unit;
+ break;
+
default:
arg->type = GTK_TYPE_INVALID;
break;
@@ -1184,18 +1241,12 @@ e_text_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
/* Update handler for the text item */
static void
-e_text_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags)
+e_text_reflow (GnomeCanvasItem *item, int flags)
{
EText *text;
- double x1, y1, x2, y2;
- ArtDRect i_bbox, c_bbox;
- int i;
text = E_TEXT (item);
- if (parent_class->update)
- (* parent_class->update) (item, affine, clip_path, flags);
-
if ( text->needs_split_into_lines ) {
split_into_lines(text);
text->needs_split_into_lines = 0;
@@ -1204,9 +1255,30 @@ e_text_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int fla
if ( text->needs_calc_line_widths ) {
calc_line_widths(text);
text->needs_calc_line_widths = 0;
- text->needs_recalc_bounds = 1;
+ text->needs_calc_height = 1;
text->needs_redraw = 1;
}
+ if ( text->needs_calc_height ) {
+ calc_height (text);
+ gnome_canvas_item_request_update(item);
+ text->needs_calc_height = 0;
+ }
+}
+
+/* Update handler for the text item */
+static void
+e_text_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags)
+{
+ EText *text;
+ double x1, y1, x2, y2;
+ ArtDRect i_bbox, c_bbox;
+ int i;
+
+ text = E_TEXT (item);
+
+ if (parent_class->update)
+ (* parent_class->update) (item, affine, clip_path, flags);
+
if ( text->needs_recalc_bounds
|| (flags & GNOME_CANVAS_UPDATE_AFFINE)) {
if (!item->canvas->aa) {
@@ -1232,6 +1304,7 @@ e_text_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int fla
art_drect_affine_transform (&c_bbox, &i_bbox, affine);
}
text->needs_recalc_bounds = 0;
+ get_bounds (text, &x1, &y1, &x2, &y2);
}
if ( text->needs_redraw ) {
gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
@@ -1415,6 +1488,10 @@ e_text_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
if (!text->text || !text->font)
return;
+ lines = text->lines;
+ if ( !lines )
+ return;
+
clip_rect = NULL;
if (text->clip) {
rect.x = text->clip_cx - x;
@@ -1426,7 +1503,6 @@ e_text_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
gdk_gc_set_clip_rectangle (fg_gc, &rect);
clip_rect = &rect;
}
- lines = text->lines;
ypos = text->cy + text->font->ascent;
if (text->stipple)
@@ -1583,6 +1659,9 @@ e_text_render (GnomeCanvasItem *item, GnomeCanvasBuf *buf)
gnome_canvas_buf_ensure_buf (buf);
lines = text->lines;
+ if ( !lines )
+ return;
+
start_i.y = get_line_ypos_item_relative (text);
art_affine_scale (affine, item->canvas->pixels_per_unit, item->canvas->pixels_per_unit);
@@ -1660,6 +1739,8 @@ e_text_point (GnomeCanvasItem *item, double x, double y,
best = 1.0e36;
lines = text->lines;
+ if ( lines )
+ return 1;
for (i = 0; i < text->num_lines; i++) {
/* Compute the coordinates of rectangle for the current line,
@@ -1790,12 +1871,15 @@ e_text_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double
static void
_get_xy_from_position (EText *text, gint position, gint *xp, gint *yp)
{
+ if ( !text->lines )
+ return;
if (xp || yp) {
struct line *lines = NULL;
int x, y;
+ double xd, yd;
int j;
- x = get_line_xpos (text, lines);
- y = text->cy;
+ x = get_line_xpos_item_relative (text, lines);
+ y = text->y + text->yofs;
for (j = 0, lines = text->lines; j < text->num_lines; lines++, j++) {
if (lines->text > text->text + position)
break;
@@ -1808,6 +1892,11 @@ _get_xy_from_position (EText *text, gint position, gint *xp, gint *yp)
lines->text,
position - (lines->text - text->text));
x -= text->xofs_edit;
+
+ xd = x; yd = y;
+ gnome_canvas_item_i2w (GNOME_CANVAS_ITEM(text), &xd, &yd);
+ gnome_canvas_w2c (GNOME_CANVAS_ITEM(text)->canvas, xd, yd, &x, &y);
+
if (xp)
*xp = x;
if (yp)
@@ -1819,9 +1908,17 @@ static gint
_get_position_from_xy (EText *text, gint x, gint y)
{
int i, j;
- int ypos = text->cy;
+ int ypos = text->y + text->yofs;
int xpos;
+ double xd, yd;
+
struct line *lines;
+
+ xd = x; yd = y;
+ gnome_canvas_c2w (GNOME_CANVAS_ITEM(text)->canvas, xd, yd, &xd, &yd);
+ gnome_canvas_item_w2i (GNOME_CANVAS_ITEM(text), &xd, &yd);
+ x = xd; y = yd;
+
j = 0;
while (y > ypos) {
ypos += text->font->ascent + text->font->descent;
@@ -1834,9 +1931,13 @@ _get_position_from_xy (EText *text, gint x, gint y)
j = 0;
i = 0;
lines = text->lines;
+
+ if ( !lines )
+ return 0;
+
lines += j;
x += text->xofs_edit;
- xpos = get_line_xpos (text, lines);
+ xpos = get_line_xpos_item_relative (text, lines);
for(i = 0; i < lines->length; i++) {
int charwidth = gdk_text_width(text->font,
lines->text + i,
@@ -1929,6 +2030,9 @@ _do_tooltip (gpointer data)
return FALSE;
lines = text->lines;
+
+ if ( !lines )
+ return FALSE;
cut_off = FALSE;
for ( lines = text->lines, i = 0; i < text->num_lines; lines++, i++ ) {
@@ -2025,7 +2129,7 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event)
text->needs_split_into_lines = 1;
else
text->needs_calc_line_widths = 1;
- gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(text));
+ e_canvas_item_request_reflow (GNOME_CANVAS_ITEM(text));
}
return_val = 0;
break;
@@ -2302,8 +2406,9 @@ e_text_command(ETextEventProcessor *tep, ETextEventProcessorCommand *command, gp
text->selection_end = _get_position(text, command);
}
_delete_selection(text);
+ e_text_free_lines(text);
text->needs_split_into_lines = 1;
- gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(text));
+ e_canvas_item_request_reflow (GNOME_CANVAS_ITEM(text));
if (text->timer) {
g_timer_reset(text->timer);
}
@@ -2314,8 +2419,9 @@ e_text_command(ETextEventProcessor *tep, ETextEventProcessorCommand *command, gp
_delete_selection(text);
}
_insert(text, command->string, command->value);
+ e_text_free_lines(text);
text->needs_split_into_lines = 1;
- gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(text));
+ e_canvas_item_request_reflow (GNOME_CANVAS_ITEM(text));
if (text->timer) {
g_timer_reset(text->timer);
}
@@ -2364,6 +2470,9 @@ e_text_command(ETextEventProcessor *tep, ETextEventProcessorCommand *command, gp
int x;
int i;
struct line *lines = text->lines;
+ if ( !lines )
+ return;
+
for (lines = text->lines, i = 0; i < text->num_lines ; i++, lines ++) {
if (lines->text - text->text > text->selection_end) {
break;
diff --git a/widgets/e-text/e-text.h b/widgets/e-text/e-text.h
index 3e1dcb5f0e..52fb951bc2 100644
--- a/widgets/e-text/e-text.h
+++ b/widgets/e-text/e-text.h
@@ -58,6 +58,8 @@ BEGIN_GNOME_DECLS
* y_offset double RW Vertical offset distance from anchor position
* text_width double R Used to query the width of the rendered text
* text_height double R Used to query the rendered height of the text
+ * width double RW A synonym for clip_width
+ * height double R A synonym for text_height
*
* These are currently ignored in the AA version:
* editable boolean RW Can this item be edited
@@ -122,6 +124,7 @@ struct _EText {
int clip_cx, clip_cy; /* Top-left canvas coordinates for clip rectangle */
int clip_cwidth, clip_cheight; /* Size of clip rectangle in pixels */
int max_width; /* Maximum width of text lines */
+ int width; /* Rendered text width in pixels */
int height; /* Rendered text height in pixels */
guint clip : 1; /* Use clip rectangle? */
@@ -182,10 +185,9 @@ struct _EText {
guint needs_redraw : 1; /* Needs redraw */
guint needs_recalc_bounds : 1; /* Need recalc_bounds */
+ guint needs_calc_height : 1; /* Need calc_height */
guint needs_calc_line_widths : 1; /* Needs calc_line_widths */
guint needs_split_into_lines : 1; /* Needs split_into_lines */
-
- gint idle;
};
struct _ETextClass {
diff --git a/widgets/misc/e-canvas.c b/widgets/misc/e-canvas.c
index 850e438386..68f1b0f9f3 100644
--- a/widgets/misc/e-canvas.c
+++ b/widgets/misc/e-canvas.c
@@ -36,6 +36,13 @@ static int emit_event (GnomeCanvas *canvas, GdkEvent *event);
static GnomeCanvasClass *parent_class = NULL;
+enum {
+ REFLOW,
+ LAST_SIGNAL
+};
+
+static guint e_canvas_signals [LAST_SIGNAL] = { 0, };
+
GtkType
e_canvas_get_type (void)
{
@@ -78,6 +85,18 @@ e_canvas_class_init (ECanvasClass *klass)
widget_class->key_release_event = e_canvas_key;
widget_class->focus_in_event = e_canvas_focus_in;
widget_class->focus_out_event = e_canvas_focus_out;
+
+ klass->reflow = NULL;
+
+ e_canvas_signals [REFLOW] =
+ gtk_signal_new ("reflow",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (ECanvasClass, reflow),
+ gtk_marshal_NONE__INT_INT,
+ GTK_TYPE_NONE, 0);
+
+ gtk_object_class_add_signals (object_class, e_canvas_signals, LAST_SIGNAL);
}
static void
@@ -299,3 +318,101 @@ e_canvas_focus_out (GtkWidget *widget, GdkEventFocus *event)
else
return FALSE;
}
+
+
+static void
+e_canvas_item_invoke_update (GnomeCanvasItem *item, int flags)
+{
+ GnomeCanvasGroup *group;
+ GList *list;
+ GnomeCanvasItem *child;
+ if ( ! gtk_object_get_data(GTK_OBJECT(item), "ECanvasItem::descendent_needs_reflow") )
+ return;
+
+ if ( GNOME_IS_CANVAS_GROUP( item ) ) {
+ group = GNOME_CANVAS_GROUP( item );
+ for ( list = group->item_list; list; list = list->next ) {
+ child = GNOME_CANVAS_ITEM(list->data);
+ e_canvas_item_invoke_update(child, flags);
+ }
+ }
+
+ if ( gtk_object_get_data(GTK_OBJECT(item), "ECanvasItem::needs_reflow") ) {
+ ECanvasItemReflowFunc func = gtk_object_get_data(GTK_OBJECT(item), "ECanvasItem::reflow_callback");
+ if ( func )
+ func(item, flags);
+ }
+
+ gtk_object_set_data(GTK_OBJECT(item), "ECanvasItem::needs_reflow", (gpointer) 0);
+ gtk_object_set_data(GTK_OBJECT(item), "ECanvasItem::descendent_needs_reflow", (gpointer) 0);
+}
+
+static void
+do_update (ECanvas *canvas)
+{
+ e_canvas_item_invoke_update (GNOME_CANVAS(canvas)->root, 0);
+}
+
+/* Idle handler for the canvas. It deals with pending updates and redraws. */
+static gint
+idle_handler (gpointer data)
+{
+ ECanvas *canvas;
+
+ GDK_THREADS_ENTER ();
+
+ canvas = E_CANVAS (data);
+ do_update (canvas);
+
+ /* Reset idle id */
+ canvas->idle_id = 0;
+
+ gtk_signal_emit (GTK_OBJECT (canvas),
+ e_canvas_signals [REFLOW]);
+
+ GDK_THREADS_LEAVE ();
+
+ return FALSE;
+}
+
+/* Convenience function to add an idle handler to a canvas */
+static void
+add_idle (ECanvas *canvas)
+{
+ if (canvas->idle_id != 0)
+ return;
+
+ canvas->idle_id = g_idle_add_full (G_PRIORITY_HIGH_IDLE, idle_handler, (gpointer) canvas, NULL);
+}
+
+static void
+e_canvas_item_descendent_needs_reflow (GnomeCanvasItem *item)
+{
+ if ( gtk_object_get_data(GTK_OBJECT(item), "ECanvasItem::descendent_needs_reflow") )
+ return;
+ gtk_object_set_data(GTK_OBJECT(item), "ECanvasItem::descendent_needs_reflow", (gpointer) 1);
+ if ( item->parent )
+ e_canvas_item_descendent_needs_reflow(item->parent);
+}
+
+void
+e_canvas_item_request_reflow (GnomeCanvasItem *item)
+{
+ gtk_object_set_data(GTK_OBJECT(item), "ECanvasItem::needs_reflow", (gpointer) 1);
+ e_canvas_item_descendent_needs_reflow(item);
+ add_idle(E_CANVAS(item->canvas));
+}
+
+void
+e_canvas_item_request_parent_reflow (GnomeCanvasItem *item)
+{
+ g_return_if_fail(item != NULL);
+ g_return_if_fail(GNOME_IS_CANVAS_ITEM(item));
+ e_canvas_item_request_reflow(item->parent);
+}
+
+void
+e_canvas_item_set_reflow_callback (GnomeCanvasItem *item, ECanvasItemReflowFunc func)
+{
+ gtk_object_set_data(GTK_OBJECT(item), "ECanvasItem::reflow_callback", (gpointer) func);
+}
diff --git a/widgets/misc/e-canvas.h b/widgets/misc/e-canvas.h
index 0ece5ae3b4..e70957b6d7 100644
--- a/widgets/misc/e-canvas.h
+++ b/widgets/misc/e-canvas.h
@@ -38,6 +38,8 @@ extern "C" {
#define E_IS_CANVAS(obj) (GTK_CHECK_TYPE ((obj), E_CANVAS_TYPE))
#define E_IS_CANVAS_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_CANVAS_TYPE))
+typedef void (*ECanvasItemReflowFunc) (GnomeCanvasItem *item,
+ gint flags);
typedef struct _ECanvas ECanvas;
typedef struct _ECanvasClass ECanvasClass;
@@ -46,12 +48,13 @@ struct _ECanvas
{
GnomeCanvas parent;
- /* item specific fields */
+ int idle_id;
};
struct _ECanvasClass
{
GnomeCanvasClass parent_class;
+ void (* reflow) (ECanvas *canvas);
};
@@ -63,6 +66,10 @@ GtkWidget *e_canvas_new (void);
*/
void e_canvas_item_grab_focus (GnomeCanvasItem *item);
+void e_canvas_item_request_reflow (GnomeCanvasItem *item);
+void e_canvas_item_request_parent_reflow (GnomeCanvasItem *item);
+void e_canvas_item_set_reflow_callback (GnomeCanvasItem *item, ECanvasItemReflowFunc func);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/widgets/misc/e-reflow.c b/widgets/misc/e-reflow.c
index 984e972f0c..4af46bd4a4 100644
--- a/widgets/misc/e-reflow.c
+++ b/widgets/misc/e-reflow.c
@@ -24,6 +24,7 @@
#include <math.h>
#include "e-reflow.h"
#include "e-canvas-utils.h"
+#include "e-canvas.h"
#include "e-util.h"
static void e_reflow_init (EReflow *card);
static void e_reflow_class_init (EReflowClass *klass);
@@ -36,10 +37,9 @@ static void e_reflow_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
int x, int y, int width, int height);
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 _update_reflow ( EReflow *reflow );
-static void _resize( GtkObject *object, gpointer data );
-static void _queue_reflow(EReflow *e_reflow);
+static void e_reflow_resize_children (GnomeCanvasItem *item);
#define E_REFLOW_DIVIDER_WIDTH 2
#define E_REFLOW_BORDER_WIDTH 7
@@ -47,13 +47,6 @@ static void _queue_reflow(EReflow *e_reflow);
static GnomeCanvasGroupClass *parent_class = NULL;
-enum {
- E_REFLOW_RESIZE,
- E_REFLOW_LAST_SIGNAL
-};
-
-static guint e_reflow_signals[E_REFLOW_LAST_SIGNAL] = { 0 };
-
/* The arguments we take */
enum {
ARG_0,
@@ -98,16 +91,6 @@ e_reflow_class_init (EReflowClass *klass)
parent_class = gtk_type_class (gnome_canvas_group_get_type ());
- e_reflow_signals[E_REFLOW_RESIZE] =
- gtk_signal_new ("resize",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EReflowClass, resize),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- gtk_object_class_add_signals (object_class, e_reflow_signals, E_REFLOW_LAST_SIGNAL);
-
gtk_object_add_arg_type ("EReflow::minimum_width", GTK_TYPE_DOUBLE,
GTK_ARG_READWRITE, ARG_MINIMUM_WIDTH);
gtk_object_add_arg_type ("EReflow::width", GTK_TYPE_DOUBLE,
@@ -149,6 +132,8 @@ e_reflow_init (EReflow *reflow)
reflow->default_cursor_shown = TRUE;
reflow->arrow_cursor = NULL;
reflow->default_cursor = NULL;
+
+ e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM(reflow), e_reflow_reflow);
}
static void
@@ -163,11 +148,11 @@ e_reflow_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
switch (arg_id){
case ARG_HEIGHT:
e_reflow->height = GTK_VALUE_DOUBLE (*arg);
- _queue_reflow(e_reflow);
+ e_canvas_item_request_reflow(item);
break;
case ARG_MINIMUM_WIDTH:
e_reflow->minimum_width = GTK_VALUE_DOUBLE (*arg);
- _queue_reflow(e_reflow);
+ e_canvas_item_request_reflow(item);
break;
}
}
@@ -214,17 +199,13 @@ e_reflow_realize (GnomeCanvasItem *item)
for(list = e_reflow->items; list; list = g_list_next(list)) {
GnomeCanvasItem *item = GNOME_CANVAS_ITEM(list->data);
- gtk_signal_connect(GTK_OBJECT(item),
- "resize",
- GTK_SIGNAL_FUNC(_resize),
- (gpointer) e_reflow);
gnome_canvas_item_set(item,
"width", (double) e_reflow->column_width,
NULL);
}
- _queue_reflow( e_reflow );
-
+ e_canvas_item_request_reflow(item);
+
adjustment = gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas));
adjustment->step_increment = (e_reflow->column_width + E_REFLOW_FULL_GUTTER) / 2;
adjustment->page_increment = adjustment->page_size - adjustment->step_increment;
@@ -365,11 +346,11 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event)
adjustment->step_increment = (e_reflow->column_width + E_REFLOW_FULL_GUTTER) / 2;
adjustment->page_increment = adjustment->page_size - adjustment->step_increment;
gtk_adjustment_changed(adjustment);
- _queue_reflow(e_reflow);
- } else {
- e_reflow->need_column_resize = TRUE;
- gnome_canvas_item_request_update(item);
+ e_reflow_resize_children(item);
+ e_canvas_item_request_reflow(item);
}
+ e_reflow->need_column_resize = TRUE;
+ gnome_canvas_item_request_update(item);
gnome_canvas_item_ungrab (item, button->time);
return TRUE;
}
@@ -452,14 +433,10 @@ e_reflow_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 ) {
- gtk_signal_connect(GTK_OBJECT(item),
- "resize",
- GTK_SIGNAL_FUNC(_resize),
- (gpointer) e_reflow);
gnome_canvas_item_set(item,
"width", (double) e_reflow->column_width,
NULL);
- _queue_reflow(e_reflow);
+ e_canvas_item_request_reflow(item);
}
}
@@ -621,6 +598,21 @@ e_reflow_update (GnomeCanvasItem *item, double affine[6], ArtSVP *clip_path, gin
}
}
+static void
+e_reflow_resize_children (GnomeCanvasItem *item)
+{
+ GList *list;
+ EReflow *e_reflow;
+
+ e_reflow = E_REFLOW (item);
+ for ( list = e_reflow->items; list; list = list->next ) {
+ GnomeCanvasItem *child = GNOME_CANVAS_ITEM(list->data);
+ gnome_canvas_item_set(child,
+ "width", (double) e_reflow->column_width,
+ NULL);
+ }
+}
+
static double
e_reflow_point (GnomeCanvasItem *item,
double x, double y, int cx, int cy,
@@ -696,8 +688,9 @@ _reflow( EReflow *e_reflow )
}
static void
-_update_reflow( EReflow *e_reflow )
+e_reflow_reflow( GnomeCanvasItem *item, int flags )
{
+ EReflow *e_reflow = E_REFLOW(item);
if ( GTK_OBJECT_FLAGS( e_reflow ) & GNOME_CANVAS_ITEM_REALIZED ) {
gdouble old_width;
@@ -719,9 +712,6 @@ _update_reflow( EReflow *e_reflow )
running_height = E_REFLOW_BORDER_WIDTH;
list = e_reflow->items;
- gtk_object_set (GTK_OBJECT(list->data),
- "width", e_reflow->column_width,
- NULL);
gtk_object_get (GTK_OBJECT(list->data),
"height", &item_height,
NULL);
@@ -733,9 +723,6 @@ _update_reflow( EReflow *e_reflow )
list = g_list_next(list);
for( ; list; list = g_list_next(list)) {
- gtk_object_set (GTK_OBJECT(list->data),
- "width", e_reflow->column_width,
- NULL);
gtk_object_get (GTK_OBJECT(list->data),
"height", &item_height,
NULL);
@@ -757,31 +744,6 @@ _update_reflow( EReflow *e_reflow )
if ( e_reflow->width < e_reflow->minimum_width )
e_reflow->width = e_reflow->minimum_width;
if (old_width != e_reflow->width)
- gtk_signal_emit_by_name (GTK_OBJECT (e_reflow), "resize");
+ e_canvas_item_request_parent_reflow(item);
}
}
-
-
-static gboolean
-_idle_reflow(gpointer data)
-{
- EReflow *e_reflow = E_REFLOW(data);
- _update_reflow(e_reflow);
- e_reflow->need_height_update = TRUE;
- gnome_canvas_item_request_update(GNOME_CANVAS_ITEM(e_reflow));
- e_reflow->idle = 0;
- return FALSE;
-}
-
-static void
-_queue_reflow(EReflow *e_reflow)
-{
- if (e_reflow->idle == 0)
- e_reflow->idle = g_idle_add(_idle_reflow, e_reflow);
-}
-
-static void
-_resize( GtkObject *object, gpointer data )
-{
- _queue_reflow(E_REFLOW(data));
-}
diff --git a/widgets/text/e-text.c b/widgets/text/e-text.c
index d9448fe783..ca41dc1d96 100644
--- a/widgets/text/e-text.c
+++ b/widgets/text/e-text.c
@@ -25,6 +25,7 @@
#include <libart_lgpl/art_rgb.h>
#include <libart_lgpl/art_rgb_bitmap_affine.h>
#include <gtk/gtkinvisible.h>
+#include "e-util/e-canvas.h"
#include "e-text-event-processor-emacs-like.h"
@@ -75,7 +76,9 @@ enum {
ARG_ELLIPSIS,
ARG_LINE_WRAP,
ARG_BREAK_CHARACTERS,
- ARG_MAX_LINES
+ ARG_MAX_LINES,
+ ARG_WIDTH,
+ ARG_HEIGHT
};
@@ -95,6 +98,7 @@ static void e_text_destroy (GtkObject *object);
static void e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);
static void e_text_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+static void e_text_reflow (GnomeCanvasItem *item, int flags);
static void e_text_update (GnomeCanvasItem *item, double *affine,
ArtSVP *clip_path, int flags);
static void e_text_realize (GnomeCanvasItem *item);
@@ -250,6 +254,10 @@ e_text_class_init (ETextClass *klass)
GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_BREAK_CHARACTERS);
gtk_object_add_arg_type ("EText::max_lines",
GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_MAX_LINES);
+ gtk_object_add_arg_type ("EText::width",
+ GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_WIDTH);
+ gtk_object_add_arg_type ("EText::height",
+ GTK_TYPE_DOUBLE, GTK_ARG_READABLE, ARG_HEIGHT);
if (!clipboard_atom)
clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
@@ -325,6 +333,8 @@ e_text_init (EText *text)
text->line_wrap = FALSE;
text->break_characters = NULL;
text->max_lines = -1;
+
+ e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM(text), e_text_reflow);
}
/* Destroy handler for the text item */
@@ -460,43 +470,14 @@ get_bounds_item_relative (EText *text, double *px1, double *py1, double *px2, do
}
}
-
-static gboolean
-idle_resize(gpointer data)
-{
- EText *text = E_TEXT(data);
- gtk_signal_emit_by_name (GTK_OBJECT (text), "resize");
- return FALSE;
-}
-
-static void
-queue_resize_signal(EText *text)
-{
- if (text->idle == 0)
- text->idle = g_idle_add(idle_resize, text);
-}
-
static void
get_bounds (EText *text, double *px1, double *py1, double *px2, double *py2)
{
GnomeCanvasItem *item;
double wx, wy;
- int old_height;
item = GNOME_CANVAS_ITEM (text);
- /* Calculate text dimensions */
-
- old_height = text->height;
-
- if (text->text && text->font)
- text->height = (text->font->ascent + text->font->descent) * text->num_lines;
- else
- text->height = 0;
-
- if (old_height != text->height)
- queue_resize_signal(text);
-
/* Get canvas pixel coordinates for text position */
wx = text->x;
@@ -573,6 +554,27 @@ get_bounds (EText *text, double *px1, double *py1, double *px2, double *py2)
}
static void
+calc_height (EText *text)
+{
+ GnomeCanvasItem *item;
+ int old_height;
+
+ item = GNOME_CANVAS_ITEM (text);
+
+ /* Calculate text dimensions */
+
+ old_height = text->height;
+
+ if (text->text && text->font)
+ text->height = (text->font->ascent + text->font->descent) * text->num_lines;
+ else
+ text->height = 0;
+
+ if (old_height != text->height)
+ e_canvas_item_request_parent_reflow(item);
+}
+
+static void
calc_ellipsis (EText *text)
{
if (text->font)
@@ -635,6 +637,16 @@ calc_line_widths (EText *text)
}
}
+static void
+e_text_free_lines(EText *text)
+{
+ if (text->lines)
+ g_free (text->lines);
+
+ text->lines = NULL;
+ text->num_lines = 0;
+}
+
#define IS_BREAKCHAR(text,c) ((text)->break_characters && strchr ((text)->break_characters, (c)))
/* Splits the text of the text item into lines */
static void
@@ -649,11 +661,8 @@ split_into_lines (EText *text)
char *linestart;
/* Free old array of lines */
+ e_text_free_lines(text);
- if (text->lines)
- g_free (text->lines);
-
- text->lines = NULL;
text->num_lines = 0;
if (!text->text)
@@ -850,6 +859,9 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
GdkColor *pcolor;
gboolean color_changed;
int have_pixel;
+
+ gboolean needs_update = 0;
+ gboolean needs_reflow = 0;
item = GNOME_CANVAS_ITEM (object);
text = E_TEXT (object);
@@ -863,17 +875,21 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
g_free (text->text);
text->text = g_strdup (GTK_VALUE_STRING (*arg));
+ e_text_free_lines(text);
text->needs_split_into_lines = 1;
+ needs_reflow = 1;
break;
case ARG_X:
text->x = GTK_VALUE_DOUBLE (*arg);
text->needs_recalc_bounds = 1;
+ needs_update = 1;
break;
case ARG_Y:
text->y = GTK_VALUE_DOUBLE (*arg);
text->needs_recalc_bounds = 1;
+ needs_update = 1;
break;
case ARG_FONT:
@@ -894,6 +910,7 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
text->needs_split_into_lines = 1;
else
text->needs_calc_line_widths = 1;
+ needs_reflow = 1;
break;
case ARG_FONTSET:
@@ -914,6 +931,7 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
text->needs_split_into_lines = 1;
else
text->needs_calc_line_widths = 1;
+ needs_reflow = 1;
break;
case ARG_FONT_GDK:
@@ -934,16 +952,19 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
text->needs_split_into_lines = 1;
else
text->needs_calc_line_widths = 1;
+ needs_reflow = 1;
break;
case ARG_ANCHOR:
text->anchor = GTK_VALUE_ENUM (*arg);
text->needs_recalc_bounds = 1;
+ needs_update = 1;
break;
case ARG_JUSTIFICATION:
text->justification = GTK_VALUE_ENUM (*arg);
text->needs_redraw = 1;
+ needs_update = 1;
break;
case ARG_CLIP_WIDTH:
@@ -953,11 +974,13 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
text->needs_split_into_lines = 1;
else
text->needs_calc_line_widths = 1;
+ needs_reflow = 1;
break;
case ARG_CLIP_HEIGHT:
text->clip_height = fabs (GTK_VALUE_DOUBLE (*arg));
text->needs_recalc_bounds = 1;
+ needs_reflow = 1;
break;
case ARG_CLIP:
@@ -967,16 +990,19 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
text->needs_split_into_lines = 1;
else
text->needs_calc_line_widths = 1;
+ needs_reflow = 1;
break;
case ARG_X_OFFSET:
text->xofs = GTK_VALUE_DOUBLE (*arg);
text->needs_recalc_bounds = 1;
+ needs_update = 1;
break;
case ARG_Y_OFFSET:
text->yofs = GTK_VALUE_DOUBLE (*arg);
text->needs_recalc_bounds = 1;
+ needs_update = 1;
break;
case ARG_FILL_COLOR:
@@ -989,6 +1015,7 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
0xff);
color_changed = TRUE;
text->needs_redraw = 1;
+ needs_update = 1;
break;
case ARG_FILL_COLOR_GDK:
@@ -1005,27 +1032,32 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
0xff);
color_changed = TRUE;
text->needs_redraw = 1;
+ needs_update = 1;
break;
case ARG_FILL_COLOR_RGBA:
text->rgba = GTK_VALUE_UINT (*arg);
color_changed = TRUE;
text->needs_redraw = 1;
+ needs_update = 1;
break;
case ARG_FILL_STIPPLE:
set_stipple (text, GTK_VALUE_BOXED (*arg), FALSE);
text->needs_redraw = 1;
+ needs_update = 1;
break;
case ARG_EDITABLE:
text->editable = GTK_VALUE_BOOL (*arg);
text->needs_redraw = 1;
+ needs_update = 1;
break;
case ARG_USE_ELLIPSIS:
text->use_ellipsis = GTK_VALUE_BOOL (*arg);
text->needs_calc_line_widths = 1;
+ needs_reflow = 1;
break;
case ARG_ELLIPSIS:
@@ -1035,11 +1067,13 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
text->ellipsis = g_strdup (GTK_VALUE_STRING (*arg));
calc_ellipsis (text);
text->needs_calc_line_widths = 1;
+ needs_reflow = 1;
break;
case ARG_LINE_WRAP:
text->line_wrap = GTK_VALUE_BOOL (*arg);
text->needs_split_into_lines = 1;
+ needs_reflow = 1;
break;
case ARG_BREAK_CHARACTERS:
@@ -1050,11 +1084,23 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
if ( GTK_VALUE_STRING (*arg) )
text->break_characters = g_strdup( GTK_VALUE_STRING (*arg) );
text->needs_split_into_lines = 1;
+ needs_reflow = 1;
break;
case ARG_MAX_LINES:
text->max_lines = GTK_VALUE_INT (*arg);
text->needs_split_into_lines = 1;
+ needs_reflow = 1;
+ break;
+
+ case ARG_WIDTH:
+ text->clip_width = fabs (GTK_VALUE_DOUBLE (*arg));
+ calc_ellipsis (text);
+ if ( text->line_wrap )
+ text->needs_split_into_lines = 1;
+ else
+ text->needs_calc_line_widths = 1;
+ needs_reflow = 1;
break;
default:
@@ -1072,7 +1118,10 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
}
- gnome_canvas_item_request_update (item);
+ if ( needs_reflow )
+ e_canvas_item_request_reflow (item);
+ if ( needs_update )
+ gnome_canvas_item_request_update (item);
}
/* Get_arg handler for the text item */
@@ -1176,6 +1225,14 @@ e_text_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
GTK_VALUE_INT (*arg) = text->max_lines;
break;
+ case ARG_WIDTH:
+ GTK_VALUE_DOUBLE (*arg) = text->clip_width;
+ break;
+
+ case ARG_HEIGHT:
+ GTK_VALUE_DOUBLE (*arg) = text->max_width / text->item.canvas->pixels_per_unit;
+ break;
+
default:
arg->type = GTK_TYPE_INVALID;
break;
@@ -1184,18 +1241,12 @@ e_text_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
/* Update handler for the text item */
static void
-e_text_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags)
+e_text_reflow (GnomeCanvasItem *item, int flags)
{
EText *text;
- double x1, y1, x2, y2;
- ArtDRect i_bbox, c_bbox;
- int i;
text = E_TEXT (item);
- if (parent_class->update)
- (* parent_class->update) (item, affine, clip_path, flags);
-
if ( text->needs_split_into_lines ) {
split_into_lines(text);
text->needs_split_into_lines = 0;
@@ -1204,9 +1255,30 @@ e_text_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int fla
if ( text->needs_calc_line_widths ) {
calc_line_widths(text);
text->needs_calc_line_widths = 0;
- text->needs_recalc_bounds = 1;
+ text->needs_calc_height = 1;
text->needs_redraw = 1;
}
+ if ( text->needs_calc_height ) {
+ calc_height (text);
+ gnome_canvas_item_request_update(item);
+ text->needs_calc_height = 0;
+ }
+}
+
+/* Update handler for the text item */
+static void
+e_text_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags)
+{
+ EText *text;
+ double x1, y1, x2, y2;
+ ArtDRect i_bbox, c_bbox;
+ int i;
+
+ text = E_TEXT (item);
+
+ if (parent_class->update)
+ (* parent_class->update) (item, affine, clip_path, flags);
+
if ( text->needs_recalc_bounds
|| (flags & GNOME_CANVAS_UPDATE_AFFINE)) {
if (!item->canvas->aa) {
@@ -1232,6 +1304,7 @@ e_text_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int fla
art_drect_affine_transform (&c_bbox, &i_bbox, affine);
}
text->needs_recalc_bounds = 0;
+ get_bounds (text, &x1, &y1, &x2, &y2);
}
if ( text->needs_redraw ) {
gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
@@ -1415,6 +1488,10 @@ e_text_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
if (!text->text || !text->font)
return;
+ lines = text->lines;
+ if ( !lines )
+ return;
+
clip_rect = NULL;
if (text->clip) {
rect.x = text->clip_cx - x;
@@ -1426,7 +1503,6 @@ e_text_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
gdk_gc_set_clip_rectangle (fg_gc, &rect);
clip_rect = &rect;
}
- lines = text->lines;
ypos = text->cy + text->font->ascent;
if (text->stipple)
@@ -1583,6 +1659,9 @@ e_text_render (GnomeCanvasItem *item, GnomeCanvasBuf *buf)
gnome_canvas_buf_ensure_buf (buf);
lines = text->lines;
+ if ( !lines )
+ return;
+
start_i.y = get_line_ypos_item_relative (text);
art_affine_scale (affine, item->canvas->pixels_per_unit, item->canvas->pixels_per_unit);
@@ -1660,6 +1739,8 @@ e_text_point (GnomeCanvasItem *item, double x, double y,
best = 1.0e36;
lines = text->lines;
+ if ( lines )
+ return 1;
for (i = 0; i < text->num_lines; i++) {
/* Compute the coordinates of rectangle for the current line,
@@ -1790,12 +1871,15 @@ e_text_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double
static void
_get_xy_from_position (EText *text, gint position, gint *xp, gint *yp)
{
+ if ( !text->lines )
+ return;
if (xp || yp) {
struct line *lines = NULL;
int x, y;
+ double xd, yd;
int j;
- x = get_line_xpos (text, lines);
- y = text->cy;
+ x = get_line_xpos_item_relative (text, lines);
+ y = text->y + text->yofs;
for (j = 0, lines = text->lines; j < text->num_lines; lines++, j++) {
if (lines->text > text->text + position)
break;
@@ -1808,6 +1892,11 @@ _get_xy_from_position (EText *text, gint position, gint *xp, gint *yp)
lines->text,
position - (lines->text - text->text));
x -= text->xofs_edit;
+
+ xd = x; yd = y;
+ gnome_canvas_item_i2w (GNOME_CANVAS_ITEM(text), &xd, &yd);
+ gnome_canvas_w2c (GNOME_CANVAS_ITEM(text)->canvas, xd, yd, &x, &y);
+
if (xp)
*xp = x;
if (yp)
@@ -1819,9 +1908,17 @@ static gint
_get_position_from_xy (EText *text, gint x, gint y)
{
int i, j;
- int ypos = text->cy;
+ int ypos = text->y + text->yofs;
int xpos;
+ double xd, yd;
+
struct line *lines;
+
+ xd = x; yd = y;
+ gnome_canvas_c2w (GNOME_CANVAS_ITEM(text)->canvas, xd, yd, &xd, &yd);
+ gnome_canvas_item_w2i (GNOME_CANVAS_ITEM(text), &xd, &yd);
+ x = xd; y = yd;
+
j = 0;
while (y > ypos) {
ypos += text->font->ascent + text->font->descent;
@@ -1834,9 +1931,13 @@ _get_position_from_xy (EText *text, gint x, gint y)
j = 0;
i = 0;
lines = text->lines;
+
+ if ( !lines )
+ return 0;
+
lines += j;
x += text->xofs_edit;
- xpos = get_line_xpos (text, lines);
+ xpos = get_line_xpos_item_relative (text, lines);
for(i = 0; i < lines->length; i++) {
int charwidth = gdk_text_width(text->font,
lines->text + i,
@@ -1929,6 +2030,9 @@ _do_tooltip (gpointer data)
return FALSE;
lines = text->lines;
+
+ if ( !lines )
+ return FALSE;
cut_off = FALSE;
for ( lines = text->lines, i = 0; i < text->num_lines; lines++, i++ ) {
@@ -2025,7 +2129,7 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event)
text->needs_split_into_lines = 1;
else
text->needs_calc_line_widths = 1;
- gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(text));
+ e_canvas_item_request_reflow (GNOME_CANVAS_ITEM(text));
}
return_val = 0;
break;
@@ -2302,8 +2406,9 @@ e_text_command(ETextEventProcessor *tep, ETextEventProcessorCommand *command, gp
text->selection_end = _get_position(text, command);
}
_delete_selection(text);
+ e_text_free_lines(text);
text->needs_split_into_lines = 1;
- gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(text));
+ e_canvas_item_request_reflow (GNOME_CANVAS_ITEM(text));
if (text->timer) {
g_timer_reset(text->timer);
}
@@ -2314,8 +2419,9 @@ e_text_command(ETextEventProcessor *tep, ETextEventProcessorCommand *command, gp
_delete_selection(text);
}
_insert(text, command->string, command->value);
+ e_text_free_lines(text);
text->needs_split_into_lines = 1;
- gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(text));
+ e_canvas_item_request_reflow (GNOME_CANVAS_ITEM(text));
if (text->timer) {
g_timer_reset(text->timer);
}
@@ -2364,6 +2470,9 @@ e_text_command(ETextEventProcessor *tep, ETextEventProcessorCommand *command, gp
int x;
int i;
struct line *lines = text->lines;
+ if ( !lines )
+ return;
+
for (lines = text->lines, i = 0; i < text->num_lines ; i++, lines ++) {
if (lines->text - text->text > text->selection_end) {
break;
diff --git a/widgets/text/e-text.h b/widgets/text/e-text.h
index 3e1dcb5f0e..52fb951bc2 100644
--- a/widgets/text/e-text.h
+++ b/widgets/text/e-text.h
@@ -58,6 +58,8 @@ BEGIN_GNOME_DECLS
* y_offset double RW Vertical offset distance from anchor position
* text_width double R Used to query the width of the rendered text
* text_height double R Used to query the rendered height of the text
+ * width double RW A synonym for clip_width
+ * height double R A synonym for text_height
*
* These are currently ignored in the AA version:
* editable boolean RW Can this item be edited
@@ -122,6 +124,7 @@ struct _EText {
int clip_cx, clip_cy; /* Top-left canvas coordinates for clip rectangle */
int clip_cwidth, clip_cheight; /* Size of clip rectangle in pixels */
int max_width; /* Maximum width of text lines */
+ int width; /* Rendered text width in pixels */
int height; /* Rendered text height in pixels */
guint clip : 1; /* Use clip rectangle? */
@@ -182,10 +185,9 @@ struct _EText {
guint needs_redraw : 1; /* Needs redraw */
guint needs_recalc_bounds : 1; /* Need recalc_bounds */
+ guint needs_calc_height : 1; /* Need calc_height */
guint needs_calc_line_widths : 1; /* Needs calc_line_widths */
guint needs_split_into_lines : 1; /* Needs split_into_lines */
-
- gint idle;
};
struct _ETextClass {