diff options
author | Lars Hamann <lars@gtk.org> | 1998-10-30 19:57:50 +0000 |
---|---|---|
committer | Lars Hamann <lars@src.gnome.org> | 1998-10-30 19:57:50 +0000 |
commit | 52f5eeab68fa6e1618932f6e5bd2d2da58af7f53 (patch) | |
tree | dd4f3d8249f5ebc486d471febab5e30c5a634328 | |
parent | fd8a1c93a9530e2f750eb948d0f3db05d6a36010 (diff) | |
download | gdk-pixbuf-52f5eeab68fa6e1618932f6e5bd2d2da58af7f53.tar.gz |
free undo_un/selection, unselect list_item before disconnect signal
Fri Oct 30 20:02:36 1998 Lars Hamann <lars@gtk.org>
* gtk/gtklist.c (gtk_list_remove_items_internal):
free undo_un/selection, unselect list_item before disconnect
signal functions
(gtk_list_destroy): removed. gtk_list_shutdown clears the list
already
(gtk_list_signal_item_select) (gtk_list_signal_item_deselect)
(gtk_list_signal_item_toggle) (gtk_list_signal_scroll_horizontal)
(gtk_list_signal_toggle_focus_row) (gtk_list_signal_select_all)
(gtk_list_signal_unselect_all) (gtk_list_signal_undo_selection)
(gtk_list_signal_start_selection) (gtk_list_signal_end_selection)
(gtk_list_signal_toggle_add_mode) (gtk_list_signal_scroll_vertical)
(gtk_list_signal_extend_selection) (gtk_list_signal_focus_lost):
new functions. These functions are signal connected to inserted
list_items, to handle key bindings and GtkItem::de/select/toggle
signals.
* gtk/gtklistitem.c (gtk_list_item_class_init): added missing
gtk_object_class_add_signals call.
(gtk_list_item_toggle_focus_row) (gtk_list_item_select_all)
(gtk_list_item_unselect_all) (gtk_list_item_undo_selection)
(gtk_list_item_start_selection) (gtk_list_item_end_selection)
(gtk_list_item_extend_selection) (gtk_list_item_scroll_horizontal)
(gtk_list_item_scroll_vertical) (gtk_list_item_toggle_add_mode):
removed. These functions are handled via connected
gtk_list_signal_* functions now
-rw-r--r-- | ChangeLog | 28 | ||||
-rw-r--r-- | ChangeLog.pre-2-0 | 28 | ||||
-rw-r--r-- | ChangeLog.pre-2-10 | 28 | ||||
-rw-r--r-- | ChangeLog.pre-2-2 | 28 | ||||
-rw-r--r-- | ChangeLog.pre-2-4 | 28 | ||||
-rw-r--r-- | ChangeLog.pre-2-6 | 28 | ||||
-rw-r--r-- | ChangeLog.pre-2-8 | 28 | ||||
-rw-r--r-- | gtk/gtklist.c | 2528 | ||||
-rw-r--r-- | gtk/gtklistitem.c | 187 |
9 files changed, 1654 insertions, 1257 deletions
@@ -1,3 +1,31 @@ +Fri Oct 30 20:02:36 1998 Lars Hamann <lars@gtk.org> + + * gtk/gtklist.c (gtk_list_remove_items_internal): + free undo_un/selection, unselect list_item before disconnect + signal functions + (gtk_list_destroy): removed. gtk_list_shutdown clears the list + already + (gtk_list_signal_item_select) (gtk_list_signal_item_deselect) + (gtk_list_signal_item_toggle) (gtk_list_signal_scroll_horizontal) + (gtk_list_signal_toggle_focus_row) (gtk_list_signal_select_all) + (gtk_list_signal_unselect_all) (gtk_list_signal_undo_selection) + (gtk_list_signal_start_selection) (gtk_list_signal_end_selection) + (gtk_list_signal_toggle_add_mode) (gtk_list_signal_scroll_vertical) + (gtk_list_signal_extend_selection) (gtk_list_signal_focus_lost): + new functions. These functions are signal connected to inserted + list_items, to handle key bindings and GtkItem::de/select/toggle + signals. + + * gtk/gtklistitem.c (gtk_list_item_class_init): added missing + gtk_object_class_add_signals call. + (gtk_list_item_toggle_focus_row) (gtk_list_item_select_all) + (gtk_list_item_unselect_all) (gtk_list_item_undo_selection) + (gtk_list_item_start_selection) (gtk_list_item_end_selection) + (gtk_list_item_extend_selection) (gtk_list_item_scroll_horizontal) + (gtk_list_item_scroll_vertical) (gtk_list_item_toggle_add_mode): + removed. These functions are handled via connected + gtk_list_signal_* functions now + Fri Oct 30 05:24:43 1998 Tim Janik <timj@gtk.org> * gtk/Makefile.am: cause the built sources to be rebuild when possible, diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index a0508147f..42b0fbd91 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,31 @@ +Fri Oct 30 20:02:36 1998 Lars Hamann <lars@gtk.org> + + * gtk/gtklist.c (gtk_list_remove_items_internal): + free undo_un/selection, unselect list_item before disconnect + signal functions + (gtk_list_destroy): removed. gtk_list_shutdown clears the list + already + (gtk_list_signal_item_select) (gtk_list_signal_item_deselect) + (gtk_list_signal_item_toggle) (gtk_list_signal_scroll_horizontal) + (gtk_list_signal_toggle_focus_row) (gtk_list_signal_select_all) + (gtk_list_signal_unselect_all) (gtk_list_signal_undo_selection) + (gtk_list_signal_start_selection) (gtk_list_signal_end_selection) + (gtk_list_signal_toggle_add_mode) (gtk_list_signal_scroll_vertical) + (gtk_list_signal_extend_selection) (gtk_list_signal_focus_lost): + new functions. These functions are signal connected to inserted + list_items, to handle key bindings and GtkItem::de/select/toggle + signals. + + * gtk/gtklistitem.c (gtk_list_item_class_init): added missing + gtk_object_class_add_signals call. + (gtk_list_item_toggle_focus_row) (gtk_list_item_select_all) + (gtk_list_item_unselect_all) (gtk_list_item_undo_selection) + (gtk_list_item_start_selection) (gtk_list_item_end_selection) + (gtk_list_item_extend_selection) (gtk_list_item_scroll_horizontal) + (gtk_list_item_scroll_vertical) (gtk_list_item_toggle_add_mode): + removed. These functions are handled via connected + gtk_list_signal_* functions now + Fri Oct 30 05:24:43 1998 Tim Janik <timj@gtk.org> * gtk/Makefile.am: cause the built sources to be rebuild when possible, diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index a0508147f..42b0fbd91 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,31 @@ +Fri Oct 30 20:02:36 1998 Lars Hamann <lars@gtk.org> + + * gtk/gtklist.c (gtk_list_remove_items_internal): + free undo_un/selection, unselect list_item before disconnect + signal functions + (gtk_list_destroy): removed. gtk_list_shutdown clears the list + already + (gtk_list_signal_item_select) (gtk_list_signal_item_deselect) + (gtk_list_signal_item_toggle) (gtk_list_signal_scroll_horizontal) + (gtk_list_signal_toggle_focus_row) (gtk_list_signal_select_all) + (gtk_list_signal_unselect_all) (gtk_list_signal_undo_selection) + (gtk_list_signal_start_selection) (gtk_list_signal_end_selection) + (gtk_list_signal_toggle_add_mode) (gtk_list_signal_scroll_vertical) + (gtk_list_signal_extend_selection) (gtk_list_signal_focus_lost): + new functions. These functions are signal connected to inserted + list_items, to handle key bindings and GtkItem::de/select/toggle + signals. + + * gtk/gtklistitem.c (gtk_list_item_class_init): added missing + gtk_object_class_add_signals call. + (gtk_list_item_toggle_focus_row) (gtk_list_item_select_all) + (gtk_list_item_unselect_all) (gtk_list_item_undo_selection) + (gtk_list_item_start_selection) (gtk_list_item_end_selection) + (gtk_list_item_extend_selection) (gtk_list_item_scroll_horizontal) + (gtk_list_item_scroll_vertical) (gtk_list_item_toggle_add_mode): + removed. These functions are handled via connected + gtk_list_signal_* functions now + Fri Oct 30 05:24:43 1998 Tim Janik <timj@gtk.org> * gtk/Makefile.am: cause the built sources to be rebuild when possible, diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index a0508147f..42b0fbd91 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,31 @@ +Fri Oct 30 20:02:36 1998 Lars Hamann <lars@gtk.org> + + * gtk/gtklist.c (gtk_list_remove_items_internal): + free undo_un/selection, unselect list_item before disconnect + signal functions + (gtk_list_destroy): removed. gtk_list_shutdown clears the list + already + (gtk_list_signal_item_select) (gtk_list_signal_item_deselect) + (gtk_list_signal_item_toggle) (gtk_list_signal_scroll_horizontal) + (gtk_list_signal_toggle_focus_row) (gtk_list_signal_select_all) + (gtk_list_signal_unselect_all) (gtk_list_signal_undo_selection) + (gtk_list_signal_start_selection) (gtk_list_signal_end_selection) + (gtk_list_signal_toggle_add_mode) (gtk_list_signal_scroll_vertical) + (gtk_list_signal_extend_selection) (gtk_list_signal_focus_lost): + new functions. These functions are signal connected to inserted + list_items, to handle key bindings and GtkItem::de/select/toggle + signals. + + * gtk/gtklistitem.c (gtk_list_item_class_init): added missing + gtk_object_class_add_signals call. + (gtk_list_item_toggle_focus_row) (gtk_list_item_select_all) + (gtk_list_item_unselect_all) (gtk_list_item_undo_selection) + (gtk_list_item_start_selection) (gtk_list_item_end_selection) + (gtk_list_item_extend_selection) (gtk_list_item_scroll_horizontal) + (gtk_list_item_scroll_vertical) (gtk_list_item_toggle_add_mode): + removed. These functions are handled via connected + gtk_list_signal_* functions now + Fri Oct 30 05:24:43 1998 Tim Janik <timj@gtk.org> * gtk/Makefile.am: cause the built sources to be rebuild when possible, diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index a0508147f..42b0fbd91 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,31 @@ +Fri Oct 30 20:02:36 1998 Lars Hamann <lars@gtk.org> + + * gtk/gtklist.c (gtk_list_remove_items_internal): + free undo_un/selection, unselect list_item before disconnect + signal functions + (gtk_list_destroy): removed. gtk_list_shutdown clears the list + already + (gtk_list_signal_item_select) (gtk_list_signal_item_deselect) + (gtk_list_signal_item_toggle) (gtk_list_signal_scroll_horizontal) + (gtk_list_signal_toggle_focus_row) (gtk_list_signal_select_all) + (gtk_list_signal_unselect_all) (gtk_list_signal_undo_selection) + (gtk_list_signal_start_selection) (gtk_list_signal_end_selection) + (gtk_list_signal_toggle_add_mode) (gtk_list_signal_scroll_vertical) + (gtk_list_signal_extend_selection) (gtk_list_signal_focus_lost): + new functions. These functions are signal connected to inserted + list_items, to handle key bindings and GtkItem::de/select/toggle + signals. + + * gtk/gtklistitem.c (gtk_list_item_class_init): added missing + gtk_object_class_add_signals call. + (gtk_list_item_toggle_focus_row) (gtk_list_item_select_all) + (gtk_list_item_unselect_all) (gtk_list_item_undo_selection) + (gtk_list_item_start_selection) (gtk_list_item_end_selection) + (gtk_list_item_extend_selection) (gtk_list_item_scroll_horizontal) + (gtk_list_item_scroll_vertical) (gtk_list_item_toggle_add_mode): + removed. These functions are handled via connected + gtk_list_signal_* functions now + Fri Oct 30 05:24:43 1998 Tim Janik <timj@gtk.org> * gtk/Makefile.am: cause the built sources to be rebuild when possible, diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index a0508147f..42b0fbd91 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,31 @@ +Fri Oct 30 20:02:36 1998 Lars Hamann <lars@gtk.org> + + * gtk/gtklist.c (gtk_list_remove_items_internal): + free undo_un/selection, unselect list_item before disconnect + signal functions + (gtk_list_destroy): removed. gtk_list_shutdown clears the list + already + (gtk_list_signal_item_select) (gtk_list_signal_item_deselect) + (gtk_list_signal_item_toggle) (gtk_list_signal_scroll_horizontal) + (gtk_list_signal_toggle_focus_row) (gtk_list_signal_select_all) + (gtk_list_signal_unselect_all) (gtk_list_signal_undo_selection) + (gtk_list_signal_start_selection) (gtk_list_signal_end_selection) + (gtk_list_signal_toggle_add_mode) (gtk_list_signal_scroll_vertical) + (gtk_list_signal_extend_selection) (gtk_list_signal_focus_lost): + new functions. These functions are signal connected to inserted + list_items, to handle key bindings and GtkItem::de/select/toggle + signals. + + * gtk/gtklistitem.c (gtk_list_item_class_init): added missing + gtk_object_class_add_signals call. + (gtk_list_item_toggle_focus_row) (gtk_list_item_select_all) + (gtk_list_item_unselect_all) (gtk_list_item_undo_selection) + (gtk_list_item_start_selection) (gtk_list_item_end_selection) + (gtk_list_item_extend_selection) (gtk_list_item_scroll_horizontal) + (gtk_list_item_scroll_vertical) (gtk_list_item_toggle_add_mode): + removed. These functions are handled via connected + gtk_list_signal_* functions now + Fri Oct 30 05:24:43 1998 Tim Janik <timj@gtk.org> * gtk/Makefile.am: cause the built sources to be rebuild when possible, diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index a0508147f..42b0fbd91 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,31 @@ +Fri Oct 30 20:02:36 1998 Lars Hamann <lars@gtk.org> + + * gtk/gtklist.c (gtk_list_remove_items_internal): + free undo_un/selection, unselect list_item before disconnect + signal functions + (gtk_list_destroy): removed. gtk_list_shutdown clears the list + already + (gtk_list_signal_item_select) (gtk_list_signal_item_deselect) + (gtk_list_signal_item_toggle) (gtk_list_signal_scroll_horizontal) + (gtk_list_signal_toggle_focus_row) (gtk_list_signal_select_all) + (gtk_list_signal_unselect_all) (gtk_list_signal_undo_selection) + (gtk_list_signal_start_selection) (gtk_list_signal_end_selection) + (gtk_list_signal_toggle_add_mode) (gtk_list_signal_scroll_vertical) + (gtk_list_signal_extend_selection) (gtk_list_signal_focus_lost): + new functions. These functions are signal connected to inserted + list_items, to handle key bindings and GtkItem::de/select/toggle + signals. + + * gtk/gtklistitem.c (gtk_list_item_class_init): added missing + gtk_object_class_add_signals call. + (gtk_list_item_toggle_focus_row) (gtk_list_item_select_all) + (gtk_list_item_unselect_all) (gtk_list_item_undo_selection) + (gtk_list_item_start_selection) (gtk_list_item_end_selection) + (gtk_list_item_extend_selection) (gtk_list_item_scroll_horizontal) + (gtk_list_item_scroll_vertical) (gtk_list_item_toggle_add_mode): + removed. These functions are handled via connected + gtk_list_signal_* functions now + Fri Oct 30 05:24:43 1998 Tim Janik <timj@gtk.org> * gtk/Makefile.am: cause the built sources to be rebuild when possible, diff --git a/gtk/gtklist.c b/gtk/gtklist.c index 6ce42f730..a0318615b 100644 --- a/gtk/gtklist.c +++ b/gtk/gtklist.c @@ -31,13 +31,21 @@ enum { #define SCROLL_TIME 100 +/** GtkList Methods **/ static void gtk_list_class_init (GtkListClass *klass); static void gtk_list_init (GtkList *list); + +/** GtkObject Methods **/ static void gtk_list_shutdown (GtkObject *object); -static void gtk_list_destroy (GtkObject *object); + +/** GtkWidget Methods **/ +static void gtk_list_size_request (GtkWidget *widget, + GtkRequisition *requisition); +static void gtk_list_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); +static void gtk_list_realize (GtkWidget *widget); static void gtk_list_map (GtkWidget *widget); static void gtk_list_unmap (GtkWidget *widget); -static void gtk_list_realize (GtkWidget *widget); static void gtk_list_draw (GtkWidget *widget, GdkRectangle *area); static gint gtk_list_expose (GtkWidget *widget, @@ -48,48 +56,87 @@ static gint gtk_list_button_press (GtkWidget *widget, GdkEventButton *event); static gint gtk_list_button_release (GtkWidget *widget, GdkEventButton *event); -static void gtk_list_size_request (GtkWidget *widget, - GtkRequisition *requisition); -static void gtk_list_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static void gtk_list_add (GtkContainer *container, - GtkWidget *widget); -static void gtk_list_remove (GtkContainer *container, - GtkWidget *widget); -static void gtk_list_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data); - -static void gtk_real_list_select_child (GtkList *list, - GtkWidget *child); -static void gtk_real_list_unselect_child (GtkList *list, - GtkWidget *child); - - -static void gtk_list_set_anchor (GtkList *list, - gboolean add_mode, - gint anchor, - GtkWidget *undo_focus_child); -static void gtk_list_fake_unselect_all (GtkList *list, - GtkWidget *item); -static void gtk_list_fake_toggle_row (GtkList *list, - GtkWidget *item); -static void gtk_list_move_focus_child (GtkList *list, - GtkScrollType scroll_type, - gfloat position); -static void gtk_list_update_extended_selection (GtkList *list, - gint row); -static void gtk_list_focus_lost (GtkWidget *item, - GdkEventKey *event, - GtkList *list); -static void gtk_list_set_focus_child (GtkContainer *container, - GtkWidget *widget); -static gint gtk_list_focus (GtkContainer *container, - GtkDirectionType direction); - - -static GtkType gtk_list_child_type (GtkContainer *container); + +/** GtkContainer Methods **/ +static void gtk_list_add (GtkContainer *container, + GtkWidget *widget); +static void gtk_list_remove (GtkContainer *container, + GtkWidget *widget); +static void gtk_list_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data); +static GtkType gtk_list_child_type (GtkContainer *container); +static void gtk_list_set_focus_child (GtkContainer *container, + GtkWidget *widget); +static gint gtk_list_focus (GtkContainer *container, + GtkDirectionType direction); + +/** GtkList Private Functions **/ +static void gtk_list_move_focus_child (GtkList *list, + GtkScrollType scroll_type, + gfloat position); +static gint gtk_list_horizontal_timeout (GtkWidget *list); +static gint gtk_list_vertical_timeout (GtkWidget *list); +static void gtk_list_remove_items_internal (GtkList *list, + GList *items, + gboolean no_unref); + +/** GtkList Selection Methods **/ +static void gtk_real_list_select_child (GtkList *list, + GtkWidget *child); +static void gtk_real_list_unselect_child (GtkList *list, + GtkWidget *child); + +/** GtkList Selection Functions **/ +static void gtk_list_set_anchor (GtkList *list, + gboolean add_mode, + gint anchor, + GtkWidget *undo_focus_child); +static void gtk_list_fake_unselect_all (GtkList *list, + GtkWidget *item); +static void gtk_list_fake_toggle_row (GtkList *list, + GtkWidget *item); +static void gtk_list_update_extended_selection (GtkList *list, + gint row); + +/** GtkListItem Signal Functions **/ +static void gtk_list_signal_focus_lost (GtkWidget *item, + GdkEventKey *event, + GtkList *list); +static void gtk_list_signal_toggle_focus_row (GtkListItem *list_item, + GtkList *list); +static void gtk_list_signal_select_all (GtkListItem *list_item, + GtkList *list); +static void gtk_list_signal_unselect_all (GtkListItem *list_item, + GtkList *list); +static void gtk_list_signal_undo_selection (GtkListItem *list_item, + GtkList *list); +static void gtk_list_signal_start_selection (GtkListItem *list_item, + GtkList *list); +static void gtk_list_signal_end_selection (GtkListItem *list_item, + GtkList *list); +static void gtk_list_signal_extend_selection (GtkListItem *list_item, + GtkScrollType scroll_type, + gfloat position, + gboolean auto_start_selection, + GtkList *list); +static void gtk_list_signal_scroll_horizontal (GtkListItem *list_item, + GtkScrollType scroll_type, + gfloat position, + GtkList *list); +static void gtk_list_signal_scroll_vertical (GtkListItem *list_item, + GtkScrollType scroll_type, + gfloat position, + GtkList *list); +static void gtk_list_signal_toggle_add_mode (GtkListItem *list_item, + GtkList *list); +static void gtk_list_signal_item_select (GtkListItem *list_item, + GtkList *list); +static void gtk_list_signal_item_deselect (GtkListItem *list_item, + GtkList *list); +static void gtk_list_signal_item_toggle (GtkListItem *list_item, + GtkList *list); static GtkContainerClass *parent_class = NULL; @@ -168,7 +215,6 @@ gtk_list_class_init (GtkListClass *class) gtk_object_class_add_signals (object_class, list_signals, LAST_SIGNAL); object_class->shutdown = gtk_list_shutdown; - object_class->destroy = gtk_list_destroy; widget_class->map = gtk_list_map; widget_class->unmap = gtk_list_unmap; @@ -193,12 +239,6 @@ gtk_list_class_init (GtkListClass *class) class->unselect_child = gtk_real_list_unselect_child; } -static GtkType -gtk_list_child_type (GtkContainer *container) -{ - return GTK_TYPE_LIST_ITEM; -} - static void gtk_list_init (GtkList *list) { @@ -229,495 +269,114 @@ gtk_list_new (void) return GTK_WIDGET (gtk_type_new (GTK_TYPE_LIST)); } + +/* Private GtkObject Methods : + * + * gtk_list_shutdown + */ static void gtk_list_shutdown (GtkObject *object) { gtk_list_clear_items (GTK_LIST (object), 0, -1); - GTK_OBJECT_CLASS (parent_class)->shutdown (object); } -static void -gtk_list_destroy (GtkObject *object) -{ - GList *node; - - GtkList *list = GTK_LIST (object); - - for (node = list->children; node; node = node->next) - { - GtkWidget *child; - - child = (GtkWidget *)node->data; - gtk_widget_ref (child); - gtk_widget_unparent (child); - gtk_widget_destroy (child); - gtk_widget_unref (child); - } - g_list_free (list->children); - list->children = NULL; - - for (node = list->selection; node; node = node->next) - { - GtkWidget *child; - - child = (GtkWidget *)node->data; - gtk_widget_unref (child); - } - g_list_free (list->selection); - list->selection = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (*GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -void -gtk_list_end_drag_selection (GtkList *list) -{ - g_return_if_fail (list != NULL); - g_return_if_fail (GTK_IS_LIST (list)); - - list->drag_selection = FALSE; - if (GTK_WIDGET_HAS_GRAB (list)) - { - gtk_grab_remove (GTK_WIDGET (list)); - gdk_pointer_ungrab (GDK_CURRENT_TIME); - } - if (list->htimer) - { - gtk_timeout_remove (list->htimer); - list->htimer = 0; - } - if (list->vtimer) - { - gtk_timeout_remove (list->vtimer); - list->vtimer = 0; - } -} - -void -gtk_list_insert_items (GtkList *list, - GList *items, - gint position) -{ - GtkWidget *widget; - GList *tmp_list; - GList *last; - gint nchildren; - - g_return_if_fail (list != NULL); - g_return_if_fail (GTK_IS_LIST (list)); - - if (!items) - return; - - gtk_list_end_drag_selection (list); - if (list->selection_mode == GTK_SELECTION_EXTENDED && list->anchor >= 0) - gtk_list_end_selection (list); - - tmp_list = items; - while (tmp_list) - { - widget = tmp_list->data; - tmp_list = tmp_list->next; - - gtk_widget_set_parent (widget, GTK_WIDGET (list)); - gtk_signal_connect (GTK_OBJECT (widget), "focus_out_event", - GTK_SIGNAL_FUNC (gtk_list_focus_lost), list); - - if (GTK_WIDGET_VISIBLE (widget->parent)) - { - if (GTK_WIDGET_REALIZED (widget->parent) && - !GTK_WIDGET_REALIZED (widget)) - gtk_widget_realize (widget); - - if (GTK_WIDGET_MAPPED (widget->parent) && - !GTK_WIDGET_MAPPED (widget)) - gtk_widget_map (widget); - } - } - - nchildren = g_list_length (list->children); - if ((position < 0) || (position > nchildren)) - position = nchildren; - - if (position == nchildren) - { - if (list->children) - { - tmp_list = g_list_last (list->children); - tmp_list->next = items; - items->prev = tmp_list; - } - else - { - list->children = items; - } - } - else - { - tmp_list = g_list_nth (list->children, position); - last = g_list_last (items); - - if (tmp_list->prev) - tmp_list->prev->next = items; - last->next = tmp_list; - items->prev = tmp_list->prev; - tmp_list->prev = last; - - if (tmp_list == list->children) - list->children = items; - } - - if (list->children && !list->selection && - (list->selection_mode == GTK_SELECTION_BROWSE)) - { - widget = list->children->data; - gtk_list_select_child (list, widget); - } - - if (GTK_WIDGET_VISIBLE (list)) - gtk_widget_queue_resize (GTK_WIDGET (list)); -} - -void -gtk_list_append_items (GtkList *list, - GList *items) -{ - g_return_if_fail (list != NULL); - g_return_if_fail (GTK_IS_LIST (list)); - - gtk_list_insert_items (list, items, -1); -} - -void -gtk_list_prepend_items (GtkList *list, - GList *items) -{ - g_return_if_fail (list != NULL); - g_return_if_fail (GTK_IS_LIST (list)); - - gtk_list_insert_items (list, items, 0); -} +/* Private GtkWidget Methods : + * + * gtk_list_size_request + * gtk_list_size_allocate + * gtk_list_realize + * gtk_list_map + * gtk_list_unmap + * gtk_list_motion_notify + * gtk_list_button_press + * gtk_list_button_release + */ static void -gtk_list_remove_items_internal (GtkList *list, - GList *items, - gboolean no_unref) -{ - GtkWidget *widget; - GtkWidget *new_focus_child; - GtkWidget *old_focus_child; - GtkContainer *container; - GList *selected_widgets; - GList *tmp_list; - GList *work; - gboolean grab_focus = FALSE; - - g_return_if_fail (list != NULL); - g_return_if_fail (GTK_IS_LIST (list)); - - if (!items) - return; - - container = GTK_CONTAINER (list); - - gtk_list_end_drag_selection (list); - if (list->selection_mode == GTK_SELECTION_EXTENDED && list->anchor >= 0) - gtk_list_end_selection (list); - - - tmp_list = items; - selected_widgets = NULL; - widget = NULL; - old_focus_child = new_focus_child = container->focus_child; - - while (tmp_list) - { - widget = tmp_list->data; - - tmp_list = tmp_list->next; - - if (no_unref) - gtk_widget_ref (widget); - - gtk_signal_disconnect_by_func - (GTK_OBJECT (widget), GTK_SIGNAL_FUNC (gtk_list_focus_lost), list); - - - if (widget == new_focus_child) - { - work = g_list_find (list->children, widget); - - if (work) - { - if (work->next) - new_focus_child = work->next->data; - else if (list->children != work && work->prev) - new_focus_child = work->prev->data; - else - new_focus_child = NULL; - - if (GTK_WIDGET_HAS_FOCUS (widget)) - grab_focus = TRUE; - } - } - - list->children = g_list_remove (list->children, widget); - - if (widget->state == GTK_STATE_SELECTED) - selected_widgets = g_list_prepend (selected_widgets, widget); - else - gtk_widget_unparent (widget); - } - - if (selected_widgets) - { - tmp_list = selected_widgets; - while (tmp_list) - { - widget = tmp_list->data; - tmp_list = tmp_list->next; - - gtk_list_unselect_child (list, widget); - - gtk_widget_unparent (widget); - } - - gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]); - } - - g_list_free (selected_widgets); - - if (new_focus_child && new_focus_child != old_focus_child) - { - if (grab_focus) - gtk_widget_grab_focus (new_focus_child); - else - gtk_container_set_focus_child (container, new_focus_child); - } - - if (GTK_WIDGET_VISIBLE (list)) - gtk_widget_queue_resize (GTK_WIDGET (list)); -} - -void -gtk_list_remove_items (GtkList *list, - GList *items) -{ - gtk_list_remove_items_internal (list, items, FALSE); -} - -void -gtk_list_remove_items_no_unref (GtkList *list, - GList *items) -{ - gtk_list_remove_items_internal (list, items, TRUE); -} - -void -gtk_list_clear_items (GtkList *list, - gint start, - gint end) -{ - GtkWidget *widget; - GList *start_list; - GList *end_list; - GList *tmp_list; - guint nchildren; - - g_return_if_fail (list != NULL); - g_return_if_fail (GTK_IS_LIST (list)); - - nchildren = g_list_length (list->children); - - if (nchildren > 0) - { - gboolean selection_changed; - - if ((end < 0) || (end > nchildren)) - end = nchildren; - - if (start >= end) - return; - - start_list = g_list_nth (list->children, start); - end_list = g_list_nth (list->children, end); - - gtk_list_end_drag_selection (list); - if (list->selection_mode == GTK_SELECTION_EXTENDED && list->anchor >= 0) - gtk_list_end_selection (list); - - if (start_list->prev) - start_list->prev->next = end_list; - if (end_list && end_list->prev) - end_list->prev->next = NULL; - if (end_list) - end_list->prev = start_list->prev; - if (start_list == list->children) - list->children = end_list; - - selection_changed = FALSE; - widget = NULL; - tmp_list = start_list; - - while (tmp_list) - { - widget = tmp_list->data; - tmp_list = tmp_list->next; - - if (widget->state == GTK_STATE_SELECTED) - { - gtk_list_unselect_child (list, widget); - selection_changed = TRUE; - } - - gtk_widget_unparent (widget); - } - - g_list_free (start_list); - - if (list->children && !list->selection && - (list->selection_mode == GTK_SELECTION_BROWSE)) - { - widget = list->children->data; - gtk_list_select_child (list, widget); - } - else if (selection_changed) - gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]); - - gtk_widget_queue_resize (GTK_WIDGET (list)); - } -} - -void -gtk_list_select_item (GtkList *list, - gint item) -{ - GList *tmp_list; - - g_return_if_fail (list != NULL); - g_return_if_fail (GTK_IS_LIST (list)); - - tmp_list = g_list_nth (list->children, item); - if (tmp_list) - gtk_list_select_child (list, GTK_WIDGET (tmp_list->data)); -} - -void -gtk_list_unselect_item (GtkList *list, - gint item) -{ - GList *tmp_list; - - g_return_if_fail (list != NULL); - g_return_if_fail (GTK_IS_LIST (list)); - - tmp_list = g_list_nth (list->children, item); - if (tmp_list) - gtk_list_unselect_child (list, GTK_WIDGET (tmp_list->data)); -} - -void -gtk_list_select_child (GtkList *list, - GtkWidget *child) -{ - gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECT_CHILD], child); -} - -void -gtk_list_unselect_child (GtkList *list, - GtkWidget *child) -{ - gtk_signal_emit (GTK_OBJECT (list), list_signals[UNSELECT_CHILD], child); -} - -gint -gtk_list_child_position (GtkList *list, - GtkWidget *child) +gtk_list_size_request (GtkWidget *widget, + GtkRequisition *requisition) { + GtkList *list; + GtkWidget *child; GList *children; - gint pos; - g_return_val_if_fail (list != NULL, -1); - g_return_val_if_fail (GTK_IS_LIST (list), -1); - g_return_val_if_fail (child != NULL, -1); + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_LIST (widget)); + g_return_if_fail (requisition != NULL); - pos = 0; - children = list->children; + list = GTK_LIST (widget); + requisition->width = 0; + requisition->height = 0; + children = list->children; while (children) { - if (child == GTK_WIDGET (children->data)) - return pos; - - pos += 1; + child = children->data; children = children->next; - } - - return -1; -} - -void -gtk_list_set_selection_mode (GtkList *list, - GtkSelectionMode mode) -{ - g_return_if_fail (list != NULL); - g_return_if_fail (GTK_IS_LIST (list)); - if (list->selection_mode == mode) - return; + if (GTK_WIDGET_VISIBLE (child)) + { + gtk_widget_size_request (child, &child->requisition); - list->selection_mode = mode; + requisition->width = MAX (requisition->width, + child->requisition.width); + requisition->height += child->requisition.height; + } + } - switch (mode) - { - case GTK_SELECTION_SINGLE: - case GTK_SELECTION_BROWSE: - gtk_list_unselect_all (list); - break; + requisition->width += GTK_CONTAINER (list)->border_width * 2; + requisition->height += GTK_CONTAINER (list)->border_width * 2; - default: - break; - } + requisition->width = MAX (requisition->width, 1); + requisition->height = MAX (requisition->height, 1); } - static void -gtk_list_map (GtkWidget *widget) +gtk_list_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) { GtkList *list; GtkWidget *child; + GtkAllocation child_allocation; GList *children; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_LIST (widget)); + g_return_if_fail (allocation != NULL); - GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED); list = GTK_LIST (widget); - gdk_window_show (widget->window); + widget->allocation = *allocation; + if (GTK_WIDGET_REALIZED (widget)) + gdk_window_move_resize (widget->window, + allocation->x, allocation->y, + allocation->width, allocation->height); - children = list->children; - while (children) + if (list->children) { - child = children->data; - children = children->next; + child_allocation.x = GTK_CONTAINER (list)->border_width; + child_allocation.y = GTK_CONTAINER (list)->border_width; + child_allocation.width = MAX (1, allocation->width - + child_allocation.x * 2); - if (GTK_WIDGET_VISIBLE (child) && - !GTK_WIDGET_MAPPED (child)) - gtk_widget_map (child); - } -} + children = list->children; -static void -gtk_list_unmap (GtkWidget *widget) -{ - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_LIST (widget)); + while (children) + { + child = children->data; + children = children->next; - GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED); - gdk_window_hide (widget->window); + if (GTK_WIDGET_VISIBLE (child)) + { + child_allocation.height = child->requisition.height; + + gtk_widget_size_allocate (child, &child_allocation); + + child_allocation.y += child_allocation.height; + } + } + } } static void @@ -743,7 +402,8 @@ gtk_list_realize (GtkWidget *widget) attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; - widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); + widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), + &attributes, attributes_mask); gdk_window_set_user_data (widget->window, widget); widget->style = gtk_style_attach (widget->style, widget->window); @@ -752,127 +412,40 @@ gtk_list_realize (GtkWidget *widget) } static void -gtk_list_draw (GtkWidget *widget, - GdkRectangle *area) +gtk_list_map (GtkWidget *widget) { GtkList *list; GtkWidget *child; - GdkRectangle child_area; GList *children; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_LIST (widget)); - g_return_if_fail (area != NULL); - - if (GTK_WIDGET_DRAWABLE (widget)) - { - list = GTK_LIST (widget); - - children = list->children; - while (children) - { - child = children->data; - children = children->next; - - if (gtk_widget_intersect (child, area, &child_area)) - gtk_widget_draw (child, &child_area); - } - } -} -static gint -gtk_list_expose (GtkWidget *widget, - GdkEventExpose *event) -{ - GtkList *list; - GtkWidget *child; - GdkEventExpose child_event; - GList *children; + GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED); + list = GTK_LIST (widget); - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_LIST (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); + gdk_window_show (widget->window); - if (GTK_WIDGET_DRAWABLE (widget)) + children = list->children; + while (children) { - list = GTK_LIST (widget); - - child_event = *event; - - children = list->children; - while (children) - { - child = children->data; - children = children->next; + child = children->data; + children = children->next; - if (GTK_WIDGET_NO_WINDOW (child) && - gtk_widget_intersect (child, &event->area, &child_event.area)) - gtk_widget_event (child, (GdkEvent*) &child_event); - } + if (GTK_WIDGET_VISIBLE (child) && + !GTK_WIDGET_MAPPED (child)) + gtk_widget_map (child); } - - return FALSE; } static void -move_horizontal (GtkList *list, - GtkAdjustment *adj, - gint diff) -{ - gfloat upper; - - adj->value += diff; - - upper = adj->upper - adj->page_size; - adj->value = MIN (adj->value, upper); - adj->value = MAX (adj->value, 0.0); - - gtk_signal_emit_by_name (GTK_OBJECT (adj), "value_changed"); -} - -static gint -horizontal_timeout (GtkWidget *list) -{ - gint x, y; - GdkEventMotion event; - GdkModifierType mask; - - g_return_val_if_fail (GTK_IS_LIST (list), FALSE); - - GTK_LIST (list)->htimer = 0; - gdk_window_get_pointer (list->window, &x, &y, &mask); - - event.is_hint = 0; - event.x = x; - event.y = y; - event.state = mask; - - gtk_list_motion_notify (list, &event); - - return FALSE; -} - -static gint -vertical_timeout (GtkWidget *list) +gtk_list_unmap (GtkWidget *widget) { - gint x; - gint y; - GdkEventMotion event; - GdkModifierType mask; - - g_return_val_if_fail (GTK_IS_LIST (list), FALSE); - - GTK_LIST (list)->vtimer = 0; - gdk_window_get_pointer (list->window, &x, &y, &mask); - - event.is_hint = 0; - event.x = x; - event.y = y; - event.state = mask; - - gtk_list_motion_notify (list, &event); + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_LIST (widget)); - return FALSE; + GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED); + gdk_window_hide (widget->window); } static gint @@ -913,17 +486,22 @@ gtk_list_motion_notify (GtkWidget *widget, if (list->htimer == 0) { list->htimer = gtk_timeout_add - (SCROLL_TIME, (GtkFunction) horizontal_timeout, widget); + (SCROLL_TIME, (GtkFunction) gtk_list_horizontal_timeout, widget); if (!((x < adj->value && adj->value <= 0) || (x > adj->value + adj->page_size && adj->value >= adj->upper - adj->page_size))) { + gfloat value; + if (x < adj->value) - move_horizontal (list, adj, - 1 + (x - adj->value) / 2 ); + value = adj->value + (x - adj->value) / 2 - 1; else - move_horizontal (list, adj, - 1 + (x - adj->value - adj->page_size) / 2); + value = adj->value + 1 + (x - adj->value - adj->page_size) / 2; + + gtk_adjustment_set_value (adj, + CLAMP (value, 0.0, + adj->upper - adj->page_size)); } } else @@ -956,8 +534,9 @@ gtk_list_motion_notify (GtkWidget *widget, if (!((y < 0 && focus_row == 0) || (y > widget->allocation.height && focus_row >= length - 1))) list->vtimer = gtk_timeout_add (SCROLL_TIME, - (GtkFunction) vertical_timeout, list); - + (GtkFunction) gtk_list_vertical_timeout, + list); + if (row != focus_row) gtk_widget_grab_focus (item); @@ -1165,89 +744,77 @@ gtk_list_button_release (GtkWidget *widget, } static void -gtk_list_size_request (GtkWidget *widget, - GtkRequisition *requisition) +gtk_list_draw (GtkWidget *widget, + GdkRectangle *area) { GtkList *list; GtkWidget *child; + GdkRectangle child_area; GList *children; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_LIST (widget)); - g_return_if_fail (requisition != NULL); - - list = GTK_LIST (widget); - requisition->width = 0; - requisition->height = 0; + g_return_if_fail (area != NULL); - children = list->children; - while (children) + if (GTK_WIDGET_DRAWABLE (widget)) { - child = children->data; - children = children->next; + list = GTK_LIST (widget); - if (GTK_WIDGET_VISIBLE (child)) + children = list->children; + while (children) { - gtk_widget_size_request (child, &child->requisition); + child = children->data; + children = children->next; - requisition->width = MAX (requisition->width, child->requisition.width); - requisition->height += child->requisition.height; + if (gtk_widget_intersect (child, area, &child_area)) + gtk_widget_draw (child, &child_area); } } - - requisition->width += GTK_CONTAINER (list)->border_width * 2; - requisition->height += GTK_CONTAINER (list)->border_width * 2; - - requisition->width = MAX (requisition->width, 1); - requisition->height = MAX (requisition->height, 1); } -static void -gtk_list_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) +static gint +gtk_list_expose (GtkWidget *widget, + GdkEventExpose *event) { GtkList *list; GtkWidget *child; - GtkAllocation child_allocation; + GdkEventExpose child_event; GList *children; - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_LIST (widget)); - g_return_if_fail (allocation != NULL); - - list = GTK_LIST (widget); - - widget->allocation = *allocation; - if (GTK_WIDGET_REALIZED (widget)) - gdk_window_move_resize (widget->window, - allocation->x, allocation->y, - allocation->width, allocation->height); + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GTK_IS_LIST (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); - if (list->children) + if (GTK_WIDGET_DRAWABLE (widget)) { - child_allocation.x = GTK_CONTAINER (list)->border_width; - child_allocation.y = GTK_CONTAINER (list)->border_width; - child_allocation.width = MAX (1, allocation->width - child_allocation.x * 2); + list = GTK_LIST (widget); - children = list->children; + child_event = *event; + children = list->children; while (children) { child = children->data; children = children->next; - if (GTK_WIDGET_VISIBLE (child)) - { - child_allocation.height = child->requisition.height; - - gtk_widget_size_allocate (child, &child_allocation); - - child_allocation.y += child_allocation.height; - } + if (GTK_WIDGET_NO_WINDOW (child) && + gtk_widget_intersect (child, &event->area, &child_event.area)) + gtk_widget_event (child, (GdkEvent*) &child_event); } } + + return FALSE; } + +/* GtkContainer Methods : + * gtk_list_add + * gtk_list_remove + * gtk_list_forall + * gtk_list_child_type + * gtk_list_set_focus_child + * gtk_list_focus + */ static void gtk_list_add (GtkContainer *container, GtkWidget *widget) @@ -1276,7 +843,6 @@ gtk_list_remove (GtkContainer *container, g_return_if_fail (widget != NULL); g_return_if_fail (container == GTK_CONTAINER (widget->parent)); - item_list = g_list_alloc (); item_list->data = widget; @@ -1311,387 +877,550 @@ gtk_list_forall (GtkContainer *container, } } +static GtkType +gtk_list_child_type (GtkContainer *container) +{ + return GTK_TYPE_LIST_ITEM; +} + static void -gtk_real_list_select_child (GtkList *list, - GtkWidget *child) +gtk_list_set_focus_child (GtkContainer *container, + GtkWidget *child) { - GList *selection; - GList *tmp_list; - GtkWidget *tmp_item; + GtkList *list; - g_return_if_fail (list != NULL); - g_return_if_fail (GTK_IS_LIST (list)); - g_return_if_fail (child != NULL); - g_return_if_fail (GTK_IS_LIST_ITEM (child)); + g_return_if_fail (container != NULL); + g_return_if_fail (GTK_IS_LIST (container)); - switch (list->selection_mode) - { - case GTK_SELECTION_SINGLE: - case GTK_SELECTION_BROWSE: - selection = list->selection; + if (child) + g_return_if_fail (GTK_IS_WIDGET (child)); - while (selection) - { - tmp_item = selection->data; + list = GTK_LIST (container); + list->last_focus_child = container->focus_child; - if (tmp_item != child) - { - tmp_list = selection; - selection = selection->next; + if (child != container->focus_child) + { + if (container->focus_child) + gtk_widget_unref (container->focus_child); + container->focus_child = child; + if (container->focus_child) + gtk_widget_ref (container->focus_child); + } - list->selection = g_list_remove_link (list->selection, tmp_list); - g_list_free (tmp_list); + /* check for v adjustment */ + if (container->focus_child) + { + GtkAdjustment *adjustment; - gtk_list_item_deselect (GTK_LIST_ITEM (tmp_item)); - gtk_widget_unref (GTK_WIDGET (tmp_item)); - } - else - selection = selection->next; - } + adjustment = gtk_object_get_data_by_id (GTK_OBJECT (container), + vadjustment_key_id); + if (adjustment) + gtk_adjustment_clamp_page (adjustment, + container->focus_child->allocation.y, + (container->focus_child->allocation.y + + container->focus_child->allocation.height)); + } - if (child->state == GTK_STATE_NORMAL) - { - list->selection = g_list_prepend (list->selection, child); - gtk_widget_ref (child); - gtk_list_item_select (GTK_LIST_ITEM (child)); - } - gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]); + switch (list->selection_mode) + { + case GTK_SELECTION_BROWSE: + if (child) + gtk_list_select_child (list, child); break; - - case GTK_SELECTION_EXTENDED: - if (list->anchor >= 0) - return; - - case GTK_SELECTION_MULTIPLE: - if (child->state == GTK_STATE_NORMAL) - { - list->selection = g_list_prepend (list->selection, child); - gtk_widget_ref (child); - gtk_list_item_select (GTK_LIST_ITEM (child)); - gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]); - } + default: break; } } -static void -gtk_real_list_unselect_child (GtkList *list, - GtkWidget *child) +static gint +gtk_list_focus (GtkContainer *container, + GtkDirectionType direction) { - g_return_if_fail (list != NULL); - g_return_if_fail (GTK_IS_LIST (list)); - g_return_if_fail (child != NULL); - g_return_if_fail (GTK_IS_LIST_ITEM (child)); + gint return_val = FALSE; - if (child->state == GTK_STATE_SELECTED) + g_return_val_if_fail (container != NULL, FALSE); + g_return_val_if_fail (GTK_IS_LIST (container), FALSE); + + if (!GTK_WIDGET_SENSITIVE (container)) + return_val = FALSE; + else if (container->focus_child == NULL || + !GTK_WIDGET_HAS_FOCUS (container->focus_child)) { - list->selection = g_list_remove (list->selection, child); - gtk_list_item_deselect (GTK_LIST_ITEM (child)); - gtk_widget_unref (child); - gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]); + if (*GTK_CONTAINER_CLASS (parent_class)->focus) + return_val = GTK_CONTAINER_CLASS (parent_class)->focus + (container, direction); } -} + + if (!return_val) + { + GtkList *list; + list = GTK_LIST (container); + if (list->selection_mode == GTK_SELECTION_EXTENDED && list->anchor >= 0) + gtk_list_end_selection (list); + } -/***************************************************************************/ + return return_val; +} -static void -gtk_list_set_anchor (GtkList *list, - gboolean add_mode, - gint anchor, - GtkWidget *undo_focus_child) + +/* Public GtkList Methods : + * + * gtk_list_insert_items + * gtk_list_append_items + * gtk_list_prepend_items + * gtk_list_remove_items + * gtk_list_remove_items_no_unref + * gtk_list_clear_items + * + * gtk_list_child_position + */ +void +gtk_list_insert_items (GtkList *list, + GList *items, + gint position) { - GList *work; + GtkWidget *widget; + GList *tmp_list; + GList *last; + gint nchildren; g_return_if_fail (list != NULL); g_return_if_fail (GTK_IS_LIST (list)); - - if (list->selection_mode != GTK_SELECTION_EXTENDED || list->anchor >= 0) + + if (!items) return; - g_list_free (list->undo_selection); - g_list_free (list->undo_unselection); - list->undo_selection = NULL; - list->undo_unselection = NULL; + gtk_list_end_drag_selection (list); + if (list->selection_mode == GTK_SELECTION_EXTENDED && list->anchor >= 0) + gtk_list_end_selection (list); - if ((work = g_list_nth (list->children, anchor))) + tmp_list = items; + while (tmp_list) { - if (add_mode) - gtk_list_fake_toggle_row (list, GTK_WIDGET (work->data)); - else - { - gtk_list_fake_unselect_all (list, GTK_WIDGET (work->data)); - list->anchor_state = GTK_STATE_SELECTED; - } - } + widget = tmp_list->data; + tmp_list = tmp_list->next; - list->anchor = anchor; - list->drag_pos = anchor; - list->undo_focus_child = undo_focus_child; -} + gtk_widget_set_parent (widget, GTK_WIDGET (list)); + gtk_signal_connect (GTK_OBJECT (widget), "focus_out_event", + GTK_SIGNAL_FUNC (gtk_list_signal_focus_lost), + list); + gtk_signal_connect (GTK_OBJECT (widget), "toggle_focus_row", + GTK_SIGNAL_FUNC (gtk_list_signal_toggle_focus_row), + list); + gtk_signal_connect (GTK_OBJECT (widget), "select_all", + GTK_SIGNAL_FUNC (gtk_list_signal_select_all), + list); + gtk_signal_connect (GTK_OBJECT (widget), "unselect_all", + GTK_SIGNAL_FUNC (gtk_list_signal_unselect_all), + list); + gtk_signal_connect (GTK_OBJECT (widget), "undo_selection", + GTK_SIGNAL_FUNC (gtk_list_signal_undo_selection), + list); + gtk_signal_connect (GTK_OBJECT (widget), "start_selection", + GTK_SIGNAL_FUNC (gtk_list_signal_start_selection), + list); + gtk_signal_connect (GTK_OBJECT (widget), "end_selection", + GTK_SIGNAL_FUNC (gtk_list_signal_end_selection), + list); + gtk_signal_connect (GTK_OBJECT (widget), "extend_selection", + GTK_SIGNAL_FUNC (gtk_list_signal_extend_selection), + list); + gtk_signal_connect (GTK_OBJECT (widget), "scroll_horizontal", + GTK_SIGNAL_FUNC (gtk_list_signal_scroll_horizontal), + list); + gtk_signal_connect (GTK_OBJECT (widget), "scroll_vertical", + GTK_SIGNAL_FUNC (gtk_list_signal_scroll_vertical), + list); + gtk_signal_connect (GTK_OBJECT (widget), "toggle_add_mode", + GTK_SIGNAL_FUNC (gtk_list_signal_toggle_add_mode), + list); + gtk_signal_connect (GTK_OBJECT (widget), "select", + GTK_SIGNAL_FUNC (gtk_list_signal_item_select), + list); + gtk_signal_connect (GTK_OBJECT (widget), "deselect", + GTK_SIGNAL_FUNC (gtk_list_signal_item_deselect), + list); + gtk_signal_connect (GTK_OBJECT (widget), "toggle", + GTK_SIGNAL_FUNC (gtk_list_signal_item_toggle), + list); -static void -gtk_list_fake_unselect_all (GtkList *list, - GtkWidget *item) -{ - GList *work; + if (GTK_WIDGET_VISIBLE (widget->parent)) + { + if (GTK_WIDGET_REALIZED (widget->parent) && + !GTK_WIDGET_REALIZED (widget)) + gtk_widget_realize (widget); - if (item && item->state == GTK_STATE_NORMAL) - gtk_widget_set_state (item, GTK_STATE_SELECTED); + if (GTK_WIDGET_MAPPED (widget->parent) && + !GTK_WIDGET_MAPPED (widget)) + gtk_widget_map (widget); + } + } - list->undo_selection = list->selection; - list->selection = NULL; - - for (work = list->undo_selection; work; work = work->next) - if (work->data != item) - gtk_widget_set_state (GTK_WIDGET (work->data), GTK_STATE_NORMAL); -} + nchildren = g_list_length (list->children); + if ((position < 0) || (position > nchildren)) + position = nchildren; -static void -gtk_list_fake_toggle_row (GtkList *list, - GtkWidget *item) -{ - if (!item) - return; - - if (item->state == GTK_STATE_NORMAL) + if (position == nchildren) { - list->anchor_state = GTK_STATE_SELECTED; - gtk_widget_set_state (item, GTK_STATE_SELECTED); + if (list->children) + { + tmp_list = g_list_last (list->children); + tmp_list->next = items; + items->prev = tmp_list; + } + else + { + list->children = items; + } } else { - list->anchor_state = GTK_STATE_NORMAL; - gtk_widget_set_state (item, GTK_STATE_NORMAL); + tmp_list = g_list_nth (list->children, position); + last = g_list_last (items); + + if (tmp_list->prev) + tmp_list->prev->next = items; + last->next = tmp_list; + items->prev = tmp_list->prev; + tmp_list->prev = last; + + if (tmp_list == list->children) + list->children = items; + } + + if (list->children && !list->selection && + (list->selection_mode == GTK_SELECTION_BROWSE)) + { + widget = list->children->data; + gtk_list_select_child (list, widget); } + + if (GTK_WIDGET_VISIBLE (list)) + gtk_widget_queue_resize (GTK_WIDGET (list)); } void -gtk_list_scroll_horizontal (GtkList *list, - GtkScrollType scroll_type, - gfloat position) +gtk_list_append_items (GtkList *list, + GList *items) { - GtkAdjustment *adj; + g_return_if_fail (list != NULL); + g_return_if_fail (GTK_IS_LIST (list)); - g_return_if_fail (list != 0); + gtk_list_insert_items (list, items, -1); +} + +void +gtk_list_prepend_items (GtkList *list, + GList *items) +{ + g_return_if_fail (list != NULL); g_return_if_fail (GTK_IS_LIST (list)); - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list)) - return; + gtk_list_insert_items (list, items, 0); +} - if (!(adj = - gtk_object_get_data_by_id (GTK_OBJECT (list), hadjustment_key_id))) - return; +void +gtk_list_remove_items (GtkList *list, + GList *items) +{ + gtk_list_remove_items_internal (list, items, FALSE); +} - switch (scroll_type) - { - case GTK_SCROLL_STEP_BACKWARD: - adj->value = CLAMP (adj->value - adj->step_increment, adj->lower, - adj->upper - adj->page_size); - break; - case GTK_SCROLL_STEP_FORWARD: - adj->value = CLAMP (adj->value + adj->step_increment, adj->lower, - adj->upper - adj->page_size); - break; - case GTK_SCROLL_PAGE_BACKWARD: - adj->value = CLAMP (adj->value - adj->page_increment, adj->lower, - adj->upper - adj->page_size); - break; - case GTK_SCROLL_PAGE_FORWARD: - adj->value = CLAMP (adj->value + adj->page_increment, adj->lower, - adj->upper - adj->page_size); - break; - case GTK_SCROLL_JUMP: - adj->value = CLAMP (adj->lower + (adj->upper - adj->lower) * position, - adj->lower, adj->upper - adj->page_size); - break; - default: - break; - } - gtk_adjustment_value_changed (adj); +void +gtk_list_remove_items_no_unref (GtkList *list, + GList *items) +{ + gtk_list_remove_items_internal (list, items, TRUE); } void -gtk_list_scroll_vertical (GtkList *list, - GtkScrollType scroll_type, - gfloat position) +gtk_list_clear_items (GtkList *list, + gint start, + gint end) { + GtkWidget *widget; + GList *start_list; + GList *end_list; + GList *tmp_list; + guint nchildren; + g_return_if_fail (list != NULL); g_return_if_fail (GTK_IS_LIST (list)); - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list)) - return; + nchildren = g_list_length (list->children); - if (list->selection_mode == GTK_SELECTION_EXTENDED) + if (nchildren > 0) { - GtkContainer *container; + gboolean selection_changed; - if (list->anchor >= 0) + if ((end < 0) || (end > nchildren)) + end = nchildren; + + if (start >= end) return; - container = GTK_CONTAINER (list); - list->undo_focus_child = container->focus_child; - gtk_list_move_focus_child (list, scroll_type, position); - if (container->focus_child != list->undo_focus_child && !list->add_mode) + start_list = g_list_nth (list->children, start); + end_list = g_list_nth (list->children, end); + + gtk_list_end_drag_selection (list); + if (list->selection_mode == GTK_SELECTION_EXTENDED && list->anchor >= 0) + gtk_list_end_selection (list); + + if (start_list->prev) + start_list->prev->next = end_list; + if (end_list && end_list->prev) + end_list->prev->next = NULL; + if (end_list) + end_list->prev = start_list->prev; + if (start_list == list->children) + list->children = end_list; + + selection_changed = FALSE; + widget = NULL; + tmp_list = start_list; + + while (tmp_list) { - gtk_list_unselect_all (list); - gtk_list_select_child (list, container->focus_child); + widget = tmp_list->data; + tmp_list = tmp_list->next; + + if (widget->state == GTK_STATE_SELECTED) + { + gtk_list_unselect_child (list, widget); + selection_changed = TRUE; + } + + gtk_widget_unparent (widget); + } + + g_list_free (start_list); + + if (list->children && !list->selection && + (list->selection_mode == GTK_SELECTION_BROWSE)) + { + widget = list->children->data; + gtk_list_select_child (list, widget); } + else if (selection_changed) + gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]); + + gtk_widget_queue_resize (GTK_WIDGET (list)); } - else - gtk_list_move_focus_child (list, scroll_type, position); } +gint +gtk_list_child_position (GtkList *list, + GtkWidget *child) +{ + GList *children; + gint pos; + + g_return_val_if_fail (list != NULL, -1); + g_return_val_if_fail (GTK_IS_LIST (list), -1); + g_return_val_if_fail (child != NULL, -1); + + pos = 0; + children = list->children; + + while (children) + { + if (child == GTK_WIDGET (children->data)) + return pos; + + pos += 1; + children = children->next; + } + + return -1; +} + + +/* Private GtkList Insert/Remove Item Functions: + * + * gtk_list_remove_items_internal + */ static void -gtk_list_move_focus_child (GtkList *list, - GtkScrollType scroll_type, - gfloat position) +gtk_list_remove_items_internal (GtkList *list, + GList *items, + gboolean no_unref) { + GtkWidget *widget; + GtkWidget *new_focus_child; + GtkWidget *old_focus_child; GtkContainer *container; + GList *tmp_list; GList *work; - GtkWidget *item; - GtkAdjustment *adj; - gint new_value; - - g_return_if_fail (list != 0); + gboolean grab_focus = FALSE; + + g_return_if_fail (list != NULL); g_return_if_fail (GTK_IS_LIST (list)); + if (!items) + return; + container = GTK_CONTAINER (list); - if (container->focus_child) - work = g_list_find (list->children, container->focus_child); - else - work = list->children; + gtk_list_end_drag_selection (list); + if (list->selection_mode == GTK_SELECTION_EXTENDED) + { + if (list->anchor >= 0) + gtk_list_end_selection (list); - if (!work) - return; + if (list->undo_selection || list->undo_unselection) + { + g_list_free (list->undo_selection); + g_list_free (list->undo_unselection); + list->undo_selection = NULL; + list->undo_unselection = NULL; + + list->anchor = -1; + list->drag_pos = -1; + list->undo_focus_child = container->focus_child; + } + } - switch (scroll_type) + tmp_list = items; + while (tmp_list) { - case GTK_SCROLL_STEP_BACKWARD: - work = work->prev; - if (work) - gtk_widget_grab_focus (GTK_WIDGET (work->data)); - break; + widget = tmp_list->data; + tmp_list = tmp_list->next; + + if (widget->state == GTK_STATE_SELECTED) + gtk_list_unselect_child (list, widget); - case GTK_SCROLL_STEP_FORWARD: - work = work->next; - if (work) - gtk_widget_grab_focus (GTK_WIDGET (work->data)); - break; + } - case GTK_SCROLL_PAGE_BACKWARD: - if (!work->prev) - return; + tmp_list = items; + old_focus_child = new_focus_child = container->focus_child; - item = work->data; - adj = gtk_object_get_data_by_id (GTK_OBJECT (list), vadjustment_key_id); + while (tmp_list) + { + widget = tmp_list->data; + tmp_list = tmp_list->next; + + if (no_unref) + gtk_widget_ref (widget); + - if (adj) + if (widget == new_focus_child) { - gboolean correct = FALSE; - - new_value = adj->value; + work = g_list_find (list->children, widget); - if (item->allocation.y <= adj->value) + if (work) { - new_value = MAX (item->allocation.y + item->allocation.height - - adj->page_size, adj->lower); - correct = TRUE; + if (work->next) + new_focus_child = work->next->data; + else if (list->children != work && work->prev) + new_focus_child = work->prev->data; + else + new_focus_child = NULL; + + if (GTK_WIDGET_HAS_FOCUS (widget)) + grab_focus = TRUE; } - - if (item->allocation.y > new_value) - for (; work; work = work->prev) - { - item = GTK_WIDGET (work->data); - if (item->allocation.y <= new_value && - item->allocation.y + item->allocation.height > new_value) - break; - } - else - for (; work; work = work->next) - { - item = GTK_WIDGET (work->data); - if (item->allocation.y <= new_value && - item->allocation.y + item->allocation.height > new_value) - break; - } - - if (correct && work && work->next && item->allocation.y < new_value) - item = work->next->data; } - else - item = list->children->data; - - gtk_widget_grab_focus (item); - break; - - case GTK_SCROLL_PAGE_FORWARD: - if (!work->next) - return; - item = work->data; - adj = gtk_object_get_data_by_id (GTK_OBJECT (list), vadjustment_key_id); + gtk_signal_disconnect_by_data (GTK_OBJECT (widget), (gpointer) list); + list->children = g_list_remove (list->children, widget); + gtk_widget_unparent (widget); + } + + if (new_focus_child && new_focus_child != old_focus_child) + { + if (grab_focus) + gtk_widget_grab_focus (new_focus_child); + else + gtk_container_set_focus_child (container, new_focus_child); + } + + if (GTK_WIDGET_VISIBLE (list)) + gtk_widget_queue_resize (GTK_WIDGET (list)); +} - if (adj) - { - gboolean correct = FALSE; - new_value = adj->value; +/* Public GtkList Selection Methods : + * + * gtk_list_set_selection_mode + * gtk_list_select_item + * gtk_list_unselect_item + * gtk_list_select_child + * gtk_list_unselect_child + * gtk_list_select_all + * gtk_list_unselect_all + * gtk_list_extend_selection + * gtk_list_end_drag_selection + * gtk_list_start_selection + * gtk_list_end_selection + * gtk_list_toggle_row + * gtk_list_toggle_focus_row + * gtk_list_toggle_add_mode + * gtk_list_undo_selection + */ +void +gtk_list_set_selection_mode (GtkList *list, + GtkSelectionMode mode) +{ + g_return_if_fail (list != NULL); + g_return_if_fail (GTK_IS_LIST (list)); - if (item->allocation.y + item->allocation.height >= - adj->value + adj->page_size) - { - new_value = item->allocation.y; - correct = TRUE; - } + if (list->selection_mode == mode) + return; - new_value = MIN (new_value + adj->page_size, adj->upper); + list->selection_mode = mode; - if (item->allocation.y > new_value) - for (; work; work = work->prev) - { - item = GTK_WIDGET (work->data); - if (item->allocation.y <= new_value && - item->allocation.y + item->allocation.height > new_value) - break; - } - else - for (; work; work = work->next) - { - item = GTK_WIDGET (work->data); - if (item->allocation.y <= new_value && - item->allocation.y + item->allocation.height > new_value) - break; - } + switch (mode) + { + case GTK_SELECTION_SINGLE: + case GTK_SELECTION_BROWSE: + gtk_list_unselect_all (list); + break; - if (correct && work && work->prev && - item->allocation.y + item->allocation.height - 1 > new_value) - item = work->prev->data; - } - else - item = g_list_last (work)->data; - - gtk_widget_grab_focus (item); + default: break; + } +} - case GTK_SCROLL_JUMP: - new_value = GTK_WIDGET(list)->allocation.height * CLAMP (position, 0, 1); +void +gtk_list_select_item (GtkList *list, + gint item) +{ + GList *tmp_list; - for (item = NULL, work = list->children; work; work =work->next) - { - item = GTK_WIDGET (work->data); - if (item->allocation.y <= new_value && - item->allocation.y + item->allocation.height > new_value) - break; - } + g_return_if_fail (list != NULL); + g_return_if_fail (GTK_IS_LIST (list)); - gtk_widget_grab_focus (item); - break; + tmp_list = g_list_nth (list->children, item); + if (tmp_list) + gtk_list_select_child (list, GTK_WIDGET (tmp_list->data)); +} - default: - break; - } +void +gtk_list_unselect_item (GtkList *list, + gint item) +{ + GList *tmp_list; + + g_return_if_fail (list != NULL); + g_return_if_fail (GTK_IS_LIST (list)); + + tmp_list = g_list_nth (list->children, item); + if (tmp_list) + gtk_list_unselect_child (list, GTK_WIDGET (tmp_list->data)); +} + +void +gtk_list_select_child (GtkList *list, + GtkWidget *child) +{ + gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECT_CHILD], child); +} + +void +gtk_list_unselect_child (GtkList *list, + GtkWidget *child) +{ + gtk_signal_emit (GTK_OBJECT (list), list_signals[UNSELECT_CHILD], child); } void @@ -1831,6 +1560,7 @@ gtk_list_extend_selection (GtkList *list, if (auto_start_selection) { gint focus_row; + focus_row = g_list_index (list->children, container->focus_child); gtk_list_set_anchor (list, list->add_mode, focus_row, container->focus_child); @@ -1843,96 +1573,48 @@ gtk_list_extend_selection (GtkList *list, (list, g_list_index (list->children, container->focus_child)); } -static void -gtk_list_update_extended_selection (GtkList *list, - gint row) +void +gtk_list_end_drag_selection (GtkList *list) { - gint i; - GList *work; - gint s1 = -1; - gint s2 = -1; - gint e1 = -1; - gint e2 = -1; - gint length; - - if (row < 0) - row = 0; - - length = g_list_length (list->children); - if (row >= length) - row = length - 1; - - if (list->selection_mode != GTK_SELECTION_EXTENDED || !list->anchor < 0) - return; + g_return_if_fail (list != NULL); + g_return_if_fail (GTK_IS_LIST (list)); - /* extending downwards */ - if (row > list->drag_pos && list->anchor <= list->drag_pos) - { - s2 = list->drag_pos + 1; - e2 = row; - } - /* extending upwards */ - else if (row < list->drag_pos && list->anchor >= list->drag_pos) + list->drag_selection = FALSE; + if (GTK_WIDGET_HAS_GRAB (list)) { - s2 = row; - e2 = list->drag_pos - 1; + gtk_grab_remove (GTK_WIDGET (list)); + gdk_pointer_ungrab (GDK_CURRENT_TIME); } - else if (row < list->drag_pos && list->anchor < list->drag_pos) + if (list->htimer) { - e1 = list->drag_pos; - /* row and drag_pos on different sides of anchor : - take back the selection between anchor and drag_pos, - select between anchor and row */ - if (row < list->anchor) - { - s1 = list->anchor + 1; - s2 = row; - e2 = list->anchor - 1; - } - /* take back the selection between anchor and drag_pos */ - else - s1 = row + 1; + gtk_timeout_remove (list->htimer); + list->htimer = 0; } - else if (row > list->drag_pos && list->anchor > list->drag_pos) + if (list->vtimer) { - s1 = list->drag_pos; - /* row and drag_pos on different sides of anchor : - take back the selection between anchor and drag_pos, - select between anchor and row */ - if (row > list->anchor) - { - e1 = list->anchor - 1; - s2 = list->anchor + 1; - e2 = row; - } - /* take back the selection between anchor and drag_pos */ - else - e1 = row - 1; + gtk_timeout_remove (list->vtimer); + list->vtimer = 0; } +} - list->drag_pos = row; +void +gtk_list_start_selection (GtkList *list) +{ + GtkContainer *container; + gint focus_row; - /* restore the elements between s1 and e1 */ - if (s1 >= 0) - { - for (i = s1, work = g_list_nth (list->children, i); i <= e1; - i++, work = work->next) - { - if (g_list_find (list->selection, work->data)) - gtk_widget_set_state (GTK_WIDGET (work->data), GTK_STATE_SELECTED); - else - gtk_widget_set_state (GTK_WIDGET (work->data), GTK_STATE_NORMAL); - } - } + g_return_if_fail (list != NULL); + g_return_if_fail (GTK_IS_LIST (list)); - /* extend the selection between s2 and e2 */ - if (s2 >= 0) - { - for (i = s2, work = g_list_nth (list->children, i); i <= e2; - i++, work = work->next) - if (GTK_WIDGET (work->data)->state != list->anchor_state) - gtk_widget_set_state (GTK_WIDGET (work->data), list->anchor_state); - } + if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list)) + return; + + container = GTK_CONTAINER (list); + + if ((focus_row = g_list_index (list->selection, container->focus_child)) + >= 0) + gtk_list_set_anchor (list, list->add_mode, + focus_row, container->focus_child); } void @@ -2005,26 +1687,6 @@ gtk_list_end_selection (GtkList *list) } void -gtk_list_start_selection (GtkList *list) -{ - GtkContainer *container; - gint focus_row; - - g_return_if_fail (list != NULL); - g_return_if_fail (GTK_IS_LIST (list)); - - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list)) - return; - - container = GTK_CONTAINER (list); - - if ((focus_row = g_list_index (list->selection, container->focus_child)) - >= 0) - gtk_list_set_anchor (list, list->add_mode, - focus_row, container->focus_child); -} - -void gtk_list_toggle_row (GtkList *list, GtkWidget *item) { @@ -2176,98 +1838,762 @@ gtk_list_undo_selection (GtkList *list) list->undo_unselection = NULL; } + +/* Private GtkList Selection Methods : + * + * gtk_real_list_select_child + * gtk_real_list_unselect_child + */ static void -gtk_list_focus_lost (GtkWidget *item, - GdkEventKey *event, - GtkList *list) +gtk_real_list_select_child (GtkList *list, + GtkWidget *child) { g_return_if_fail (list != NULL); g_return_if_fail (GTK_IS_LIST (list)); - g_return_if_fail (item != NULL); - g_return_if_fail (GTK_IS_LIST_ITEM (item)); + g_return_if_fail (child != NULL); + g_return_if_fail (GTK_IS_LIST_ITEM (child)); - if (list->selection_mode == GTK_SELECTION_EXTENDED && list->anchor >= 0 && - item == GTK_CONTAINER (list)->focus_child) - gtk_list_end_selection (list); + switch (child->state) + { + case GTK_STATE_SELECTED: + case GTK_STATE_INSENSITIVE: + break; + default: + gtk_list_item_select (GTK_LIST_ITEM (child)); + break; + } } static void -gtk_list_set_focus_child (GtkContainer *container, - GtkWidget *child) +gtk_real_list_unselect_child (GtkList *list, + GtkWidget *child) { - GtkList *list; + g_return_if_fail (list != NULL); + g_return_if_fail (GTK_IS_LIST (list)); + g_return_if_fail (child != NULL); + g_return_if_fail (GTK_IS_LIST_ITEM (child)); - g_return_if_fail (container != NULL); - g_return_if_fail (GTK_IS_LIST (container)); + if (child->state == GTK_STATE_SELECTED) + gtk_list_item_deselect (GTK_LIST_ITEM (child)); +} - if (child) - g_return_if_fail (GTK_IS_WIDGET (child)); - list = GTK_LIST (container); - list->last_focus_child = container->focus_child; +/* Private GtkList Selection Functions : + * + * gtk_list_set_anchor + * gtk_list_fake_unselect_all + * gtk_list_fake_toggle_row + * gtk_list_update_extended_selection + */ +static void +gtk_list_set_anchor (GtkList *list, + gboolean add_mode, + gint anchor, + GtkWidget *undo_focus_child) +{ + GList *work; - if (child != container->focus_child) + g_return_if_fail (list != NULL); + g_return_if_fail (GTK_IS_LIST (list)); + + if (list->selection_mode != GTK_SELECTION_EXTENDED || list->anchor >= 0) + return; + + g_list_free (list->undo_selection); + g_list_free (list->undo_unselection); + list->undo_selection = NULL; + list->undo_unselection = NULL; + + if ((work = g_list_nth (list->children, anchor))) { - if (container->focus_child) - gtk_widget_unref (container->focus_child); - container->focus_child = child; - if (container->focus_child) - gtk_widget_ref (container->focus_child); + if (add_mode) + gtk_list_fake_toggle_row (list, GTK_WIDGET (work->data)); + else + { + gtk_list_fake_unselect_all (list, GTK_WIDGET (work->data)); + list->anchor_state = GTK_STATE_SELECTED; + } } - /* check for v adjustment */ - if (container->focus_child) + list->anchor = anchor; + list->drag_pos = anchor; + list->undo_focus_child = undo_focus_child; +} + +static void +gtk_list_fake_unselect_all (GtkList *list, + GtkWidget *item) +{ + GList *work; + + if (item && item->state == GTK_STATE_NORMAL) + gtk_widget_set_state (item, GTK_STATE_SELECTED); + + list->undo_selection = list->selection; + list->selection = NULL; + + for (work = list->undo_selection; work; work = work->next) + if (work->data != item) + gtk_widget_set_state (GTK_WIDGET (work->data), GTK_STATE_NORMAL); +} + +static void +gtk_list_fake_toggle_row (GtkList *list, + GtkWidget *item) +{ + if (!item) + return; + + if (item->state == GTK_STATE_NORMAL) { - GtkAdjustment *adjustment; + list->anchor_state = GTK_STATE_SELECTED; + gtk_widget_set_state (item, GTK_STATE_SELECTED); + } + else + { + list->anchor_state = GTK_STATE_NORMAL; + gtk_widget_set_state (item, GTK_STATE_NORMAL); + } +} - adjustment = gtk_object_get_data_by_id (GTK_OBJECT (container), - vadjustment_key_id); - if (adjustment) - gtk_adjustment_clamp_page (adjustment, - container->focus_child->allocation.y, - (container->focus_child->allocation.y + - container->focus_child->allocation.height)); +static void +gtk_list_update_extended_selection (GtkList *list, + gint row) +{ + gint i; + GList *work; + gint s1 = -1; + gint s2 = -1; + gint e1 = -1; + gint e2 = -1; + gint length; + + if (row < 0) + row = 0; + + length = g_list_length (list->children); + if (row >= length) + row = length - 1; + + if (list->selection_mode != GTK_SELECTION_EXTENDED || !list->anchor < 0) + return; + + /* extending downwards */ + if (row > list->drag_pos && list->anchor <= list->drag_pos) + { + s2 = list->drag_pos + 1; + e2 = row; + } + /* extending upwards */ + else if (row < list->drag_pos && list->anchor >= list->drag_pos) + { + s2 = row; + e2 = list->drag_pos - 1; + } + else if (row < list->drag_pos && list->anchor < list->drag_pos) + { + e1 = list->drag_pos; + /* row and drag_pos on different sides of anchor : + take back the selection between anchor and drag_pos, + select between anchor and row */ + if (row < list->anchor) + { + s1 = list->anchor + 1; + s2 = row; + e2 = list->anchor - 1; + } + /* take back the selection between anchor and drag_pos */ + else + s1 = row + 1; + } + else if (row > list->drag_pos && list->anchor > list->drag_pos) + { + s1 = list->drag_pos; + /* row and drag_pos on different sides of anchor : + take back the selection between anchor and drag_pos, + select between anchor and row */ + if (row > list->anchor) + { + e1 = list->anchor - 1; + s2 = list->anchor + 1; + e2 = row; + } + /* take back the selection between anchor and drag_pos */ + else + e1 = row - 1; } - switch (list->selection_mode) + list->drag_pos = row; + + /* restore the elements between s1 and e1 */ + if (s1 >= 0) { - case GTK_SELECTION_BROWSE: - if (child) - gtk_list_select_child (list, child); + for (i = s1, work = g_list_nth (list->children, i); i <= e1; + i++, work = work->next) + { + if (g_list_find (list->selection, work->data)) + gtk_widget_set_state (GTK_WIDGET (work->data), GTK_STATE_SELECTED); + else + gtk_widget_set_state (GTK_WIDGET (work->data), GTK_STATE_NORMAL); + } + } + + /* extend the selection between s2 and e2 */ + if (s2 >= 0) + { + for (i = s2, work = g_list_nth (list->children, i); i <= e2; + i++, work = work->next) + if (GTK_WIDGET (work->data)->state != list->anchor_state) + gtk_widget_set_state (GTK_WIDGET (work->data), list->anchor_state); + } +} + + +/* Public GtkList Scroll Methods : + * + * gtk_list_scroll_horizontal + * gtk_list_scroll_vertical + */ +void +gtk_list_scroll_horizontal (GtkList *list, + GtkScrollType scroll_type, + gfloat position) +{ + GtkAdjustment *adj; + + g_return_if_fail (list != 0); + g_return_if_fail (GTK_IS_LIST (list)); + + if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list)) + return; + + if (!(adj = + gtk_object_get_data_by_id (GTK_OBJECT (list), hadjustment_key_id))) + return; + + switch (scroll_type) + { + case GTK_SCROLL_STEP_BACKWARD: + adj->value = CLAMP (adj->value - adj->step_increment, adj->lower, + adj->upper - adj->page_size); + break; + case GTK_SCROLL_STEP_FORWARD: + adj->value = CLAMP (adj->value + adj->step_increment, adj->lower, + adj->upper - adj->page_size); + break; + case GTK_SCROLL_PAGE_BACKWARD: + adj->value = CLAMP (adj->value - adj->page_increment, adj->lower, + adj->upper - adj->page_size); + break; + case GTK_SCROLL_PAGE_FORWARD: + adj->value = CLAMP (adj->value + adj->page_increment, adj->lower, + adj->upper - adj->page_size); + break; + case GTK_SCROLL_JUMP: + adj->value = CLAMP (adj->lower + (adj->upper - adj->lower) * position, + adj->lower, adj->upper - adj->page_size); break; default: break; } + gtk_adjustment_value_changed (adj); } +void +gtk_list_scroll_vertical (GtkList *list, + GtkScrollType scroll_type, + gfloat position) +{ + g_return_if_fail (list != NULL); + g_return_if_fail (GTK_IS_LIST (list)); -static gint -gtk_list_focus (GtkContainer *container, - GtkDirectionType direction) + if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list)) + return; + + if (list->selection_mode == GTK_SELECTION_EXTENDED) + { + GtkContainer *container; + + if (list->anchor >= 0) + return; + + container = GTK_CONTAINER (list); + list->undo_focus_child = container->focus_child; + gtk_list_move_focus_child (list, scroll_type, position); + if (container->focus_child != list->undo_focus_child && !list->add_mode) + { + gtk_list_unselect_all (list); + gtk_list_select_child (list, container->focus_child); + } + } + else + gtk_list_move_focus_child (list, scroll_type, position); +} + + +/* Private GtkList Scroll/Focus Functions : + * + * gtk_list_move_focus_child + * gtk_list_horizontal_timeout + * gtk_list_vertical_timeout + */ +static void +gtk_list_move_focus_child (GtkList *list, + GtkScrollType scroll_type, + gfloat position) { - gint return_val = FALSE; + GtkContainer *container; + GList *work; + GtkWidget *item; + GtkAdjustment *adj; + gint new_value; - g_return_val_if_fail (container != NULL, FALSE); - g_return_val_if_fail (GTK_IS_LIST (container), FALSE); + g_return_if_fail (list != 0); + g_return_if_fail (GTK_IS_LIST (list)); - if (!GTK_WIDGET_SENSITIVE (container)) - return_val = FALSE; - else if (container->focus_child == NULL || - !GTK_WIDGET_HAS_FOCUS (container->focus_child)) + container = GTK_CONTAINER (list); + + if (container->focus_child) + work = g_list_find (list->children, container->focus_child); + else + work = list->children; + + if (!work) + return; + + switch (scroll_type) { - if (*GTK_CONTAINER_CLASS (parent_class)->focus) - return_val = GTK_CONTAINER_CLASS (parent_class)->focus - (container, direction); + case GTK_SCROLL_STEP_BACKWARD: + work = work->prev; + if (work) + gtk_widget_grab_focus (GTK_WIDGET (work->data)); + break; + + case GTK_SCROLL_STEP_FORWARD: + work = work->next; + if (work) + gtk_widget_grab_focus (GTK_WIDGET (work->data)); + break; + + case GTK_SCROLL_PAGE_BACKWARD: + if (!work->prev) + return; + + item = work->data; + adj = gtk_object_get_data_by_id (GTK_OBJECT (list), vadjustment_key_id); + + if (adj) + { + gboolean correct = FALSE; + + new_value = adj->value; + + if (item->allocation.y <= adj->value) + { + new_value = MAX (item->allocation.y + item->allocation.height + - adj->page_size, adj->lower); + correct = TRUE; + } + + if (item->allocation.y > new_value) + for (; work; work = work->prev) + { + item = GTK_WIDGET (work->data); + if (item->allocation.y <= new_value && + item->allocation.y + item->allocation.height > new_value) + break; + } + else + for (; work; work = work->next) + { + item = GTK_WIDGET (work->data); + if (item->allocation.y <= new_value && + item->allocation.y + item->allocation.height > new_value) + break; + } + + if (correct && work && work->next && item->allocation.y < new_value) + item = work->next->data; + } + else + item = list->children->data; + + gtk_widget_grab_focus (item); + break; + + case GTK_SCROLL_PAGE_FORWARD: + if (!work->next) + return; + + item = work->data; + adj = gtk_object_get_data_by_id (GTK_OBJECT (list), vadjustment_key_id); + + if (adj) + { + gboolean correct = FALSE; + + new_value = adj->value; + + if (item->allocation.y + item->allocation.height >= + adj->value + adj->page_size) + { + new_value = item->allocation.y; + correct = TRUE; + } + + new_value = MIN (new_value + adj->page_size, adj->upper); + + if (item->allocation.y > new_value) + for (; work; work = work->prev) + { + item = GTK_WIDGET (work->data); + if (item->allocation.y <= new_value && + item->allocation.y + item->allocation.height > new_value) + break; + } + else + for (; work; work = work->next) + { + item = GTK_WIDGET (work->data); + if (item->allocation.y <= new_value && + item->allocation.y + item->allocation.height > new_value) + break; + } + + if (correct && work && work->prev && + item->allocation.y + item->allocation.height - 1 > new_value) + item = work->prev->data; + } + else + item = g_list_last (work)->data; + + gtk_widget_grab_focus (item); + break; + + case GTK_SCROLL_JUMP: + new_value = GTK_WIDGET(list)->allocation.height * CLAMP (position, 0, 1); + + for (item = NULL, work = list->children; work; work =work->next) + { + item = GTK_WIDGET (work->data); + if (item->allocation.y <= new_value && + item->allocation.y + item->allocation.height > new_value) + break; + } + + gtk_widget_grab_focus (item); + break; + + default: + break; } - - if (!return_val) +} + +static gint +gtk_list_horizontal_timeout (GtkWidget *list) +{ + gint x, y; + GdkEventMotion event; + GdkModifierType mask; + + g_return_val_if_fail (GTK_IS_LIST (list), FALSE); + + GTK_LIST (list)->htimer = 0; + gdk_window_get_pointer (list->window, &x, &y, &mask); + + event.is_hint = 0; + event.x = x; + event.y = y; + event.state = mask; + + gtk_list_motion_notify (list, &event); + + return FALSE; +} + +static gint +gtk_list_vertical_timeout (GtkWidget *list) +{ + gint x; + gint y; + GdkEventMotion event; + GdkModifierType mask; + + g_return_val_if_fail (GTK_IS_LIST (list), FALSE); + + GTK_LIST (list)->vtimer = 0; + gdk_window_get_pointer (list->window, &x, &y, &mask); + + event.is_hint = 0; + event.x = x; + event.y = y; + event.state = mask; + + gtk_list_motion_notify (list, &event); + + return FALSE; +} + + +/* Private GtkListItem Signal Functions : + * + * gtk_list_signal_focus_lost + * gtk_list_signal_toggle_focus_row + * gtk_list_signal_select_all + * gtk_list_signal_unselect_all + * gtk_list_signal_undo_selection + * gtk_list_signal_start_selection + * gtk_list_signal_end_selection + * gtk_list_signal_extend_selection + * gtk_list_signal_scroll_horizontal + * gtk_list_signal_scroll_vertical + * gtk_list_signal_toggle_add_mode + * gtk_list_signal_item_select + * gtk_list_signal_item_deselect + * gtk_list_signal_item_toggle + */ +static void +gtk_list_signal_focus_lost (GtkWidget *item, + GdkEventKey *event, + GtkList *list) +{ + g_return_if_fail (list != NULL); + g_return_if_fail (GTK_IS_LIST (list)); + g_return_if_fail (item != NULL); + g_return_if_fail (GTK_IS_LIST_ITEM (item)); + + if (list->selection_mode == GTK_SELECTION_EXTENDED && + list->anchor >= 0 && + item == GTK_CONTAINER (list)->focus_child) + gtk_list_end_selection (list); +} + +static void +gtk_list_signal_toggle_focus_row (GtkListItem *list_item, + GtkList *list) +{ + g_return_if_fail (list_item != 0); + g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); + g_return_if_fail (list != NULL); + g_return_if_fail (GTK_IS_LIST (list)); + + gtk_list_toggle_focus_row (list); +} + +static void +gtk_list_signal_select_all (GtkListItem *list_item, + GtkList *list) +{ + g_return_if_fail (list_item != 0); + g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); + g_return_if_fail (list != NULL); + g_return_if_fail (GTK_IS_LIST (list)); + + gtk_list_select_all (list); +} + +static void +gtk_list_signal_unselect_all (GtkListItem *list_item, + GtkList *list) +{ + g_return_if_fail (list_item != 0); + g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); + g_return_if_fail (list != NULL); + g_return_if_fail (GTK_IS_LIST (list)); + + gtk_list_unselect_all (list); +} + +static void +gtk_list_signal_undo_selection (GtkListItem *list_item, + GtkList *list) +{ + g_return_if_fail (list_item != 0); + g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); + g_return_if_fail (list != NULL); + g_return_if_fail (GTK_IS_LIST (list)); + + gtk_list_undo_selection (list); +} + +static void +gtk_list_signal_start_selection (GtkListItem *list_item, + GtkList *list) +{ + g_return_if_fail (list_item != 0); + g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); + g_return_if_fail (list != NULL); + g_return_if_fail (GTK_IS_LIST (list)); + + gtk_list_start_selection (list); +} + +static void +gtk_list_signal_end_selection (GtkListItem *list_item, + GtkList *list) +{ + g_return_if_fail (list_item != 0); + g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); + g_return_if_fail (list != NULL); + g_return_if_fail (GTK_IS_LIST (list)); + + gtk_list_end_selection (list); +} + +static void +gtk_list_signal_extend_selection (GtkListItem *list_item, + GtkScrollType scroll_type, + gfloat position, + gboolean auto_start_selection, + GtkList *list) +{ + g_return_if_fail (list_item != 0); + g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); + g_return_if_fail (list != NULL); + g_return_if_fail (GTK_IS_LIST (list)); + + gtk_list_extend_selection (list, scroll_type, position, + auto_start_selection); +} + +static void +gtk_list_signal_scroll_horizontal (GtkListItem *list_item, + GtkScrollType scroll_type, + gfloat position, + GtkList *list) +{ + g_return_if_fail (list_item != 0); + g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); + g_return_if_fail (list != NULL); + g_return_if_fail (GTK_IS_LIST (list)); + + gtk_list_scroll_horizontal (list, scroll_type, position); +} + +static void +gtk_list_signal_scroll_vertical (GtkListItem *list_item, + GtkScrollType scroll_type, + gfloat position, + GtkList *list) +{ + g_return_if_fail (list_item != 0); + g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); + g_return_if_fail (list != NULL); + g_return_if_fail (GTK_IS_LIST (list)); + + gtk_list_scroll_vertical (list, scroll_type, position); +} + +static void +gtk_list_signal_toggle_add_mode (GtkListItem *list_item, + GtkList *list) +{ + g_return_if_fail (list_item != 0); + g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); + g_return_if_fail (list != NULL); + g_return_if_fail (GTK_IS_LIST (list)); + + gtk_list_toggle_add_mode (list); +} + +static void +gtk_list_signal_item_select (GtkListItem *list_item, + GtkList *list) +{ + GList *selection; + GList *tmp_list; + GList *sel_list; + + g_return_if_fail (list_item != 0); + g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); + g_return_if_fail (list != NULL); + g_return_if_fail (GTK_IS_LIST (list)); + + if (GTK_WIDGET (list_item)->state != GTK_STATE_SELECTED) + return; + + switch (list->selection_mode) { - GtkList *list; + case GTK_SELECTION_SINGLE: + case GTK_SELECTION_BROWSE: + sel_list = NULL; + selection = list->selection; - list = GTK_LIST (container); - if (list->selection_mode == GTK_SELECTION_EXTENDED && list->anchor >= 0) - gtk_list_end_selection (list); + while (selection) + { + tmp_list = selection; + selection = selection->next; + + if (tmp_list->data == list_item) + sel_list = tmp_list; + else + gtk_list_item_deselect (GTK_LIST_ITEM (tmp_list->data)); + } + + if (!sel_list) + { + list->selection = g_list_prepend (list->selection, list_item); + gtk_widget_ref (GTK_WIDGET (list_item)); + } + gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]); + break; + case GTK_SELECTION_EXTENDED: + if (list->anchor >= 0) + return; + case GTK_SELECTION_MULTIPLE: + if (!g_list_find (list->selection, list_item)) + { + list->selection = g_list_prepend (list->selection, list_item); + gtk_widget_ref (GTK_WIDGET (list_item)); + gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]); + } + break; } +} - return return_val; +static void +gtk_list_signal_item_deselect (GtkListItem *list_item, + GtkList *list) +{ + GList *node; + + g_return_if_fail (list_item != 0); + g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); + g_return_if_fail (list != NULL); + g_return_if_fail (GTK_IS_LIST (list)); + + if (GTK_WIDGET (list_item)->state != GTK_STATE_NORMAL) + return; + + node = g_list_find (list->selection, list_item); + + if (node) + { + list->selection = g_list_remove_link (list->selection, node); + g_list_free_1 (node); + gtk_widget_unref (GTK_WIDGET (list_item)); + gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]); + } +} + +static void +gtk_list_signal_item_toggle (GtkListItem *list_item, + GtkList *list) +{ + g_return_if_fail (list_item != 0); + g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); + g_return_if_fail (list != NULL); + g_return_if_fail (GTK_IS_LIST (list)); + + switch (GTK_WIDGET (list_item)->state) + { + case GTK_STATE_SELECTED: + gtk_list_signal_item_select (list_item, list); + break; + case GTK_STATE_NORMAL: + gtk_list_signal_item_deselect (list_item, list); + break; + default: + break; + } } diff --git a/gtk/gtklistitem.c b/gtk/gtklistitem.c index d81ad3719..bab73bd2c 100644 --- a/gtk/gtklistitem.c +++ b/gtk/gtklistitem.c @@ -63,24 +63,6 @@ static void gtk_real_list_item_deselect (GtkItem *item); static void gtk_real_list_item_toggle (GtkItem *item); -static void gtk_list_item_toggle_focus_row (GtkListItem *list_item); -static void gtk_list_item_select_all (GtkListItem *list_item); -static void gtk_list_item_unselect_all (GtkListItem *list_item); -static void gtk_list_item_undo_selection (GtkListItem *list_item); -static void gtk_list_item_start_selection (GtkListItem *list_item); -static void gtk_list_item_end_selection (GtkListItem *list_item); -static void gtk_list_item_extend_selection (GtkListItem *list_item, - GtkScrollType scroll_type, - gfloat position, - gboolean auto_start_selection); -static void gtk_list_item_scroll_horizontal (GtkListItem *list_item, - GtkScrollType scroll_type, - gfloat position); -static void gtk_list_item_scroll_vertical (GtkListItem *list_item, - GtkScrollType scroll_type, - gfloat position); -static void gtk_list_item_toggle_add_mode (GtkListItem *list_item); - static GtkItemClass *parent_class = NULL; static guint list_item_signals[LAST_SIGNAL] = {0}; @@ -195,6 +177,7 @@ gtk_list_item_class_init (GtkListItemClass *class) gtk_marshal_NONE__ENUM_FLOAT, GTK_TYPE_NONE, 2, GTK_TYPE_ENUM, GTK_TYPE_FLOAT); + gtk_object_class_add_signals (object_class, list_item_signals, LAST_SIGNAL); widget_class->realize = gtk_list_item_realize; widget_class->size_request = gtk_list_item_size_request; @@ -210,16 +193,16 @@ gtk_list_item_class_init (GtkListItemClass *class) item_class->deselect = gtk_real_list_item_deselect; item_class->toggle = gtk_real_list_item_toggle; - class->toggle_focus_row = gtk_list_item_toggle_focus_row; - class->select_all = gtk_list_item_select_all; - class->unselect_all = gtk_list_item_unselect_all; - class->undo_selection = gtk_list_item_undo_selection; - class->start_selection = gtk_list_item_start_selection; - class->end_selection = gtk_list_item_end_selection; - class->extend_selection = gtk_list_item_extend_selection; - class->scroll_horizontal = gtk_list_item_scroll_horizontal; - class->scroll_vertical = gtk_list_item_scroll_vertical; - class->toggle_add_mode = gtk_list_item_toggle_add_mode; + class->toggle_focus_row = NULL; + class->select_all = NULL; + class->unselect_all = NULL; + class->undo_selection = NULL; + class->start_selection = NULL; + class->end_selection = NULL; + class->extend_selection = NULL; + class->scroll_horizontal = NULL; + class->scroll_vertical = NULL; + class->toggle_add_mode = NULL; { GtkBindingSet *binding_set; @@ -619,7 +602,15 @@ gtk_real_list_item_select (GtkItem *item) g_return_if_fail (item != NULL); g_return_if_fail (GTK_IS_LIST_ITEM (item)); - gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_SELECTED); + switch (GTK_WIDGET (item)->state) + { + case GTK_STATE_SELECTED: + case GTK_STATE_INSENSITIVE: + break; + default: + gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_SELECTED); + break; + } } static void @@ -628,10 +619,8 @@ gtk_real_list_item_deselect (GtkItem *item) g_return_if_fail (item != NULL); g_return_if_fail (GTK_IS_LIST_ITEM (item)); - if (GTK_WIDGET (item)->state == GTK_STATE_NORMAL) - return; - - gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_NORMAL); + if (GTK_WIDGET (item)->state == GTK_STATE_SELECTED) + gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_NORMAL); } static void @@ -640,129 +629,15 @@ gtk_real_list_item_toggle (GtkItem *item) g_return_if_fail (item != NULL); g_return_if_fail (GTK_IS_LIST_ITEM (item)); - if (GTK_WIDGET (item)->parent && GTK_IS_LIST (GTK_WIDGET (item)->parent)) - gtk_list_select_child (GTK_LIST (GTK_WIDGET (item)->parent), - GTK_WIDGET (item)); - else + switch (GTK_WIDGET (item)->state) { - /* Should we really bother with this bit? A listitem not in a list? - * -Johannes Keukelaar - * yes, always be on the save side! - * -timj - */ - if (GTK_WIDGET (item)->state == GTK_STATE_SELECTED) - gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_NORMAL); - else - gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_SELECTED); + case GTK_STATE_SELECTED: + gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_NORMAL); + break; + case GTK_STATE_INSENSITIVE: + break; + default: + gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_SELECTED); + break; } } - -static void -gtk_list_item_toggle_focus_row (GtkListItem *list_item) -{ - g_return_if_fail (list_item != 0); - g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); - - if (GTK_IS_LIST (GTK_WIDGET (list_item)->parent)) - gtk_list_toggle_focus_row (GTK_LIST (GTK_WIDGET (list_item)->parent)); -} - -static void -gtk_list_item_select_all (GtkListItem *list_item) -{ - g_return_if_fail (list_item != 0); - g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); - - if (GTK_IS_LIST (GTK_WIDGET (list_item)->parent)) - gtk_list_select_all (GTK_LIST (GTK_WIDGET (list_item)->parent)); -} - -static void -gtk_list_item_unselect_all (GtkListItem *list_item) -{ - g_return_if_fail (list_item != 0); - g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); - - if (GTK_IS_LIST (GTK_WIDGET (list_item)->parent)) - gtk_list_unselect_all (GTK_LIST (GTK_WIDGET (list_item)->parent)); -} - -static void -gtk_list_item_undo_selection (GtkListItem *list_item) -{ - g_return_if_fail (list_item != 0); - g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); - - if (GTK_IS_LIST (GTK_WIDGET (list_item)->parent)) - gtk_list_undo_selection (GTK_LIST (GTK_WIDGET (list_item)->parent)); -} - -static void -gtk_list_item_start_selection (GtkListItem *list_item) -{ - g_return_if_fail (list_item != 0); - g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); - - if (GTK_IS_LIST (GTK_WIDGET (list_item)->parent)) - gtk_list_start_selection (GTK_LIST (GTK_WIDGET (list_item)->parent)); -} - -static void -gtk_list_item_end_selection (GtkListItem *list_item) -{ - g_return_if_fail (list_item != 0); - g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); - - if (GTK_IS_LIST (GTK_WIDGET (list_item)->parent)) - gtk_list_end_selection (GTK_LIST (GTK_WIDGET (list_item)->parent)); -} - -static void -gtk_list_item_extend_selection (GtkListItem *list_item, - GtkScrollType scroll_type, - gfloat position, - gboolean auto_start_selection) -{ - g_return_if_fail (list_item != 0); - g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); - - if (GTK_IS_LIST (GTK_WIDGET (list_item)->parent)) - gtk_list_extend_selection (GTK_LIST (GTK_WIDGET (list_item)->parent), - scroll_type, position, auto_start_selection); -} - -static void -gtk_list_item_scroll_horizontal (GtkListItem *list_item, - GtkScrollType scroll_type, - gfloat position) -{ - g_return_if_fail (list_item != 0); - g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); - - if (GTK_IS_LIST (GTK_WIDGET (list_item)->parent)) - gtk_list_scroll_horizontal (GTK_LIST (GTK_WIDGET (list_item)->parent), - scroll_type, position); -} - -static void -gtk_list_item_scroll_vertical (GtkListItem *list_item, - GtkScrollType scroll_type, - gfloat position) -{ - g_return_if_fail (list_item != 0); - g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); - - if (GTK_IS_LIST (GTK_WIDGET (list_item)->parent)) - gtk_list_scroll_vertical (GTK_LIST (GTK_WIDGET (list_item)->parent), - scroll_type, position); -} - -static void -gtk_list_item_toggle_add_mode (GtkListItem *list_item) -{ - g_return_if_fail (list_item != 0); - g_return_if_fail (GTK_IS_LIST_ITEM (list_item)); - - if (GTK_IS_LIST (GTK_WIDGET (list_item)->parent)) - gtk_list_toggle_add_mode (GTK_LIST (GTK_WIDGET (list_item)->parent)); -} |