diff options
author | Chris Toshok <toshok@ximian.com> | 2003-02-17 10:38:15 +0800 |
---|---|---|
committer | Chris Toshok <toshok@src.gnome.org> | 2003-02-17 10:38:15 +0800 |
commit | baa50a5c8934d74573914b6425a5457f420fba93 (patch) | |
tree | 1364d3782247632088cf6b0bfe97bfbcd08e8ae8 /widgets/misc/e-reflow.c | |
parent | 9e048335b618fea2076c690479cd655d35a56515 (diff) | |
download | gsoc2013-evolution-baa50a5c8934d74573914b6425a5457f420fba93.tar.gz gsoc2013-evolution-baa50a5c8934d74573914b6425a5457f420fba93.tar.zst gsoc2013-evolution-baa50a5c8934d74573914b6425a5457f420fba93.zip |
enable this function to reflow the view from a particular column onward.
2003-02-16 Chris Toshok <toshok@ximian.com>
* gal/widgets/e-reflow.c (reflow_columns): enable this function to
reflow the view from a particular column onward. This is useful
if you have a huge model and the only changes are happening at the
end (as is normally the case if you're appending to a large
model.)
(item_changed): calculate the height of the changed item here, so
we aren't doing it as we reflow the model. For now, reflow the
entire model. Further optimization can be done here.
(item_removed): new function. remove the item and reflow from the
column that contained it.
(items_inserted): calculate the heights of the new items, and
calculate the lowest numbered column containing one of the
inserted items. reflow from there.
(model_changed): calculate the heights of everything here.
(comparison_changed): new function, clear the sorter and reflow.
(disconnect_model): disconnect comparison_changed and
model_item_removed.
(connect_model): connect comparison_changed and
model_item_removed.
(adjustment_changed): use queue_incarnate here, instead of forcing
the reflow model to incarnate as we scroll. Not sure if this is
actually the right solution, but it does make the scrollbar more
responsive at the cost of redraw speed.
* gal/widgets/e-reflow.h (struct _EReflow): add slots for the new
signal ids, as well as "reflow_from_column".
* gal/widgets/e-reflow-model.c (e_reflow_model_class_init): create
the comparison_changed and model_item_removed signals.
(e_reflow_model_comparison_changed): new function, emit the
comparison_changed signal.
(e_reflow_model_item_removed): new function, emit the
model_item_removed signal.
* gal/widgets/e-reflow-model.h: add comparison_changed and
model_item_removed signals.
svn path=/trunk/; revision=19917
Diffstat (limited to 'widgets/misc/e-reflow.c')
-rw-r--r-- | widgets/misc/e-reflow.c | 114 |
1 files changed, 92 insertions, 22 deletions
diff --git a/widgets/misc/e-reflow.c b/widgets/misc/e-reflow.c index e70cd61d0b..70b1f4a470 100644 --- a/widgets/misc/e-reflow.c +++ b/widgets/misc/e-reflow.c @@ -257,28 +257,32 @@ reflow_columns (EReflow *reflow) { GSList *list; int count; + int start; int i; - int column_count; + int column_count, column_start; double running_height; - g_free (reflow->columns); - reflow->column_count = 0; - reflow->columns = NULL; + if (reflow->reflow_from_column <= 1) { + start = 0; + column_count = 1; + column_start = 0; + } + else { + /* we start one column before the earliest new entry, + so we can handle the case where the new entry is + inserted at the start of the column */ + column_start = reflow->reflow_from_column - 1; + start = reflow->columns[column_start]; + column_count = column_start; + } list = NULL; running_height = E_REFLOW_BORDER_WIDTH; - column_count = 1; - count = reflow->count; - for (i = 0; i < count; i++) { + count = reflow->count - start; + for (i = start; i < count; i++) { int unsorted = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), i); - if (reflow->heights[unsorted] == -1) { - if (reflow->model) - reflow->heights[unsorted] = e_reflow_model_height (reflow->model, unsorted, GNOME_CANVAS_GROUP (reflow)); - else - reflow->heights[unsorted] = 0; - } if (i != 0 && running_height + reflow->heights[unsorted] + E_REFLOW_BORDER_WIDTH > reflow->height) { list = g_slist_prepend (list, GINT_TO_POINTER(i)); column_count ++; @@ -288,20 +292,22 @@ reflow_columns (EReflow *reflow) } reflow->column_count = column_count; - reflow->columns = g_new (int, column_count); + reflow->columns = g_renew (int, reflow->columns, column_count); column_count --; - for (; column_count > 0; column_count--) { + + for (; column_count > column_start; column_count--) { GSList *to_free; reflow->columns[column_count] = GPOINTER_TO_INT(list->data); to_free = list; list = list->next; g_slist_free_1 (to_free); } - reflow->columns[0] = 0; + reflow->columns[column_start] = start; queue_incarnate (reflow); reflow->need_reflow_columns = FALSE; + reflow->reflow_from_column = -1; } static void @@ -310,19 +316,46 @@ item_changed (EReflowModel *model, int i, EReflow *reflow) if (i < 0 || i >= reflow->count) return; - reflow->heights[i] = -1; + reflow->heights[i] = e_reflow_model_height (reflow->model, i, GNOME_CANVAS_GROUP (reflow)); if (reflow->items[i] != NULL) e_reflow_model_reincarnate (model, i, reflow->items[i]); e_sorter_array_clean (reflow->sorter); + reflow->reflow_from_column = -1; reflow->need_reflow_columns = TRUE; e_canvas_item_request_reflow(GNOME_CANVAS_ITEM (reflow)); } static void +item_removed (EReflowModel *model, int i, EReflow *reflow) +{ + int c; + int sorted; + + if (i < 0 || i >= reflow->count) + return; + + sorted = e_sorter_model_to_sorted (E_SORTER (reflow->sorter), i); + for (c = reflow->column_count - 1; c >= 0; c--) { + int start_of_column = reflow->columns[c]; + + if (start_of_column <= sorted) { + reflow->reflow_from_column = c; + reflow->need_reflow_columns = TRUE; + set_empty (reflow); + e_canvas_item_request_reflow(GNOME_CANVAS_ITEM (reflow)); + + break; + } + } +} + +static void items_inserted (EReflowModel *model, int position, int count, EReflow *reflow) { - int i; + int i, c; int oldcount; + int lowest_column; + if (position < 0 || position > reflow->count) return; @@ -340,7 +373,7 @@ items_inserted (EReflowModel *model, int position, int count, EReflow *reflow) memmove (reflow->items + position + count, reflow->items + position, (reflow->count - position - count) * sizeof (GnomeCanvasItem *)); for (i = position; i < position + count; i++) { reflow->items[i] = 0; - reflow->heights[i] = -1; + reflow->heights[i] = e_reflow_model_height (reflow->model, i, GNOME_CANVAS_GROUP (reflow)); } e_selection_model_simple_set_row_count (E_SELECTION_MODEL_SIMPLE (reflow->selection), reflow->count); @@ -348,6 +381,23 @@ items_inserted (EReflowModel *model, int position, int count, EReflow *reflow) e_sorter_array_append (reflow->sorter, count); else e_sorter_array_set_count (reflow->sorter, reflow->count); + + for (i = position; i < position + count; i ++) { + int sorted = e_sorter_model_to_sorted (E_SORTER (reflow->sorter), i); + int c; + + for (c = reflow->column_count - 1; c >= 0; c--) { + int start_of_column = reflow->columns[c]; + + if (start_of_column <= sorted) { + if (reflow->reflow_from_column == -1 + || reflow->reflow_from_column > c) + reflow->reflow_from_column = c; + break; + } + } + } + reflow->need_reflow_columns = TRUE; set_empty (reflow); e_canvas_item_request_reflow(GNOME_CANVAS_ITEM (reflow)); @@ -377,7 +427,7 @@ model_changed (EReflowModel *model, EReflow *reflow) count = reflow->count; for (i = 0; i < count; i++) { reflow->items[i] = 0; - reflow->heights[i] = -1; + reflow->heights[i] = e_reflow_model_height (reflow->model, i, GNOME_CANVAS_GROUP (reflow)); } e_selection_model_simple_set_row_count (E_SELECTION_MODEL_SIMPLE (reflow->selection), count); @@ -391,6 +441,15 @@ model_changed (EReflowModel *model, EReflow *reflow) } static void +comparison_changed (EReflowModel *model, EReflow *reflow) +{ + e_sorter_array_clean (reflow->sorter); + reflow->reflow_from_column = -1; + reflow->need_reflow_columns = TRUE; + e_canvas_item_request_reflow(GNOME_CANVAS_ITEM (reflow)); +} + +static void set_empty(EReflow *reflow) { if (reflow->count == 0) { @@ -416,7 +475,6 @@ set_empty(EReflow *reflow) "width", reflow->minimum_width, "clip", TRUE, "use_ellipsis", TRUE, - "font_gdk", gtk_style_get_font (GTK_WIDGET(GNOME_CANVAS_ITEM(reflow)->canvas)->style), "fill_color", "black", "justification", GTK_JUSTIFY_CENTER, "text", reflow->empty_message, @@ -444,13 +502,19 @@ disconnect_model (EReflow *reflow) g_signal_handler_disconnect (reflow->model, reflow->model_changed_id); g_signal_handler_disconnect (reflow->model, + reflow->comparison_changed_id); + g_signal_handler_disconnect (reflow->model, reflow->model_items_inserted_id); g_signal_handler_disconnect (reflow->model, + reflow->model_item_removed_id); + g_signal_handler_disconnect (reflow->model, reflow->model_item_changed_id); g_object_unref (reflow->model); reflow->model_changed_id = 0; + reflow->comparison_changed_id = 0; reflow->model_items_inserted_id = 0; + reflow->model_item_removed_id = 0; reflow->model_item_changed_id = 0; reflow->model = NULL; } @@ -489,9 +553,15 @@ connect_model (EReflow *reflow, EReflowModel *model) reflow->model_changed_id = g_signal_connect (reflow->model, "model_changed", G_CALLBACK (model_changed), reflow); + reflow->comparison_changed_id = + g_signal_connect (reflow->model, "comparison_changed", + G_CALLBACK (comparison_changed), reflow); reflow->model_items_inserted_id = g_signal_connect (reflow->model, "model_items_inserted", G_CALLBACK (items_inserted), reflow); + reflow->model_item_removed_id = + g_signal_connect (reflow->model, "model_item_removed", + G_CALLBACK (item_removed), reflow); reflow->model_item_changed_id = g_signal_connect (reflow->model, "model_item_changed", G_CALLBACK (item_changed), reflow); @@ -501,7 +571,7 @@ connect_model (EReflow *reflow, EReflowModel *model) static void adjustment_changed (GtkAdjustment *adjustment, EReflow *reflow) { - incarnate (reflow); + queue_incarnate (reflow); } static void |