Commit 1aa00e52 authored by Matthias Clasen's avatar Matthias Clasen Committed by Matthias Clasen

Support separators in combo boxes and more generally in tree views

2004-07-07  Matthias Clasen  <mclasen@redhat.com>

	Support separators in combo boxes and more generally in tree
	views  (#135873):

	* gtk/gtkcombobox.h:
	* gtk/gtkcombobox.c (gtk_combo_box_get_row_separator_column):
	* gtk/gtkcombobox.c (gtk_combo_box_set_row_separator_column):
	Add a ::row-separator-column property with getter and setter,
	which can indicate a boolean model column to determine which
	rows are separators.

	* gtk/gtkcombobox.c: Display separator rows as separator menu
	items in menu mode, and by using the new treeview separator
	functionality in list mode.

	* gtk/gtktreeview.h:
	* gtk/gtktreeview.c (gtk_tree_view_get_row_separator_func):
	* gtk/gtktreeview.c (gtk_tree_view_set_row_separator_func):
	Add a callback to determine whether a row is a separator.

	* gtk/gtktreeview.c (gtk_tree_view_bin_expose):
	* gtk/gtktreeview.c (gtk_tree_view_create_row_drag_icon):
	* gtk/gtktreeview.c (validate_row): Use the new callback
	to determine whether a row is a separator, and draw it
	as a separator then. Since separators should take up less
	vertical space than regular rows, this requires removing
	the redundant MAX(...,expander_size) calls which appear in
	many places. Instead, the MAX() is now only done in
	validate_row(), and only if the row is not a separator.
	To catch possible side effects of this intrusive change,
	I have left EXPANDER_MAX() calls in place of the MAX() calls
	which will emit a warning if something breaks. They should
	be removed before 2.6.

	* gtk/gtktreeselection.c (row_is_selectable): Don't let
	separator rows be selected.

	* tests/testcombo.c (create_blaat): Add a separator column.
parent a346f4a8
2004-07-07 Matthias Clasen <mclasen@redhat.com>
Support separators in combo boxes and more generally in tree
views (#135873):
* gtk/gtkcombobox.h:
* gtk/gtkcombobox.c (gtk_combo_box_get_row_separator_column):
* gtk/gtkcombobox.c (gtk_combo_box_set_row_separator_column):
Add a ::row-separator-column property with getter and setter,
which can indicate a boolean model column to determine which
rows are separators.
* gtk/gtkcombobox.c: Display separator rows as separator menu
items in menu mode, and by using the new treeview separator
functionality in list mode.
* gtk/gtktreeview.h:
* gtk/gtktreeview.c (gtk_tree_view_get_row_separator_func):
* gtk/gtktreeview.c (gtk_tree_view_set_row_separator_func):
Add a callback to determine whether a row is a separator.
* gtk/gtktreeview.c (gtk_tree_view_bin_expose):
* gtk/gtktreeview.c (gtk_tree_view_create_row_drag_icon):
* gtk/gtktreeview.c (validate_row): Use the new callback
to determine whether a row is a separator, and draw it
as a separator then. Since separators should take up less
vertical space than regular rows, this requires removing
the redundant MAX(...,expander_size) calls which appear in
many places. Instead, the MAX() is now only done in
validate_row(), and only if the row is not a separator.
To catch possible side effects of this intrusive change,
I have left EXPANDER_MAX() calls in place of the MAX() calls
which will emit a warning if something breaks. They should
be removed before 2.6.
* gtk/gtktreeselection.c (row_is_selectable): Don't let
separator rows be selected.
* tests/testcombo.c (create_blaat): Add a separator column.
Tue Jul 6 22:58:00 2004 Matthias Clasen <maclas@gmx.de>
* gdk/x11/gdkwindow-x11.c (gdk_x11_window_set_user_time): Fix
......
2004-07-07 Matthias Clasen <mclasen@redhat.com>
Support separators in combo boxes and more generally in tree
views (#135873):
* gtk/gtkcombobox.h:
* gtk/gtkcombobox.c (gtk_combo_box_get_row_separator_column):
* gtk/gtkcombobox.c (gtk_combo_box_set_row_separator_column):
Add a ::row-separator-column property with getter and setter,
which can indicate a boolean model column to determine which
rows are separators.
* gtk/gtkcombobox.c: Display separator rows as separator menu
items in menu mode, and by using the new treeview separator
functionality in list mode.
* gtk/gtktreeview.h:
* gtk/gtktreeview.c (gtk_tree_view_get_row_separator_func):
* gtk/gtktreeview.c (gtk_tree_view_set_row_separator_func):
Add a callback to determine whether a row is a separator.
* gtk/gtktreeview.c (gtk_tree_view_bin_expose):
* gtk/gtktreeview.c (gtk_tree_view_create_row_drag_icon):
* gtk/gtktreeview.c (validate_row): Use the new callback
to determine whether a row is a separator, and draw it
as a separator then. Since separators should take up less
vertical space than regular rows, this requires removing
the redundant MAX(...,expander_size) calls which appear in
many places. Instead, the MAX() is now only done in
validate_row(), and only if the row is not a separator.
To catch possible side effects of this intrusive change,
I have left EXPANDER_MAX() calls in place of the MAX() calls
which will emit a warning if something breaks. They should
be removed before 2.6.
* gtk/gtktreeselection.c (row_is_selectable): Don't let
separator rows be selected.
* tests/testcombo.c (create_blaat): Add a separator column.
Tue Jul 6 22:58:00 2004 Matthias Clasen <maclas@gmx.de>
* gdk/x11/gdkwindow-x11.c (gdk_x11_window_set_user_time): Fix
......
2004-07-07 Matthias Clasen <mclasen@redhat.com>
Support separators in combo boxes and more generally in tree
views (#135873):
* gtk/gtkcombobox.h:
* gtk/gtkcombobox.c (gtk_combo_box_get_row_separator_column):
* gtk/gtkcombobox.c (gtk_combo_box_set_row_separator_column):
Add a ::row-separator-column property with getter and setter,
which can indicate a boolean model column to determine which
rows are separators.
* gtk/gtkcombobox.c: Display separator rows as separator menu
items in menu mode, and by using the new treeview separator
functionality in list mode.
* gtk/gtktreeview.h:
* gtk/gtktreeview.c (gtk_tree_view_get_row_separator_func):
* gtk/gtktreeview.c (gtk_tree_view_set_row_separator_func):
Add a callback to determine whether a row is a separator.
* gtk/gtktreeview.c (gtk_tree_view_bin_expose):
* gtk/gtktreeview.c (gtk_tree_view_create_row_drag_icon):
* gtk/gtktreeview.c (validate_row): Use the new callback
to determine whether a row is a separator, and draw it
as a separator then. Since separators should take up less
vertical space than regular rows, this requires removing
the redundant MAX(...,expander_size) calls which appear in
many places. Instead, the MAX() is now only done in
validate_row(), and only if the row is not a separator.
To catch possible side effects of this intrusive change,
I have left EXPANDER_MAX() calls in place of the MAX() calls
which will emit a warning if something breaks. They should
be removed before 2.6.
* gtk/gtktreeselection.c (row_is_selectable): Don't let
separator rows be selected.
* tests/testcombo.c (create_blaat): Add a separator column.
Tue Jul 6 22:58:00 2004 Matthias Clasen <maclas@gmx.de>
* gdk/x11/gdkwindow-x11.c (gdk_x11_window_set_user_time): Fix
......
2004-07-07 Matthias Clasen <mclasen@redhat.com>
Support separators in combo boxes and more generally in tree
views (#135873):
* gtk/gtkcombobox.h:
* gtk/gtkcombobox.c (gtk_combo_box_get_row_separator_column):
* gtk/gtkcombobox.c (gtk_combo_box_set_row_separator_column):
Add a ::row-separator-column property with getter and setter,
which can indicate a boolean model column to determine which
rows are separators.
* gtk/gtkcombobox.c: Display separator rows as separator menu
items in menu mode, and by using the new treeview separator
functionality in list mode.
* gtk/gtktreeview.h:
* gtk/gtktreeview.c (gtk_tree_view_get_row_separator_func):
* gtk/gtktreeview.c (gtk_tree_view_set_row_separator_func):
Add a callback to determine whether a row is a separator.
* gtk/gtktreeview.c (gtk_tree_view_bin_expose):
* gtk/gtktreeview.c (gtk_tree_view_create_row_drag_icon):
* gtk/gtktreeview.c (validate_row): Use the new callback
to determine whether a row is a separator, and draw it
as a separator then. Since separators should take up less
vertical space than regular rows, this requires removing
the redundant MAX(...,expander_size) calls which appear in
many places. Instead, the MAX() is now only done in
validate_row(), and only if the row is not a separator.
To catch possible side effects of this intrusive change,
I have left EXPANDER_MAX() calls in place of the MAX() calls
which will emit a warning if something breaks. They should
be removed before 2.6.
* gtk/gtktreeselection.c (row_is_selectable): Don't let
separator rows be selected.
* tests/testcombo.c (create_blaat): Add a separator column.
Tue Jul 6 22:58:00 2004 Matthias Clasen <maclas@gmx.de>
* gdk/x11/gdkwindow-x11.c (gdk_x11_window_set_user_time): Fix
......
......@@ -32,6 +32,7 @@
#include "gtkliststore.h"
#include "gtkmain.h"
#include "gtkmenu.h"
#include "gtkseparatormenuitem.h"
#include "gtktearoffmenuitem.h"
#include "gtktogglebutton.h"
#include "gtktreeselection.h"
......@@ -73,6 +74,7 @@ struct _GtkComboBoxPrivate
gint col_column;
gint row_column;
gint separator_column;
gint wrap_width;
......@@ -171,6 +173,7 @@ enum {
PROP_WRAP_WIDTH,
PROP_ROW_SPAN_COLUMN,
PROP_COLUMN_SPAN_COLUMN,
PROP_ROW_SEPARATOR_COLUMN,
PROP_ACTIVE,
PROP_ADD_TEAROFFS
};
......@@ -482,9 +485,9 @@ gtk_combo_box_class_init (GtkComboBoxClass *klass)
g_param_spec_int ("row_span_column",
P_("Row span column"),
P_("TreeModel column containing the row span values"),
0,
-1,
G_MAXINT,
0,
-1,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
......@@ -492,9 +495,19 @@ gtk_combo_box_class_init (GtkComboBoxClass *klass)
g_param_spec_int ("column_span_column",
P_("Column span column"),
P_("TreeModel column containing the column span values"),
0,
-1,
G_MAXINT,
0,
-1,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_ROW_SEPARATOR_COLUMN,
g_param_spec_int ("row_separator_column",
P_("Row separator column"),
P_("Boolean TreeModel column specifying which rows are separators"),
-1,
G_MAXINT,
-1,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
......@@ -563,6 +576,7 @@ gtk_combo_box_init (GtkComboBox *combo_box)
combo_box->priv->active_item = -1;
combo_box->priv->col_column = -1;
combo_box->priv->row_column = -1;
combo_box->priv->separator_column = -1;
}
static void
......@@ -591,6 +605,10 @@ gtk_combo_box_set_property (GObject *object,
gtk_combo_box_set_column_span_column (combo_box, g_value_get_int (value));
break;
case PROP_ROW_SEPARATOR_COLUMN:
gtk_combo_box_set_row_separator_column (combo_box, g_value_get_int (value));
break;
case PROP_ACTIVE:
gtk_combo_box_set_active (combo_box, g_value_get_int (value));
break;
......@@ -630,6 +648,10 @@ gtk_combo_box_get_property (GObject *object,
g_value_set_int (value, combo_box->priv->col_column);
break;
case PROP_ROW_SEPARATOR_COLUMN:
g_value_set_int (value, combo_box->priv->separator_column);
break;
case PROP_ACTIVE:
g_value_set_int (value, gtk_combo_box_get_active (combo_box));
break;
......@@ -1153,7 +1175,10 @@ menu_row_is_sensitive (GtkComboBox *combo_box,
GtkWidget *cell_view;
GList *cells, *list;
gboolean sensitive;
if (!GTK_IS_CELL_VIEW_MENU_ITEM (item))
return FALSE;
cell_view = gtk_bin_get_child (GTK_BIN (item));
gtk_cell_view_set_cell_data (GTK_CELL_VIEW (cell_view));
......@@ -1186,6 +1211,19 @@ tree_column_row_is_sensitive (GtkComboBox *combo_box,
if (!combo_box->priv->column)
return TRUE;
if (combo_box->priv->separator_column != -1)
{
gboolean is_separator;
gtk_tree_model_get (combo_box->priv->model,
iter,
combo_box->priv->separator_column, &is_separator,
-1);
if (is_separator)
return FALSE;
}
gtk_tree_view_column_cell_set_cell_data (combo_box->priv->column,
combo_box->priv->model,
iter, FALSE, FALSE);
......@@ -1266,14 +1304,14 @@ update_menu_sensitivity (GtkComboBox *combo_box)
children = gtk_container_get_children (GTK_CONTAINER (menu));
child = children;
if (child && GTK_IS_TEAROFF_MENU_ITEM (child->data))
child = child->next;
for (i = 0; i < items; i++, child = child->next)
{
GtkWidget *item = GTK_WIDGET (child->data);
gboolean sensitive;
if (!GTK_IS_CELL_VIEW_MENU_ITEM (item))
continue;
sensitive = menu_row_is_sensitive (combo_box, item);
gtk_widget_set_sensitive (item, sensitive);
}
......@@ -1327,7 +1365,7 @@ gtk_combo_box_popup (GtkComboBox *combo_box)
gtk_widget_show_all (combo_box->priv->popup_frame);
gtk_combo_box_list_position (combo_box, &x, &y, &width, &height);
gtk_widget_set_size_request (combo_box->priv->popup_window, width, -1);
gtk_window_move (GTK_WINDOW (combo_box->priv->popup_window), x, y);
......@@ -1378,6 +1416,7 @@ gtk_combo_box_popdown (GtkComboBox *combo_box)
}
gtk_combo_box_list_remove_grabs (combo_box);
gtk_widget_hide_all (combo_box->priv->popup_window);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (combo_box->priv->button),
FALSE);
......@@ -1755,8 +1794,7 @@ gtk_combo_box_scroll_event (GtkWidget *widget,
GdkEventScroll *event)
{
GtkComboBox *combo_box = GTK_COMBO_BOX (widget);
gint index;
gint items;
gint index, new_index, items;
index = gtk_combo_box_get_active (combo_box);
......@@ -1765,11 +1803,23 @@ gtk_combo_box_scroll_event (GtkWidget *widget,
items = gtk_tree_model_iter_n_children (combo_box->priv->model, NULL);
if (event->direction == GDK_SCROLL_UP)
index--;
else
index++;
{
new_index = index - 1;
while (new_index >= 0 && !row_is_sensitive (combo_box, new_index))
new_index--;
if (new_index < 0)
new_index = index;
}
else
{
new_index = index + 1;
while (new_index < items && !row_is_sensitive (combo_box, new_index))
new_index++;
if (new_index == items)
new_index = index;
}
gtk_combo_box_set_active (combo_box, CLAMP (index, 0, items - 1));
gtk_combo_box_set_active (combo_box, CLAMP (new_index, 0, items - 1));
}
return TRUE;
......@@ -1905,16 +1955,33 @@ gtk_combo_box_menu_fill (GtkComboBox *combo_box)
for (i = 0; i < items; i++)
{
GtkTreePath *path;
GtkTreeIter iter;
gboolean is_separator;
path = gtk_tree_path_new_from_indices (i, -1);
tmp = gtk_cell_view_menu_item_new_from_model (combo_box->priv->model,
path);
g_signal_connect (tmp, "activate",
G_CALLBACK (gtk_combo_box_menu_item_activate),
combo_box);
cell_view_sync_cells (combo_box,
GTK_CELL_VIEW (GTK_BIN (tmp)->child));
if (combo_box->priv->separator_column != -1)
{
gtk_tree_model_get_iter (combo_box->priv->model, &iter, path);
gtk_tree_model_get (combo_box->priv->model, &iter,
combo_box->priv->separator_column, &is_separator, -1);
}
else
is_separator = FALSE;
if (is_separator)
tmp = gtk_separator_menu_item_new ();
else
{
tmp = gtk_cell_view_menu_item_new_from_model (combo_box->priv->model,
path);
g_signal_connect (tmp, "activate",
G_CALLBACK (gtk_combo_box_menu_item_activate),
combo_box);
cell_view_sync_cells (combo_box,
GTK_CELL_VIEW (GTK_BIN (tmp)->child));
}
gtk_menu_shell_append (GTK_MENU_SHELL (menu), tmp);
......@@ -2345,6 +2412,21 @@ gtk_combo_box_menu_row_changed (GtkTreeModel *model,
* list style
*/
static gboolean
row_is_separator (GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data)
{
GtkComboBox *combo_box = GTK_COMBO_BOX (data);
gboolean is_separator = FALSE;
if (combo_box->priv->separator_column != -1)
gtk_tree_model_get (combo_box->priv->model, iter,
combo_box->priv->separator_column, &is_separator, -1);
return is_separator;
}
static void
gtk_combo_box_list_setup (GtkComboBox *combo_box)
{
......@@ -2399,7 +2481,8 @@ gtk_combo_box_list_setup (GtkComboBox *combo_box)
FALSE);
gtk_tree_view_set_hover_selection (GTK_TREE_VIEW (combo_box->priv->tree_view),
TRUE);
gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW (combo_box->priv->tree_view),
row_is_separator, combo_box, NULL);
if (combo_box->priv->model)
gtk_tree_view_set_model (GTK_TREE_VIEW (combo_box->priv->tree_view),
combo_box->priv->model);
......@@ -3303,7 +3386,7 @@ gtk_combo_box_set_row_span_column (GtkComboBox *combo_box,
g_return_if_fail (GTK_IS_COMBO_BOX (combo_box));
col = gtk_tree_model_get_n_columns (combo_box->priv->model);
g_return_if_fail (row_span >= 0 && row_span < col);
g_return_if_fail (row_span >= -1 && row_span < col);
if (row_span != combo_box->priv->row_column)
{
......@@ -3353,7 +3436,7 @@ gtk_combo_box_set_column_span_column (GtkComboBox *combo_box,
g_return_if_fail (GTK_IS_COMBO_BOX (combo_box));
col = gtk_tree_model_get_n_columns (combo_box->priv->model);
g_return_if_fail (column_span >= 0 && column_span < col);
g_return_if_fail (column_span >= -1 && column_span < col);
if (column_span != combo_box->priv->col_column)
{
......@@ -3876,3 +3959,54 @@ gtk_combo_box_set_add_tearoffs (GtkComboBox *combo_box,
g_object_notify (G_OBJECT (combo_box), "add_tearoffs");
}
}
/**
* gtk_combo_box_set_row_separator_column:
* @combo_box: a #GtkComboBox
* @column: the index of a boolean model column, or -1 to
* turn off separators
*
* Sets the row separator column index.
* This model column contains boolean values which indicate
* whether a row is to be drawn as a separator or now.
* Setting the index to -1 turns off separators.
*
* Since: 2.6
**/
void
gtk_combo_box_set_row_separator_column (GtkComboBox *combo_box,
gint column)
{
gint col;
g_return_if_fail (GTK_IS_COMBO_BOX (combo_box));
col = gtk_tree_model_get_n_columns (combo_box->priv->model);
g_return_if_fail (column >= -1 && column < col);
if (combo_box->priv->separator_column != column)
{
combo_box->priv->separator_column = column;
gtk_widget_queue_draw (combo_box);
g_object_notify (G_OBJECT (combo_box), "row_separator_column");
}
}
/**
* gtk_combo_box_get_row_separator_column:
* @combo_box: a #GtkComboBox
*
* Returns the current row separator column index.
*
* Return value: the row separator column index
*
* Since: 2.6
**/
gint
gtk_combo_box_get_row_separator_column (GtkComboBox *combo_box)
{
g_return_val_if_fail (GTK_IS_COMBO_BOX (combo_box), -1);
return combo_box->priv->separator_column;
}
......@@ -94,6 +94,10 @@ void gtk_combo_box_set_model (GtkComboBox *combo_box,
GtkTreeModel *model);
GtkTreeModel *gtk_combo_box_get_model (GtkComboBox *combo_box);
void gtk_combo_box_set_row_separator_column (GtkComboBox *combo_box,
gint column);
gint gtk_combo_box_get_row_separator_column (GtkComboBox *combo_box);
/* convenience -- text */
GtkWidget *gtk_combo_box_new_text (void);
void gtk_combo_box_append_text (GtkComboBox *combo_box,
......
......@@ -1319,21 +1319,29 @@ row_is_selectable (GtkTreeSelection *selection,
GtkTreePath *path)
{
GList *list;
gboolean sensitive;
sensitive = FALSE;
GtkTreeIter iter;
gboolean sensitive = FALSE;
if (!gtk_tree_model_get_iter (selection->tree_view->priv->model, &iter, path))
sensitive = TRUE;
if (!sensitive && selection->tree_view->priv->row_separator_func)
{
/* never allow separators to be selected */
if ((* selection->tree_view->priv->row_separator_func) (selection->tree_view->priv->model,
&iter,
selection->tree_view->priv->row_separator_data))
return FALSE;
}
for (list = selection->tree_view->priv->columns; list && !sensitive; list = list->next)
{
GtkTreeViewColumn *column = GTK_TREE_VIEW_COLUMN (list->data);
GtkTreeIter iter;
if (!column->visible)
continue;
if (gtk_tree_model_get_iter (selection->tree_view->priv->model, &iter, path))
sensitive = tree_column_is_sensitive (column, selection->tree_view->priv->model, &iter);
else
sensitive = TRUE;
sensitive = tree_column_is_sensitive (column, selection->tree_view->priv->model, &iter);
}
if (!sensitive)
......
......@@ -62,6 +62,8 @@
#define BACKGROUND_FIRST_PIXEL(tree_view,tree,node) (RBTREE_Y_TO_TREE_WINDOW_Y (tree_view, _gtk_rbtree_node_find_offset ((tree), (node))))
#define CELL_FIRST_PIXEL(tree_view,tree,node,separator) (BACKGROUND_FIRST_PIXEL (tree_view,tree,node) + separator/2)
#define EXPANDER_MAX(height,expander_size,tree_view,tree,node) check_expander_max (height, expander_size, tree_view, tree, node)
typedef struct _GtkTreeViewChild GtkTreeViewChild;
struct _GtkTreeViewChild
......@@ -423,6 +425,12 @@ static void gtk_tree_view_tree_window_to_tree_coords (GtkTreeView *tree_view,
gint wy,
gint *tx,
gint *ty);
static gint check_expander_max (gint height,
gint expander_size,
GtkTreeView *tree_view,
GtkRBTree *tree,
GtkRBNode *node);
static GtkContainerClass *parent_class = NULL;
static guint tree_view_signals [LAST_SIGNAL] = { 0 };
......@@ -1346,6 +1354,12 @@ gtk_tree_view_destroy (GtkObject *object)
tree_view->priv->search_user_data = NULL;
}
if (tree_view->priv->row_separator_destroy)
{
(* tree_view->priv->row_separator_destroy) (tree_view->priv->row_separator_data);
tree_view->priv->row_separator_data = NULL;
}
gtk_tree_view_set_model (tree_view, NULL);
if (GTK_OBJECT_CLASS (parent_class)->destroy)
......@@ -2155,8 +2169,9 @@ gtk_tree_view_button_press (GtkWidget *widget,
path = _gtk_tree_view_find_path (tree_view, tree, node);
depth = gtk_tree_path_get_depth (path);
background_area.y = y_offset + event->y;
background_area.height = MAX (GTK_RBNODE_GET_HEIGHT (node),
tree_view->priv->expander_size);
background_area.height = EXPANDER_MAX (GTK_RBNODE_GET_HEIGHT (node),
tree_view->priv->expander_size,
tree_view, tree, node);
background_area.x = 0;
......@@ -2621,7 +2636,8 @@ coords_are_over_arrow (GtkTreeView *tree_view,
arrow.y = BACKGROUND_FIRST_PIXEL (tree_view, tree, node);
arrow.height = MAX (BACKGROUND_HEIGHT (node), tree_view->priv->expander_size);
arrow.height = EXPANDER_MAX (BACKGROUND_HEIGHT (node), tree_view->priv->expander_size,
tree_view, tree, node);
gtk_tree_view_get_arrow_xrange (tree_view, tree, &arrow.x, &x2);
......@@ -3309,7 +3325,7 @@ gtk_tree_view_bin_expose (GtkWidget *widget,
path);
depth = gtk_tree_path_get_depth (path);
gtk_tree_path_free (path);
cursor_path = NULL;
drag_dest_path = NULL;
......@@ -3330,7 +3346,7 @@ gtk_tree_view_bin_expose (GtkWidget *widget,
gdk_drawable_get_size (tree_view->priv->bin_window,
&bin_window_width, NULL);
n_visible_columns = 0;
for (list = tree_view->priv->columns; list; list = list->next)
{
......@@ -3355,8 +3371,17 @@ gtk_tree_view_bin_expose (GtkWidget *widget,
do
{
gboolean parity;
gboolean is_separator = FALSE;
if (tree_view->priv->row_separator_func)
{
is_separator = (* tree_view->priv->row_separator_func) (tree_view->priv->model,
&iter,
tree_view->priv->row_separator_data);
}
max_height = MAX (BACKGROUND_HEIGHT (node), tree_view->priv->expander_size);
max_height = EXPANDER_MAX (BACKGROUND_HEIGHT (node), tree_view->priv->expander_size,
tree_view, tree, node);
x_offset = -event->area.x;
cell_offset = 0;
......@@ -3499,12 +3524,23 @@ gtk_tree_view_bin_expose (GtkWidget *widget,
* level of the tree we're dropping at.
*/
highlight_x = cell_area.x;
_gtk_tree_view_column_cell_render (column,
event->window,
&background_area,
&cell_area,
&event->area,
flags);
if (is_separator)
gtk_paint_hline (widget->style,
event->window,
state,
&cell_area,
widget,
NULL,
cell_area.x,
cell_area.x + cell_area.width,
cell_area.y + cell_area.height / 2);
else
_gtk_tree_view_column_cell_render (column,
event->window,
&background_area,
&cell_area,
&event->area,
flags);
if ((node->flags & GTK_RBNODE_IS_PARENT) == GTK_RBNODE_IS_PARENT)
{
gint x, y;
......@@ -3517,12 +3553,23 @@ gtk_tree_view_bin_expose (GtkWidget *widget,
}
else
{
_gtk_tree_view_column_cell_render (column,
event->window,
&background_area,
&cell_area,
&event->area,
flags);
if (is_separator)
gtk_paint_hline (widget->style,
event->window,
state,
&cell_area,
widget,
NULL,
cell_area.x,
cell_area.x + cell_area.width,
cell_area.y + cell_area.height / 2);
else
_gtk_tree_view_column_cell_render (column,
event->window,
&background_area,
&cell_area,
&event->area,
flags);
}
if (node == cursor && has_special_cell &&
((column == tree_view->priv->focus_column &&
......@@ -3579,8 +3626,9 @@ gtk_tree_view_bin_expose (GtkWidget *widget,
"treeview-drop-indicator",
0, BACKGROUND_FIRST_PIXEL (tree_view, tree, node)
- focus_line_width / 2,
width, MAX(BACKGROUND_HEIGHT (node),
tree_view->priv->expander_size)
width, EXPANDER_MAX(BACKGROUND_HEIGHT (node),
tree_view->priv->expander_size,
tree_view, tree, node)
- focus_line_width + 1);
break;
}
......@@ -3621,8 +3669,9 @@ gtk_tree_view_bin_expose (GtkWidget *widget,
0,
BACKGROUND_FIRST_PIXEL (tree_view, tree, node),
width,
MAX (BACKGROUND_HEIGHT (node),
tree_view->priv->expander_size));
EXPANDER_MAX (BACKGROUND_HEIGHT (node),
tree_view->priv->expander_size,
tree_view, tree, node));
}
y_offset += max_height;
......@@ -4265,16 +4314,26 @@ validate_row (GtkTreeView *tree_view,
gint horizontal_separator;
gint depth = gtk_tree_path_get_depth (path);
gboolean retval = FALSE;
gboolean is_separator = FALSE;
gint focus_pad;