forked from AuroraMiddleware/gtk
Minor fix.
Tue Dec 4 18:38:35 2001 Jonathan Blandford <jrb@redhat.com> * demos/gtk-demo/main.c: (create_tree): Minor fix. * docs/tree-column-sizing.txt: Update * gtk/gtkrbtree.[ch]: Massive work to support validation. * gtk/gtktreemodel.c: Doc fixes. * gtk/gtktreeview.c: Incremental reflow added. * gtk/gtktreeviewcolumn.c: ditto * gtk/gtktreeviewcolumn.h: ditto
This commit is contained in:
parent
57506c438b
commit
d1a858c837
@ -1,30 +1,19 @@
|
||||
The way that the GtkTreeView calculates sizing is pretty confusing.
|
||||
This is written down to help keep track of it in my head, and thus help
|
||||
anyone who hopes to work with the code in the future.
|
||||
-jrb
|
||||
|
||||
HOW THE GTKTREEVIEW CALCULATES SIZE:
|
||||
====================================
|
||||
When the view is given a new model, the first thing it does is walk
|
||||
When the view is given a new model, the first thing it does is walk
|
||||
through the model at the top level, creating an GtkRBNode for each
|
||||
element of the model. Each node has a height of 0. The RBTree is kept
|
||||
updated as the models structure changes. Additionally, the user can
|
||||
expand, collapse, and select rows at this stage. The RBTree is accurate
|
||||
-- it just doesn't have a height for any row.
|
||||
|
||||
When the TreeView is realized, it calculates the actual height of each
|
||||
row by walking the tree and measuring them. While doing so, it gets the
|
||||
size of each column.
|
||||
|
||||
|
||||
|
||||
Columns are initially marked as 'dirty'. When sized,
|
||||
gtk_tree_view_check_dirty_and_clean () is called on each column. This
|
||||
function walks through all visible columns, and sees if they're dirty or
|
||||
not. If any are dirty, it then walks the tree, calling
|
||||
gtk_tree_view_calc_size on each row. gtk_tree_view_calc_size requests
|
||||
the size of every dirty column in the tree. Finally, it updates the
|
||||
size of the widget (including adjustments).
|
||||
-- it just has a height of zero for every row.
|
||||
|
||||
When the widget is realized, it calls install_presize_handler, to setup
|
||||
the first-run function. This is run before the expose event.
|
||||
|
||||
HOW THE GTKTREEVIEWCOLUMN STORES SIZE:
|
||||
======================================
|
||||
@ -32,23 +21,46 @@ HOW THE GTKTREEVIEWCOLUMN STORES SIZE:
|
||||
There are a number of size related fields in the GtkTreeViewColumn
|
||||
structure. These are all valid after realization:
|
||||
|
||||
sizing The sizing method to use when calculating the size
|
||||
of the column. Can be grow_only, resizable, auto, and fixed.
|
||||
column_type The sizing method to use when calculating the size
|
||||
of the column. Can be GROW_ONLY, AUTO, and FIXED.
|
||||
|
||||
requested_width The width of the column as requested by the column
|
||||
button_request The width as requested by the button.
|
||||
|
||||
width The actual width. This is requested width for all
|
||||
columns but possibly the last one.
|
||||
requested_width The width of the column as requested by the column.
|
||||
It is the max requested width of the bcells in the
|
||||
column. If the column_type is AUTO, then it is
|
||||
recalculated when a column changes. Otherwise, it
|
||||
only grows.
|
||||
|
||||
resized_width The width after the user has resized the column.
|
||||
|
||||
width The actual width of the column as displayed.
|
||||
|
||||
fixed_width The requested fixed width for the column iff it's
|
||||
sizing type is set to GTK_TREE_VIEW_COLUMN_FIXED.
|
||||
Used instead of requested_width in that case.
|
||||
|
||||
min_width The minimum width the column can be
|
||||
min_width The minimum width the column can be. If set to -1,
|
||||
this field is considered unset.
|
||||
|
||||
max_width The maximum width the column can be. This can be
|
||||
overridden for the last column, if the tree_view is
|
||||
actually wider than the sum of all of the columns
|
||||
requested_widths.
|
||||
requested_widths. If set to -1, this field is
|
||||
considered unset.
|
||||
|
||||
|
||||
use_resized_width Use resized_width to determine the size.
|
||||
|
||||
|
||||
--
|
||||
tree_view->priv->width = the width the widget wants to be, including headers.
|
||||
tree_view->priv->height = the height the widget requests. It's the sum
|
||||
of the width of all visible columns.
|
||||
|
||||
Both of these are calculated in _gtk_tree_view_update_size
|
||||
|
||||
--
|
||||
|
||||
The following invariants are true:
|
||||
|
||||
@ -56,12 +68,9 @@ min_width is less than or equal to width
|
||||
|
||||
max_width is greater than or equal to width
|
||||
|
||||
min_width <= max_width
|
||||
|
||||
(sizing == GTK_TREE_VIEW_COLUMN_FIXED) => (requested_width == fixed_width)
|
||||
|
||||
(column != last visible column) => width == requested_width
|
||||
(column != last visible column) => width == CLAMP (requested_width, min_width, max_width)
|
||||
|
||||
|
||||
/* Functions needed by gtktreeview for gtktreeviewcolumn */
|
||||
size_request_button
|
||||
set_width (for resizing resizable columns)
|
||||
calculate_width
|
||||
|
121
gtk/gtkrbtree.c
121
gtk/gtkrbtree.c
@ -571,9 +571,10 @@ _gtk_rbtree_remove (GtkRBTree *tree)
|
||||
|
||||
|
||||
GtkRBNode *
|
||||
_gtk_rbtree_insert_after (GtkRBTree *tree,
|
||||
GtkRBNode *current,
|
||||
gint height)
|
||||
_gtk_rbtree_insert_after (GtkRBTree *tree,
|
||||
GtkRBNode *current,
|
||||
gint height,
|
||||
gboolean valid)
|
||||
{
|
||||
GtkRBNode *node;
|
||||
gboolean right = TRUE;
|
||||
@ -633,13 +634,19 @@ _gtk_rbtree_insert_after (GtkRBTree *tree,
|
||||
if (gtk_debug_flags & GTK_DEBUG_TREE)
|
||||
_gtk_rbtree_test (G_STRLOC, tree);
|
||||
|
||||
if (valid)
|
||||
_gtk_rbtree_node_mark_valid (tree, node);
|
||||
else
|
||||
_gtk_rbtree_node_mark_invalid (tree, node);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
GtkRBNode *
|
||||
_gtk_rbtree_insert_before (GtkRBTree *tree,
|
||||
GtkRBNode *current,
|
||||
gint height)
|
||||
_gtk_rbtree_insert_before (GtkRBTree *tree,
|
||||
GtkRBNode *current,
|
||||
gint height,
|
||||
gboolean valid)
|
||||
{
|
||||
GtkRBNode *node;
|
||||
gboolean left = TRUE;
|
||||
@ -699,6 +706,11 @@ _gtk_rbtree_insert_before (GtkRBTree *tree,
|
||||
if (gtk_debug_flags & GTK_DEBUG_TREE)
|
||||
_gtk_rbtree_test (G_STRLOC, tree);
|
||||
|
||||
if (valid)
|
||||
_gtk_rbtree_node_mark_valid (tree, node);
|
||||
else
|
||||
_gtk_rbtree_node_mark_invalid (tree, node);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -775,16 +787,20 @@ void
|
||||
_gtk_rbtree_node_mark_valid (GtkRBTree *tree,
|
||||
GtkRBNode *node)
|
||||
{
|
||||
if (! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID))
|
||||
if ((!GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID)) &&
|
||||
(!GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID)))
|
||||
return;
|
||||
|
||||
GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_INVALID);
|
||||
GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_COLUMN_INVALID);
|
||||
|
||||
do
|
||||
{
|
||||
if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) ||
|
||||
if ((GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID)) ||
|
||||
(GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID)) ||
|
||||
(node->children && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)) ||
|
||||
(node->left && GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) ||
|
||||
(node->right && GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)))
|
||||
(node->left != tree->nil && GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) ||
|
||||
(node->right != tree->nil && GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)))
|
||||
return;
|
||||
|
||||
GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
|
||||
@ -798,6 +814,34 @@ _gtk_rbtree_node_mark_valid (GtkRBTree *tree,
|
||||
while (node);
|
||||
}
|
||||
|
||||
|
||||
/* Assume tree is the root node as it doesn't set DESCENDANTS_INVALID above.
|
||||
*/
|
||||
void
|
||||
_gtk_rbtree_column_invalid (GtkRBTree *tree)
|
||||
{
|
||||
GtkRBNode *node;
|
||||
|
||||
if (tree == NULL)
|
||||
return;
|
||||
node = tree->root;
|
||||
g_assert (node);
|
||||
|
||||
while (node->left != tree->nil)
|
||||
node = node->left;
|
||||
|
||||
do
|
||||
{
|
||||
if (! (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID)))
|
||||
GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_COLUMN_INVALID);
|
||||
GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
|
||||
|
||||
if (node->children)
|
||||
_gtk_rbtree_column_invalid (node->children);
|
||||
}
|
||||
while ((node = _gtk_rbtree_next (tree, node)) != NULL);
|
||||
}
|
||||
|
||||
typedef struct _GtkRBReorder
|
||||
{
|
||||
GtkRBTree *children;
|
||||
@ -849,6 +893,14 @@ gtk_rbtree_reorder_fixup (GtkRBTree *tree,
|
||||
node->offset += node->children->root->offset;
|
||||
node->parity += node->children->root->parity;
|
||||
}
|
||||
|
||||
if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) ||
|
||||
(node->right != tree->nil && GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID)) ||
|
||||
(node->left != tree->nil && GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID)) ||
|
||||
(node->children && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)))
|
||||
GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
|
||||
else
|
||||
GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_DESCENDANTS_INVALID);
|
||||
}
|
||||
|
||||
/* It basically pulls everything out of the tree, rearranges it, and puts it
|
||||
@ -990,20 +1042,24 @@ _gtk_rbtree_node_find_parity (GtkRBTree *tree,
|
||||
}
|
||||
|
||||
gint
|
||||
_gtk_rbtree_find_offset (GtkRBTree *tree,
|
||||
gint height,
|
||||
GtkRBTree **new_tree,
|
||||
GtkRBNode **new_node)
|
||||
_gtk_rbtree_real_find_offset (GtkRBTree *tree,
|
||||
gint height,
|
||||
GtkRBTree **new_tree,
|
||||
GtkRBNode **new_node)
|
||||
{
|
||||
GtkRBNode *tmp_node;
|
||||
|
||||
g_assert (tree);
|
||||
|
||||
if (height < 0)
|
||||
{
|
||||
*new_tree = NULL;
|
||||
*new_node = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
tmp_node = tree->root;
|
||||
while (tmp_node != tree->nil &&
|
||||
(tmp_node->left->offset > height ||
|
||||
@ -1033,20 +1089,40 @@ _gtk_rbtree_find_offset (GtkRBTree *tree,
|
||||
*new_node = tmp_node;
|
||||
return (height - tmp_node->left->offset);
|
||||
}
|
||||
return _gtk_rbtree_find_offset (tmp_node->children,
|
||||
height - tmp_node->left->offset -
|
||||
(tmp_node->offset -
|
||||
tmp_node->left->offset -
|
||||
tmp_node->right->offset -
|
||||
tmp_node->children->root->offset),
|
||||
new_tree,
|
||||
new_node);
|
||||
return _gtk_rbtree_real_find_offset (tmp_node->children,
|
||||
height - tmp_node->left->offset -
|
||||
(tmp_node->offset -
|
||||
tmp_node->left->offset -
|
||||
tmp_node->right->offset -
|
||||
tmp_node->children->root->offset),
|
||||
new_tree,
|
||||
new_node);
|
||||
}
|
||||
*new_tree = tree;
|
||||
*new_node = tmp_node;
|
||||
return (height - tmp_node->left->offset);
|
||||
}
|
||||
|
||||
gint
|
||||
_gtk_rbtree_find_offset (GtkRBTree *tree,
|
||||
gint height,
|
||||
GtkRBTree **new_tree,
|
||||
GtkRBNode **new_node)
|
||||
{
|
||||
GtkRBNode *tmp_node;
|
||||
|
||||
g_assert (tree);
|
||||
|
||||
if ((height < 0) ||
|
||||
(height >= tree->root->offset))
|
||||
{
|
||||
*new_tree = NULL;
|
||||
*new_node = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
_gtk_rbtree_real_find_offset (tree, height, new_tree, new_node);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_rbtree_remove_node (GtkRBTree *tree,
|
||||
@ -1069,7 +1145,6 @@ _gtk_rbtree_remove_node (GtkRBTree *tree,
|
||||
if (gtk_debug_flags & GTK_DEBUG_TREE)
|
||||
_gtk_rbtree_test (G_STRLOC, tree);
|
||||
|
||||
|
||||
if (node->left == tree->nil || node->right == tree->nil)
|
||||
{
|
||||
y = node;
|
||||
|
@ -37,8 +37,16 @@ typedef enum
|
||||
GTK_RBNODE_IS_SEMI_COLLAPSED = 1 << 5,
|
||||
GTK_RBNODE_IS_SEMI_EXPANDED = 1 << 6,
|
||||
GTK_RBNODE_INVALID = 1 << 7,
|
||||
GTK_RBNODE_DESCENDANTS_INVALID = 1 << 8,
|
||||
GTK_RBNODE_NON_COLORS = GTK_RBNODE_IS_PARENT | GTK_RBNODE_IS_SELECTED | GTK_RBNODE_IS_PRELIT | GTK_RBNODE_IS_SEMI_COLLAPSED | GTK_RBNODE_IS_SEMI_EXPANDED | GTK_RBNODE_INVALID | GTK_RBNODE_DESCENDANTS_INVALID
|
||||
GTK_RBNODE_COLUMN_INVALID = 1 << 8,
|
||||
GTK_RBNODE_DESCENDANTS_INVALID = 1 << 9,
|
||||
GTK_RBNODE_NON_COLORS = GTK_RBNODE_IS_PARENT |
|
||||
GTK_RBNODE_IS_SELECTED |
|
||||
GTK_RBNODE_IS_PRELIT |
|
||||
GTK_RBNODE_IS_SEMI_COLLAPSED |
|
||||
GTK_RBNODE_IS_SEMI_EXPANDED |
|
||||
GTK_RBNODE_INVALID |
|
||||
GTK_RBNODE_COLUMN_INVALID |
|
||||
GTK_RBNODE_DESCENDANTS_INVALID
|
||||
} GtkRBNodeColor;
|
||||
|
||||
typedef struct _GtkRBTree GtkRBTree;
|
||||
@ -93,6 +101,7 @@ struct _GtkRBNode
|
||||
GtkRBTree *children;
|
||||
};
|
||||
|
||||
|
||||
#define GTK_RBNODE_GET_COLOR(node) (node?(((node->flags>K_RBNODE_RED)==GTK_RBNODE_RED)?GTK_RBNODE_RED:GTK_RBNODE_BLACK):GTK_RBNODE_BLACK)
|
||||
#define GTK_RBNODE_SET_COLOR(node,color) if((node->flags&color)!=color)node->flags=node->flags^(GTK_RBNODE_RED|GTK_RBNODE_BLACK)
|
||||
#define GTK_RBNODE_GET_HEIGHT(node) (node->offset-(node->left->offset+node->right->offset+(node->children?node->children->root->offset:0)))
|
||||
@ -109,10 +118,12 @@ void _gtk_rbtree_remove (GtkRBTree *tree);
|
||||
void _gtk_rbtree_destroy (GtkRBTree *tree);
|
||||
GtkRBNode *_gtk_rbtree_insert_before (GtkRBTree *tree,
|
||||
GtkRBNode *node,
|
||||
gint height);
|
||||
gint height,
|
||||
gboolean valid);
|
||||
GtkRBNode *_gtk_rbtree_insert_after (GtkRBTree *tree,
|
||||
GtkRBNode *node,
|
||||
gint height);
|
||||
gint height,
|
||||
gboolean valid);
|
||||
void _gtk_rbtree_remove_node (GtkRBTree *tree,
|
||||
GtkRBNode *node);
|
||||
void _gtk_rbtree_reorder (GtkRBTree *tree,
|
||||
@ -127,6 +138,7 @@ void _gtk_rbtree_node_mark_invalid(GtkRBTree *tree,
|
||||
GtkRBNode *node);
|
||||
void _gtk_rbtree_node_mark_valid (GtkRBTree *tree,
|
||||
GtkRBNode *node);
|
||||
void _gtk_rbtree_column_invalid (GtkRBTree *tree);
|
||||
gint _gtk_rbtree_node_find_offset (GtkRBTree *tree,
|
||||
GtkRBNode *node);
|
||||
gint _gtk_rbtree_node_find_parity (GtkRBTree *tree,
|
||||
|
@ -1093,6 +1093,16 @@ gtk_tree_model_row_has_child_toggled (GtkTreeModel *tree_model,
|
||||
g_signal_emit_by_name (tree_model, "row_has_child_toggled", path, iter);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_tree_model_row_deleted:
|
||||
* @tree_model: A #GtkTreeModel
|
||||
* @path: A #GtkTreePath pointing to the previous location of the deleted row.
|
||||
*
|
||||
* Emits the "row_deleted" signal on @tree_model. This should be called by
|
||||
* models after a row has been removed. The location pointed to by @path should
|
||||
* be the location that the row previously was at. It may not be a valid
|
||||
* location anymore.
|
||||
**/
|
||||
void
|
||||
gtk_tree_model_row_deleted (GtkTreeModel *tree_model,
|
||||
GtkTreePath *path)
|
||||
|
@ -29,8 +29,6 @@ extern "C" {
|
||||
#include <gtk/gtktreeselection.h>
|
||||
#include <gtk/gtkrbtree.h>
|
||||
|
||||
|
||||
|
||||
#define TREE_VIEW_DRAG_WIDTH 6
|
||||
|
||||
typedef enum
|
||||
@ -53,11 +51,12 @@ enum
|
||||
DRAG_COLUMN_WINDOW_STATE_ARROW_LEFT = 3,
|
||||
DRAG_COLUMN_WINDOW_STATE_ARROW_RIGHT = 4
|
||||
};
|
||||
|
||||
#define GTK_TREE_VIEW_SET_FLAG(tree_view, flag) G_STMT_START{ (tree_view->priv->flags|=flag); }G_STMT_END
|
||||
#define GTK_TREE_VIEW_UNSET_FLAG(tree_view, flag) G_STMT_START{ (tree_view->priv->flags&=~(flag)); }G_STMT_END
|
||||
#define GTK_TREE_VIEW_FLAG_SET(tree_view, flag) ((tree_view->priv->flags&flag)==flag)
|
||||
#define TREE_VIEW_HEADER_HEIGHT(tree_view) (GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_HEADERS_VISIBLE)?tree_view->priv->header_height:0)
|
||||
#define TREE_VIEW_COLUMN_WIDTH(column) (CLAMP (column->width, (column->min_width!=-1)?column->min_width:column->width, (column->max_width!=-1)?column->max_width:column->width))
|
||||
#define TREE_VIEW_COLUMN_REQUESTED_WIDTH(column) (CLAMP (column->requested_width, (column->min_width!=-1)?column->min_width:column->requested_width, (column->max_width!=-1)?column->max_width:column->requested_width))
|
||||
#define TREE_VIEW_DRAW_EXPANDERS(tree_view) (!GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_IS_LIST)&>K_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_SHOW_EXPANDERS))
|
||||
|
||||
/* This lovely little value is used to determine how far away from the title bar
|
||||
@ -108,6 +107,8 @@ struct _GtkTreeViewPrivate
|
||||
|
||||
GtkTreeViewColumn *expander_column;
|
||||
GtkTreeViewColumn *edited_column;
|
||||
guint presize_handler_timer;
|
||||
guint validate_rows_timer;
|
||||
|
||||
/* Focus code */
|
||||
GtkTreeViewColumn *focus_column;
|
||||
@ -117,7 +118,6 @@ struct _GtkTreeViewPrivate
|
||||
GtkTreeRowReference *cursor;
|
||||
|
||||
/* Column Resizing */
|
||||
GdkGC *xor_gc;
|
||||
gint drag_pos;
|
||||
gint x_drag;
|
||||
|
||||
@ -173,6 +173,7 @@ struct _GtkTreeViewPrivate
|
||||
guint drag_column_window_state : 3;
|
||||
/* hint to display rows in alternating colors */
|
||||
guint has_rules : 1;
|
||||
guint mark_rows_col_dirty : 1;
|
||||
|
||||
/* interactive search */
|
||||
guint enable_search : 1;
|
||||
@ -183,8 +184,6 @@ struct _GtkTreeViewPrivate
|
||||
GtkDestroyNotify search_destroy;
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
#define TREE_VIEW_INTERNAL_ASSERT(expr, ret) G_STMT_START{ \
|
||||
if (!(expr)) \
|
||||
{ \
|
||||
@ -202,57 +201,22 @@ struct _GtkTreeViewPrivate
|
||||
return ret; \
|
||||
}; }G_STMT_END
|
||||
|
||||
#define TREE_VIEW_INTERNAL_ASSERT_VOID(expr) G_STMT_START{ \
|
||||
if (!(expr)) \
|
||||
{ \
|
||||
g_log (G_LOG_DOMAIN, \
|
||||
G_LOG_LEVEL_CRITICAL, \
|
||||
"file %s: line %d (%s): assertion `%s' failed.\n" \
|
||||
"There is a disparity between the internal view of the GtkTreeView,\n" \
|
||||
"and the GtkTreeModel. This generally means that the model has changed\n"\
|
||||
"without letting the view know. Any display from now on is likely to\n" \
|
||||
"be incorrect.\n", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
__PRETTY_FUNCTION__, \
|
||||
#expr); \
|
||||
return; \
|
||||
}; }G_STMT_END
|
||||
|
||||
#else
|
||||
|
||||
#define TREE_VIEW_INTERNAL_ASSERT(expr, ret) G_STMT_START{ \
|
||||
if (!(expr)) \
|
||||
{ \
|
||||
g_log (G_LOG_DOMAIN, \
|
||||
G_LOG_LEVEL_CRITICAL, \
|
||||
"file %s: line %d: assertion `%s' failed.\n" \
|
||||
"There is a disparity between the internal view of the GtkTreeView,\n" \
|
||||
"and the GtkTreeModel. This generally means that the model has changed\n"\
|
||||
"without letting the view know. Any display from now on is likely to\n" \
|
||||
"be incorrect.\n", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
#expr); \
|
||||
return ret; \
|
||||
}; }G_STMT_END
|
||||
|
||||
#define TREE_VIEW_INTERNAL_ASSERT_VOID(expr) G_STMT_START{ \
|
||||
if (!(expr)) \
|
||||
{ \
|
||||
g_log (G_LOG_DOMAIN, \
|
||||
G_LOG_LEVEL_CRITICAL, \
|
||||
"file %s: line %d: assertion '%s' failed.\n" \
|
||||
"file %s: line %d (%s): assertion `%s' failed.\n" \
|
||||
"There is a disparity between the internal view of the GtkTreeView,\n" \
|
||||
"and the GtkTreeModel. This generally means that the model has changed\n"\
|
||||
"without letting the view know. Any display from now on is likely to\n" \
|
||||
"be incorrect.\n", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
__PRETTY_FUNCTION__, \
|
||||
#expr); \
|
||||
return; \
|
||||
}; }G_STMT_END
|
||||
#endif
|
||||
|
||||
|
||||
/* functions that shouldn't be exported */
|
||||
@ -268,7 +232,6 @@ gboolean _gtk_tree_view_find_node (GtkTreeView *tree_v
|
||||
GtkTreePath *_gtk_tree_view_find_path (GtkTreeView *tree_view,
|
||||
GtkRBTree *tree,
|
||||
GtkRBNode *node);
|
||||
void _gtk_tree_view_update_size (GtkTreeView *tree_view);
|
||||
void _gtk_tree_view_child_move_resize (GtkTreeView *tree_view,
|
||||
GtkWidget *widget,
|
||||
gint x,
|
||||
@ -296,7 +259,7 @@ gboolean _gtk_tree_view_column_cell_event (GtkTreeViewColumn *tree_column,
|
||||
void _gtk_tree_view_column_start_editing (GtkTreeViewColumn *tree_column,
|
||||
GtkCellEditable *editable_widget);
|
||||
void _gtk_tree_view_column_stop_editing (GtkTreeViewColumn *tree_column);
|
||||
|
||||
void _gtk_tree_view_install_mark_rows_col_dirty (GtkTreeView *tree_view);
|
||||
|
||||
GtkTreeSelection* _gtk_tree_selection_new (void);
|
||||
GtkTreeSelection* _gtk_tree_selection_new_with_tree_view (GtkTreeView *tree_view);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -302,6 +302,7 @@ gtk_tree_view_column_init (GtkTreeViewColumn *tree_column)
|
||||
tree_column->requested_width = -1;
|
||||
tree_column->min_width = -1;
|
||||
tree_column->max_width = -1;
|
||||
tree_column->resized_width = 0;
|
||||
tree_column->column_type = GTK_TREE_VIEW_COLUMN_GROW_ONLY;
|
||||
tree_column->visible = TRUE;
|
||||
tree_column->resizable = FALSE;
|
||||
@ -315,6 +316,7 @@ gtk_tree_view_column_init (GtkTreeViewColumn *tree_column)
|
||||
tree_column->sort_column_id = -1;
|
||||
tree_column->reorderable = FALSE;
|
||||
tree_column->maybe_reordered = FALSE;
|
||||
tree_column->use_resized_width = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -355,6 +357,11 @@ gtk_tree_view_column_set_property (GObject *object,
|
||||
g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_RESIZABLE:
|
||||
gtk_tree_view_column_set_resizable (tree_column,
|
||||
g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_SIZING:
|
||||
gtk_tree_view_column_set_sizing (tree_column,
|
||||
g_value_get_enum (value));
|
||||
@ -433,6 +440,11 @@ gtk_tree_view_column_get_property (GObject *object,
|
||||
gtk_tree_view_column_get_visible (tree_column));
|
||||
break;
|
||||
|
||||
case PROP_RESIZABLE:
|
||||
g_value_set_boolean (value,
|
||||
gtk_tree_view_column_get_resizable (tree_column));
|
||||
break;
|
||||
|
||||
case PROP_WIDTH:
|
||||
g_value_set_int (value,
|
||||
gtk_tree_view_column_get_width (tree_column));
|
||||
@ -711,8 +723,6 @@ gtk_tree_view_column_update_button (GtkTreeViewColumn *tree_column)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gtk_tree_view_column_cell_set_dirty (tree_column);
|
||||
}
|
||||
|
||||
/* Button signal handlers
|
||||
@ -787,7 +797,7 @@ gtk_tree_view_column_button_clicked (GtkWidget *widget, gpointer data)
|
||||
|
||||
static void
|
||||
gtk_tree_view_model_sort_column_changed (GtkTreeSortable *sortable,
|
||||
GtkTreeViewColumn *column)
|
||||
GtkTreeViewColumn *column)
|
||||
{
|
||||
gint sort_column_id;
|
||||
GtkSortType order;
|
||||
@ -998,29 +1008,6 @@ _gtk_tree_view_column_unset_tree_view (GtkTreeViewColumn *column)
|
||||
column->button = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_tree_view_column_set_width (GtkTreeViewColumn *tree_column,
|
||||
gint width)
|
||||
{
|
||||
if (tree_column->min_width != -1 &&
|
||||
width <= tree_column->min_width)
|
||||
width = tree_column->min_width;
|
||||
else if (tree_column->max_width != -1 &&
|
||||
width > tree_column->max_width)
|
||||
width = tree_column->max_width;
|
||||
|
||||
if (tree_column->width == width)
|
||||
return;
|
||||
|
||||
tree_column->width = width;
|
||||
|
||||
g_object_notify (G_OBJECT (tree_column), "width");
|
||||
|
||||
if (tree_column->tree_view != NULL)
|
||||
gtk_widget_queue_resize (tree_column->tree_view);
|
||||
|
||||
}
|
||||
|
||||
/* Public Functions */
|
||||
|
||||
|
||||
@ -1142,6 +1129,12 @@ gtk_tree_view_column_pack_end (GtkTreeViewColumn *tree_column,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gtk_tree_view_column_clear:
|
||||
* @tree_column: A #GtkTreeViewColumn
|
||||
*
|
||||
* Unsets all the mappings on all renderers on the @tree_column.
|
||||
**/
|
||||
void
|
||||
gtk_tree_view_column_clear (GtkTreeViewColumn *tree_column)
|
||||
{
|
||||
@ -1161,6 +1154,15 @@ gtk_tree_view_column_clear (GtkTreeViewColumn *tree_column)
|
||||
tree_column->cell_list = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_tree_view_column_get_cell_renderers:
|
||||
* @tree_column: A #GtkTreeViewColumn
|
||||
*
|
||||
* Returns a newly allocated #GList of all the cell renderers in the column, in no
|
||||
* particular order. The list must be freed with g_list_free()
|
||||
*
|
||||
* Return value: A list of #GtkCellRenderers
|
||||
**/
|
||||
GList *
|
||||
gtk_tree_view_column_get_cell_renderers (GtkTreeViewColumn *tree_column)
|
||||
{
|
||||
@ -1431,6 +1433,8 @@ gtk_tree_view_column_set_resizable (GtkTreeViewColumn *tree_column,
|
||||
if (tree_column->resizable == resizable)
|
||||
return;
|
||||
|
||||
tree_column->resizable = resizable;
|
||||
|
||||
if (resizable && tree_column->column_type == GTK_TREE_VIEW_COLUMN_AUTOSIZE)
|
||||
gtk_tree_view_column_set_sizing (tree_column, GTK_TREE_VIEW_COLUMN_GROW_ONLY);
|
||||
|
||||
@ -1537,16 +1541,21 @@ gtk_tree_view_column_set_fixed_width (GtkTreeViewColumn *tree_column,
|
||||
return;
|
||||
|
||||
tree_column->fixed_width = fixed_width;
|
||||
tree_column->requested_width = fixed_width;
|
||||
_gtk_tree_view_column_set_width (tree_column, fixed_width);
|
||||
|
||||
if (tree_column->tree_view &&
|
||||
GTK_WIDGET_REALIZED (tree_column->tree_view) &&
|
||||
tree_column->column_type == GTK_TREE_VIEW_COLUMN_FIXED)
|
||||
{
|
||||
gtk_widget_queue_resize (tree_column->tree_view);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_tree_view_column_get_fixed_width:
|
||||
* @tree_column: a #GtkTreeViewColumn
|
||||
*
|
||||
* Gets the fixed width of the column. This value is only meaning may not be the
|
||||
* actual width of the column on the screen, just what is requested.
|
||||
* Gets the fixed width of the column. This value is only meaning may not be
|
||||
* the actual width of the column on the screen, just what is requested.
|
||||
*
|
||||
* Return value: the fixed width of the column
|
||||
**/
|
||||
@ -1570,41 +1579,26 @@ void
|
||||
gtk_tree_view_column_set_min_width (GtkTreeViewColumn *tree_column,
|
||||
gint min_width)
|
||||
{
|
||||
gint real_min_width;
|
||||
|
||||
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
|
||||
g_return_if_fail (min_width >= -1);
|
||||
|
||||
if (min_width == tree_column->min_width)
|
||||
return;
|
||||
|
||||
if (tree_column->tree_view == NULL)
|
||||
if (tree_column->visible &&
|
||||
tree_column->tree_view != NULL &&
|
||||
GTK_WIDGET_REALIZED (tree_column->tree_view))
|
||||
{
|
||||
tree_column->min_width = min_width;
|
||||
return;
|
||||
}
|
||||
|
||||
real_min_width = (tree_column->min_width == -1) ?
|
||||
tree_column->button->requisition.width : tree_column->min_width;
|
||||
|
||||
/* We want to queue a resize if the either the old min_size or the
|
||||
* new min_size determined the size of the column */
|
||||
if (GTK_WIDGET_REALIZED (tree_column->tree_view))
|
||||
{
|
||||
if ((tree_column->min_width > tree_column->width) ||
|
||||
(tree_column->min_width == -1 &&
|
||||
tree_column->button->requisition.width > tree_column->width) ||
|
||||
(min_width > tree_column->width) ||
|
||||
(min_width == -1 &&
|
||||
tree_column->button->requisition.width > tree_column->width))
|
||||
if (min_width > tree_column->width)
|
||||
gtk_widget_queue_resize (tree_column->tree_view);
|
||||
}
|
||||
|
||||
if (tree_column->max_width != -1 && tree_column->max_width < real_min_width)
|
||||
tree_column->max_width = real_min_width;
|
||||
|
||||
tree_column->min_width = min_width;
|
||||
|
||||
if (tree_column->max_width != -1 && tree_column->max_width < min_width)
|
||||
{
|
||||
tree_column->max_width = min_width;
|
||||
g_object_notify (G_OBJECT (tree_column), "max_width");
|
||||
}
|
||||
g_object_notify (G_OBJECT (tree_column), "min_width");
|
||||
}
|
||||
|
||||
@ -1633,40 +1627,32 @@ gtk_tree_view_column_get_min_width (GtkTreeViewColumn *tree_column)
|
||||
* Sets the maximum width of the @tree_column. If @max_width is -1, then the
|
||||
* maximum width is unset. Note, the column can actually be wider than max
|
||||
* width if it's the last column in a view. In this case, the column expands to
|
||||
* fill the view.
|
||||
* fill any extra space.
|
||||
**/
|
||||
void
|
||||
gtk_tree_view_column_set_max_width (GtkTreeViewColumn *tree_column,
|
||||
gint max_width)
|
||||
{
|
||||
gint real_max_width;
|
||||
|
||||
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
|
||||
g_return_if_fail (max_width >= -1);
|
||||
|
||||
if (max_width == tree_column->max_width)
|
||||
return;
|
||||
|
||||
if (tree_column->tree_view == NULL)
|
||||
if (tree_column->visible &&
|
||||
tree_column->tree_view != NULL &&
|
||||
GTK_WIDGET_REALIZED (tree_column->tree_view))
|
||||
{
|
||||
tree_column->max_width = max_width;
|
||||
return;
|
||||
if (max_width != -1 && max_width < tree_column->width)
|
||||
gtk_widget_queue_resize (tree_column->tree_view);
|
||||
}
|
||||
|
||||
real_max_width = tree_column->max_width == -1 ?
|
||||
tree_column->button->requisition.width : tree_column->max_width;
|
||||
|
||||
if (tree_column->tree_view &&
|
||||
GTK_WIDGET_REALIZED (tree_column->tree_view) &&
|
||||
((tree_column->max_width < tree_column->width) ||
|
||||
(max_width != -1 && max_width < tree_column->width)))
|
||||
gtk_widget_queue_resize (tree_column->tree_view);
|
||||
|
||||
tree_column->max_width = max_width;
|
||||
|
||||
if (real_max_width > max_width)
|
||||
tree_column->max_width = max_width;
|
||||
|
||||
if (max_width != -1 && max_width < tree_column->min_width)
|
||||
{
|
||||
tree_column->min_width = max_width;
|
||||
g_object_notify (G_OBJECT (tree_column), "min_width");
|
||||
}
|
||||
g_object_notify (G_OBJECT (tree_column), "max_width");
|
||||
}
|
||||
|
||||
@ -1692,7 +1678,7 @@ gtk_tree_view_column_get_max_width (GtkTreeViewColumn *tree_column)
|
||||
* @tree_column: a #GtkTreeViewColumn
|
||||
*
|
||||
* Emits the "clicked" signal on the column. This function will only work if
|
||||
* the user could have conceivably clicked on the button.
|
||||
* @tree_column is clickable.
|
||||
**/
|
||||
void
|
||||
gtk_tree_view_column_clicked (GtkTreeViewColumn *tree_column)
|
||||
@ -1759,10 +1745,11 @@ gtk_tree_view_column_set_clickable (GtkTreeViewColumn *tree_column,
|
||||
{
|
||||
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
|
||||
|
||||
if (tree_column->clickable == (clickable?TRUE:FALSE))
|
||||
clickable = !! clickable;
|
||||
if (tree_column->clickable == clickable)
|
||||
return;
|
||||
|
||||
tree_column->clickable = (clickable?TRUE:FALSE);
|
||||
tree_column->clickable = clickable;
|
||||
gtk_tree_view_column_update_button (tree_column);
|
||||
g_object_notify (G_OBJECT (tree_column), "clickable");
|
||||
}
|
||||
@ -1773,7 +1760,7 @@ gtk_tree_view_column_set_clickable (GtkTreeViewColumn *tree_column,
|
||||
*
|
||||
* Returns %TRUE if the user can click on the header for the column.
|
||||
*
|
||||
* Return value: whether the user can click the column header
|
||||
* Return value: TRUE if user can click the column header
|
||||
**/
|
||||
gboolean
|
||||
gtk_tree_view_column_get_clickable (GtkTreeViewColumn *tree_column)
|
||||
@ -2207,10 +2194,8 @@ gtk_tree_view_column_cell_render_or_focus (GtkTreeViewColumn *tree_column,
|
||||
for (list = tree_column->cell_list; list; list = list->next)
|
||||
{
|
||||
GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
|
||||
gboolean visible;
|
||||
|
||||
g_object_get (info->cell, "visible", &visible, NULL);
|
||||
if (visible == FALSE)
|
||||
if (! info->cell->visible)
|
||||
continue;
|
||||
|
||||
if (info->expand == TRUE)
|
||||
@ -2225,13 +2210,11 @@ gtk_tree_view_column_cell_render_or_focus (GtkTreeViewColumn *tree_column,
|
||||
for (list = tree_column->cell_list; list; list = list->next)
|
||||
{
|
||||
GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
|
||||
gboolean visible;
|
||||
|
||||
if (info->pack == GTK_PACK_END)
|
||||
continue;
|
||||
|
||||
g_object_get (info->cell, "visible", &visible, NULL);
|
||||
if (visible == FALSE)
|
||||
if (! info->cell->visible)
|
||||
continue;
|
||||
|
||||
real_cell_area.width = info->requested_width +
|
||||
@ -2270,13 +2253,11 @@ gtk_tree_view_column_cell_render_or_focus (GtkTreeViewColumn *tree_column,
|
||||
for (list = g_list_last (tree_column->cell_list); list; list = list->prev)
|
||||
{
|
||||
GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
|
||||
gboolean visible;
|
||||
|
||||
if (info->pack == GTK_PACK_START)
|
||||
continue;
|
||||
|
||||
g_object_get (info->cell, "visible", &visible, NULL);
|
||||
if (visible == FALSE)
|
||||
if (! info->cell->visible)
|
||||
continue;
|
||||
|
||||
real_cell_area.width = info->requested_width +
|
||||
@ -2462,11 +2443,8 @@ gtk_tree_view_column_cell_is_visible (GtkTreeViewColumn *tree_column)
|
||||
for (list = tree_column->cell_list; list; list = list->next)
|
||||
{
|
||||
GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
|
||||
gboolean visible;
|
||||
|
||||
g_object_get (G_OBJECT (info->cell), "visible", &visible, NULL);
|
||||
|
||||
if (visible)
|
||||
if (info->cell->visible)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -2485,9 +2463,14 @@ gtk_tree_view_column_cell_set_dirty (GtkTreeViewColumn *tree_column)
|
||||
info->requested_width = 0;
|
||||
}
|
||||
tree_column->dirty = TRUE;
|
||||
tree_column->requested_width = 0;
|
||||
|
||||
if (tree_column->tree_view)
|
||||
gtk_widget_queue_resize (tree_column->tree_view);
|
||||
if (tree_column->tree_view &&
|
||||
GTK_WIDGET_REALIZED (tree_column->tree_view))
|
||||
{
|
||||
_gtk_tree_view_install_mark_rows_col_dirty (GTK_TREE_VIEW (tree_column->tree_view));
|
||||
gtk_widget_queue_resize (tree_column->tree_view);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -66,11 +66,16 @@ struct _GtkTreeViewColumn
|
||||
GtkCellEditable *editable_widget;
|
||||
gfloat xalign;
|
||||
guint property_changed_signal;
|
||||
|
||||
gint spacing;
|
||||
gint fixed_width;
|
||||
gint width;
|
||||
|
||||
/* Sizing fields */
|
||||
/* see gtk+/doc/tree-column-sizing.txt for more information on them */
|
||||
GtkTreeViewColumnSizing column_type;
|
||||
gint requested_width;
|
||||
gint button_request;
|
||||
gint resized_width;
|
||||
gint width;
|
||||
gint fixed_width;
|
||||
gint min_width;
|
||||
gint max_width;
|
||||
|
||||
@ -80,7 +85,6 @@ struct _GtkTreeViewColumn
|
||||
|
||||
gchar *title;
|
||||
GList *cell_list;
|
||||
GtkTreeViewColumnSizing column_type;
|
||||
|
||||
/* Sorting */
|
||||
guint sort_clicked_signal;
|
||||
@ -96,6 +100,7 @@ struct _GtkTreeViewColumn
|
||||
guint show_sort_indicator : 1;
|
||||
guint maybe_reordered : 1;
|
||||
guint reorderable : 1;
|
||||
guint use_resized_width : 1;
|
||||
};
|
||||
|
||||
struct _GtkTreeViewColumnClass
|
||||
|
Loading…
Reference in New Issue
Block a user