forked from AuroraMiddleware/gtk
Support insensitive cells in tree views and combo boxes.
This commit is contained in:
parent
7c200f8a9c
commit
310fd268e7
46
ChangeLog
46
ChangeLog
@ -1,3 +1,49 @@
|
||||
Wed May 26 23:26:51 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
Support insensitive cells in tree views and combo boxes:
|
||||
|
||||
* gtk/gtkcellrenderer.h:
|
||||
* gtk/gtkcellrenderer.c: Add a ::sensitive property.
|
||||
|
||||
* gtk/gtkcellrendererpixbuf.c (gtk_cell_renderer_pixbuf_render):
|
||||
* gtk/gtkcellrenderertext.c (gtk_cell_renderer_text_render):
|
||||
* gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_render):
|
||||
Support drawing insensitive.
|
||||
|
||||
* gtk/gtkcellview.h:
|
||||
* gtk/gtkcellview.c (gtk_cell_view_get_cell_renderers): New
|
||||
function to obtain the cell renderers from a cell view. Also
|
||||
export gtk_cell_view_set_cell_data().
|
||||
|
||||
* gtk/gtktreeselection.c (tree_column_is_sensitive):
|
||||
* gtk/gtktreeselection.c (row_is_selectable): Helper functions
|
||||
to determine whether all visible cells in a row are insensitive
|
||||
and whether a row is selectable. A row is not selectable if the
|
||||
user function says so or if all visible cells are insensitive.
|
||||
* gtk/gtktreeselection.c (_gtk_tree_selection_internal_select_node):
|
||||
* gtk/gtktreeselection.c (gtk_tree_selection_real_select_node):
|
||||
Use row_is_selectable().
|
||||
|
||||
* gtk/gtkcombobox.c (row_is_sensitive):
|
||||
* gtk/gtkcombobox.c (tree_column_row_is_sensitive):
|
||||
* gtk/gtkcombobox.c (menu_row_is_sensitive): Helper functions
|
||||
to determine row sensitivity in menu or list mode.
|
||||
|
||||
* gtk/gtkcombobox.c (update_menu_sensitivity): Helper function
|
||||
to set up sensitivity menu items from the underlying rows.
|
||||
|
||||
* gtk/gtkcombobox.c (gtk_combo_box_popup):
|
||||
* gtk/gtkcombobox.c (gtk_combo_box_menu_button_press): Use
|
||||
update_menu_sensitivity().
|
||||
|
||||
* gtk/gtkcombobox.c (gtk_combo_box_list_setup): Setup the cell
|
||||
data funcs.
|
||||
|
||||
* gtk/gtkcombobox.c (gtk_combo_box_key_press): Skip insensitive
|
||||
rows.
|
||||
|
||||
* tests/testcombo.c (main): Make some rows insensitive.
|
||||
|
||||
2004-05-26 Robert Ögren <gtk@roboros.com>
|
||||
|
||||
* gdk/win32/gdkinput-win32.c (_gdk_input_other_event): Send key
|
||||
|
@ -1,3 +1,49 @@
|
||||
Wed May 26 23:26:51 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
Support insensitive cells in tree views and combo boxes:
|
||||
|
||||
* gtk/gtkcellrenderer.h:
|
||||
* gtk/gtkcellrenderer.c: Add a ::sensitive property.
|
||||
|
||||
* gtk/gtkcellrendererpixbuf.c (gtk_cell_renderer_pixbuf_render):
|
||||
* gtk/gtkcellrenderertext.c (gtk_cell_renderer_text_render):
|
||||
* gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_render):
|
||||
Support drawing insensitive.
|
||||
|
||||
* gtk/gtkcellview.h:
|
||||
* gtk/gtkcellview.c (gtk_cell_view_get_cell_renderers): New
|
||||
function to obtain the cell renderers from a cell view. Also
|
||||
export gtk_cell_view_set_cell_data().
|
||||
|
||||
* gtk/gtktreeselection.c (tree_column_is_sensitive):
|
||||
* gtk/gtktreeselection.c (row_is_selectable): Helper functions
|
||||
to determine whether all visible cells in a row are insensitive
|
||||
and whether a row is selectable. A row is not selectable if the
|
||||
user function says so or if all visible cells are insensitive.
|
||||
* gtk/gtktreeselection.c (_gtk_tree_selection_internal_select_node):
|
||||
* gtk/gtktreeselection.c (gtk_tree_selection_real_select_node):
|
||||
Use row_is_selectable().
|
||||
|
||||
* gtk/gtkcombobox.c (row_is_sensitive):
|
||||
* gtk/gtkcombobox.c (tree_column_row_is_sensitive):
|
||||
* gtk/gtkcombobox.c (menu_row_is_sensitive): Helper functions
|
||||
to determine row sensitivity in menu or list mode.
|
||||
|
||||
* gtk/gtkcombobox.c (update_menu_sensitivity): Helper function
|
||||
to set up sensitivity menu items from the underlying rows.
|
||||
|
||||
* gtk/gtkcombobox.c (gtk_combo_box_popup):
|
||||
* gtk/gtkcombobox.c (gtk_combo_box_menu_button_press): Use
|
||||
update_menu_sensitivity().
|
||||
|
||||
* gtk/gtkcombobox.c (gtk_combo_box_list_setup): Setup the cell
|
||||
data funcs.
|
||||
|
||||
* gtk/gtkcombobox.c (gtk_combo_box_key_press): Skip insensitive
|
||||
rows.
|
||||
|
||||
* tests/testcombo.c (main): Make some rows insensitive.
|
||||
|
||||
2004-05-26 Robert Ögren <gtk@roboros.com>
|
||||
|
||||
* gdk/win32/gdkinput-win32.c (_gdk_input_other_event): Send key
|
||||
|
@ -1,3 +1,49 @@
|
||||
Wed May 26 23:26:51 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
Support insensitive cells in tree views and combo boxes:
|
||||
|
||||
* gtk/gtkcellrenderer.h:
|
||||
* gtk/gtkcellrenderer.c: Add a ::sensitive property.
|
||||
|
||||
* gtk/gtkcellrendererpixbuf.c (gtk_cell_renderer_pixbuf_render):
|
||||
* gtk/gtkcellrenderertext.c (gtk_cell_renderer_text_render):
|
||||
* gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_render):
|
||||
Support drawing insensitive.
|
||||
|
||||
* gtk/gtkcellview.h:
|
||||
* gtk/gtkcellview.c (gtk_cell_view_get_cell_renderers): New
|
||||
function to obtain the cell renderers from a cell view. Also
|
||||
export gtk_cell_view_set_cell_data().
|
||||
|
||||
* gtk/gtktreeselection.c (tree_column_is_sensitive):
|
||||
* gtk/gtktreeselection.c (row_is_selectable): Helper functions
|
||||
to determine whether all visible cells in a row are insensitive
|
||||
and whether a row is selectable. A row is not selectable if the
|
||||
user function says so or if all visible cells are insensitive.
|
||||
* gtk/gtktreeselection.c (_gtk_tree_selection_internal_select_node):
|
||||
* gtk/gtktreeselection.c (gtk_tree_selection_real_select_node):
|
||||
Use row_is_selectable().
|
||||
|
||||
* gtk/gtkcombobox.c (row_is_sensitive):
|
||||
* gtk/gtkcombobox.c (tree_column_row_is_sensitive):
|
||||
* gtk/gtkcombobox.c (menu_row_is_sensitive): Helper functions
|
||||
to determine row sensitivity in menu or list mode.
|
||||
|
||||
* gtk/gtkcombobox.c (update_menu_sensitivity): Helper function
|
||||
to set up sensitivity menu items from the underlying rows.
|
||||
|
||||
* gtk/gtkcombobox.c (gtk_combo_box_popup):
|
||||
* gtk/gtkcombobox.c (gtk_combo_box_menu_button_press): Use
|
||||
update_menu_sensitivity().
|
||||
|
||||
* gtk/gtkcombobox.c (gtk_combo_box_list_setup): Setup the cell
|
||||
data funcs.
|
||||
|
||||
* gtk/gtkcombobox.c (gtk_combo_box_key_press): Skip insensitive
|
||||
rows.
|
||||
|
||||
* tests/testcombo.c (main): Make some rows insensitive.
|
||||
|
||||
2004-05-26 Robert Ögren <gtk@roboros.com>
|
||||
|
||||
* gdk/win32/gdkinput-win32.c (_gdk_input_other_event): Send key
|
||||
|
@ -1,3 +1,49 @@
|
||||
Wed May 26 23:26:51 2004 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
Support insensitive cells in tree views and combo boxes:
|
||||
|
||||
* gtk/gtkcellrenderer.h:
|
||||
* gtk/gtkcellrenderer.c: Add a ::sensitive property.
|
||||
|
||||
* gtk/gtkcellrendererpixbuf.c (gtk_cell_renderer_pixbuf_render):
|
||||
* gtk/gtkcellrenderertext.c (gtk_cell_renderer_text_render):
|
||||
* gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_render):
|
||||
Support drawing insensitive.
|
||||
|
||||
* gtk/gtkcellview.h:
|
||||
* gtk/gtkcellview.c (gtk_cell_view_get_cell_renderers): New
|
||||
function to obtain the cell renderers from a cell view. Also
|
||||
export gtk_cell_view_set_cell_data().
|
||||
|
||||
* gtk/gtktreeselection.c (tree_column_is_sensitive):
|
||||
* gtk/gtktreeselection.c (row_is_selectable): Helper functions
|
||||
to determine whether all visible cells in a row are insensitive
|
||||
and whether a row is selectable. A row is not selectable if the
|
||||
user function says so or if all visible cells are insensitive.
|
||||
* gtk/gtktreeselection.c (_gtk_tree_selection_internal_select_node):
|
||||
* gtk/gtktreeselection.c (gtk_tree_selection_real_select_node):
|
||||
Use row_is_selectable().
|
||||
|
||||
* gtk/gtkcombobox.c (row_is_sensitive):
|
||||
* gtk/gtkcombobox.c (tree_column_row_is_sensitive):
|
||||
* gtk/gtkcombobox.c (menu_row_is_sensitive): Helper functions
|
||||
to determine row sensitivity in menu or list mode.
|
||||
|
||||
* gtk/gtkcombobox.c (update_menu_sensitivity): Helper function
|
||||
to set up sensitivity menu items from the underlying rows.
|
||||
|
||||
* gtk/gtkcombobox.c (gtk_combo_box_popup):
|
||||
* gtk/gtkcombobox.c (gtk_combo_box_menu_button_press): Use
|
||||
update_menu_sensitivity().
|
||||
|
||||
* gtk/gtkcombobox.c (gtk_combo_box_list_setup): Setup the cell
|
||||
data funcs.
|
||||
|
||||
* gtk/gtkcombobox.c (gtk_combo_box_key_press): Skip insensitive
|
||||
rows.
|
||||
|
||||
* tests/testcombo.c (main): Make some rows insensitive.
|
||||
|
||||
2004-05-26 Robert Ögren <gtk@roboros.com>
|
||||
|
||||
* gdk/win32/gdkinput-win32.c (_gdk_input_other_event): Send key
|
||||
|
@ -50,6 +50,7 @@ enum {
|
||||
PROP_ZERO,
|
||||
PROP_MODE,
|
||||
PROP_VISIBLE,
|
||||
PROP_SENSITIVE,
|
||||
PROP_XALIGN,
|
||||
PROP_YALIGN,
|
||||
PROP_XPAD,
|
||||
@ -111,6 +112,7 @@ gtk_cell_renderer_init (GtkCellRenderer *cell)
|
||||
cell->yalign = 0.5;
|
||||
cell->xpad = 0;
|
||||
cell->ypad = 0;
|
||||
cell->sensitive = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -162,8 +164,14 @@ gtk_cell_renderer_class_init (GtkCellRendererClass *class)
|
||||
P_("visible"),
|
||||
P_("Display the cell"),
|
||||
TRUE,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_WRITABLE));
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_SENSITIVE,
|
||||
g_param_spec_boolean ("sensitive",
|
||||
P_("Sensitive"),
|
||||
P_("Display the cell sensitive"),
|
||||
TRUE,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_XALIGN,
|
||||
@ -293,6 +301,9 @@ gtk_cell_renderer_get_property (GObject *object,
|
||||
case PROP_VISIBLE:
|
||||
g_value_set_boolean (value, cell->visible);
|
||||
break;
|
||||
case PROP_SENSITIVE:
|
||||
g_value_set_boolean (value, cell->sensitive);
|
||||
break;
|
||||
case PROP_XALIGN:
|
||||
g_value_set_float (value, cell->xalign);
|
||||
break;
|
||||
@ -355,6 +366,9 @@ gtk_cell_renderer_set_property (GObject *object,
|
||||
case PROP_VISIBLE:
|
||||
cell->visible = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_SENSITIVE:
|
||||
cell->sensitive = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_XALIGN:
|
||||
cell->xalign = g_value_get_float (value);
|
||||
break;
|
||||
|
@ -71,6 +71,7 @@ struct _GtkCellRenderer
|
||||
guint is_expander : 1;
|
||||
guint is_expanded : 1;
|
||||
guint cell_background_set : 1;
|
||||
guint sensitive : 1;
|
||||
};
|
||||
|
||||
struct _GtkCellRendererClass
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <config.h>
|
||||
#include <stdlib.h>
|
||||
#include "gtkcellrendererpixbuf.h"
|
||||
#include "gtkiconfactory.h"
|
||||
#include "gtkintl.h"
|
||||
|
||||
static void gtk_cell_renderer_pixbuf_get_property (GObject *object,
|
||||
@ -72,6 +73,7 @@ struct _GtkCellRendererPixbufPrivate
|
||||
gchar *stock_id;
|
||||
GtkIconSize stock_size;
|
||||
gchar *stock_detail;
|
||||
GdkPixbuf *insensitive;
|
||||
};
|
||||
|
||||
|
||||
@ -201,6 +203,9 @@ gtk_cell_renderer_pixbuf_finalize (GObject *object)
|
||||
if (priv->stock_detail)
|
||||
g_free (priv->stock_detail);
|
||||
|
||||
if (priv->insensitive)
|
||||
g_object_unref (priv->insensitive);
|
||||
|
||||
(* G_OBJECT_CLASS (parent_class)->finalize) (object);
|
||||
}
|
||||
|
||||
@ -467,6 +472,36 @@ gtk_cell_renderer_pixbuf_render (GtkCellRenderer *cell,
|
||||
pix_rect.width -= cell->xpad * 2;
|
||||
pix_rect.height -= cell->ypad * 2;
|
||||
|
||||
if (GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE || !cell->sensitive)
|
||||
{
|
||||
if (!priv->insensitive)
|
||||
{
|
||||
GtkIconSource *source;
|
||||
|
||||
source = gtk_icon_source_new ();
|
||||
gtk_icon_source_set_pixbuf (source, pixbuf);
|
||||
/* The size here is arbitrary; since size isn't
|
||||
* wildcarded in the souce, it isn't supposed to be
|
||||
* scaled by the engine function
|
||||
*/
|
||||
gtk_icon_source_set_size (source, GTK_ICON_SIZE_SMALL_TOOLBAR);
|
||||
gtk_icon_source_set_size_wildcarded (source, FALSE);
|
||||
|
||||
priv->insensitive = gtk_style_render_icon (widget->style,
|
||||
source,
|
||||
gtk_widget_get_direction (widget),
|
||||
GTK_STATE_INSENSITIVE,
|
||||
/* arbitrary */
|
||||
(GtkIconSize)-1,
|
||||
widget,
|
||||
"gtkcellrendererpixbuf");
|
||||
|
||||
gtk_icon_source_free (source);
|
||||
}
|
||||
|
||||
pixbuf = priv->insensitive;
|
||||
}
|
||||
|
||||
if (gdk_rectangle_intersect (cell_area, &pix_rect, &draw_rect) &&
|
||||
gdk_rectangle_intersect (expose_area, &draw_rect, &draw_rect))
|
||||
gdk_draw_pixbuf (window,
|
||||
|
@ -1374,8 +1374,11 @@ gtk_cell_renderer_text_render (GtkCellRenderer *cell,
|
||||
|
||||
gtk_cell_renderer_text_get_size (cell, widget, cell_area, &x_offset, &y_offset, NULL, NULL);
|
||||
|
||||
|
||||
if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED)
|
||||
if (!cell->sensitive)
|
||||
{
|
||||
state = GTK_STATE_INSENSITIVE;
|
||||
}
|
||||
else if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED)
|
||||
{
|
||||
if (GTK_WIDGET_HAS_FOCUS (widget))
|
||||
state = GTK_STATE_SELECTED;
|
||||
|
@ -348,7 +348,11 @@ gtk_cell_renderer_toggle_render (GtkCellRenderer *cell,
|
||||
else
|
||||
shadow = celltoggle->active ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
|
||||
|
||||
if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED)
|
||||
if (!cell->sensitive)
|
||||
{
|
||||
state = GTK_STATE_INSENSITIVE;
|
||||
}
|
||||
else if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED)
|
||||
{
|
||||
if (GTK_WIDGET_HAS_FOCUS (widget))
|
||||
state = GTK_STATE_SELECTED;
|
||||
|
@ -80,7 +80,6 @@ static void gtk_cell_view_set_valuesv (GtkCellView *cel
|
||||
va_list args);
|
||||
static GtkCellViewCellInfo *gtk_cell_view_get_cell_info (GtkCellView *cellview,
|
||||
GtkCellRenderer *renderer);
|
||||
static void gtk_cell_view_set_cell_data (GtkCellView *cellview);
|
||||
|
||||
|
||||
static void gtk_cell_view_cell_layout_pack_start (GtkCellLayout *layout,
|
||||
@ -527,7 +526,7 @@ gtk_cell_view_get_cell_info (GtkCellView *cellview,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
gtk_cell_view_set_cell_data (GtkCellView *cellview)
|
||||
{
|
||||
GList *i;
|
||||
@ -979,3 +978,20 @@ gtk_cell_view_set_background_color (GtkCellView *view,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GList *
|
||||
gtk_cell_view_get_cell_renderers (GtkCellView *cell_view)
|
||||
{
|
||||
GList *retval = NULL, *list;
|
||||
|
||||
g_return_val_if_fail (cell_view != NULL, NULL);
|
||||
|
||||
for (list = cell_view->priv->cell_list; list; list = list->next)
|
||||
{
|
||||
GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)list->data;
|
||||
|
||||
retval = g_list_prepend (retval, info->cell);
|
||||
}
|
||||
|
||||
return g_list_reverse (retval);
|
||||
}
|
||||
|
@ -76,6 +76,8 @@ gboolean gtk_cell_view_get_size_of_row (GtkCellView *cell_v
|
||||
|
||||
void gtk_cell_view_set_background_color (GtkCellView *cell_view,
|
||||
const GdkColor *color);
|
||||
void gtk_cell_view_set_cell_data (GtkCellView *cellview);
|
||||
GList *gtk_cell_view_get_cell_renderers (GtkCellView *cellview);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -1142,6 +1142,140 @@ gtk_combo_box_list_position (GtkComboBox *combo_box,
|
||||
*y -= *height;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
menu_row_is_sensitive (GtkComboBox *combo_box,
|
||||
GtkWidget *item)
|
||||
{
|
||||
GtkWidget *cell_view;
|
||||
GList *cells, *list;
|
||||
gboolean sensitive;
|
||||
|
||||
cell_view = gtk_bin_get_child (GTK_BIN (item));
|
||||
|
||||
gtk_cell_view_set_cell_data (GTK_CELL_VIEW (cell_view));
|
||||
cells = gtk_cell_view_get_cell_renderers (GTK_CELL_VIEW (cell_view));
|
||||
|
||||
sensitive = FALSE;
|
||||
list = cells;
|
||||
while (list)
|
||||
{
|
||||
g_object_get (G_OBJECT (list->data), "sensitive", &sensitive, NULL);
|
||||
|
||||
if (sensitive)
|
||||
break;
|
||||
|
||||
list = list->next;
|
||||
}
|
||||
g_list_free (cells);
|
||||
|
||||
return sensitive;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
tree_column_row_is_sensitive (GtkComboBox *combo_box,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
GList *cells, *list;
|
||||
gboolean sensitive;
|
||||
|
||||
if (!combo_box->priv->column)
|
||||
return TRUE;
|
||||
|
||||
gtk_tree_view_column_cell_set_cell_data (combo_box->priv->column,
|
||||
combo_box->priv->model,
|
||||
iter, FALSE, FALSE);
|
||||
|
||||
cells = gtk_tree_view_column_get_cell_renderers (combo_box->priv->column);
|
||||
|
||||
sensitive = FALSE;
|
||||
list = cells;
|
||||
while (list)
|
||||
{
|
||||
g_object_get (G_OBJECT (list->data), "sensitive", &sensitive, NULL);
|
||||
|
||||
if (sensitive)
|
||||
break;
|
||||
|
||||
list = list->next;
|
||||
}
|
||||
g_list_free (cells);
|
||||
|
||||
return sensitive;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
row_is_sensitive (GtkComboBox *combo_box,
|
||||
gint index)
|
||||
{
|
||||
gboolean sensitive;
|
||||
|
||||
if (!combo_box->priv->model)
|
||||
return TRUE;
|
||||
|
||||
if (GTK_IS_MENU (combo_box->priv->popup_widget))
|
||||
{
|
||||
GtkWidget *item;
|
||||
GList *children, *child;
|
||||
|
||||
children = gtk_container_get_children (GTK_CONTAINER (combo_box->priv->popup_widget));
|
||||
child = children;
|
||||
if (GTK_IS_TEAROFF_MENU_ITEM (child->data))
|
||||
child = child->next;
|
||||
child = g_list_nth (child, index);
|
||||
item = GTK_WIDGET (child->data);
|
||||
g_list_free (children);
|
||||
|
||||
sensitive = menu_row_is_sensitive (combo_box, item);
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkTreePath *path;
|
||||
GtkTreeIter iter;
|
||||
|
||||
path = gtk_tree_path_new_from_indices (index, -1);
|
||||
if (gtk_tree_model_get_iter (combo_box->priv->model, &iter, path))
|
||||
sensitive = tree_column_row_is_sensitive (combo_box, &iter);
|
||||
else
|
||||
sensitive = TRUE;
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
}
|
||||
|
||||
return sensitive;
|
||||
}
|
||||
|
||||
static void
|
||||
update_menu_sensitivity (GtkComboBox *combo_box)
|
||||
{
|
||||
gint i, items;
|
||||
GtkWidget *menu;
|
||||
GList *children, *child;
|
||||
|
||||
if (!combo_box->priv->model)
|
||||
return;
|
||||
|
||||
items = gtk_tree_model_iter_n_children (combo_box->priv->model, NULL);
|
||||
menu = combo_box->priv->popup_widget;
|
||||
|
||||
children = gtk_container_get_children (GTK_CONTAINER (menu));
|
||||
child = children;
|
||||
|
||||
if (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;
|
||||
|
||||
sensitive = menu_row_is_sensitive (combo_box, item);
|
||||
gtk_widget_set_sensitive (item, sensitive);
|
||||
}
|
||||
g_list_free (children);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_combo_box_popup:
|
||||
* @combo_box: a #GtkComboBox
|
||||
@ -1165,6 +1299,7 @@ gtk_combo_box_popup (GtkComboBox *combo_box)
|
||||
|
||||
if (GTK_IS_MENU (combo_box->priv->popup_widget))
|
||||
{
|
||||
update_menu_sensitivity (combo_box);
|
||||
gtk_menu_set_active (GTK_MENU (combo_box->priv->popup_widget),
|
||||
combo_box->priv->active_item);
|
||||
|
||||
@ -1957,7 +2092,7 @@ gtk_combo_box_menu_button_press (GtkWidget *widget,
|
||||
if (event->type == GDK_BUTTON_PRESS && event->button == 1)
|
||||
{
|
||||
combo_box->priv->popup_in_progress = TRUE;
|
||||
|
||||
update_menu_sensitivity (combo_box);
|
||||
gtk_menu_set_active (GTK_MENU (combo_box->priv->popup_widget),
|
||||
combo_box->priv->active_item);
|
||||
|
||||
@ -2295,6 +2430,10 @@ gtk_combo_box_list_setup (GtkComboBox *combo_box)
|
||||
j->data,
|
||||
GPOINTER_TO_INT (j->next->data));
|
||||
}
|
||||
|
||||
gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo_box->priv->column),
|
||||
info->cell, info->func, info->func_data,
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (combo_box->priv->active_item != -1)
|
||||
@ -2484,22 +2623,34 @@ gtk_combo_box_key_press (GtkWidget *widget,
|
||||
case GDK_Down:
|
||||
case GDK_KP_Down:
|
||||
new_index = index + 1;
|
||||
while (new_index < items && !row_is_sensitive (combo_box, new_index))
|
||||
new_index++;
|
||||
if (new_index == items)
|
||||
new_index = index;
|
||||
break;
|
||||
case GDK_Up:
|
||||
case GDK_KP_Up:
|
||||
new_index = index - 1;
|
||||
while (new_index >= 0 && !row_is_sensitive (combo_box, new_index))
|
||||
new_index--;
|
||||
if (new_index < 0)
|
||||
new_index = index;
|
||||
break;
|
||||
case GDK_Page_Up:
|
||||
case GDK_KP_Page_Up:
|
||||
case GDK_Home:
|
||||
case GDK_KP_Home:
|
||||
new_index = 0;
|
||||
while (new_index < items - 1 && !row_is_sensitive (combo_box, new_index))
|
||||
new_index++;
|
||||
break;
|
||||
case GDK_Page_Down:
|
||||
case GDK_KP_Page_Down:
|
||||
case GDK_End:
|
||||
case GDK_KP_End:
|
||||
new_index = items - 1;
|
||||
while (new_index > 0 && !row_is_sensitive (combo_box, new_index))
|
||||
new_index--;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
|
@ -1279,6 +1279,73 @@ gtk_tree_selection_unselect_range (GtkTreeSelection *selection,
|
||||
g_signal_emit (selection, tree_selection_signals[CHANGED], 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
tree_column_is_sensitive (GtkTreeViewColumn *column,
|
||||
GtkTreeModel *model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
GList *cells, *list;
|
||||
gboolean sensitive;
|
||||
gboolean visible;
|
||||
|
||||
gtk_tree_view_column_cell_set_cell_data (column, model,
|
||||
iter, FALSE, FALSE);
|
||||
|
||||
cells = gtk_tree_view_column_get_cell_renderers (column);
|
||||
|
||||
list = cells;
|
||||
while (list)
|
||||
{
|
||||
g_object_get (G_OBJECT (list->data),
|
||||
"sensitive", &sensitive,
|
||||
"visible", &visible,
|
||||
NULL);
|
||||
|
||||
if (visible && sensitive)
|
||||
break;
|
||||
|
||||
list = list->next;
|
||||
}
|
||||
g_list_free (cells);
|
||||
|
||||
return sensitive;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
row_is_selectable (GtkTreeSelection *selection,
|
||||
GtkRBNode *node,
|
||||
GtkTreePath *path)
|
||||
{
|
||||
GList *list;
|
||||
gboolean sensitive;
|
||||
|
||||
sensitive = 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;
|
||||
}
|
||||
|
||||
if (!sensitive)
|
||||
return FALSE;
|
||||
|
||||
if (selection->user_func)
|
||||
return (*selection->user_func) (selection, selection->tree_view->priv->model, path,
|
||||
GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED),
|
||||
selection->user_data);
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Called internally by gtktreeview.c It handles actually selecting the tree.
|
||||
*/
|
||||
|
||||
@ -1328,17 +1395,7 @@ _gtk_tree_selection_internal_select_node (GtkTreeSelection *selection,
|
||||
{
|
||||
/* We only want to select the new node if we can unselect the old one,
|
||||
* and we can select the new one. */
|
||||
if (selection->user_func)
|
||||
{
|
||||
if ((*selection->user_func) (selection, selection->tree_view->priv->model, path,
|
||||
GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED),
|
||||
selection->user_data))
|
||||
dirty = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dirty = TRUE;
|
||||
}
|
||||
dirty = row_is_selectable (selection, node, path);
|
||||
|
||||
/* if dirty is FALSE, we weren't able to select the new one, otherwise, we try to
|
||||
* unselect the new one
|
||||
@ -1455,15 +1512,7 @@ gtk_tree_selection_real_select_node (GtkTreeSelection *selection,
|
||||
if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED) != select)
|
||||
{
|
||||
path = _gtk_tree_view_find_path (selection->tree_view, tree, node);
|
||||
if (selection->user_func)
|
||||
{
|
||||
if ((*selection->user_func) (selection, selection->tree_view->priv->model, path,
|
||||
GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED),
|
||||
selection->user_data))
|
||||
selected = TRUE;
|
||||
}
|
||||
else
|
||||
selected = TRUE;
|
||||
selected = row_is_selectable (selection, node, path);
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
|
||||
|
@ -183,6 +183,26 @@ setup_combo_entry (GtkWidget *entry_box)
|
||||
"klaas");
|
||||
}
|
||||
|
||||
static void
|
||||
set_sensitive (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
gpointer data)
|
||||
{
|
||||
GtkTreePath *path;
|
||||
gint *indices;
|
||||
gboolean sensitive;
|
||||
|
||||
path = gtk_tree_model_get_path (tree_model, iter);
|
||||
indices = gtk_tree_path_get_indices (path);
|
||||
|
||||
sensitive = indices[0] % 2;
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
g_object_set (cell, "sensitive", sensitive, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
@ -259,6 +279,10 @@ main (int argc, char **argv)
|
||||
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer,
|
||||
"pixbuf", 0,
|
||||
NULL);
|
||||
gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combobox),
|
||||
renderer,
|
||||
set_sensitive,
|
||||
NULL, NULL);
|
||||
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox),
|
||||
@ -267,7 +291,10 @@ main (int argc, char **argv)
|
||||
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer,
|
||||
"text", 1,
|
||||
NULL);
|
||||
|
||||
gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combobox),
|
||||
renderer,
|
||||
set_sensitive,
|
||||
NULL, NULL);
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), 1);
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user