[goocanvas] Fixed text alignment bug in tables.
- From: Damon Chaplin <damon src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goocanvas] Fixed text alignment bug in tables.
- Date: Wed, 14 Sep 2011 09:09:31 +0000 (UTC)
commit 12268ad65f2d5b408492323026717beafebaec08
Author: Damon Chaplin <damon gnome org>
Date: Wed Sep 14 10:07:45 2011 +0100
Fixed text alignment bug in tables.
2011-09-14 Damon Chaplin <damon gnome org>
* src/goocanvasitem.h: added get_requested_area_for_width() method.
get_requested_height() didn't work for aligned text items as the
position of the item moves horizontally due to the allocated width,
and this wasn't being taken into account in the layout code.
* src/goocanvastable.c (goo_canvas_table_update_requested_heights): use
get_requested_area_for_width() if available.
* src/goocanvastext.c (goo_canvas_text_get_requested_area_for_width):
use this instead of get_requested_height() so aligned text should work.
* demo/mv-demo-table.c:
* demo/demo-table.c: added tests for the above.
.gitignore | 2 +
ChangeLog | 16 ++++
demo/demo-table.c | 187 ++++++++++++++++++++++++++++++++++++--------
demo/mv-demo-table.c | 181 ++++++++++++++++++++++++++++++++++++--------
src/goocanvasitem.c | 34 ++++++++
src/goocanvasitem.h | 19 ++++-
src/goocanvasitemsimple.c | 6 ++
src/goocanvastable.c | 42 +++++++++-
src/goocanvastext.c | 80 +++++++++++++------
9 files changed, 469 insertions(+), 98 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 7096234..592f385 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,8 @@
*.loT
*.la
*.gmo
+*.orig
+*.rej
*~
Makefile
diff --git a/ChangeLog b/ChangeLog
index 6dbc360..2d88c06 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2011-09-14 Damon Chaplin <damon gnome org>
+
+ * src/goocanvasitem.h: added get_requested_area_for_width() method.
+ get_requested_height() didn't work for aligned text items as the
+ position of the item moves horizontally due to the allocated width,
+ and this wasn't being taken into account in the layout code.
+
+ * src/goocanvastable.c (goo_canvas_table_update_requested_heights): use
+ get_requested_area_for_width() if available.
+
+ * src/goocanvastext.c (goo_canvas_text_get_requested_area_for_width):
+ use this instead of get_requested_height() so aligned text should work.
+
+ * demo/mv-demo-table.c:
+ * demo/demo-table.c: added tests for the above.
+
2011-08-17 Damon Chaplin <damon gnome org>
* src/goocanvastext.c (goo_canvas_text_get_requested_height): when
diff --git a/demo/demo-table.c b/demo/demo-table.c
index 35ede48..94bd244 100644
--- a/demo/demo-table.c
+++ b/demo/demo-table.c
@@ -5,7 +5,9 @@
#define DEMO_RECT_ITEM 0
#define DEMO_TEXT_ITEM 1
-#define DEMO_WIDGET_ITEM 2
+#define DEMO_TEXT_ITEM_2 2
+#define DEMO_TEXT_ITEM_3 3
+#define DEMO_WIDGET_ITEM 4
static gboolean
@@ -31,7 +33,11 @@ create_demo_item (GooCanvasItem *table,
gint column,
gint rows,
gint columns,
- gchar *text)
+ gchar *text,
+ gdouble width,
+ gdouble xalign,
+ gdouble yalign,
+ PangoAlignment text_alignment)
{
GooCanvasItem *item = NULL;
GtkWidget *widget;
@@ -46,7 +52,11 @@ create_demo_item (GooCanvasItem *table,
NULL);
break;
case DEMO_TEXT_ITEM:
- item = goo_canvas_text_new (table, text, 0, 0, -1, GOO_CANVAS_ANCHOR_NW, NULL);
+ case DEMO_TEXT_ITEM_2:
+ case DEMO_TEXT_ITEM_3:
+ item = goo_canvas_text_new (table, text, 0, 0, width, GOO_CANVAS_ANCHOR_NW,
+ "alignment", text_alignment,
+ NULL);
break;
case DEMO_WIDGET_ITEM:
widget = gtk_button_new_with_label (text);
@@ -64,17 +74,23 @@ create_demo_item (GooCanvasItem *table,
g_value_set_uint (&value, columns);
goo_canvas_item_set_child_property (table, item, "columns", &value);
+ goo_canvas_item_set_child_properties (table, item,
+ "x-expand", TRUE,
+ "y-expand", TRUE,
+ "x-align", xalign,
+ "y-align", yalign,
+ NULL);
+
/* Test the get function. */
goo_canvas_item_get_child_property (table, item, "row", &value);
new_row = g_value_get_uint (&value);
if (new_row != row)
g_warning ("Got bad row setting: %i should be: %i\n", new_row, row);
-#if 1
+ /* If we make the item's fill the cells then alignment can't be used. */
+#if 0
goo_canvas_item_set_child_properties (table, item,
- "x-expand", TRUE,
"x-fill", TRUE,
- "y-expand", TRUE,
"y-fill", TRUE,
NULL);
#endif
@@ -94,7 +110,8 @@ create_table (GooCanvasItem *parent,
gdouble y,
gdouble rotation,
gdouble scale,
- gint demo_item_type)
+ gint demo_item_type,
+ gboolean show_grid_lines)
{
GooCanvasItem *table;
@@ -103,6 +120,13 @@ create_table (GooCanvasItem *parent,
"row-spacing", 4.0,
"column-spacing", 4.0,
NULL);
+
+ if (show_grid_lines)
+ g_object_set (table,
+ "horz-grid-line-width", 1.0f,
+ "vert-grid-line-width", 1.0f,
+ NULL);
+
goo_canvas_item_translate (table, x, y);
#if 1
goo_canvas_item_rotate (table, rotation, 0, 0);
@@ -128,27 +152,110 @@ create_table (GooCanvasItem *parent,
if (embedding_level)
{
gint level = embedding_level - 1;
- create_table (table, 0, 0, level, 50, 50, 0, 0.7, demo_item_type);
- create_table (table, 0, 1, level, 50, 50, 45, 1.0, demo_item_type);
- create_table (table, 0, 2, level, 50, 50, 90, 1.0, demo_item_type);
- create_table (table, 1, 0, level, 50, 50, 135, 1.0, demo_item_type);
- create_table (table, 1, 1, level, 50, 50, 180, 1.5, demo_item_type);
- create_table (table, 1, 2, level, 50, 50, 225, 1.0, demo_item_type);
- create_table (table, 2, 0, level, 50, 50, 270, 1.0, demo_item_type);
- create_table (table, 2, 1, level, 50, 50, 315, 1.0, demo_item_type);
- create_table (table, 2, 2, level, 50, 50, 360, 2.0, demo_item_type);
+ create_table (table, 0, 0, level, 50, 50, 0, 0.7, demo_item_type,
+ show_grid_lines);
+ create_table (table, 0, 1, level, 50, 50, 45, 1.0, demo_item_type,
+ show_grid_lines);
+ create_table (table, 0, 2, level, 50, 50, 90, 1.0, demo_item_type,
+ show_grid_lines);
+ create_table (table, 1, 0, level, 50, 50, 135, 1.0, demo_item_type,
+ show_grid_lines);
+ create_table (table, 1, 1, level, 50, 50, 180, 1.5, demo_item_type,
+ show_grid_lines);
+ create_table (table, 1, 2, level, 50, 50, 225, 1.0, demo_item_type,
+ show_grid_lines);
+ create_table (table, 2, 0, level, 50, 50, 270, 1.0, demo_item_type,
+ show_grid_lines);
+ create_table (table, 2, 1, level, 50, 50, 315, 1.0, demo_item_type,
+ show_grid_lines);
+ create_table (table, 2, 2, level, 50, 50, 360, 2.0, demo_item_type,
+ show_grid_lines);
+ }
+ else if (demo_item_type == DEMO_TEXT_ITEM_2)
+ {
+ create_demo_item (table, demo_item_type, 0, 0, 1, 1,
+ "(0.0,0.0)\nleft\naligned",
+ -1, 0, 0, PANGO_ALIGN_LEFT);
+ create_demo_item (table, demo_item_type, 0, 1, 1, 1,
+ "(0.5,0.0)\ncenter\naligned",
+ -1, 0.5, 0, PANGO_ALIGN_CENTER);
+ create_demo_item (table, demo_item_type, 0, 2, 1, 1,
+ "(1.0,0.0)\nright\naligned",
+ -1, 1, 0, PANGO_ALIGN_RIGHT);
+
+ /* The layout width shouldn't really make any difference in this test. */
+ create_demo_item (table, demo_item_type, 1, 0, 1, 1,
+ "(0.5,0.5)\ncenter\naligned",
+ 50, 0.5, 0.5, PANGO_ALIGN_CENTER);
+ create_demo_item (table, demo_item_type, 1, 1, 1, 1,
+ "(0.0,1.0)\nright\naligned",
+ 100, 0, 1.0, PANGO_ALIGN_RIGHT);
+ create_demo_item (table, demo_item_type, 1, 2, 1, 1,
+ "(0.0,0.5)\nleft\naligned",
+ 200, 0, 0.5, PANGO_ALIGN_LEFT);
+
+ create_demo_item (table, demo_item_type, 2, 0, 1, 1,
+ "(1.0,1.0)\ncenter\naligned",
+ -1, 1, 1, PANGO_ALIGN_CENTER);
+ create_demo_item (table, demo_item_type, 2, 1, 1, 1,
+ "(1,0.5)\nright\naligned",
+ -1, 1.0, 0.5, PANGO_ALIGN_RIGHT);
+ create_demo_item (table, demo_item_type, 2, 2, 1, 1,
+ "(0.0,0.0)\nleft\naligned",
+ -1, 0, 0, PANGO_ALIGN_LEFT);
+ }
+ else if (demo_item_type == DEMO_TEXT_ITEM_3)
+ {
+ create_demo_item (table, demo_item_type, 0, 0, 1, 1,
+ "width 50 align 0.0, 0.0 text left aligned",
+ 50, 0, 0, PANGO_ALIGN_LEFT);
+ create_demo_item (table, demo_item_type, 0, 1, 1, 1,
+ "width 100 align 0.5, 0.0 text center aligned",
+ 100, 0.5, 0, PANGO_ALIGN_CENTER);
+ create_demo_item (table, demo_item_type, 0, 2, 1, 1,
+ "width 150 align 1.0, 0.0 text right aligned",
+ 150, 1, 0, PANGO_ALIGN_RIGHT);
+
+ create_demo_item (table, demo_item_type, 1, 0, 1, 1,
+ "width 50 align 0.5, 0.5 text center aligned",
+ 50, 0.5, 0.5, PANGO_ALIGN_CENTER);
+ create_demo_item (table, demo_item_type, 1, 1, 1, 1,
+ "width 100 align 0.0, 1.0 text right aligned",
+ 100, 0, 1.0, PANGO_ALIGN_RIGHT);
+ create_demo_item (table, demo_item_type, 1, 2, 1, 1,
+ "width 200 align 0.0, 0.5 text left aligned",
+ 200, 0, 0.5, PANGO_ALIGN_LEFT);
+
+ create_demo_item (table, demo_item_type, 2, 0, 1, 1,
+ "width 50 align 1.0, 1.0 text center aligned",
+ 50, 1, 1, PANGO_ALIGN_CENTER);
+ create_demo_item (table, demo_item_type, 2, 1, 1, 1,
+ "width 100 align 1, 0.5 text right aligned",
+ 100, 1.0, 0.5, PANGO_ALIGN_RIGHT);
+ create_demo_item (table, demo_item_type, 2, 2, 1, 1,
+ "width 50 align 0.0, 0.0 text left aligned",
+ 50, 0, 0, PANGO_ALIGN_LEFT);
}
else
{
- create_demo_item (table, demo_item_type, 0, 0, 1, 1, "(0,0)");
- create_demo_item (table, demo_item_type, 0, 1, 1, 1, "(1,0)");
- create_demo_item (table, demo_item_type, 0, 2, 1, 1, "(2,0)");
- create_demo_item (table, demo_item_type, 1, 0, 1, 1, "(0,1)");
- create_demo_item (table, demo_item_type, 1, 1, 1, 1, "(1,1)");
- create_demo_item (table, demo_item_type, 1, 2, 1, 1, "(2,1)");
- create_demo_item (table, demo_item_type, 2, 0, 1, 1, "(0,2)");
- create_demo_item (table, demo_item_type, 2, 1, 1, 1, "(1,2)");
- create_demo_item (table, demo_item_type, 2, 2, 1, 1, "(2,2)");
+ create_demo_item (table, demo_item_type, 0, 0, 1, 1, "(0,0)",
+ -1, 0, 0.5, PANGO_ALIGN_LEFT);
+ create_demo_item (table, demo_item_type, 0, 1, 1, 1, "(1,0)",
+ -1, 0, 0.5, PANGO_ALIGN_LEFT);
+ create_demo_item (table, demo_item_type, 0, 2, 1, 1, "(2,0)",
+ -1, 0, 0.5, PANGO_ALIGN_LEFT);
+ create_demo_item (table, demo_item_type, 1, 0, 1, 1, "(0,1)",
+ -1, 0, 0.5, PANGO_ALIGN_LEFT);
+ create_demo_item (table, demo_item_type, 1, 1, 1, 1, "(1,1)",
+ -1, 0, 0.5, PANGO_ALIGN_LEFT);
+ create_demo_item (table, demo_item_type, 1, 2, 1, 1, "(2,1)",
+ -1, 0, 0.5, PANGO_ALIGN_LEFT);
+ create_demo_item (table, demo_item_type, 2, 0, 1, 1, "(0,2)",
+ -1, 0, 0.5, PANGO_ALIGN_LEFT);
+ create_demo_item (table, demo_item_type, 2, 1, 1, 1, "(1,2)",
+ -1, 0, 0.5, PANGO_ALIGN_LEFT);
+ create_demo_item (table, demo_item_type, 2, 2, 1, 1, "(2,2)",
+ -1, 0, 0.5, PANGO_ALIGN_LEFT);
}
return table;
@@ -285,7 +392,7 @@ create_table_page (void)
canvas = goo_canvas_new ();
gtk_widget_set_size_request (canvas, 600, 450);
- goo_canvas_set_bounds (GOO_CANVAS (canvas), 0, 0, 1000, 2000);
+ goo_canvas_set_bounds (GOO_CANVAS (canvas), 0, 0, 1000, 3000);
gtk_container_add (GTK_CONTAINER (scrolled_win), canvas);
root = goo_canvas_get_root_item (GOO_CANVAS (canvas));
@@ -296,28 +403,40 @@ create_table_page (void)
#endif
#if 1
- create_table (root, -1, -1, 0, 10, 10, 0, 1.0, DEMO_TEXT_ITEM);
- create_table (root, -1, -1, 0, 180, 10, 30, 1.0, DEMO_TEXT_ITEM);
- create_table (root, -1, -1, 0, 350, 10, 60, 1.0, DEMO_TEXT_ITEM);
- create_table (root, -1, -1, 0, 500, 10, 90, 1.0, DEMO_TEXT_ITEM);
+ create_table (root, -1, -1, 0, 10, 10, 0, 1.0, DEMO_TEXT_ITEM, FALSE);
+ create_table (root, -1, -1, 0, 180, 10, 30, 1.0, DEMO_TEXT_ITEM, FALSE);
+ create_table (root, -1, -1, 0, 350, 10, 60, 1.0, DEMO_TEXT_ITEM, FALSE);
+ create_table (root, -1, -1, 0, 500, 10, 90, 1.0, DEMO_TEXT_ITEM, FALSE);
#endif
#if 1
- table = create_table (root, -1, -1, 0, 30, 150, 0, 1.0, DEMO_TEXT_ITEM);
+ table = create_table (root, -1, -1, 0, 30, 150, 0, 1.0, DEMO_TEXT_ITEM, FALSE);
g_object_set (table, "width", 300.0, "height", 100.0, NULL);
#endif
#if 1
- create_table (root, -1, -1, 1, 200, 200, 30, 0.8, DEMO_TEXT_ITEM);
+ table = create_table (root, -1, -1, 0, 30, 1400, 0, 1.0, DEMO_TEXT_ITEM_2, TRUE);
+ g_object_set (table, "width", 300.0, "height", 300.0, NULL);
+
+ table = create_table (root, -1, -1, 0, 630, 1430, 30, 1.0, DEMO_TEXT_ITEM_2, TRUE);
+ g_object_set (table, "width", 300.0, "height", 300.0, NULL);
+
+
+ table = create_table (root, -1, -1, 0, 30, 1800, 0, 1.0, DEMO_TEXT_ITEM_3, TRUE);
+ table = create_table (root, -1, -1, 0, 630, 1830, 30, 1.0, DEMO_TEXT_ITEM_3, TRUE);
+#endif
+
+#if 1
+ create_table (root, -1, -1, 1, 200, 200, 30, 0.8, DEMO_TEXT_ITEM, FALSE);
#endif
#if 1
- table = create_table (root, -1, -1, 0, 10, 700, 0, 1.0, DEMO_WIDGET_ITEM);
+ table = create_table (root, -1, -1, 0, 10, 700, 0, 1.0, DEMO_WIDGET_ITEM, FALSE);
g_object_set (table, "width", 300.0, "height", 200.0, NULL);
#endif
- create_width_for_height_table (root, 100, 1000, 200, -1, 0);
#if 1
+ create_width_for_height_table (root, 100, 1000, 200, -1, 0);
create_width_for_height_table (root, 100, 1200, 300, -1, 0);
create_width_for_height_table (root, 500, 1000, 200, -1, 30);
diff --git a/demo/mv-demo-table.c b/demo/mv-demo-table.c
index 9ad4d08..ff9542a 100644
--- a/demo/mv-demo-table.c
+++ b/demo/mv-demo-table.c
@@ -5,6 +5,8 @@
#define DEMO_RECT_ITEM 0
#define DEMO_TEXT_ITEM 1
+#define DEMO_TEXT_ITEM_2 2
+#define DEMO_TEXT_ITEM_3 3
static GooCanvas *canvas;
@@ -31,7 +33,11 @@ create_demo_item (GooCanvasItemModel *table,
gint column,
gint rows,
gint columns,
- gchar *text)
+ gchar *text,
+ gdouble width,
+ gdouble xalign,
+ gdouble yalign,
+ PangoAlignment text_alignment)
{
GooCanvasItemModel *model = NULL;
GooCanvasItem *item;
@@ -46,7 +52,10 @@ create_demo_item (GooCanvasItemModel *table,
NULL);
break;
case DEMO_TEXT_ITEM:
- model = goo_canvas_text_model_new (table, text, 0, 0, -1, GOO_CANVAS_ANCHOR_NW,
+ case DEMO_TEXT_ITEM_2:
+ case DEMO_TEXT_ITEM_3:
+ model = goo_canvas_text_model_new (table, text, 0, 0, width, GOO_CANVAS_ANCHOR_NW,
+ "alignment", text_alignment,
NULL);
break;
}
@@ -61,17 +70,23 @@ create_demo_item (GooCanvasItemModel *table,
g_value_set_uint (&value, columns);
goo_canvas_item_model_set_child_property (table, model, "columns", &value);
+ goo_canvas_item_model_set_child_properties (table, model,
+ "x-expand", TRUE,
+ "y-expand", TRUE,
+ "x-align", xalign,
+ "y-align", yalign,
+ NULL);
+
/* Test the get function. */
goo_canvas_item_model_get_child_property (table, model, "row", &value);
new_row = g_value_get_uint (&value);
if (new_row != row)
g_warning ("Got bad row setting: %i should be: %i\n", new_row, row);
-#if 1
+ /* If we make the item's fill the cells then alignment can't be used. */
+#if 0
goo_canvas_item_model_set_child_properties (table, model,
- "x-expand", TRUE,
"x-fill", TRUE,
- "y-expand", TRUE,
"y-fill", TRUE,
NULL);
#endif
@@ -92,7 +107,8 @@ create_table (GooCanvasItemModel *parent,
gdouble y,
gdouble rotation,
gdouble scale,
- gint demo_item_type)
+ gint demo_item_type,
+ gboolean show_grid_lines)
{
GooCanvasItemModel *table;
@@ -101,6 +117,13 @@ create_table (GooCanvasItemModel *parent,
"row-spacing", 4.0,
"column-spacing", 4.0,
NULL);
+
+ if (show_grid_lines)
+ g_object_set (table,
+ "horz-grid-line-width", 1.0f,
+ "vert-grid-line-width", 1.0f,
+ NULL);
+
goo_canvas_item_model_translate (table, x, y);
#if 1
goo_canvas_item_model_rotate (table, rotation, 0, 0);
@@ -126,27 +149,110 @@ create_table (GooCanvasItemModel *parent,
if (embedding_level)
{
gint level = embedding_level - 1;
- create_table (table, 0, 0, level, 50, 50, 0, 0.7, demo_item_type);
- create_table (table, 0, 1, level, 50, 50, 45, 1.0, demo_item_type);
- create_table (table, 0, 2, level, 50, 50, 90, 1.0, demo_item_type);
- create_table (table, 1, 0, level, 50, 50, 135, 1.0, demo_item_type);
- create_table (table, 1, 1, level, 50, 50, 180, 1.5, demo_item_type);
- create_table (table, 1, 2, level, 50, 50, 225, 1.0, demo_item_type);
- create_table (table, 2, 0, level, 50, 50, 270, 1.0, demo_item_type);
- create_table (table, 2, 1, level, 50, 50, 315, 1.0, demo_item_type);
- create_table (table, 2, 2, level, 50, 50, 360, 2.0, demo_item_type);
+ create_table (table, 0, 0, level, 50, 50, 0, 0.7, demo_item_type,
+ show_grid_lines);
+ create_table (table, 0, 1, level, 50, 50, 45, 1.0, demo_item_type,
+ show_grid_lines);
+ create_table (table, 0, 2, level, 50, 50, 90, 1.0, demo_item_type,
+ show_grid_lines);
+ create_table (table, 1, 0, level, 50, 50, 135, 1.0, demo_item_type,
+ show_grid_lines);
+ create_table (table, 1, 1, level, 50, 50, 180, 1.5, demo_item_type,
+ show_grid_lines);
+ create_table (table, 1, 2, level, 50, 50, 225, 1.0, demo_item_type,
+ show_grid_lines);
+ create_table (table, 2, 0, level, 50, 50, 270, 1.0, demo_item_type,
+ show_grid_lines);
+ create_table (table, 2, 1, level, 50, 50, 315, 1.0, demo_item_type,
+ show_grid_lines);
+ create_table (table, 2, 2, level, 50, 50, 360, 2.0, demo_item_type,
+ show_grid_lines);
+ }
+ else if (demo_item_type == DEMO_TEXT_ITEM_2)
+ {
+ create_demo_item (table, demo_item_type, 0, 0, 1, 1,
+ "(0.0,0.0)\nleft\naligned",
+ -1, 0, 0, PANGO_ALIGN_LEFT);
+ create_demo_item (table, demo_item_type, 0, 1, 1, 1,
+ "(0.5,0.0)\ncenter\naligned",
+ -1, 0.5, 0, PANGO_ALIGN_CENTER);
+ create_demo_item (table, demo_item_type, 0, 2, 1, 1,
+ "(1.0,0.0)\nright\naligned",
+ -1, 1, 0, PANGO_ALIGN_RIGHT);
+
+ /* The layout width shouldn't really make any difference in this test. */
+ create_demo_item (table, demo_item_type, 1, 0, 1, 1,
+ "(0.5,0.5)\ncenter\naligned",
+ 50, 0.5, 0.5, PANGO_ALIGN_CENTER);
+ create_demo_item (table, demo_item_type, 1, 1, 1, 1,
+ "(0.0,1.0)\nright\naligned",
+ 100, 0, 1.0, PANGO_ALIGN_RIGHT);
+ create_demo_item (table, demo_item_type, 1, 2, 1, 1,
+ "(0.0,0.5)\nleft\naligned",
+ 200, 0, 0.5, PANGO_ALIGN_LEFT);
+
+ create_demo_item (table, demo_item_type, 2, 0, 1, 1,
+ "(1.0,1.0)\ncenter\naligned",
+ -1, 1, 1, PANGO_ALIGN_CENTER);
+ create_demo_item (table, demo_item_type, 2, 1, 1, 1,
+ "(1,0.5)\nright\naligned",
+ -1, 1.0, 0.5, PANGO_ALIGN_RIGHT);
+ create_demo_item (table, demo_item_type, 2, 2, 1, 1,
+ "(0.0,0.0)\nleft\naligned",
+ -1, 0, 0, PANGO_ALIGN_LEFT);
+ }
+ else if (demo_item_type == DEMO_TEXT_ITEM_3)
+ {
+ create_demo_item (table, demo_item_type, 0, 0, 1, 1,
+ "width 50 align 0.0, 0.0 text left aligned",
+ 50, 0, 0, PANGO_ALIGN_LEFT);
+ create_demo_item (table, demo_item_type, 0, 1, 1, 1,
+ "width 100 align 0.5, 0.0 text center aligned",
+ 100, 0.5, 0, PANGO_ALIGN_CENTER);
+ create_demo_item (table, demo_item_type, 0, 2, 1, 1,
+ "width 150 align 1.0, 0.0 text right aligned",
+ 150, 1, 0, PANGO_ALIGN_RIGHT);
+
+ create_demo_item (table, demo_item_type, 1, 0, 1, 1,
+ "width 50 align 0.5, 0.5 text center aligned",
+ 50, 0.5, 0.5, PANGO_ALIGN_CENTER);
+ create_demo_item (table, demo_item_type, 1, 1, 1, 1,
+ "width 100 align 0.0, 1.0 text right aligned",
+ 100, 0, 1.0, PANGO_ALIGN_RIGHT);
+ create_demo_item (table, demo_item_type, 1, 2, 1, 1,
+ "width 200 align 0.0, 0.5 text left aligned",
+ 200, 0, 0.5, PANGO_ALIGN_LEFT);
+
+ create_demo_item (table, demo_item_type, 2, 0, 1, 1,
+ "width 50 align 1.0, 1.0 text center aligned",
+ 50, 1, 1, PANGO_ALIGN_CENTER);
+ create_demo_item (table, demo_item_type, 2, 1, 1, 1,
+ "width 100 align 1, 0.5 text right aligned",
+ 100, 1.0, 0.5, PANGO_ALIGN_RIGHT);
+ create_demo_item (table, demo_item_type, 2, 2, 1, 1,
+ "width 50 align 0.0, 0.0 text left aligned",
+ 50, 0, 0, PANGO_ALIGN_LEFT);
}
else
{
- create_demo_item (table, demo_item_type, 0, 0, 1, 1, "(0,0)");
- create_demo_item (table, demo_item_type, 0, 1, 1, 1, "(1,0)");
- create_demo_item (table, demo_item_type, 0, 2, 1, 1, "(2,0)");
- create_demo_item (table, demo_item_type, 1, 0, 1, 1, "(0,1)");
- create_demo_item (table, demo_item_type, 1, 1, 1, 1, "(1,1)");
- create_demo_item (table, demo_item_type, 1, 2, 1, 1, "(2,1)");
- create_demo_item (table, demo_item_type, 2, 0, 1, 1, "(0,2)");
- create_demo_item (table, demo_item_type, 2, 1, 1, 1, "(1,2)");
- create_demo_item (table, demo_item_type, 2, 2, 1, 1, "(2,2)");
+ create_demo_item (table, demo_item_type, 0, 0, 1, 1, "(0,0)",
+ -1, 0, 0.5, PANGO_ALIGN_LEFT);
+ create_demo_item (table, demo_item_type, 0, 1, 1, 1, "(1,0)",
+ -1, 0, 0.5, PANGO_ALIGN_LEFT);
+ create_demo_item (table, demo_item_type, 0, 2, 1, 1, "(2,0)",
+ -1, 0, 0.5, PANGO_ALIGN_LEFT);
+ create_demo_item (table, demo_item_type, 1, 0, 1, 1, "(0,1)",
+ -1, 0, 0.5, PANGO_ALIGN_LEFT);
+ create_demo_item (table, demo_item_type, 1, 1, 1, 1, "(1,1)",
+ -1, 0, 0.5, PANGO_ALIGN_LEFT);
+ create_demo_item (table, demo_item_type, 1, 2, 1, 1, "(2,1)",
+ -1, 0, 0.5, PANGO_ALIGN_LEFT);
+ create_demo_item (table, demo_item_type, 2, 0, 1, 1, "(0,2)",
+ -1, 0, 0.5, PANGO_ALIGN_LEFT);
+ create_demo_item (table, demo_item_type, 2, 1, 1, 1, "(1,2)",
+ -1, 0, 0.5, PANGO_ALIGN_LEFT);
+ create_demo_item (table, demo_item_type, 2, 2, 1, 1, "(2,2)",
+ -1, 0, 0.5, PANGO_ALIGN_LEFT);
}
return table;
@@ -289,7 +395,7 @@ create_table_page (void)
canvas = (GooCanvas*) goo_canvas_new ();
gtk_widget_set_size_request ((GtkWidget*) canvas, 600, 450);
- goo_canvas_set_bounds (canvas, 0, 0, 1000, 2000);
+ goo_canvas_set_bounds (canvas, 0, 0, 1000, 3000);
gtk_container_add (GTK_CONTAINER (scrolled_win), (GtkWidget*) canvas);
root = goo_canvas_group_model_new (NULL, NULL);
@@ -302,23 +408,34 @@ create_table_page (void)
#endif
#if 1
- create_table (root, -1, -1, 0, 10, 10, 0, 1.0, DEMO_TEXT_ITEM);
- create_table (root, -1, -1, 0, 180, 10, 30, 1.0, DEMO_TEXT_ITEM);
- create_table (root, -1, -1, 0, 350, 10, 60, 1.0, DEMO_TEXT_ITEM);
- create_table (root, -1, -1, 0, 500, 10, 90, 1.0, DEMO_TEXT_ITEM);
+ create_table (root, -1, -1, 0, 10, 10, 0, 1.0, DEMO_TEXT_ITEM, FALSE);
+ create_table (root, -1, -1, 0, 180, 10, 30, 1.0, DEMO_TEXT_ITEM, FALSE);
+ create_table (root, -1, -1, 0, 350, 10, 60, 1.0, DEMO_TEXT_ITEM, FALSE);
+ create_table (root, -1, -1, 0, 500, 10, 90, 1.0, DEMO_TEXT_ITEM, FALSE);
#endif
#if 1
- table = create_table (root, -1, -1, 0, 30, 150, 0, 1.0, DEMO_TEXT_ITEM);
+ table = create_table (root, -1, -1, 0, 30, 150, 0, 1.0, DEMO_TEXT_ITEM, FALSE);
g_object_set (table, "width", 300.0, "height", 100.0, NULL);
#endif
#if 1
- create_table (root, -1, -1, 1, 200, 200, 30, 0.8, DEMO_TEXT_ITEM);
+ table = create_table (root, -1, -1, 0, 30, 1400, 0, 1.0, DEMO_TEXT_ITEM_2, TRUE);
+ g_object_set (table, "width", 300.0, "height", 300.0, NULL);
+
+ table = create_table (root, -1, -1, 0, 630, 1430, 30, 1.0, DEMO_TEXT_ITEM_2, TRUE);
+ g_object_set (table, "width", 300.0, "height", 300.0, NULL);
+
+ table = create_table (root, -1, -1, 0, 30, 1800, 0, 1.0, DEMO_TEXT_ITEM_3, TRUE);
+ table = create_table (root, -1, -1, 0, 630, 1830, 30, 1.0, DEMO_TEXT_ITEM_3, TRUE);
+#endif
+
+#if 1
+ create_table (root, -1, -1, 1, 200, 200, 30, 0.8, DEMO_TEXT_ITEM, FALSE);
#endif
#if 0
- table = create_table (root, -1, -1, 0, 10, 700, 0, 1.0, DEMO_WIDGET_ITEM);
+ table = create_table (root, -1, -1, 0, 10, 700, 0, 1.0, DEMO_WIDGET_ITEM, FALSE);
g_object_set (table, "width", 300.0, "height", 200.0, NULL);
#endif
diff --git a/src/goocanvasitem.c b/src/goocanvasitem.c
index 205f7b4..4010b4d 100644
--- a/src/goocanvasitem.c
+++ b/src/goocanvasitem.c
@@ -1753,6 +1753,40 @@ goo_canvas_item_get_requested_area (GooCanvasItem *item,
/**
+ * goo_canvas_item_get_requested_area_for_width:
+ * @item: a #GooCanvasItem.
+ * @cr: a cairo context.
+ * @width: the allocated width.
+ * @requested_area: a #GooCanvasBounds to return the requested area in, in the
+ * parent's coordinate space. If %FALSE is returned, this is undefined.
+ *
+ * This function is only intended to be used when implementing new canvas
+ * items, specifically layout items such as #GooCanvasTable.
+ *
+ * It gets the requested area of a child item, assuming it is allocated the
+ * given width. This is useful for text items whose requested height may change
+ * depending on the allocated width.
+ *
+ * Returns: %TRUE if the item's requested area changes due to the new allocated
+ * width.
+ **/
+gboolean
+goo_canvas_item_get_requested_area_for_width (GooCanvasItem *item,
+ cairo_t *cr,
+ gdouble width,
+ GooCanvasBounds *requested_area)
+{
+ GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+
+ if (iface->get_requested_area_for_width)
+ return iface->get_requested_area_for_width (item, cr, width, requested_area);
+ else
+ return FALSE;
+}
+
+
+
+/**
* goo_canvas_item_get_requested_height:
* @item: a #GooCanvasItem.
* @cr: a cairo context.
diff --git a/src/goocanvasitem.h b/src/goocanvasitem.h
index 76c61ec..d86c3bc 100644
--- a/src/goocanvasitem.h
+++ b/src/goocanvasitem.h
@@ -100,6 +100,13 @@ typedef struct _GooCanvasItem GooCanvasItem;
* @get_requested_area: returns the requested area of the item, in its parent's
* coordinate space. This is only used for items in layout containers such as
* #GooCanvasTable.
+ * @get_requested_height: returns the requested height of the item,
+ * given a particular allocated width, using the parent's coordinate space.
+ * Note that this method should only be used if the position of the item
+ * remains unchanged. If the position might change use
+ * get_requested_area_for_width() instead.
+ * @get_requested_area_for_width: returns the requested bounds of the item,
+ * given a particular allocated width, using the parent's coordinate space.
* @allocate_area: allocates the item's area, in its parent's coordinate space.
* The item must recalculate its bounds and request redraws of parts of the
* canvas if necessary. This is only used for items in layout containers such
@@ -111,8 +118,6 @@ typedef struct _GooCanvasItem GooCanvasItem;
* @is_visible: returns %TRUE if the item is currently visible.
* @get_is_static: returns %TRUE if the item is static.
* @set_is_static: notifies the item whether it is static or not.
- * @get_requested_height: returns the requested height of the item,
- * given a particular allocated width, using the parent's coordinate space.
* @get_model: gets the model that the canvas item is viewing.
* @set_model: sets the model that the canvas item will view.
* @enter_notify_event: signal emitted when the mouse enters the item.
@@ -292,13 +297,17 @@ struct _GooCanvasItemIface
GooCanvasItem *target,
GdkEventScroll *event);
+ gboolean (* get_requested_area_for_width)(GooCanvasItem *item,
+ cairo_t *cr,
+ gdouble width,
+ GooCanvasBounds *requested_area);
+
/*< private >*/
/* Padding for future expansion */
void (*_goo_canvas_reserved1) (void);
void (*_goo_canvas_reserved2) (void);
void (*_goo_canvas_reserved3) (void);
- void (*_goo_canvas_reserved4) (void);
};
@@ -445,6 +454,10 @@ void goo_canvas_item_paint (GooCanvasItem *item,
gboolean goo_canvas_item_get_requested_area (GooCanvasItem *item,
cairo_t *cr,
GooCanvasBounds *requested_area);
+gboolean goo_canvas_item_get_requested_area_for_width (GooCanvasItem *item,
+ cairo_t *cr,
+ gdouble width,
+ GooCanvasBounds *requested_area);
gdouble goo_canvas_item_get_requested_height (GooCanvasItem *item,
cairo_t *cr,
gdouble width);
diff --git a/src/goocanvasitemsimple.c b/src/goocanvasitemsimple.c
index 8d3f001..e5e8941 100644
--- a/src/goocanvasitemsimple.c
+++ b/src/goocanvasitemsimple.c
@@ -1333,6 +1333,12 @@ goo_canvas_item_simple_allocate_area (GooCanvasItem *item,
simple->bounds.x2 += x_offset;
simple->bounds.y2 += y_offset;
+#if 0
+ g_print ("Offsets: %g, %g Allocated bounds: %g,%g - %g,%g\n",
+ x_offset, y_offset, simple->bounds.x1,
+ simple->bounds.y1, simple->bounds.x2, simple->bounds.y2);
+#endif
+
/* Request a redraw of the new bounds. */
goo_canvas_request_item_redraw (simple->canvas, &simple->bounds, simple_data->is_static);
}
diff --git a/src/goocanvastable.c b/src/goocanvastable.c
index 66c18ee..1fe086e 100644
--- a/src/goocanvastable.c
+++ b/src/goocanvastable.c
@@ -1877,6 +1877,8 @@ goo_canvas_table_update_requested_heights (GooCanvasItem *item,
GooCanvasTableChildLayoutData *child_data;
gint start_column, end_column, i, row, end;
gdouble x, max_width, width, requested_width, requested_height, height = 0.0;
+ GooCanvasItemIface *iface;
+ GooCanvasBounds bounds;
/* Just return if we've already calculated requested heights for this exact
width. */
@@ -1912,10 +1914,42 @@ goo_canvas_table_update_requested_heights (GooCanvasItem *item,
if (!(child->flags[HORZ] & GOO_CANVAS_TABLE_CHILD_FILL))
width = MIN (max_width, requested_width);
- requested_height = goo_canvas_item_get_requested_height (child_item, cr,
- width);
- if (requested_height >= 0.0)
- child_data->requested_size[VERT] = requested_height;
+ iface = GOO_CANVAS_ITEM_GET_IFACE (child_item);
+
+ /* See if the child supports the new get_requested_area_for_width()
+ method, which can handles the bounds being changed by the change
+ in width & height. */
+ if (iface->get_requested_area_for_width)
+ {
+ if (iface->get_requested_area_for_width (child_item, cr, width,
+ &bounds))
+ {
+ /* Remember the requested position and size of the child. */
+ child_data->requested_position[HORZ] = bounds.x1;
+ child_data->requested_position[VERT] = bounds.y1;
+
+ child_data->requested_size[HORZ] = bounds.x2 - bounds.x1;
+
+ if (layout_data->integer_layout)
+ child_data->requested_size[VERT] = ceil (bounds.y2 - bounds.y1);
+ else
+ child_data->requested_size[VERT] = bounds.y2 - bounds.y1;
+ }
+ }
+ else if (iface->get_requested_height)
+ {
+ requested_height = iface->get_requested_height (child_item, cr,
+ width);
+ if (requested_height >= 0.0)
+ {
+ child_data->requested_size[HORZ] = width;
+
+ if (layout_data->integer_layout)
+ child_data->requested_size[VERT] = ceil (requested_height);
+ else
+ child_data->requested_size[VERT] = requested_height;
+ }
+ }
}
/* Now recalculate the requested heights of each row. */
diff --git a/src/goocanvastext.c b/src/goocanvastext.c
index 496089b..a1d88b1 100644
--- a/src/goocanvastext.c
+++ b/src/goocanvastext.c
@@ -488,8 +488,8 @@ goo_canvas_text_create_layout (GooCanvasItemSimpleData *simple_data,
/* If the text width has been set, that width is used to do the alignment
positioning. Otherwise the actual width is used. */
- if (text_data->width > 0)
- align_width = text_data->width;
+ if (layout_width > 0)
+ align_width = layout_width;
else
align_width = logical_width;
@@ -540,7 +540,7 @@ goo_canvas_text_create_layout (GooCanvasItemSimpleData *simple_data,
bounds->x1 = origin_x;
bounds->y1 = origin_y;
- if (text_data->width > 0)
+ if (layout_width > 0)
{
/* If the text width has been set, and the alignment isn't
PANGO_ALIGN_LEFT, we need to adjust for the difference between
@@ -744,29 +744,38 @@ goo_canvas_text_paint (GooCanvasItemSimple *simple,
}
-static gdouble
-goo_canvas_text_get_requested_height (GooCanvasItem *item,
- cairo_t *cr,
- gdouble width)
+static gboolean
+goo_canvas_text_get_requested_area_for_width (GooCanvasItem *item,
+ cairo_t *cr,
+ gdouble width,
+ GooCanvasBounds *requested_area)
{
GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
GooCanvasItemSimpleData *simple_data = simple->simple_data;
GooCanvasText *text = (GooCanvasText*) item;
GooCanvasTextPrivate *priv = goo_canvas_text_get_private (text);
PangoLayout *layout;
- gdouble height;
+ cairo_matrix_t matrix;
+ double x_offset, y_offset;
/* If we have a transformation besides a simple scale & translation, just
return -1 as we can't adjust the height in that case. */
if (simple_data->clip_path_commands
|| (simple_data->transform && (simple_data->transform->xy != 0.0
|| simple_data->transform->yx != 0.0)))
- return -1;
+ return FALSE;
cairo_save (cr);
if (simple_data->transform)
cairo_transform (cr, simple_data->transform);
+ /* Remove any current translation, to avoid the 16-bit cairo limit. */
+ cairo_get_matrix (cr, &matrix);
+ x_offset = matrix.x0;
+ y_offset = matrix.y0;
+ matrix.x0 = matrix.y0 = 0.0;
+ cairo_set_matrix (cr, &matrix);
+
/* Convert the width from the parent's coordinate space. Note that we only
need to support a simple scale operation here. */
text->layout_width = width;
@@ -779,28 +788,49 @@ goo_canvas_text_get_requested_height (GooCanvasItem *item,
&simple->bounds, NULL, NULL);
g_object_unref (layout);
- if (priv->height < 0.0)
- {
- height = simple->bounds.y2 - simple->bounds.y1;
- }
- else
- {
- height = priv->height;
- simple->bounds.y2 = simple->bounds.y1 + height;
- }
+ /* If the height is set, use that. */
+ if (priv->height > 0.0)
+ simple->bounds.y2 = simple->bounds.y1 + priv->height;
- /* Convert to the parent's coordinate space. As above, we only need to
- support a simple scale operation here. */
- if (simple_data->transform)
- height *= simple_data->transform->yy;
+
+ /* Convert to device space. */
+ cairo_user_to_device (cr, &simple->bounds.x1, &simple->bounds.y1);
+ cairo_user_to_device (cr, &simple->bounds.x2, &simple->bounds.y2);
+
+ /* Add the translation back to the bounds. */
+ simple->bounds.x1 += x_offset;
+ simple->bounds.y1 += y_offset;
+ simple->bounds.x2 += x_offset;
+ simple->bounds.y2 += y_offset;
+
+ /* Restore the item's proper transformation matrix. */
+ matrix.x0 = x_offset;
+ matrix.y0 = y_offset;
+ cairo_set_matrix (cr, &matrix);
+
+ /* Convert back to user space. */
+ cairo_device_to_user (cr, &simple->bounds.x1, &simple->bounds.y1);
+ cairo_device_to_user (cr, &simple->bounds.x2, &simple->bounds.y2);
+
+
+ /* Copy the user bounds to the requested area. */
+ *requested_area = simple->bounds;
+
+ /* Convert to the parent's coordinate space. */
+ goo_canvas_item_simple_user_bounds_to_parent (simple, cr, requested_area);
/* Convert the item's bounds to device space. */
goo_canvas_item_simple_user_bounds_to_device (simple, cr, &simple->bounds);
+#if 0
+ g_print ("Width: %g Requested bounds: %g,%g - %g,%g\n",
+ width, simple->bounds.x1, simple->bounds.y1,
+ simple->bounds.x2, simple->bounds.y2);
+#endif
+
cairo_restore (cr);
- /* Return the new requested height of the text. */
- return height;
+ return TRUE;
}
@@ -861,7 +891,7 @@ goo_canvas_text_set_model (GooCanvasItem *item,
static void
canvas_item_interface_init (GooCanvasItemIface *iface)
{
- iface->get_requested_height = goo_canvas_text_get_requested_height;
+ iface->get_requested_area_for_width = goo_canvas_text_get_requested_area_for_width;
iface->set_model = goo_canvas_text_set_model;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]