1997-11-24 22:37:52 +00:00
|
|
|
/* GTK - The GIMP Toolkit
|
|
|
|
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Library General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
#include "gtklist.h"
|
|
|
|
#include "gtklistitem.h"
|
|
|
|
#include "gtkmain.h"
|
|
|
|
#include "gtksignal.h"
|
|
|
|
|
|
|
|
|
|
|
|
enum {
|
|
|
|
SELECTION_CHANGED,
|
|
|
|
SELECT_CHILD,
|
|
|
|
UNSELECT_CHILD,
|
|
|
|
LAST_SIGNAL
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
typedef void (*GtkListSignal) (GtkObject *object,
|
|
|
|
gpointer arg1,
|
|
|
|
gpointer data);
|
|
|
|
|
|
|
|
|
|
|
|
static void gtk_list_class_init (GtkListClass *klass);
|
|
|
|
static void gtk_list_init (GtkList *list);
|
|
|
|
static void gtk_list_destroy (GtkObject *object);
|
|
|
|
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,
|
|
|
|
GdkEventExpose *event);
|
|
|
|
static gint gtk_list_motion_notify (GtkWidget *widget,
|
|
|
|
GdkEventMotion *event);
|
|
|
|
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_foreach (GtkContainer *container,
|
|
|
|
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_marshal_signal (GtkObject *object,
|
|
|
|
GtkSignalFunc func,
|
|
|
|
gpointer func_data,
|
|
|
|
GtkArg *args);
|
|
|
|
|
|
|
|
|
|
|
|
static GtkContainerClass *parent_class = NULL;
|
|
|
|
static gint list_signals[LAST_SIGNAL] = { 0 };
|
|
|
|
|
|
|
|
|
|
|
|
guint
|
|
|
|
gtk_list_get_type ()
|
|
|
|
{
|
|
|
|
static guint list_type = 0;
|
|
|
|
|
|
|
|
if (!list_type)
|
|
|
|
{
|
|
|
|
GtkTypeInfo list_info =
|
|
|
|
{
|
|
|
|
"GtkList",
|
|
|
|
sizeof (GtkList),
|
|
|
|
sizeof (GtkListClass),
|
|
|
|
(GtkClassInitFunc) gtk_list_class_init,
|
|
|
|
(GtkObjectInitFunc) gtk_list_init,
|
1998-01-16 00:49:51 +00:00
|
|
|
(GtkArgSetFunc) NULL,
|
|
|
|
(GtkArgGetFunc) NULL,
|
1997-11-24 22:37:52 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
list_type = gtk_type_unique (gtk_container_get_type (), &list_info);
|
|
|
|
}
|
|
|
|
|
|
|
|
return list_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_list_class_init (GtkListClass *class)
|
|
|
|
{
|
|
|
|
GtkObjectClass *object_class;
|
|
|
|
GtkWidgetClass *widget_class;
|
|
|
|
GtkContainerClass *container_class;
|
|
|
|
|
|
|
|
object_class = (GtkObjectClass*) class;
|
|
|
|
widget_class = (GtkWidgetClass*) class;
|
|
|
|
container_class = (GtkContainerClass*) class;
|
|
|
|
|
|
|
|
parent_class = gtk_type_class (gtk_container_get_type ());
|
|
|
|
|
|
|
|
list_signals[SELECTION_CHANGED] =
|
|
|
|
gtk_signal_new ("selection_changed",
|
|
|
|
GTK_RUN_FIRST,
|
|
|
|
object_class->type,
|
|
|
|
GTK_SIGNAL_OFFSET (GtkListClass, selection_changed),
|
|
|
|
gtk_signal_default_marshaller,
|
|
|
|
GTK_TYPE_NONE, 0);
|
|
|
|
list_signals[SELECT_CHILD] =
|
|
|
|
gtk_signal_new ("select_child",
|
|
|
|
GTK_RUN_FIRST,
|
|
|
|
object_class->type,
|
|
|
|
GTK_SIGNAL_OFFSET (GtkListClass, select_child),
|
|
|
|
gtk_list_marshal_signal,
|
|
|
|
GTK_TYPE_NONE, 1,
|
|
|
|
GTK_TYPE_WIDGET);
|
|
|
|
list_signals[UNSELECT_CHILD] =
|
|
|
|
gtk_signal_new ("unselect_child",
|
|
|
|
GTK_RUN_FIRST,
|
|
|
|
object_class->type,
|
|
|
|
GTK_SIGNAL_OFFSET (GtkListClass, unselect_child),
|
|
|
|
gtk_list_marshal_signal,
|
|
|
|
GTK_TYPE_NONE, 1,
|
|
|
|
GTK_TYPE_WIDGET);
|
|
|
|
|
|
|
|
gtk_object_class_add_signals (object_class, list_signals, LAST_SIGNAL);
|
|
|
|
|
|
|
|
object_class->destroy = gtk_list_destroy;
|
|
|
|
|
|
|
|
widget_class->map = gtk_list_map;
|
|
|
|
widget_class->unmap = gtk_list_unmap;
|
|
|
|
widget_class->realize = gtk_list_realize;
|
|
|
|
widget_class->draw = gtk_list_draw;
|
|
|
|
widget_class->expose_event = gtk_list_expose;
|
|
|
|
widget_class->motion_notify_event = gtk_list_motion_notify;
|
|
|
|
widget_class->button_press_event = gtk_list_button_press;
|
|
|
|
widget_class->button_release_event = gtk_list_button_release;
|
|
|
|
widget_class->size_request = gtk_list_size_request;
|
|
|
|
widget_class->size_allocate = gtk_list_size_allocate;
|
|
|
|
|
|
|
|
container_class->add = gtk_list_add;
|
|
|
|
container_class->remove = gtk_list_remove;
|
|
|
|
container_class->foreach = gtk_list_foreach;
|
|
|
|
|
|
|
|
class->selection_changed = NULL;
|
|
|
|
class->select_child = gtk_real_list_select_child;
|
|
|
|
class->unselect_child = gtk_real_list_unselect_child;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_list_init (GtkList *list)
|
|
|
|
{
|
|
|
|
list->children = NULL;
|
|
|
|
list->selection = NULL;
|
|
|
|
list->timer = 0;
|
|
|
|
list->selection_start_pos = 0;
|
|
|
|
list->selection_end_pos = 0;
|
|
|
|
list->selection_mode = GTK_SELECTION_SINGLE;
|
|
|
|
list->scroll_direction = 0;
|
|
|
|
list->have_grab = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
GtkWidget*
|
|
|
|
gtk_list_new ()
|
|
|
|
{
|
|
|
|
return GTK_WIDGET (gtk_type_new (gtk_list_get_type ()));
|
|
|
|
}
|
|
|
|
|
1998-01-30 23:47:09 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
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;
|
|
|
|
|
|
|
|
tmp_list = items;
|
|
|
|
while (tmp_list)
|
|
|
|
{
|
|
|
|
widget = tmp_list->data;
|
|
|
|
tmp_list = tmp_list->next;
|
|
|
|
|
|
|
|
gtk_widget_set_parent (widget, GTK_WIDGET (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);
|
|
|
|
}
|
|
|
|
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
static void
|
|
|
|
gtk_list_remove_items_internal (GtkList *list,
|
|
|
|
GList *items,
|
|
|
|
gboolean no_unref)
|
1997-11-24 22:37:52 +00:00
|
|
|
{
|
|
|
|
GtkWidget *widget;
|
|
|
|
GList *selected_widgets;
|
|
|
|
GList *tmp_list;
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
g_return_if_fail (list != NULL);
|
|
|
|
g_return_if_fail (GTK_IS_LIST (list));
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
tmp_list = items;
|
|
|
|
selected_widgets = NULL;
|
|
|
|
widget = NULL;
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
while (tmp_list)
|
|
|
|
{
|
|
|
|
widget = tmp_list->data;
|
|
|
|
tmp_list = tmp_list->next;
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
if (widget->state == GTK_STATE_SELECTED)
|
|
|
|
selected_widgets = g_list_prepend (selected_widgets, widget);
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
list->children = g_list_remove (list->children, widget);
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
if (GTK_WIDGET_MAPPED (widget))
|
|
|
|
gtk_widget_unmap (widget);
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
|
|
|
|
if (no_unref)
|
|
|
|
gtk_widget_ref (widget);
|
1997-11-24 22:37:52 +00:00
|
|
|
gtk_widget_unparent (widget);
|
|
|
|
}
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
if (selected_widgets)
|
|
|
|
{
|
|
|
|
tmp_list = selected_widgets;
|
|
|
|
while (tmp_list)
|
|
|
|
{
|
|
|
|
widget = tmp_list->data;
|
|
|
|
tmp_list = tmp_list->next;
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
gtk_list_unselect_child (list, widget);
|
|
|
|
}
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
|
|
|
|
}
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
g_list_free (selected_widgets);
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
if (list->children && !list->selection &&
|
|
|
|
(list->selection_mode == GTK_SELECTION_BROWSE))
|
|
|
|
{
|
|
|
|
widget = list->children->data;
|
|
|
|
gtk_list_select_child (list, widget);
|
|
|
|
}
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
if (GTK_WIDGET_VISIBLE (list))
|
|
|
|
gtk_widget_queue_resize (GTK_WIDGET (list));
|
|
|
|
}
|
|
|
|
|
new function to perform the same actions as gtk_list_remove_items, but
Thu Feb 5 02:13:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtklist.h:
* gtk/gtklist.c (gtk_list_remove_items_no_unref): new function
to perform the same actions as gtk_list_remove_items, but
supply the removed widgets with an additional reference count.
* gtk/gtkmain.c (gtk_main_iteration_do): ignore events
with event_widget == NULL, since they are bogus events
from destroyed GdkWindows, exept for the case where
event->type==GDK_PROPERTY_NOTIFY. Always handle expired
timeout functions when returning from this function.
* gtk/gtkwidget.c (gtk_widget_event): ignore GDK_EXPOSE events
if event->window == NULL. Also, if this function couldn't handle
the event for any reason (including failing assumptions), make
the return value to look as if the event had been handled to
avoid further processing (and warnings).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c: remove gtk_widget_sink, because there is
no point in providing such a function.
* gdk/gdk.c (gdk_init): changed options `-name' and `-class'
to `--name' and `--class', because the old names would
confuse getopt(). these arguments have been introduced in the
changes from gtk+970916 to gtk+970925 without a ChangeLog entry,
changing argument names is painful, it would be nice if people
would care about compatibility and consistency in the first place!
1998-02-05 03:53:41 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
void
|
|
|
|
gtk_list_clear_items (GtkList *list,
|
|
|
|
gint start,
|
|
|
|
gint end)
|
|
|
|
{
|
|
|
|
GtkWidget *widget;
|
|
|
|
GList *start_list;
|
|
|
|
GList *end_list;
|
|
|
|
GList *tmp_list;
|
|
|
|
gint nchildren;
|
|
|
|
gint selection_changed;
|
|
|
|
|
|
|
|
g_return_if_fail (list != NULL);
|
|
|
|
g_return_if_fail (GTK_IS_LIST (list));
|
|
|
|
|
|
|
|
nchildren = g_list_length (list->children);
|
|
|
|
|
|
|
|
if (nchildren > 0)
|
|
|
|
{
|
|
|
|
if ((end < 0) || (end > nchildren))
|
|
|
|
end = nchildren;
|
|
|
|
|
1998-02-28 20:19:20 +00:00
|
|
|
if (start >= end)
|
|
|
|
return;
|
1997-11-24 22:37:52 +00:00
|
|
|
|
|
|
|
start_list = g_list_nth (list->children, start);
|
|
|
|
end_list = g_list_nth (list->children, end);
|
|
|
|
|
|
|
|
if (start_list->prev)
|
1998-02-28 20:19:20 +00:00
|
|
|
start_list->prev->next = end_list;
|
1997-11-24 22:37:52 +00:00
|
|
|
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)
|
|
|
|
{
|
|
|
|
selection_changed = TRUE;
|
|
|
|
list->selection = g_list_remove (list->selection, widget);
|
1998-01-30 23:47:09 +00:00
|
|
|
gtk_widget_unref (widget);
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
|
|
|
|
1998-01-30 23:47:09 +00:00
|
|
|
gtk_widget_unparent (widget);
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
|
|
|
|
1998-02-28 20:19:20 +00:00
|
|
|
g_list_free (start_list);
|
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
if (list->children && !list->selection &&
|
|
|
|
(list->selection_mode == GTK_SELECTION_BROWSE))
|
|
|
|
{
|
|
|
|
widget = list->children->data;
|
1998-02-28 20:19:20 +00:00
|
|
|
gtk_list_select_child (list, widget);
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gtk_list_set_selection_mode (GtkList *list,
|
|
|
|
GtkSelectionMode mode)
|
|
|
|
{
|
|
|
|
g_return_if_fail (list != NULL);
|
|
|
|
g_return_if_fail (GTK_IS_LIST (list));
|
|
|
|
|
|
|
|
list->selection_mode = mode;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_list_map (GtkWidget *widget)
|
|
|
|
{
|
|
|
|
GtkList *list;
|
|
|
|
GtkWidget *child;
|
|
|
|
GList *children;
|
|
|
|
|
|
|
|
g_return_if_fail (widget != NULL);
|
|
|
|
g_return_if_fail (GTK_IS_LIST (widget));
|
|
|
|
|
|
|
|
GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
|
|
|
|
list = GTK_LIST (widget);
|
|
|
|
|
|
|
|
gdk_window_show (widget->window);
|
|
|
|
|
|
|
|
children = list->children;
|
|
|
|
while (children)
|
|
|
|
{
|
|
|
|
child = children->data;
|
|
|
|
children = children->next;
|
|
|
|
|
|
|
|
if (GTK_WIDGET_VISIBLE (child) &&
|
|
|
|
!GTK_WIDGET_MAPPED (child))
|
|
|
|
gtk_widget_map (child);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_list_unmap (GtkWidget *widget)
|
|
|
|
{
|
|
|
|
g_return_if_fail (widget != NULL);
|
|
|
|
g_return_if_fail (GTK_IS_LIST (widget));
|
|
|
|
|
|
|
|
GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
|
|
|
|
gdk_window_hide (widget->window);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_list_realize (GtkWidget *widget)
|
|
|
|
{
|
|
|
|
GdkWindowAttr attributes;
|
|
|
|
gint attributes_mask;
|
|
|
|
|
|
|
|
g_return_if_fail (widget != NULL);
|
|
|
|
g_return_if_fail (GTK_IS_LIST (widget));
|
|
|
|
|
|
|
|
GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
|
|
|
|
|
|
|
|
attributes.window_type = GDK_WINDOW_CHILD;
|
|
|
|
attributes.x = widget->allocation.x;
|
|
|
|
attributes.y = widget->allocation.y;
|
|
|
|
attributes.width = widget->allocation.width;
|
|
|
|
attributes.height = widget->allocation.height;
|
|
|
|
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_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
|
|
|
|
|
1998-01-18 15:09:10 +00:00
|
|
|
widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
|
1997-11-24 22:37:52 +00:00
|
|
|
gdk_window_set_user_data (widget->window, widget);
|
|
|
|
|
|
|
|
widget->style = gtk_style_attach (widget->style, widget->window);
|
1998-02-13 05:26:33 +00:00
|
|
|
gdk_window_set_background (widget->window,
|
|
|
|
&widget->style->base[GTK_STATE_NORMAL]);
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
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 (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;
|
|
|
|
|
|
|
|
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 (GTK_WIDGET_DRAWABLE (widget))
|
|
|
|
{
|
|
|
|
list = GTK_LIST (widget);
|
|
|
|
|
|
|
|
child_event = *event;
|
|
|
|
|
|
|
|
children = list->children;
|
|
|
|
while (children)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
gtk_list_motion_notify (GtkWidget *widget,
|
|
|
|
GdkEventMotion *event)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
|
|
|
|
g_print ("gtk_list_motion_notify\n");
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
gtk_list_button_press (GtkWidget *widget,
|
|
|
|
GdkEventButton *event)
|
|
|
|
{
|
|
|
|
GtkList *list;
|
|
|
|
GtkWidget *item;
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
list = GTK_LIST (widget);
|
|
|
|
item = gtk_get_event_widget ((GdkEvent*) event);
|
1998-01-30 23:47:09 +00:00
|
|
|
|
|
|
|
if (!item)
|
|
|
|
return FALSE;
|
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
while (!gtk_type_is_a (GTK_WIDGET_TYPE (item), gtk_list_item_get_type ()))
|
|
|
|
item = item->parent;
|
|
|
|
|
|
|
|
gtk_list_select_child (list, item);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
gtk_list_button_release (GtkWidget *widget,
|
|
|
|
GdkEventButton *event)
|
|
|
|
{
|
|
|
|
GtkList *list;
|
|
|
|
GtkWidget *item;
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
list = GTK_LIST (widget);
|
|
|
|
item = gtk_get_event_widget ((GdkEvent*) event);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_list_size_request (GtkWidget *widget,
|
|
|
|
GtkRequisition *requisition)
|
|
|
|
{
|
|
|
|
GtkList *list;
|
|
|
|
GtkWidget *child;
|
|
|
|
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;
|
|
|
|
|
|
|
|
children = list->children;
|
|
|
|
while (children)
|
|
|
|
{
|
|
|
|
child = children->data;
|
|
|
|
children = children->next;
|
|
|
|
|
|
|
|
if (GTK_WIDGET_VISIBLE (child))
|
|
|
|
{
|
|
|
|
gtk_widget_size_request (child, &child->requisition);
|
|
|
|
|
|
|
|
requisition->width = MAX (requisition->width, child->requisition.width);
|
|
|
|
requisition->height += child->requisition.height;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
if (list->children)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_list_add (GtkContainer *container,
|
|
|
|
GtkWidget *widget)
|
|
|
|
{
|
|
|
|
GtkList *list;
|
|
|
|
|
|
|
|
g_return_if_fail (container != NULL);
|
|
|
|
g_return_if_fail (GTK_IS_LIST (container));
|
|
|
|
g_return_if_fail (widget != NULL);
|
|
|
|
|
|
|
|
list = GTK_LIST (container);
|
|
|
|
|
|
|
|
gtk_widget_set_parent (widget, GTK_WIDGET (container));
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
list->children = g_list_append (list->children, widget);
|
|
|
|
|
|
|
|
if (!list->selection && (list->selection_mode == GTK_SELECTION_BROWSE))
|
1998-01-30 23:47:09 +00:00
|
|
|
gtk_list_select_child (list, widget);
|
1997-11-24 22:37:52 +00:00
|
|
|
|
|
|
|
if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
|
|
|
|
gtk_widget_queue_resize (widget);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_list_remove (GtkContainer *container,
|
|
|
|
GtkWidget *widget)
|
|
|
|
{
|
|
|
|
GList *item_list;
|
|
|
|
|
|
|
|
g_return_if_fail (container != NULL);
|
|
|
|
g_return_if_fail (GTK_IS_LIST (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;
|
|
|
|
|
|
|
|
gtk_list_remove_items (GTK_LIST (container), item_list);
|
|
|
|
|
|
|
|
g_list_free (item_list);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_list_foreach (GtkContainer *container,
|
|
|
|
GtkCallback callback,
|
|
|
|
gpointer callback_data)
|
|
|
|
{
|
|
|
|
GtkList *list;
|
|
|
|
GtkWidget *child;
|
|
|
|
GList *children;
|
|
|
|
|
|
|
|
g_return_if_fail (container != NULL);
|
|
|
|
g_return_if_fail (GTK_IS_LIST (container));
|
|
|
|
g_return_if_fail (callback != NULL);
|
|
|
|
|
|
|
|
list = GTK_LIST (container);
|
|
|
|
children = list->children;
|
|
|
|
|
|
|
|
while (children)
|
|
|
|
{
|
|
|
|
child = children->data;
|
|
|
|
children = children->next;
|
|
|
|
|
|
|
|
(* callback) (child, callback_data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_real_list_select_child (GtkList *list,
|
|
|
|
GtkWidget *child)
|
|
|
|
{
|
|
|
|
GList *selection;
|
|
|
|
GList *tmp_list;
|
|
|
|
GtkWidget *tmp_item;
|
|
|
|
|
|
|
|
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));
|
|
|
|
|
|
|
|
switch (list->selection_mode)
|
|
|
|
{
|
|
|
|
case GTK_SELECTION_SINGLE:
|
|
|
|
selection = list->selection;
|
|
|
|
|
|
|
|
while (selection)
|
|
|
|
{
|
|
|
|
tmp_item = selection->data;
|
|
|
|
|
|
|
|
if (tmp_item != child)
|
|
|
|
{
|
|
|
|
gtk_list_item_deselect (GTK_LIST_ITEM (tmp_item));
|
1998-01-30 23:47:09 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
tmp_list = selection;
|
|
|
|
selection = selection->next;
|
|
|
|
|
|
|
|
list->selection = g_list_remove_link (list->selection, tmp_list);
|
1998-01-30 23:47:09 +00:00
|
|
|
gtk_widget_unref (GTK_WIDGET (tmp_item));
|
1997-11-24 22:37:52 +00:00
|
|
|
|
|
|
|
g_list_free (tmp_list);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
selection = selection->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (child->state == GTK_STATE_NORMAL)
|
|
|
|
{
|
|
|
|
gtk_list_item_select (GTK_LIST_ITEM (child));
|
|
|
|
list->selection = g_list_prepend (list->selection, child);
|
1998-01-30 23:47:09 +00:00
|
|
|
gtk_widget_ref (child);
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
|
|
|
else if (child->state == GTK_STATE_SELECTED)
|
|
|
|
{
|
|
|
|
gtk_list_item_deselect (GTK_LIST_ITEM (child));
|
|
|
|
list->selection = g_list_remove (list->selection, child);
|
1998-01-30 23:47:09 +00:00
|
|
|
gtk_widget_unref (child);
|
1997-11-24 22:37:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GTK_SELECTION_BROWSE:
|
|
|
|
selection = list->selection;
|
|
|
|
|
|
|
|
while (selection)
|
|
|
|
{
|
|
|
|
tmp_item = selection->data;
|
|
|
|
|
|
|
|
if (tmp_item != child)
|
|
|
|
{
|
|
|
|
gtk_list_item_deselect (GTK_LIST_ITEM (tmp_item));
|
1998-01-30 23:47:09 +00:00
|
|
|
|
1997-11-24 22:37:52 +00:00
|
|
|
tmp_list = selection;
|
|
|
|
selection = selection->next;
|
|
|
|
|
|
|
|
list->selection = g_list_remove_link (list->selection, tmp_list);
|
1998-01-30 23:47:09 +00:00
|
|
|
gtk_widget_unref (GTK_WIDGET (tmp_item));
|
1997-11-24 22:37:52 +00:00
|
|
|
|
|
|
|
g_list_free (tmp_list);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
selection = selection->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (child->state == GTK_STATE_NORMAL)
|
|
|
|
{
|
|
|
|
gtk_list_item_select (GTK_LIST_ITEM (child));
|
|
|
|
list->selection = g_list_prepend (list->selection, child);
|
1998-01-30 23:47:09 +00:00
|
|
|
gtk_widget_ref (child);
|
1997-11-24 22:37:52 +00:00
|
|
|
gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GTK_SELECTION_MULTIPLE:
|
|
|
|
if (child->state == GTK_STATE_NORMAL)
|
|
|
|
{
|
|
|
|
gtk_list_item_select (GTK_LIST_ITEM (child));
|
|
|
|
list->selection = g_list_prepend (list->selection, child);
|
1998-01-30 23:47:09 +00:00
|
|
|
gtk_widget_ref (child);
|
1997-11-24 22:37:52 +00:00
|
|
|
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);
|
1998-01-30 23:47:09 +00:00
|
|
|
gtk_widget_unref (child);
|
1997-11-24 22:37:52 +00:00
|
|
|
gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GTK_SELECTION_EXTENDED:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_real_list_unselect_child (GtkList *list,
|
|
|
|
GtkWidget *child)
|
|
|
|
{
|
|
|
|
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));
|
|
|
|
|
|
|
|
switch (list->selection_mode)
|
|
|
|
{
|
|
|
|
case GTK_SELECTION_SINGLE:
|
|
|
|
case GTK_SELECTION_MULTIPLE:
|
|
|
|
case GTK_SELECTION_BROWSE:
|
|
|
|
if (child->state == GTK_STATE_SELECTED)
|
|
|
|
{
|
|
|
|
gtk_list_item_deselect (GTK_LIST_ITEM (child));
|
|
|
|
list->selection = g_list_remove (list->selection, child);
|
1998-01-30 23:47:09 +00:00
|
|
|
gtk_widget_unref (child);
|
1997-11-24 22:37:52 +00:00
|
|
|
gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GTK_SELECTION_EXTENDED:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_list_marshal_signal (GtkObject *object,
|
|
|
|
GtkSignalFunc func,
|
|
|
|
gpointer func_data,
|
|
|
|
GtkArg *args)
|
|
|
|
{
|
|
|
|
GtkListSignal rfunc;
|
|
|
|
|
|
|
|
rfunc = (GtkListSignal) func;
|
|
|
|
|
|
|
|
(* rfunc) (object, GTK_VALUE_OBJECT (args[0]), func_data);
|
|
|
|
}
|