diff options
-rw-r--r-- | widgets/TODO | 10 | ||||
-rw-r--r-- | widgets/e-table-item.c | 142 | ||||
-rw-r--r-- | widgets/e-table-item.h | 3 | ||||
-rw-r--r-- | widgets/e-table/TODO | 10 | ||||
-rw-r--r-- | widgets/e-table/e-table-item.c | 142 | ||||
-rw-r--r-- | widgets/e-table/e-table-item.h | 3 | ||||
-rw-r--r-- | widgets/e-table/table-test.c | 1 | ||||
-rw-r--r-- | widgets/table-test.c | 1 | ||||
-rw-r--r-- | widgets/table/e-table-item.c | 142 | ||||
-rw-r--r-- | widgets/table/e-table-item.h | 3 | ||||
-rw-r--r-- | widgets/table/table-test.c | 1 |
11 files changed, 386 insertions, 72 deletions
diff --git a/widgets/TODO b/widgets/TODO index c6d2010be8..20d491b4fa 100644 --- a/widgets/TODO +++ b/widgets/TODO @@ -8,3 +8,13 @@ Implement the two methods for row finding: by full thing, or by a factor. Add editing mouse grabbing for scrolling + + +1. Make sure that all values are updated on header changes and table + model changes (they are slightly out of sync now) + +* Correctness + + * Make sure we can boot and shutdown with no memory leaks. + + * Run Insure on the thing. diff --git a/widgets/e-table-item.c b/widgets/e-table-item.c index 16b85fab6e..3b35f6c156 100644 --- a/widgets/e-table-item.c +++ b/widgets/e-table-item.c @@ -20,6 +20,7 @@ enum { ARG_TABLE_MODEL, ARG_TABLE_X, ARG_TABLE_Y, + ARG_TABLE_DRAW_GRID, ARG_LENGHT_THRESHOLD }; @@ -32,7 +33,7 @@ eti_realize_cell_views (ETableItem *eti) /* * Now realize the various ECells */ - eti->n_cells = e_table_header_count (eti->header); + eti->n_cells = eti->cols; eti->cell_views = g_new (ECellView *, eti->n_cells); for (i = 0; i < eti->n_cells; i++){ @@ -125,10 +126,13 @@ eti_row_height (ETableItem *eti, int row) static int eti_get_height (ETableItem *eti) { - const int rows = e_table_model_row_count (eti->table_model); + const int rows = eti->rows; int row; int height = 0; + if (rows == 0) + return 0; + if (rows > eti->length_threshold){ height = eti_row_height (eti, 0) * rows; @@ -138,14 +142,21 @@ eti_get_height (ETableItem *eti) for (row = 0; row < rows; row++) height += eti_row_height (eti, row); + /* Add division lines pixels */ + height += rows; + return height; } static void eti_table_model_changed (ETableModel *table_model, ETableItem *eti) { - eti->height = eti_get_height (eti); + eti->cols = e_table_model_column_count (eti->table_model); + eti->rows = e_table_model_row_count (eti->table_model); + if (eti->cell_views) + eti->height = eti_get_height (eti); + eti_update (GNOME_CANVAS_ITEM (eti), NULL, NULL, 0); } @@ -159,11 +170,56 @@ eti_request_redraw (ETableItem *eti) eti->y1 + eti->height + 1); } +static int +eti_col_diff (ETableItem *eti, int start_col, int end_col) +{ + int col, total; + + total = 0; + for (col = start_col; col < end_col; col++){ + ETableCol *ecol = e_table_header_get_column (eti->header, col); + + total += ecol->width; + } + + return total; +} + +static int +eti_row_diff (ETableItem *eti, int start_row, int end_row) +{ + int row, total; + + total = 0; + + for (row = start_row; row < end_row; row++) + total += eti_row_height (eti, row) + 1; + + return total; +} + +static void +eti_request_region_redraw (ETableItem *eti, int start_col, int start_row, int end_col, int end_row) +{ + GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas; + int x1, y1, width, height; + int col, row; + + x1 = eti_col_diff (eti, 0, start_col); + y1 = eti_row_diff (eti, 0, start_row); + width = eti_col_diff (eti, start_col, end_col); + height = eti_row_diff (eti, start_col, end_row); + + gnome_canvas_request_redraw (canvas, + eti->x1 + x1, eti->y1 + y1, + eti->y1 + width + 1, + eti->x1 + height + 1); +} + static void eti_table_model_row_selection (ETableModel *table_model, int row, gboolean selected, ETableItem *eti) { - /* FIXME: we should optimize this to only redraw the selection change */ - eti_request_redraw (eti); + eti_request_region_redraw (eti, 0, row, eti->cols, row); } static void @@ -173,12 +229,14 @@ eti_add_table_model (ETableItem *eti, ETableModel *table_model) eti->table_model = table_model; gtk_object_ref (GTK_OBJECT (table_model)); + eti->table_model_change_id = gtk_signal_connect ( GTK_OBJECT (table_model), "model_changed", GTK_SIGNAL_FUNC (eti_table_model_changed), eti); eti->table_model_selection_id = gtk_signal_connect ( GTK_OBJECT (table_model), "row_selection", GTK_SIGNAL_FUNC (eti_table_model_row_selection), eti); + eti_table_model_changed (table_model, eti); } static void @@ -269,6 +327,8 @@ eti_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) eti->length_threshold = GTK_VALUE_INT (*arg); break; + case ARG_TABLE_DRAW_GRID: + eti->draw_grid = GTK_VALUE_BOOL (*arg); } eti_update (item, NULL, NULL, 0); } @@ -300,7 +360,7 @@ eti_realize (GnomeCanvasItem *item) eti->fill_gc = canvas_widget->style->white_gc; gdk_gc_ref (canvas_widget->style->white_gc); eti->grid_gc = gdk_gc_new (window); - gdk_gc_set_foreground (eti->grid_gc, &canvas_widget->style->fg [GTK_STATE_NORMAL]); + gdk_gc_set_foreground (eti->grid_gc, &canvas_widget->style->bg [GTK_STATE_NORMAL]); eti_realize_cell_views (eti); @@ -354,12 +414,15 @@ static void eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height) { ETableItem *eti = E_TABLE_ITEM (item); - const int rows = e_table_model_row_count (eti->table_model); - const int cols = e_table_header_count (eti->header); + const int rows = eti->rows; + const int cols = eti->cols; int row, col, y1, y2; int first_col, last_col, x_offset; + int first_row, last_row, y_offset, yd; int x1, x2; + int heights; + printf ("Rect: %d %d %d %d\n", x, y, width, height); /* * Clear the background */ @@ -395,17 +458,15 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, if (first_col == -1) return; -#if 0 - printf ("Cols %d %d\n", first_col, last_col); -#endif - /* - * Draw individual lines + * Compute row span. */ + first_row = -1; + y_offset = 0; y1 = y2 = eti->y1; for (row = eti->top_item; row < rows; row++, y1 = y2){ int xd; - + y2 += eti_row_height (eti, row); if (y1 > y + height) @@ -413,17 +474,38 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, if (y2 < y) continue; + + if (first_row == -1){ + y_offset = y1 - y; + first_row = row; + } + } + last_row = row; + + if (first_row == -1) + return; + + /* + * Draw cells + */ + yd = y_offset; + for (row = first_row; row < last_row; row++){ + int xd, height; - if (eti->draw_grid) - gdk_draw_line (drawable, eti->grid_gc, 0, y - y2, width, y - y2); + height = eti_row_height (eti, row); xd = x_offset; + printf ("paint: %d %d\n", yd, yd + height); for (col = first_col; col < last_col; col++){ ETableCol *ecol = e_table_header_get_column (eti->header, col); - draw_cell (eti, drawable, col, row, xd, y1 - y, xd + ecol->width, y2 - y); + draw_cell (eti, drawable, col, row, xd, yd, xd + ecol->width, yd + height); + xd += ecol->width; } + yd += height + 1; + gdk_draw_line (drawable, eti->grid_gc, + eti->x1 - x, yd -1, eti->x1 + eti->width - x, yd -1); } } @@ -439,8 +521,8 @@ eti_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, static gboolean find_cell (ETableItem *eti, double x, double y, int *col_res, int *row_res) { - const int cols = e_table_header_count (eti->header); - const int rows = e_table_model_row_count (eti->table_model); + const int cols = eti->cols; + const int rows = eti->rows; gdouble x1, y1, x2, y2; int col, row; @@ -470,7 +552,7 @@ find_cell (ETableItem *eti, double x, double y, int *col_res, int *row_res) if (y < y1) return FALSE; - y2 += eti_row_height (eti, row); + y2 += eti_row_height (eti, row) + 1; if (y > y2) continue; @@ -482,6 +564,13 @@ find_cell (ETableItem *eti, double x, double y, int *col_res, int *row_res) return TRUE; } +static void +eti_select (ETableItem *eti, int col, int row) +{ + eti->selected_col = col; + eti->selected_row = row; +} + static int eti_event (GnomeCanvasItem *item, GdkEvent *e) { @@ -493,13 +582,16 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e) case GDK_BUTTON_RELEASE: case GDK_2BUTTON_PRESS: { int col, row; - + if (!find_cell (eti, e->button.x, e->button.y, &col, &row)) return TRUE; - ecell_view = eti->cell_views [col]; - printf ("Found: %d %d\n", col, row); - e_cell_event (ecell_view, e, col, row); + if (eti->selected_row == row && eti->selected_col == col){ + ecell_view = eti->cell_views [col]; + + e_cell_event (ecell_view, e, col, row); + } else + eti_select (eti, col, row); break; } @@ -544,6 +636,8 @@ eti_class_init (GtkObjectClass *object_class) GTK_ARG_WRITABLE, ARG_TABLE_X); gtk_object_add_arg_type ("ETableItem::y", GTK_TYPE_INT, GTK_ARG_WRITABLE, ARG_TABLE_Y); + gtk_object_add_arg_type ("ETableItem::drawgrid", GTK_TYPE_BOOL, + GTK_ARG_WRITABLE, ARG_TABLE_DRAW_GRID); } GtkType diff --git a/widgets/e-table-item.h b/widgets/e-table-item.h index b4b4c73361..fc36363413 100644 --- a/widgets/e-table-item.h +++ b/widgets/e-table-item.h @@ -20,6 +20,7 @@ typedef struct { int width, height; int top_item; + int cols, rows; /* * Ids for the signals we connect to @@ -47,6 +48,8 @@ typedef struct { * the size */ int length_threshold; + + int selected_col, selected_row; } ETableItem; typedef struct { diff --git a/widgets/e-table/TODO b/widgets/e-table/TODO index c6d2010be8..20d491b4fa 100644 --- a/widgets/e-table/TODO +++ b/widgets/e-table/TODO @@ -8,3 +8,13 @@ Implement the two methods for row finding: by full thing, or by a factor. Add editing mouse grabbing for scrolling + + +1. Make sure that all values are updated on header changes and table + model changes (they are slightly out of sync now) + +* Correctness + + * Make sure we can boot and shutdown with no memory leaks. + + * Run Insure on the thing. diff --git a/widgets/e-table/e-table-item.c b/widgets/e-table/e-table-item.c index 16b85fab6e..3b35f6c156 100644 --- a/widgets/e-table/e-table-item.c +++ b/widgets/e-table/e-table-item.c @@ -20,6 +20,7 @@ enum { ARG_TABLE_MODEL, ARG_TABLE_X, ARG_TABLE_Y, + ARG_TABLE_DRAW_GRID, ARG_LENGHT_THRESHOLD }; @@ -32,7 +33,7 @@ eti_realize_cell_views (ETableItem *eti) /* * Now realize the various ECells */ - eti->n_cells = e_table_header_count (eti->header); + eti->n_cells = eti->cols; eti->cell_views = g_new (ECellView *, eti->n_cells); for (i = 0; i < eti->n_cells; i++){ @@ -125,10 +126,13 @@ eti_row_height (ETableItem *eti, int row) static int eti_get_height (ETableItem *eti) { - const int rows = e_table_model_row_count (eti->table_model); + const int rows = eti->rows; int row; int height = 0; + if (rows == 0) + return 0; + if (rows > eti->length_threshold){ height = eti_row_height (eti, 0) * rows; @@ -138,14 +142,21 @@ eti_get_height (ETableItem *eti) for (row = 0; row < rows; row++) height += eti_row_height (eti, row); + /* Add division lines pixels */ + height += rows; + return height; } static void eti_table_model_changed (ETableModel *table_model, ETableItem *eti) { - eti->height = eti_get_height (eti); + eti->cols = e_table_model_column_count (eti->table_model); + eti->rows = e_table_model_row_count (eti->table_model); + if (eti->cell_views) + eti->height = eti_get_height (eti); + eti_update (GNOME_CANVAS_ITEM (eti), NULL, NULL, 0); } @@ -159,11 +170,56 @@ eti_request_redraw (ETableItem *eti) eti->y1 + eti->height + 1); } +static int +eti_col_diff (ETableItem *eti, int start_col, int end_col) +{ + int col, total; + + total = 0; + for (col = start_col; col < end_col; col++){ + ETableCol *ecol = e_table_header_get_column (eti->header, col); + + total += ecol->width; + } + + return total; +} + +static int +eti_row_diff (ETableItem *eti, int start_row, int end_row) +{ + int row, total; + + total = 0; + + for (row = start_row; row < end_row; row++) + total += eti_row_height (eti, row) + 1; + + return total; +} + +static void +eti_request_region_redraw (ETableItem *eti, int start_col, int start_row, int end_col, int end_row) +{ + GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas; + int x1, y1, width, height; + int col, row; + + x1 = eti_col_diff (eti, 0, start_col); + y1 = eti_row_diff (eti, 0, start_row); + width = eti_col_diff (eti, start_col, end_col); + height = eti_row_diff (eti, start_col, end_row); + + gnome_canvas_request_redraw (canvas, + eti->x1 + x1, eti->y1 + y1, + eti->y1 + width + 1, + eti->x1 + height + 1); +} + static void eti_table_model_row_selection (ETableModel *table_model, int row, gboolean selected, ETableItem *eti) { - /* FIXME: we should optimize this to only redraw the selection change */ - eti_request_redraw (eti); + eti_request_region_redraw (eti, 0, row, eti->cols, row); } static void @@ -173,12 +229,14 @@ eti_add_table_model (ETableItem *eti, ETableModel *table_model) eti->table_model = table_model; gtk_object_ref (GTK_OBJECT (table_model)); + eti->table_model_change_id = gtk_signal_connect ( GTK_OBJECT (table_model), "model_changed", GTK_SIGNAL_FUNC (eti_table_model_changed), eti); eti->table_model_selection_id = gtk_signal_connect ( GTK_OBJECT (table_model), "row_selection", GTK_SIGNAL_FUNC (eti_table_model_row_selection), eti); + eti_table_model_changed (table_model, eti); } static void @@ -269,6 +327,8 @@ eti_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) eti->length_threshold = GTK_VALUE_INT (*arg); break; + case ARG_TABLE_DRAW_GRID: + eti->draw_grid = GTK_VALUE_BOOL (*arg); } eti_update (item, NULL, NULL, 0); } @@ -300,7 +360,7 @@ eti_realize (GnomeCanvasItem *item) eti->fill_gc = canvas_widget->style->white_gc; gdk_gc_ref (canvas_widget->style->white_gc); eti->grid_gc = gdk_gc_new (window); - gdk_gc_set_foreground (eti->grid_gc, &canvas_widget->style->fg [GTK_STATE_NORMAL]); + gdk_gc_set_foreground (eti->grid_gc, &canvas_widget->style->bg [GTK_STATE_NORMAL]); eti_realize_cell_views (eti); @@ -354,12 +414,15 @@ static void eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height) { ETableItem *eti = E_TABLE_ITEM (item); - const int rows = e_table_model_row_count (eti->table_model); - const int cols = e_table_header_count (eti->header); + const int rows = eti->rows; + const int cols = eti->cols; int row, col, y1, y2; int first_col, last_col, x_offset; + int first_row, last_row, y_offset, yd; int x1, x2; + int heights; + printf ("Rect: %d %d %d %d\n", x, y, width, height); /* * Clear the background */ @@ -395,17 +458,15 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, if (first_col == -1) return; -#if 0 - printf ("Cols %d %d\n", first_col, last_col); -#endif - /* - * Draw individual lines + * Compute row span. */ + first_row = -1; + y_offset = 0; y1 = y2 = eti->y1; for (row = eti->top_item; row < rows; row++, y1 = y2){ int xd; - + y2 += eti_row_height (eti, row); if (y1 > y + height) @@ -413,17 +474,38 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, if (y2 < y) continue; + + if (first_row == -1){ + y_offset = y1 - y; + first_row = row; + } + } + last_row = row; + + if (first_row == -1) + return; + + /* + * Draw cells + */ + yd = y_offset; + for (row = first_row; row < last_row; row++){ + int xd, height; - if (eti->draw_grid) - gdk_draw_line (drawable, eti->grid_gc, 0, y - y2, width, y - y2); + height = eti_row_height (eti, row); xd = x_offset; + printf ("paint: %d %d\n", yd, yd + height); for (col = first_col; col < last_col; col++){ ETableCol *ecol = e_table_header_get_column (eti->header, col); - draw_cell (eti, drawable, col, row, xd, y1 - y, xd + ecol->width, y2 - y); + draw_cell (eti, drawable, col, row, xd, yd, xd + ecol->width, yd + height); + xd += ecol->width; } + yd += height + 1; + gdk_draw_line (drawable, eti->grid_gc, + eti->x1 - x, yd -1, eti->x1 + eti->width - x, yd -1); } } @@ -439,8 +521,8 @@ eti_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, static gboolean find_cell (ETableItem *eti, double x, double y, int *col_res, int *row_res) { - const int cols = e_table_header_count (eti->header); - const int rows = e_table_model_row_count (eti->table_model); + const int cols = eti->cols; + const int rows = eti->rows; gdouble x1, y1, x2, y2; int col, row; @@ -470,7 +552,7 @@ find_cell (ETableItem *eti, double x, double y, int *col_res, int *row_res) if (y < y1) return FALSE; - y2 += eti_row_height (eti, row); + y2 += eti_row_height (eti, row) + 1; if (y > y2) continue; @@ -482,6 +564,13 @@ find_cell (ETableItem *eti, double x, double y, int *col_res, int *row_res) return TRUE; } +static void +eti_select (ETableItem *eti, int col, int row) +{ + eti->selected_col = col; + eti->selected_row = row; +} + static int eti_event (GnomeCanvasItem *item, GdkEvent *e) { @@ -493,13 +582,16 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e) case GDK_BUTTON_RELEASE: case GDK_2BUTTON_PRESS: { int col, row; - + if (!find_cell (eti, e->button.x, e->button.y, &col, &row)) return TRUE; - ecell_view = eti->cell_views [col]; - printf ("Found: %d %d\n", col, row); - e_cell_event (ecell_view, e, col, row); + if (eti->selected_row == row && eti->selected_col == col){ + ecell_view = eti->cell_views [col]; + + e_cell_event (ecell_view, e, col, row); + } else + eti_select (eti, col, row); break; } @@ -544,6 +636,8 @@ eti_class_init (GtkObjectClass *object_class) GTK_ARG_WRITABLE, ARG_TABLE_X); gtk_object_add_arg_type ("ETableItem::y", GTK_TYPE_INT, GTK_ARG_WRITABLE, ARG_TABLE_Y); + gtk_object_add_arg_type ("ETableItem::drawgrid", GTK_TYPE_BOOL, + GTK_ARG_WRITABLE, ARG_TABLE_DRAW_GRID); } GtkType diff --git a/widgets/e-table/e-table-item.h b/widgets/e-table/e-table-item.h index b4b4c73361..fc36363413 100644 --- a/widgets/e-table/e-table-item.h +++ b/widgets/e-table/e-table-item.h @@ -20,6 +20,7 @@ typedef struct { int width, height; int top_item; + int cols, rows; /* * Ids for the signals we connect to @@ -47,6 +48,8 @@ typedef struct { * the size */ int length_threshold; + + int selected_col, selected_row; } ETableItem; typedef struct { diff --git a/widgets/e-table/table-test.c b/widgets/e-table/table-test.c index d7c14e900f..73be9e5ecd 100644 --- a/widgets/e-table/table-test.c +++ b/widgets/e-table/table-test.c @@ -233,6 +233,7 @@ main (int argc, char *argv []) "ETableModel", e_table_model, "x", 10, "y", 30, + "drawgrid", TRUE, NULL); gtk_main (); diff --git a/widgets/table-test.c b/widgets/table-test.c index d7c14e900f..73be9e5ecd 100644 --- a/widgets/table-test.c +++ b/widgets/table-test.c @@ -233,6 +233,7 @@ main (int argc, char *argv []) "ETableModel", e_table_model, "x", 10, "y", 30, + "drawgrid", TRUE, NULL); gtk_main (); diff --git a/widgets/table/e-table-item.c b/widgets/table/e-table-item.c index 16b85fab6e..3b35f6c156 100644 --- a/widgets/table/e-table-item.c +++ b/widgets/table/e-table-item.c @@ -20,6 +20,7 @@ enum { ARG_TABLE_MODEL, ARG_TABLE_X, ARG_TABLE_Y, + ARG_TABLE_DRAW_GRID, ARG_LENGHT_THRESHOLD }; @@ -32,7 +33,7 @@ eti_realize_cell_views (ETableItem *eti) /* * Now realize the various ECells */ - eti->n_cells = e_table_header_count (eti->header); + eti->n_cells = eti->cols; eti->cell_views = g_new (ECellView *, eti->n_cells); for (i = 0; i < eti->n_cells; i++){ @@ -125,10 +126,13 @@ eti_row_height (ETableItem *eti, int row) static int eti_get_height (ETableItem *eti) { - const int rows = e_table_model_row_count (eti->table_model); + const int rows = eti->rows; int row; int height = 0; + if (rows == 0) + return 0; + if (rows > eti->length_threshold){ height = eti_row_height (eti, 0) * rows; @@ -138,14 +142,21 @@ eti_get_height (ETableItem *eti) for (row = 0; row < rows; row++) height += eti_row_height (eti, row); + /* Add division lines pixels */ + height += rows; + return height; } static void eti_table_model_changed (ETableModel *table_model, ETableItem *eti) { - eti->height = eti_get_height (eti); + eti->cols = e_table_model_column_count (eti->table_model); + eti->rows = e_table_model_row_count (eti->table_model); + if (eti->cell_views) + eti->height = eti_get_height (eti); + eti_update (GNOME_CANVAS_ITEM (eti), NULL, NULL, 0); } @@ -159,11 +170,56 @@ eti_request_redraw (ETableItem *eti) eti->y1 + eti->height + 1); } +static int +eti_col_diff (ETableItem *eti, int start_col, int end_col) +{ + int col, total; + + total = 0; + for (col = start_col; col < end_col; col++){ + ETableCol *ecol = e_table_header_get_column (eti->header, col); + + total += ecol->width; + } + + return total; +} + +static int +eti_row_diff (ETableItem *eti, int start_row, int end_row) +{ + int row, total; + + total = 0; + + for (row = start_row; row < end_row; row++) + total += eti_row_height (eti, row) + 1; + + return total; +} + +static void +eti_request_region_redraw (ETableItem *eti, int start_col, int start_row, int end_col, int end_row) +{ + GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas; + int x1, y1, width, height; + int col, row; + + x1 = eti_col_diff (eti, 0, start_col); + y1 = eti_row_diff (eti, 0, start_row); + width = eti_col_diff (eti, start_col, end_col); + height = eti_row_diff (eti, start_col, end_row); + + gnome_canvas_request_redraw (canvas, + eti->x1 + x1, eti->y1 + y1, + eti->y1 + width + 1, + eti->x1 + height + 1); +} + static void eti_table_model_row_selection (ETableModel *table_model, int row, gboolean selected, ETableItem *eti) { - /* FIXME: we should optimize this to only redraw the selection change */ - eti_request_redraw (eti); + eti_request_region_redraw (eti, 0, row, eti->cols, row); } static void @@ -173,12 +229,14 @@ eti_add_table_model (ETableItem *eti, ETableModel *table_model) eti->table_model = table_model; gtk_object_ref (GTK_OBJECT (table_model)); + eti->table_model_change_id = gtk_signal_connect ( GTK_OBJECT (table_model), "model_changed", GTK_SIGNAL_FUNC (eti_table_model_changed), eti); eti->table_model_selection_id = gtk_signal_connect ( GTK_OBJECT (table_model), "row_selection", GTK_SIGNAL_FUNC (eti_table_model_row_selection), eti); + eti_table_model_changed (table_model, eti); } static void @@ -269,6 +327,8 @@ eti_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) eti->length_threshold = GTK_VALUE_INT (*arg); break; + case ARG_TABLE_DRAW_GRID: + eti->draw_grid = GTK_VALUE_BOOL (*arg); } eti_update (item, NULL, NULL, 0); } @@ -300,7 +360,7 @@ eti_realize (GnomeCanvasItem *item) eti->fill_gc = canvas_widget->style->white_gc; gdk_gc_ref (canvas_widget->style->white_gc); eti->grid_gc = gdk_gc_new (window); - gdk_gc_set_foreground (eti->grid_gc, &canvas_widget->style->fg [GTK_STATE_NORMAL]); + gdk_gc_set_foreground (eti->grid_gc, &canvas_widget->style->bg [GTK_STATE_NORMAL]); eti_realize_cell_views (eti); @@ -354,12 +414,15 @@ static void eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height) { ETableItem *eti = E_TABLE_ITEM (item); - const int rows = e_table_model_row_count (eti->table_model); - const int cols = e_table_header_count (eti->header); + const int rows = eti->rows; + const int cols = eti->cols; int row, col, y1, y2; int first_col, last_col, x_offset; + int first_row, last_row, y_offset, yd; int x1, x2; + int heights; + printf ("Rect: %d %d %d %d\n", x, y, width, height); /* * Clear the background */ @@ -395,17 +458,15 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, if (first_col == -1) return; -#if 0 - printf ("Cols %d %d\n", first_col, last_col); -#endif - /* - * Draw individual lines + * Compute row span. */ + first_row = -1; + y_offset = 0; y1 = y2 = eti->y1; for (row = eti->top_item; row < rows; row++, y1 = y2){ int xd; - + y2 += eti_row_height (eti, row); if (y1 > y + height) @@ -413,17 +474,38 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, if (y2 < y) continue; + + if (first_row == -1){ + y_offset = y1 - y; + first_row = row; + } + } + last_row = row; + + if (first_row == -1) + return; + + /* + * Draw cells + */ + yd = y_offset; + for (row = first_row; row < last_row; row++){ + int xd, height; - if (eti->draw_grid) - gdk_draw_line (drawable, eti->grid_gc, 0, y - y2, width, y - y2); + height = eti_row_height (eti, row); xd = x_offset; + printf ("paint: %d %d\n", yd, yd + height); for (col = first_col; col < last_col; col++){ ETableCol *ecol = e_table_header_get_column (eti->header, col); - draw_cell (eti, drawable, col, row, xd, y1 - y, xd + ecol->width, y2 - y); + draw_cell (eti, drawable, col, row, xd, yd, xd + ecol->width, yd + height); + xd += ecol->width; } + yd += height + 1; + gdk_draw_line (drawable, eti->grid_gc, + eti->x1 - x, yd -1, eti->x1 + eti->width - x, yd -1); } } @@ -439,8 +521,8 @@ eti_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, static gboolean find_cell (ETableItem *eti, double x, double y, int *col_res, int *row_res) { - const int cols = e_table_header_count (eti->header); - const int rows = e_table_model_row_count (eti->table_model); + const int cols = eti->cols; + const int rows = eti->rows; gdouble x1, y1, x2, y2; int col, row; @@ -470,7 +552,7 @@ find_cell (ETableItem *eti, double x, double y, int *col_res, int *row_res) if (y < y1) return FALSE; - y2 += eti_row_height (eti, row); + y2 += eti_row_height (eti, row) + 1; if (y > y2) continue; @@ -482,6 +564,13 @@ find_cell (ETableItem *eti, double x, double y, int *col_res, int *row_res) return TRUE; } +static void +eti_select (ETableItem *eti, int col, int row) +{ + eti->selected_col = col; + eti->selected_row = row; +} + static int eti_event (GnomeCanvasItem *item, GdkEvent *e) { @@ -493,13 +582,16 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e) case GDK_BUTTON_RELEASE: case GDK_2BUTTON_PRESS: { int col, row; - + if (!find_cell (eti, e->button.x, e->button.y, &col, &row)) return TRUE; - ecell_view = eti->cell_views [col]; - printf ("Found: %d %d\n", col, row); - e_cell_event (ecell_view, e, col, row); + if (eti->selected_row == row && eti->selected_col == col){ + ecell_view = eti->cell_views [col]; + + e_cell_event (ecell_view, e, col, row); + } else + eti_select (eti, col, row); break; } @@ -544,6 +636,8 @@ eti_class_init (GtkObjectClass *object_class) GTK_ARG_WRITABLE, ARG_TABLE_X); gtk_object_add_arg_type ("ETableItem::y", GTK_TYPE_INT, GTK_ARG_WRITABLE, ARG_TABLE_Y); + gtk_object_add_arg_type ("ETableItem::drawgrid", GTK_TYPE_BOOL, + GTK_ARG_WRITABLE, ARG_TABLE_DRAW_GRID); } GtkType diff --git a/widgets/table/e-table-item.h b/widgets/table/e-table-item.h index b4b4c73361..fc36363413 100644 --- a/widgets/table/e-table-item.h +++ b/widgets/table/e-table-item.h @@ -20,6 +20,7 @@ typedef struct { int width, height; int top_item; + int cols, rows; /* * Ids for the signals we connect to @@ -47,6 +48,8 @@ typedef struct { * the size */ int length_threshold; + + int selected_col, selected_row; } ETableItem; typedef struct { diff --git a/widgets/table/table-test.c b/widgets/table/table-test.c index d7c14e900f..73be9e5ecd 100644 --- a/widgets/table/table-test.c +++ b/widgets/table/table-test.c @@ -233,6 +233,7 @@ main (int argc, char *argv []) "ETableModel", e_table_model, "x", 10, "y", 30, + "drawgrid", TRUE, NULL); gtk_main (); |