* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
*/
#include "gtklist.h"
#include "gtklistitem.h"
static GtkContainerClass *parent_class = NULL;
-static gint list_signals[LAST_SIGNAL] = { 0 };
+static guint list_signals[LAST_SIGNAL] = { 0 };
guint
sizeof (GtkListClass),
(GtkClassInitFunc) gtk_list_class_init,
(GtkObjectInitFunc) gtk_list_init,
- (GtkArgFunc) NULL,
+ (GtkArgSetFunc) NULL,
+ (GtkArgGetFunc) NULL,
};
list_type = gtk_type_unique (gtk_container_get_type (), &list_info);
return GTK_WIDGET (gtk_type_new (gtk_list_get_type ()));
}
+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_insert_items (GtkList *list,
GList *items,
gtk_list_insert_items (list, items, 0);
}
-void
-gtk_list_remove_items (GtkList *list,
- GList *items)
+static void
+gtk_list_remove_items_internal (GtkList *list,
+ GList *items,
+ gboolean no_unref)
{
GtkWidget *widget;
GList *selected_widgets;
GList *tmp_list;
-
+
g_return_if_fail (list != NULL);
g_return_if_fail (GTK_IS_LIST (list));
-
+
tmp_list = items;
selected_widgets = NULL;
widget = NULL;
-
+
while (tmp_list)
{
widget = tmp_list->data;
tmp_list = tmp_list->next;
-
+
if (widget->state == GTK_STATE_SELECTED)
selected_widgets = g_list_prepend (selected_widgets, widget);
-
+
list->children = g_list_remove (list->children, widget);
-
+
if (GTK_WIDGET_MAPPED (widget))
gtk_widget_unmap (widget);
-
+
+ if (no_unref)
+ gtk_widget_ref (widget);
gtk_widget_unparent (widget);
}
-
+
if (selected_widgets)
{
tmp_list = selected_widgets;
{
widget = tmp_list->data;
tmp_list = tmp_list->next;
-
+
gtk_list_unselect_child (list, widget);
}
-
+
gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
}
-
+
g_list_free (selected_widgets);
-
+
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_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,
GList *start_list;
GList *end_list;
GList *tmp_list;
- gint nchildren;
- gint selection_changed;
+ guint nchildren;
+ gboolean selection_changed;
g_return_if_fail (list != NULL);
g_return_if_fail (GTK_IS_LIST (list));
if ((end < 0) || (end > nchildren))
end = nchildren;
- g_return_if_fail (start < end);
+ if (start >= end)
+ return;
start_list = g_list_nth (list->children, start);
end_list = g_list_nth (list->children, end);
if (start_list->prev)
- start_list->prev->next = end_list;
+ start_list->prev->next = end_list;
if (end_list && end_list->prev)
end_list->prev->next = NULL;
if (end_list)
{
selection_changed = TRUE;
list->selection = g_list_remove (list->selection, widget);
+ gtk_widget_unref (widget);
}
- /* list->children = g_list_remove (list->children, widget); */
- /* gtk_widget_unparent (widget); */
-
- gtk_widget_destroy (widget);
+ gtk_widget_unparent (widget);
}
+ g_list_free (start_list);
+
if (list->children && !list->selection &&
(list->selection_mode == GTK_SELECTION_BROWSE))
{
- gtk_list_select_child (list, widget);
widget = list->children->data;
+ gtk_list_select_child (list, widget);
}
if (selection_changed)
}
-static void
-gtk_list_destroy (GtkObject *object)
-{
- GtkList *list;
- GtkWidget *child;
- GList *children;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (GTK_IS_LIST (object));
-
- list = GTK_LIST (object);
-
- children = list->children;
- while (children)
- {
- child = children->data;
- children = children->next;
-
- child->parent = NULL;
- gtk_object_unref (GTK_OBJECT (child));
- gtk_widget_destroy (child);
- }
-
- g_list_free (list->children);
- g_list_free (list->selection);
-
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
static void
gtk_list_map (GtkWidget *widget)
{
attributes.wclass = GDK_INPUT_OUTPUT;
attributes.visual = gtk_widget_get_visual (widget);
attributes.colormap = gtk_widget_get_colormap (widget);
- attributes.event_mask = GDK_EXPOSURE_MASK;
+ attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
- widget->window = gdk_window_new (widget->parent->window, &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);
- gdk_window_set_background (widget->window, &widget->style->white);
+ gdk_window_set_background (widget->window,
+ &widget->style->base[GTK_STATE_NORMAL]);
}
static void
g_return_val_if_fail (GTK_IS_LIST (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
- g_print ("gtk_list_motion_notify\n");
+ /* g_print ("gtk_list_motion_notify\n"); */
return FALSE;
}
list = GTK_LIST (widget);
item = gtk_get_event_widget ((GdkEvent*) event);
-
- while (!gtk_type_is_a (GTK_WIDGET_TYPE (item), gtk_list_item_get_type ()))
+
+ while (item && !GTK_IS_LIST_ITEM (item))
item = item->parent;
+ if (!item || (item->parent != widget))
+ return FALSE;
+
gtk_list_select_child (list, item);
return FALSE;
{
child_allocation.x = GTK_CONTAINER (list)->border_width;
child_allocation.y = GTK_CONTAINER (list)->border_width;
- child_allocation.width = allocation->width - child_allocation.x * 2;
+ child_allocation.width = MAX (1, allocation->width - child_allocation.x * 2);
children = list->children;
g_return_if_fail (container != NULL);
g_return_if_fail (GTK_IS_LIST (container));
g_return_if_fail (widget != NULL);
+ g_return_if_fail (GTK_IS_LIST_ITEM (widget));
list = GTK_LIST (container);
list->children = g_list_append (list->children, widget);
if (!list->selection && (list->selection_mode == GTK_SELECTION_BROWSE))
- {
- gtk_list_select_child (list, widget);
- }
+ gtk_list_select_child (list, widget);
if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
gtk_widget_queue_resize (widget);
if (tmp_item != child)
{
gtk_list_item_deselect (GTK_LIST_ITEM (tmp_item));
-
+
tmp_list = selection;
selection = selection->next;
list->selection = g_list_remove_link (list->selection, tmp_list);
+ gtk_widget_unref (GTK_WIDGET (tmp_item));
g_list_free (tmp_list);
}
{
gtk_list_item_select (GTK_LIST_ITEM (child));
list->selection = g_list_prepend (list->selection, child);
+ gtk_widget_ref (child);
}
else if (child->state == GTK_STATE_SELECTED)
{
gtk_list_item_deselect (GTK_LIST_ITEM (child));
list->selection = g_list_remove (list->selection, child);
+ gtk_widget_unref (child);
}
gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
if (tmp_item != child)
{
gtk_list_item_deselect (GTK_LIST_ITEM (tmp_item));
-
+
tmp_list = selection;
selection = selection->next;
list->selection = g_list_remove_link (list->selection, tmp_list);
+ gtk_widget_unref (GTK_WIDGET (tmp_item));
g_list_free (tmp_list);
}
{
gtk_list_item_select (GTK_LIST_ITEM (child));
list->selection = g_list_prepend (list->selection, child);
+ gtk_widget_ref (child);
gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
}
break;
{
gtk_list_item_select (GTK_LIST_ITEM (child));
list->selection = g_list_prepend (list->selection, child);
+ gtk_widget_ref (child);
gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
}
else if (child->state == GTK_STATE_SELECTED)
{
gtk_list_item_deselect (GTK_LIST_ITEM (child));
list->selection = g_list_remove (list->selection, child);
+ gtk_widget_unref (child);
gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
}
break;
{
gtk_list_item_deselect (GTK_LIST_ITEM (child));
list->selection = g_list_remove (list->selection, child);
+ gtk_widget_unref (child);
gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
}
break;