forked from AuroraMiddleware/gtk
Fix #316087.
2008-07-11 Kristian Rietveld <kris@gtk.org> Bug 316087 - Resizing columns is chaotic * gtk/gtktreeprivate.h: add new member fields. * gtk/gtktreeview.c (gtk_tree_view_init), (validate_row): set post validation flag, (gtk_tree_view_size_allocate_columns): rework the size allocation mechanism to only recalculate the expand values if the width of the widget, content or the column configuration has changed, (gtk_tree_view_size_allocate): move call to size_allocate_columns() to before the adjustment updates so the proper width is used after we updated it, (gtk_tree_view_button_press), (gtk_tree_view_motion_resize_column): use the column width minus the expand value for the resized width, (gtk_tree_view_move_column_after): update call to gtk_tree_view_size_allocate_columns(). * gtk/gtktreeviewcolumn.c (gtk_tree_view_column_set_expand): set use resized width to FALSE. * tests/Makefile.am: * tests/testtreecolumnsizing.c: new interactive test program for testing column resizing with different column configurations. svn path=/trunk/; revision=20818
This commit is contained in:
parent
1d510a9e84
commit
2cc1247433
26
ChangeLog
26
ChangeLog
@ -1,3 +1,29 @@
|
|||||||
|
2008-07-11 Kristian Rietveld <kris@gtk.org>
|
||||||
|
|
||||||
|
Bug 316087 - Resizing columns is chaotic
|
||||||
|
|
||||||
|
* gtk/gtktreeprivate.h: add new member fields.
|
||||||
|
|
||||||
|
* gtk/gtktreeview.c (gtk_tree_view_init), (validate_row): set post
|
||||||
|
validation flag,
|
||||||
|
(gtk_tree_view_size_allocate_columns): rework the size allocation
|
||||||
|
mechanism to only recalculate the expand values if the width of the
|
||||||
|
widget, content or the column configuration has changed,
|
||||||
|
(gtk_tree_view_size_allocate): move call to size_allocate_columns()
|
||||||
|
to before the adjustment updates so the proper width is used after
|
||||||
|
we updated it,
|
||||||
|
(gtk_tree_view_button_press), (gtk_tree_view_motion_resize_column):
|
||||||
|
use the column width minus the expand value for the resized width,
|
||||||
|
(gtk_tree_view_move_column_after): update call to
|
||||||
|
gtk_tree_view_size_allocate_columns().
|
||||||
|
|
||||||
|
* gtk/gtktreeviewcolumn.c (gtk_tree_view_column_set_expand): set use
|
||||||
|
resized width to FALSE.
|
||||||
|
|
||||||
|
* tests/Makefile.am:
|
||||||
|
* tests/testtreecolumnsizing.c: new interactive test program
|
||||||
|
for testing column resizing with different column configurations.
|
||||||
|
|
||||||
2008-07-11 Simos Xenitellis <simos@gnome.org>
|
2008-07-11 Simos Xenitellis <simos@gnome.org>
|
||||||
|
|
||||||
* gtk/compose-parse.py:
|
* gtk/compose-parse.py:
|
||||||
|
@ -236,6 +236,8 @@ struct _GtkTreeViewPrivate
|
|||||||
|
|
||||||
guint in_grab : 1;
|
guint in_grab : 1;
|
||||||
|
|
||||||
|
guint post_validation_flag : 1;
|
||||||
|
|
||||||
|
|
||||||
/* Auto expand/collapse timeout in hover mode */
|
/* Auto expand/collapse timeout in hover mode */
|
||||||
guint auto_expand_timeout;
|
guint auto_expand_timeout;
|
||||||
@ -268,6 +270,10 @@ struct _GtkTreeViewPrivate
|
|||||||
GdkGC *tree_line_gc;
|
GdkGC *tree_line_gc;
|
||||||
|
|
||||||
gint tooltip_column;
|
gint tooltip_column;
|
||||||
|
|
||||||
|
gint last_extra_space;
|
||||||
|
gint last_extra_space_per_column;
|
||||||
|
gint last_number_of_expand_columns;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
@ -1370,6 +1370,8 @@ gtk_tree_view_init (GtkTreeView *tree_view)
|
|||||||
tree_view->priv->tree_lines_enabled = FALSE;
|
tree_view->priv->tree_lines_enabled = FALSE;
|
||||||
|
|
||||||
tree_view->priv->tooltip_column = -1;
|
tree_view->priv->tooltip_column = -1;
|
||||||
|
|
||||||
|
tree_view->priv->post_validation_flag = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1988,6 +1990,7 @@ gtk_tree_view_update_size (GtkTreeView *tree_view)
|
|||||||
|
|
||||||
tree_view->priv->prev_width = tree_view->priv->width;
|
tree_view->priv->prev_width = tree_view->priv->width;
|
||||||
tree_view->priv->width = 0;
|
tree_view->priv->width = 0;
|
||||||
|
|
||||||
/* keep this in sync with size_allocate below */
|
/* keep this in sync with size_allocate below */
|
||||||
for (list = tree_view->priv->columns, i = 0; list; list = list->next, i++)
|
for (list = tree_view->priv->columns, i = 0; list; list = list->next, i++)
|
||||||
{
|
{
|
||||||
@ -2150,18 +2153,20 @@ gtk_tree_view_get_real_requested_width_from_column (GtkTreeView *tree_view
|
|||||||
|
|
||||||
/* GtkWidget::size_allocate helper */
|
/* GtkWidget::size_allocate helper */
|
||||||
static void
|
static void
|
||||||
gtk_tree_view_size_allocate_columns (GtkWidget *widget)
|
gtk_tree_view_size_allocate_columns (GtkWidget *widget,
|
||||||
|
gboolean *width_changed)
|
||||||
{
|
{
|
||||||
GtkTreeView *tree_view;
|
GtkTreeView *tree_view;
|
||||||
GList *list, *first_column, *last_column;
|
GList *list, *first_column, *last_column;
|
||||||
GtkTreeViewColumn *column;
|
GtkTreeViewColumn *column;
|
||||||
GtkAllocation allocation;
|
GtkAllocation allocation;
|
||||||
gint width = 0;
|
gint width = 0;
|
||||||
gint extra, extra_per_column;
|
gint extra, extra_per_column, extra_for_last;
|
||||||
gint full_requested_width = 0;
|
gint full_requested_width = 0;
|
||||||
gint number_of_expand_columns = 0;
|
gint number_of_expand_columns = 0;
|
||||||
gboolean column_changed = FALSE;
|
gboolean column_changed = FALSE;
|
||||||
gboolean rtl;
|
gboolean rtl;
|
||||||
|
gboolean update_expand;
|
||||||
|
|
||||||
tree_view = GTK_TREE_VIEW (widget);
|
tree_view = GTK_TREE_VIEW (widget);
|
||||||
|
|
||||||
@ -2196,12 +2201,42 @@ gtk_tree_view_size_allocate_columns (GtkWidget *widget)
|
|||||||
number_of_expand_columns++;
|
number_of_expand_columns++;
|
||||||
}
|
}
|
||||||
|
|
||||||
extra = MAX (widget->allocation.width - full_requested_width, 0);
|
/* Only update the expand value if the width of the widget has changed,
|
||||||
|
* or the number of expand columns has changed, or if there are no expand
|
||||||
|
* columns, or if we didn't have an size-allocation yet after the
|
||||||
|
* last validated node.
|
||||||
|
*/
|
||||||
|
update_expand = (width_changed && *width_changed == TRUE)
|
||||||
|
|| number_of_expand_columns != tree_view->priv->last_number_of_expand_columns
|
||||||
|
|| number_of_expand_columns == 0
|
||||||
|
|| tree_view->priv->post_validation_flag == TRUE;
|
||||||
|
|
||||||
|
tree_view->priv->post_validation_flag = FALSE;
|
||||||
|
|
||||||
|
if (!update_expand)
|
||||||
|
{
|
||||||
|
extra = tree_view->priv->last_extra_space;
|
||||||
|
extra_for_last = MAX (widget->allocation.width - full_requested_width - extra, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
extra = MAX (widget->allocation.width - full_requested_width, 0);
|
||||||
|
extra_for_last = 0;
|
||||||
|
|
||||||
|
tree_view->priv->last_extra_space = extra;
|
||||||
|
}
|
||||||
|
|
||||||
if (number_of_expand_columns > 0)
|
if (number_of_expand_columns > 0)
|
||||||
extra_per_column = extra/number_of_expand_columns;
|
extra_per_column = extra/number_of_expand_columns;
|
||||||
else
|
else
|
||||||
extra_per_column = 0;
|
extra_per_column = 0;
|
||||||
|
|
||||||
|
if (update_expand)
|
||||||
|
{
|
||||||
|
tree_view->priv->last_extra_space_per_column = extra_per_column;
|
||||||
|
tree_view->priv->last_number_of_expand_columns = number_of_expand_columns;
|
||||||
|
}
|
||||||
|
|
||||||
for (list = (rtl ? last_column : first_column);
|
for (list = (rtl ? last_column : first_column);
|
||||||
list != (rtl ? first_column->prev : last_column->next);
|
list != (rtl ? first_column->prev : last_column->next);
|
||||||
list = (rtl ? list->prev : list->next))
|
list = (rtl ? list->prev : list->next))
|
||||||
@ -2257,6 +2292,12 @@ gtk_tree_view_size_allocate_columns (GtkWidget *widget)
|
|||||||
column->width += extra;
|
column->width += extra;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* In addition to expand, the last column can get even more
|
||||||
|
* extra space so all available space is filled up.
|
||||||
|
*/
|
||||||
|
if (extra_for_last > 0 && list == last_column)
|
||||||
|
column->width += extra_for_last;
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (column), "width");
|
g_object_notify (G_OBJECT (column), "width");
|
||||||
|
|
||||||
allocation.width = column->width;
|
allocation.width = column->width;
|
||||||
@ -2274,6 +2315,12 @@ gtk_tree_view_size_allocate_columns (GtkWidget *widget)
|
|||||||
TREE_VIEW_DRAG_WIDTH, allocation.height);
|
TREE_VIEW_DRAG_WIDTH, allocation.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We change the width here. The user might have been resizing columns,
|
||||||
|
* so the total width of the tree view changes.
|
||||||
|
*/
|
||||||
|
tree_view->priv->width = width;
|
||||||
|
*width_changed = TRUE;
|
||||||
|
|
||||||
if (column_changed)
|
if (column_changed)
|
||||||
gtk_widget_queue_draw (GTK_WIDGET (tree_view));
|
gtk_widget_queue_draw (GTK_WIDGET (tree_view));
|
||||||
}
|
}
|
||||||
@ -2310,6 +2357,10 @@ gtk_tree_view_size_allocate (GtkWidget *widget,
|
|||||||
gtk_widget_size_allocate (child->widget, &allocation);
|
gtk_widget_size_allocate (child->widget, &allocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We size-allocate the columns first because the width of the
|
||||||
|
* tree view (used in updating the adjustments below) might change.
|
||||||
|
*/
|
||||||
|
gtk_tree_view_size_allocate_columns (widget, &width_changed);
|
||||||
|
|
||||||
tree_view->priv->hadjustment->page_size = allocation->width;
|
tree_view->priv->hadjustment->page_size = allocation->width;
|
||||||
tree_view->priv->hadjustment->page_increment = allocation->width * 0.9;
|
tree_view->priv->hadjustment->page_increment = allocation->width * 0.9;
|
||||||
@ -2318,28 +2369,30 @@ gtk_tree_view_size_allocate (GtkWidget *widget,
|
|||||||
tree_view->priv->hadjustment->upper = MAX (tree_view->priv->hadjustment->page_size, tree_view->priv->width);
|
tree_view->priv->hadjustment->upper = MAX (tree_view->priv->hadjustment->page_size, tree_view->priv->width);
|
||||||
|
|
||||||
if (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL)
|
if (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL)
|
||||||
{
|
{
|
||||||
if (allocation->width < tree_view->priv->width)
|
if (allocation->width < tree_view->priv->width)
|
||||||
{
|
{
|
||||||
if (tree_view->priv->init_hadjust_value)
|
if (tree_view->priv->init_hadjust_value)
|
||||||
{
|
{
|
||||||
tree_view->priv->hadjustment->value = MAX (tree_view->priv->width - allocation->width, 0);
|
tree_view->priv->hadjustment->value = MAX (tree_view->priv->width - allocation->width, 0);
|
||||||
tree_view->priv->init_hadjust_value = FALSE;
|
tree_view->priv->init_hadjust_value = FALSE;
|
||||||
}
|
}
|
||||||
else if(allocation->width != old_width)
|
else if (allocation->width != old_width)
|
||||||
tree_view->priv->hadjustment->value = CLAMP(tree_view->priv->hadjustment->value - allocation->width + old_width, 0, tree_view->priv->width - allocation->width);
|
{
|
||||||
else
|
tree_view->priv->hadjustment->value = CLAMP (tree_view->priv->hadjustment->value - allocation->width + old_width, 0, tree_view->priv->width - allocation->width);
|
||||||
tree_view->priv->hadjustment->value = CLAMP(tree_view->priv->width - (tree_view->priv->prev_width - tree_view->priv->hadjustment->value), 0, tree_view->priv->width - allocation->width);
|
}
|
||||||
}
|
else
|
||||||
|
tree_view->priv->hadjustment->value = CLAMP (tree_view->priv->width - (tree_view->priv->prev_width - tree_view->priv->hadjustment->value), 0, tree_view->priv->width - allocation->width);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tree_view->priv->hadjustment->value = 0;
|
tree_view->priv->hadjustment->value = 0;
|
||||||
tree_view->priv->init_hadjust_value = TRUE;
|
tree_view->priv->init_hadjust_value = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (tree_view->priv->hadjustment->value + allocation->width > tree_view->priv->width)
|
if (tree_view->priv->hadjustment->value + allocation->width > tree_view->priv->width)
|
||||||
tree_view->priv->hadjustment->value = MAX (tree_view->priv->width - allocation->width, 0);
|
tree_view->priv->hadjustment->value = MAX (tree_view->priv->width - allocation->width, 0);
|
||||||
|
|
||||||
gtk_adjustment_changed (tree_view->priv->hadjustment);
|
gtk_adjustment_changed (tree_view->priv->hadjustment);
|
||||||
|
|
||||||
@ -2379,8 +2432,6 @@ gtk_tree_view_size_allocate (GtkWidget *widget,
|
|||||||
allocation->height - TREE_VIEW_HEADER_HEIGHT (tree_view));
|
allocation->height - TREE_VIEW_HEADER_HEIGHT (tree_view));
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_tree_view_size_allocate_columns (widget);
|
|
||||||
|
|
||||||
if (tree_view->priv->tree == NULL)
|
if (tree_view->priv->tree == NULL)
|
||||||
invalidate_empty_focus (tree_view);
|
invalidate_empty_focus (tree_view);
|
||||||
|
|
||||||
@ -2820,7 +2871,7 @@ gtk_tree_view_button_press (GtkWidget *widget,
|
|||||||
|
|
||||||
gtk_grab_add (widget);
|
gtk_grab_add (widget);
|
||||||
GTK_TREE_VIEW_SET_FLAG (tree_view, GTK_TREE_VIEW_IN_COLUMN_RESIZE);
|
GTK_TREE_VIEW_SET_FLAG (tree_view, GTK_TREE_VIEW_IN_COLUMN_RESIZE);
|
||||||
column->resized_width = column->width;
|
column->resized_width = column->width - tree_view->priv->last_extra_space_per_column;
|
||||||
|
|
||||||
/* block attached dnd signal handler */
|
/* block attached dnd signal handler */
|
||||||
drag_data = g_object_get_data (G_OBJECT (widget), "gtk-site-data");
|
drag_data = g_object_get_data (G_OBJECT (widget), "gtk-site-data");
|
||||||
@ -3524,6 +3575,8 @@ gtk_tree_view_motion_resize_column (GtkWidget *widget,
|
|||||||
{
|
{
|
||||||
column->use_resized_width = TRUE;
|
column->use_resized_width = TRUE;
|
||||||
column->resized_width = new_width;
|
column->resized_width = new_width;
|
||||||
|
if (column->expand)
|
||||||
|
column->resized_width -= tree_view->priv->last_extra_space_per_column;
|
||||||
gtk_widget_queue_resize (widget);
|
gtk_widget_queue_resize (widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5619,6 +5672,7 @@ validate_row (GtkTreeView *tree_view,
|
|||||||
_gtk_rbtree_node_set_height (tree, node, height);
|
_gtk_rbtree_node_set_height (tree, node, height);
|
||||||
}
|
}
|
||||||
_gtk_rbtree_node_mark_valid (tree, node);
|
_gtk_rbtree_node_mark_valid (tree, node);
|
||||||
|
tree_view->priv->post_validation_flag = TRUE;
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@ -11408,7 +11462,7 @@ gtk_tree_view_move_column_after (GtkTreeView *tree_view,
|
|||||||
if (GTK_WIDGET_REALIZED (tree_view))
|
if (GTK_WIDGET_REALIZED (tree_view))
|
||||||
{
|
{
|
||||||
gtk_widget_queue_resize (GTK_WIDGET (tree_view));
|
gtk_widget_queue_resize (GTK_WIDGET (tree_view));
|
||||||
gtk_tree_view_size_allocate_columns (GTK_WIDGET (tree_view));
|
gtk_tree_view_size_allocate_columns (GTK_WIDGET (tree_view), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_signal_emit (tree_view, tree_view_signals[COLUMNS_CHANGED], 0);
|
g_signal_emit (tree_view, tree_view_signals[COLUMNS_CHANGED], 0);
|
||||||
|
@ -2141,6 +2141,13 @@ gtk_tree_view_column_set_expand (GtkTreeViewColumn *tree_column,
|
|||||||
tree_column->tree_view != NULL &&
|
tree_column->tree_view != NULL &&
|
||||||
GTK_WIDGET_REALIZED (tree_column->tree_view))
|
GTK_WIDGET_REALIZED (tree_column->tree_view))
|
||||||
{
|
{
|
||||||
|
/* We want to continue using the original width of the
|
||||||
|
* column that includes additional space added by the user
|
||||||
|
* resizing the columns and possibly extra (expanded) space, which
|
||||||
|
* are not included in the resized width.
|
||||||
|
*/
|
||||||
|
tree_column->use_resized_width = FALSE;
|
||||||
|
|
||||||
gtk_widget_queue_resize (tree_column->tree_view);
|
gtk_widget_queue_resize (tree_column->tree_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +72,7 @@ noinst_PROGRAMS = $(TEST_PROGS) \
|
|||||||
testtreefocus \
|
testtreefocus \
|
||||||
testtreeflow \
|
testtreeflow \
|
||||||
testtreecolumns \
|
testtreecolumns \
|
||||||
|
testtreecolumnsizing \
|
||||||
testtreesort \
|
testtreesort \
|
||||||
treestoretest \
|
treestoretest \
|
||||||
testxinerama \
|
testxinerama \
|
||||||
@ -145,6 +146,7 @@ testtreeview_DEPENDENCIES = $(DEPS)
|
|||||||
testtreefocus_DEPENDENCIES = $(DEPS)
|
testtreefocus_DEPENDENCIES = $(DEPS)
|
||||||
testtreeflow_DEPENDENCIES = $(DEPS)
|
testtreeflow_DEPENDENCIES = $(DEPS)
|
||||||
testtreecolumns_DEPENDENCIES = $(DEPS)
|
testtreecolumns_DEPENDENCIES = $(DEPS)
|
||||||
|
testtreecolumnsizing_DEPENDENCIES = $(DEPS)
|
||||||
testtreesort_DEPENDENCIES = $(DEPS)
|
testtreesort_DEPENDENCIES = $(DEPS)
|
||||||
treestoretest_DEPENDENCIES = $(TEST_DEPS)
|
treestoretest_DEPENDENCIES = $(TEST_DEPS)
|
||||||
testxinerama_DEPENDENCIES = $(TEST_DEPS)
|
testxinerama_DEPENDENCIES = $(TEST_DEPS)
|
||||||
@ -200,6 +202,7 @@ testtreeview_LDADD = $(LDADDS)
|
|||||||
testtreefocus_LDADD = $(LDADDS)
|
testtreefocus_LDADD = $(LDADDS)
|
||||||
testtreeflow_LDADD = $(LDADDS)
|
testtreeflow_LDADD = $(LDADDS)
|
||||||
testtreecolumns_LDADD = $(LDADDS)
|
testtreecolumns_LDADD = $(LDADDS)
|
||||||
|
testtreecolumnsizing_LDADD = $(LDADDS)
|
||||||
testtreesort_LDADD = $(LDADDS)
|
testtreesort_LDADD = $(LDADDS)
|
||||||
testtext_LDADD = $(LDADDS)
|
testtext_LDADD = $(LDADDS)
|
||||||
treestoretest_LDADD = $(LDADDS)
|
treestoretest_LDADD = $(LDADDS)
|
||||||
|
237
tests/testtreecolumnsizing.c
Normal file
237
tests/testtreecolumnsizing.c
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
/* testtreecolumnsizing.c: Test case for tree view column resizing.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 Kristian Rietveld <kris@gtk.org>
|
||||||
|
*
|
||||||
|
* This work is provided "as is"; redistribution and modification
|
||||||
|
* in whole or in part, in any medium, physical or electronic is
|
||||||
|
* permitted without restriction.
|
||||||
|
*
|
||||||
|
* This work is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* In no event shall the authors or contributors be liable for any
|
||||||
|
* direct, indirect, incidental, special, exemplary, or consequential
|
||||||
|
* damages (including, but not limited to, procurement of substitute
|
||||||
|
* goods or services; loss of use, data, or profits; or business
|
||||||
|
* interruption) however caused and on any theory of liability, whether
|
||||||
|
* in contract, strict liability, or tort (including negligence or
|
||||||
|
* otherwise) arising in any way out of the use of this software, even
|
||||||
|
* if advised of the possibility of such damage.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define NO_EXPAND "No expandable columns"
|
||||||
|
#define SINGLE_EXPAND "One expandable column"
|
||||||
|
#define MULTI_EXPAND "Multiple expandable columns"
|
||||||
|
#define LAST_EXPAND "Last column is expandable"
|
||||||
|
#define BORDER_EXPAND "First and last columns are expandable"
|
||||||
|
#define ALL_EXPAND "All columns are expandable"
|
||||||
|
|
||||||
|
#define N_ROWS 10
|
||||||
|
|
||||||
|
|
||||||
|
static GtkTreeModel *
|
||||||
|
create_model (void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
GtkListStore *store;
|
||||||
|
|
||||||
|
store = gtk_list_store_new (5,
|
||||||
|
G_TYPE_STRING,
|
||||||
|
G_TYPE_STRING,
|
||||||
|
G_TYPE_STRING,
|
||||||
|
G_TYPE_STRING,
|
||||||
|
G_TYPE_STRING);
|
||||||
|
|
||||||
|
for (i = 0; i < N_ROWS; i++)
|
||||||
|
{
|
||||||
|
gchar *str;
|
||||||
|
|
||||||
|
str = g_strdup_printf ("Row %d", i);
|
||||||
|
gtk_list_store_insert_with_values (store, NULL, i,
|
||||||
|
0, str,
|
||||||
|
1, "Blah blah blah blah blah",
|
||||||
|
2, "Less blah",
|
||||||
|
3, "Medium length",
|
||||||
|
4, "Eek",
|
||||||
|
-1);
|
||||||
|
g_free (str);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GTK_TREE_MODEL (store);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
toggle_long_content_row (GtkToggleButton *button,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GtkTreeModel *model;
|
||||||
|
|
||||||
|
model = gtk_tree_view_get_model (GTK_TREE_VIEW (user_data));
|
||||||
|
if (gtk_tree_model_iter_n_children (model, NULL) == N_ROWS)
|
||||||
|
{
|
||||||
|
gtk_list_store_insert_with_values (GTK_LIST_STORE (model), NULL, N_ROWS,
|
||||||
|
0, "Very very very very longggggg",
|
||||||
|
1, "Blah blah blah blah blah",
|
||||||
|
2, "Less blah",
|
||||||
|
3, "Medium length",
|
||||||
|
4, "Eek we make the scrollbar appear",
|
||||||
|
-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GtkTreeIter iter;
|
||||||
|
|
||||||
|
gtk_tree_model_iter_nth_child (model, &iter, NULL, N_ROWS);
|
||||||
|
gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
combo_box_changed (GtkComboBox *combo_box,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
gchar *str;
|
||||||
|
GList *list;
|
||||||
|
GList *columns;
|
||||||
|
|
||||||
|
str = gtk_combo_box_get_active_text (GTK_COMBO_BOX (combo_box));
|
||||||
|
if (!str)
|
||||||
|
return;
|
||||||
|
|
||||||
|
columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (user_data));
|
||||||
|
|
||||||
|
if (!strcmp (str, NO_EXPAND))
|
||||||
|
{
|
||||||
|
for (list = columns; list; list = list->next)
|
||||||
|
gtk_tree_view_column_set_expand (list->data, FALSE);
|
||||||
|
}
|
||||||
|
else if (!strcmp (str, SINGLE_EXPAND))
|
||||||
|
{
|
||||||
|
for (list = columns; list; list = list->next)
|
||||||
|
{
|
||||||
|
if (list->prev && !list->prev->prev)
|
||||||
|
/* This is the second column */
|
||||||
|
gtk_tree_view_column_set_expand (list->data, TRUE);
|
||||||
|
else
|
||||||
|
gtk_tree_view_column_set_expand (list->data, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!strcmp (str, MULTI_EXPAND))
|
||||||
|
{
|
||||||
|
for (list = columns; list; list = list->next)
|
||||||
|
{
|
||||||
|
if (list->prev && !list->prev->prev)
|
||||||
|
/* This is the second column */
|
||||||
|
gtk_tree_view_column_set_expand (list->data, TRUE);
|
||||||
|
else if (list->prev && !list->prev->prev->prev)
|
||||||
|
/* This is the third column */
|
||||||
|
gtk_tree_view_column_set_expand (list->data, TRUE);
|
||||||
|
else
|
||||||
|
gtk_tree_view_column_set_expand (list->data, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!strcmp (str, LAST_EXPAND))
|
||||||
|
{
|
||||||
|
for (list = columns; list->next; list = list->next)
|
||||||
|
gtk_tree_view_column_set_expand (list->data, FALSE);
|
||||||
|
/* This is the last column */
|
||||||
|
gtk_tree_view_column_set_expand (list->data, TRUE);
|
||||||
|
}
|
||||||
|
else if (!strcmp (str, BORDER_EXPAND))
|
||||||
|
{
|
||||||
|
gtk_tree_view_column_set_expand (columns->data, TRUE);
|
||||||
|
for (list = columns->next; list->next; list = list->next)
|
||||||
|
gtk_tree_view_column_set_expand (list->data, FALSE);
|
||||||
|
/* This is the last column */
|
||||||
|
gtk_tree_view_column_set_expand (list->data, TRUE);
|
||||||
|
}
|
||||||
|
else if (!strcmp (str, ALL_EXPAND))
|
||||||
|
{
|
||||||
|
for (list = columns; list; list = list->next)
|
||||||
|
gtk_tree_view_column_set_expand (list->data, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (str);
|
||||||
|
g_list_free (columns);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
GtkWidget *window;
|
||||||
|
GtkWidget *vbox;
|
||||||
|
GtkWidget *combo_box;
|
||||||
|
GtkWidget *sw;
|
||||||
|
GtkWidget *tree_view;
|
||||||
|
GtkWidget *button;
|
||||||
|
|
||||||
|
gtk_init (&argc, &argv);
|
||||||
|
|
||||||
|
/* Window and box */
|
||||||
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
|
gtk_window_set_default_size (GTK_WINDOW (window), 640, 480);
|
||||||
|
g_signal_connect (window, "delete-event", G_CALLBACK (gtk_main_quit), NULL);
|
||||||
|
gtk_container_set_border_width (GTK_CONTAINER (window), 5);
|
||||||
|
|
||||||
|
vbox = gtk_vbox_new (FALSE, 5);
|
||||||
|
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||||
|
|
||||||
|
/* Option menu contents */
|
||||||
|
combo_box = gtk_combo_box_new_text ();
|
||||||
|
|
||||||
|
gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), NO_EXPAND);
|
||||||
|
gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), SINGLE_EXPAND);
|
||||||
|
gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), MULTI_EXPAND);
|
||||||
|
gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), LAST_EXPAND);
|
||||||
|
gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), BORDER_EXPAND);
|
||||||
|
gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), ALL_EXPAND);
|
||||||
|
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), combo_box, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
/* Scrolled window and tree view */
|
||||||
|
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||||
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||||
|
GTK_POLICY_AUTOMATIC,
|
||||||
|
GTK_POLICY_AUTOMATIC);
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
|
||||||
|
|
||||||
|
tree_view = gtk_tree_view_new_with_model (create_model ());
|
||||||
|
gtk_container_add (GTK_CONTAINER (sw), tree_view);
|
||||||
|
|
||||||
|
for (i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
GtkTreeViewColumn *column;
|
||||||
|
|
||||||
|
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
|
||||||
|
i, "Header",
|
||||||
|
gtk_cell_renderer_text_new (),
|
||||||
|
"text", i,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
column = gtk_tree_view_get_column (GTK_TREE_VIEW (tree_view), i);
|
||||||
|
gtk_tree_view_column_set_resizable (column, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Toggle button for long content row */
|
||||||
|
button = gtk_toggle_button_new_with_label ("Toggle long content row");
|
||||||
|
g_signal_connect (button, "toggled",
|
||||||
|
G_CALLBACK (toggle_long_content_row), tree_view);
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
/* Set up option menu callback and default item */
|
||||||
|
g_signal_connect (combo_box, "changed",
|
||||||
|
G_CALLBACK (combo_box_changed), tree_view);
|
||||||
|
gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0);
|
||||||
|
|
||||||
|
/* Done */
|
||||||
|
gtk_widget_show_all (window);
|
||||||
|
|
||||||
|
gtk_main ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user