mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-05 16:20:10 +00:00
Lots of scrolling fixes. Made scrolling work properly in not fully
2006-12-26 Kristian Rietveld <kris@gtk.org> Lots of scrolling fixes. Made scrolling work properly in not fully validated tree views; fixed a bunch of corner cases. * gtk/gtktreeview.c (validate_visible_area): if a row's dy is past upper - page_size, we know it is located at the end so the test for dy + height has been dropped. In the same case if area_below < 0, we know this is the last node in the tree view so area_above is page_size - height of this row. (validate_visible_area): got rid of subtracting new_height - old_height from area_{below,above}, it didn't make any sense at all and the full height of the row should be subtracted instead. (validate_visible_area): when scrolling to a given path, set the top row directly together with the dy offset, then sync that top_row to the dy. (gtk_tree_view_set_top_row): new function to directly set a top_row. (gtk_tree_view_dy_to_top_row): refactored to use gtk_tree_view_set_top_row(). (gtk_tree_view_top_row_to_dy): make sure dy >= 0 when done. (gtk_tree_view_adjustment_changed): only update our dy and top_row if the adjustment's dy actually changed.
This commit is contained in:
parent
0b75f7a30f
commit
a3bc63b9e2
23
ChangeLog
23
ChangeLog
@ -1,3 +1,26 @@
|
||||
2006-12-26 Kristian Rietveld <kris@gtk.org>
|
||||
|
||||
Lots of scrolling fixes. Made scrolling work properly in not fully
|
||||
validated tree views; fixed a bunch of corner cases.
|
||||
|
||||
* gtk/gtktreeview.c (validate_visible_area): if a row's dy is past
|
||||
upper - page_size, we know it is located at the end so the test for
|
||||
dy + height has been dropped.
|
||||
In the same case if area_below < 0, we know this is the last node
|
||||
in the tree view so area_above is page_size - height of this row.
|
||||
(validate_visible_area): got rid of subtracting new_height -
|
||||
old_height from area_{below,above}, it didn't make any sense at
|
||||
all and the full height of the row should be subtracted instead.
|
||||
(validate_visible_area): when scrolling to a given path, set the
|
||||
top row directly together with the dy offset, then sync that top_row
|
||||
to the dy.
|
||||
(gtk_tree_view_set_top_row): new function to directly set a top_row.
|
||||
(gtk_tree_view_dy_to_top_row): refactored to use
|
||||
gtk_tree_view_set_top_row().
|
||||
(gtk_tree_view_top_row_to_dy): make sure dy >= 0 when done.
|
||||
(gtk_tree_view_adjustment_changed): only update our dy and
|
||||
top_row if the adjustment's dy actually changed.
|
||||
|
||||
2006-12-26 Christian Persch <chpe@cvs.gnome.org>
|
||||
|
||||
* gtk/gtknotebook.c: (gtk_notebook_real_insert_page):
|
||||
|
@ -295,6 +295,9 @@ static gboolean validate_rows (GtkTreeView *tree_view);
|
||||
static gboolean presize_handler_callback (gpointer data);
|
||||
static void install_presize_handler (GtkTreeView *tree_view);
|
||||
static void install_scroll_sync_handler (GtkTreeView *tree_view);
|
||||
static void gtk_tree_view_set_top_row (GtkTreeView *tree_view,
|
||||
GtkTreePath *path,
|
||||
gint offset);
|
||||
static void gtk_tree_view_dy_to_top_row (GtkTreeView *tree_view);
|
||||
static void gtk_tree_view_top_row_to_dy (GtkTreeView *tree_view);
|
||||
static void invalidate_empty_focus (GtkTreeView *tree_view);
|
||||
@ -5684,8 +5687,7 @@ validate_visible_area (GtkTreeView *tree_view)
|
||||
- area_above - height;
|
||||
}
|
||||
else if (dy >= (tree_view->priv->vadjustment->upper -
|
||||
tree_view->priv->vadjustment->page_size)
|
||||
&& dy + height <= tree_view->priv->vadjustment->upper)
|
||||
tree_view->priv->vadjustment->page_size))
|
||||
{
|
||||
/* row at the end -- fixed */
|
||||
area_above = dy - (tree_view->priv->vadjustment->upper -
|
||||
@ -5695,7 +5697,7 @@ validate_visible_area (GtkTreeView *tree_view)
|
||||
|
||||
if (area_below < 0)
|
||||
{
|
||||
area_above += area_below;
|
||||
area_above = tree_view->priv->vadjustment->page_size - height;
|
||||
area_below = 0;
|
||||
}
|
||||
}
|
||||
@ -5802,8 +5804,6 @@ validate_visible_area (GtkTreeView *tree_view)
|
||||
*/
|
||||
while (node && area_below > 0)
|
||||
{
|
||||
gint new_height;
|
||||
|
||||
if (node->children)
|
||||
{
|
||||
GtkTreeIter parent = iter;
|
||||
@ -5861,24 +5861,15 @@ validate_visible_area (GtkTreeView *tree_view)
|
||||
if (!node)
|
||||
break;
|
||||
|
||||
new_height = GTK_RBNODE_GET_HEIGHT (node);
|
||||
|
||||
if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) ||
|
||||
GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID))
|
||||
{
|
||||
gint old_height = new_height;
|
||||
|
||||
_gtk_tree_view_queue_draw_node (tree_view, tree, node, NULL);
|
||||
if (validate_row (tree_view, tree, node, &iter, path))
|
||||
{
|
||||
new_height = GTK_RBNODE_GET_HEIGHT (node);
|
||||
size_changed = TRUE;
|
||||
|
||||
area_below -= new_height - old_height;
|
||||
}
|
||||
}
|
||||
|
||||
area_below -= ROW_HEIGHT (tree_view, new_height);
|
||||
area_below -= ROW_HEIGHT (tree_view, GTK_RBNODE_GET_HEIGHT (node));
|
||||
}
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
@ -5892,8 +5883,6 @@ validate_visible_area (GtkTreeView *tree_view)
|
||||
/* We walk backwards */
|
||||
while (area_above > 0)
|
||||
{
|
||||
gint new_height;
|
||||
|
||||
_gtk_rbtree_prev_full (tree, node, &tree, &node);
|
||||
if (! gtk_tree_path_prev (above_path) && node != NULL)
|
||||
{
|
||||
@ -5905,23 +5894,14 @@ validate_visible_area (GtkTreeView *tree_view)
|
||||
if (node == NULL)
|
||||
break;
|
||||
|
||||
new_height = GTK_RBNODE_GET_HEIGHT (node);
|
||||
|
||||
if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) ||
|
||||
GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID))
|
||||
{
|
||||
gint old_height = new_height;
|
||||
|
||||
_gtk_tree_view_queue_draw_node (tree_view, tree, node, NULL);
|
||||
if (validate_row (tree_view, tree, node, &iter, above_path))
|
||||
{
|
||||
new_height = GTK_RBNODE_GET_HEIGHT (node);
|
||||
size_changed = TRUE;
|
||||
|
||||
area_above -= new_height - old_height;
|
||||
}
|
||||
size_changed = TRUE;
|
||||
}
|
||||
area_above -= ROW_HEIGHT (tree_view, new_height);
|
||||
area_above -= ROW_HEIGHT (tree_view, GTK_RBNODE_GET_HEIGHT (node));
|
||||
}
|
||||
|
||||
/* if we scrolled to a path, we need to set the dy here,
|
||||
@ -5929,15 +5909,8 @@ validate_visible_area (GtkTreeView *tree_view)
|
||||
*/
|
||||
if (tree_view->priv->scroll_to_path)
|
||||
{
|
||||
gint dy;
|
||||
|
||||
if (node != NULL)
|
||||
dy = _gtk_rbtree_node_find_offset (tree, node) - area_above;
|
||||
else
|
||||
dy = 0;
|
||||
|
||||
gtk_adjustment_set_value (tree_view->priv->vadjustment, dy);
|
||||
gtk_tree_view_dy_to_top_row (tree_view);
|
||||
gtk_tree_view_set_top_row (tree_view, above_path, -area_above);
|
||||
gtk_tree_view_top_row_to_dy (tree_view);
|
||||
|
||||
need_redraw = TRUE;
|
||||
}
|
||||
@ -6278,33 +6251,49 @@ install_scroll_sync_handler (GtkTreeView *tree_view)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_view_set_top_row (GtkTreeView *tree_view,
|
||||
GtkTreePath *path,
|
||||
gint offset)
|
||||
{
|
||||
gtk_tree_row_reference_free (tree_view->priv->top_row);
|
||||
|
||||
if (!path)
|
||||
{
|
||||
tree_view->priv->top_row = NULL;
|
||||
tree_view->priv->top_row_dy = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tree_view->priv->top_row = gtk_tree_row_reference_new_proxy (G_OBJECT (tree_view), tree_view->priv->model, path);
|
||||
tree_view->priv->top_row_dy = offset;
|
||||
}
|
||||
}
|
||||
|
||||
/* Always call this iff dy is in the visible range. If the tree is empty, then
|
||||
* it's set to be NULL, and top_row_dy is 0;
|
||||
*/
|
||||
static void
|
||||
gtk_tree_view_dy_to_top_row (GtkTreeView *tree_view)
|
||||
{
|
||||
gint offset;
|
||||
GtkTreePath *path;
|
||||
GtkRBTree *tree;
|
||||
GtkRBNode *node;
|
||||
|
||||
gtk_tree_row_reference_free (tree_view->priv->top_row);
|
||||
if (tree_view->priv->tree == NULL)
|
||||
tree = NULL;
|
||||
else
|
||||
tree_view->priv->top_row_dy = _gtk_rbtree_find_offset (tree_view->priv->tree,
|
||||
tree_view->priv->dy,
|
||||
&tree, &node);
|
||||
if (tree == NULL)
|
||||
{
|
||||
tree_view->priv->top_row = NULL;
|
||||
tree_view->priv->top_row_dy = 0;
|
||||
return;
|
||||
gtk_tree_view_set_top_row (tree_view, NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = _gtk_rbtree_find_offset (tree_view->priv->tree,
|
||||
tree_view->priv->dy,
|
||||
&tree, &node);
|
||||
path = _gtk_tree_view_find_path (tree_view, tree, node);
|
||||
gtk_tree_view_set_top_row (tree_view, path, offset);
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
|
||||
path = _gtk_tree_view_find_path (tree_view, tree, node);
|
||||
tree_view->priv->top_row = gtk_tree_row_reference_new_proxy (G_OBJECT (tree_view), tree_view->priv->model, path);
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -6352,6 +6341,8 @@ gtk_tree_view_top_row_to_dy (GtkTreeView *tree_view)
|
||||
if (tree_view->priv->dy + tree_view->priv->vadjustment->page_size > tree_view->priv->height)
|
||||
tree_view->priv->dy = tree_view->priv->height - tree_view->priv->vadjustment->page_size;
|
||||
|
||||
tree_view->priv->dy = MAX (0, tree_view->priv->dy);
|
||||
|
||||
gtk_adjustment_set_value (tree_view->priv->vadjustment,
|
||||
(gdouble)tree_view->priv->dy);
|
||||
}
|
||||
@ -10368,9 +10359,12 @@ gtk_tree_view_adjustment_changed (GtkAdjustment *adjustment,
|
||||
}
|
||||
gdk_window_scroll (tree_view->priv->bin_window, 0, dy);
|
||||
|
||||
/* update our dy and top_row */
|
||||
tree_view->priv->dy = (int) tree_view->priv->vadjustment->value;
|
||||
gtk_tree_view_dy_to_top_row (tree_view);
|
||||
if (tree_view->priv->dy != (int) tree_view->priv->vadjustment->value)
|
||||
{
|
||||
/* update our dy and top_row */
|
||||
tree_view->priv->dy = (int) tree_view->priv->vadjustment->value;
|
||||
gtk_tree_view_dy_to_top_row (tree_view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user