[dia] layer-editor: bring minimal gtklist in-tree
- From: Zander <zbrown src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] layer-editor: bring minimal gtklist in-tree
- Date: Thu, 23 Apr 2020 11:45:12 +0000 (UTC)
commit 25fc84df597036cbe47c33ac11f105cc1d14089a
Author: Zander Brown <zbrown gnome org>
Date: Sun Apr 5 01:07:13 2020 +0100
layer-editor: bring minimal gtklist in-tree
DiaList is GtkList stripped of alternative selection modes, horizontal
scrolling and drag-n-drop
DiaListItem is a combination of GtkListItem and GtkItem supporting only
the basic selection case
This allows us to stop using GtkList, the latest gtk2 deprecation
warning
app/dia-change.c | 2 +-
app/dia-list-item.c | 301 ++++++++++
app/dia-list-item.h | 50 ++
app/dia-list.c | 1097 +++++++++++++++++++++++++++++++++++
app/dia-list.h | 75 +++
app/layer-editor/dia-layer-widget.c | 107 ++--
app/layer-editor/dia-layer-widget.h | 9 +-
app/meson.build | 6 +
meson.build | 1 +
9 files changed, 1589 insertions(+), 59 deletions(-)
---
diff --git a/app/dia-change.c b/app/dia-change.c
index b48689f1..3b523204 100644
--- a/app/dia-change.c
+++ b/app/dia-change.c
@@ -38,7 +38,7 @@ static void
dia_change_real_revert (DiaChange *self,
Diagram *diagram)
{
- g_critical ("%s doesn't implement revert", DIA_CHANGE_TYPE_NAME (self));
+ g_critical ("%s doesn't implement revert", DIA_CHANGE_TYPE_NAME (self));
}
diff --git a/app/dia-list-item.c b/app/dia-list-item.c
new file mode 100644
index 00000000..8719708d
--- /dev/null
+++ b/app/dia-list-item.c
@@ -0,0 +1,301 @@
+/* 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 Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "dia-list-item.h"
+
+
+G_DEFINE_TYPE (DiaListItem, dia_list_item, GTK_TYPE_BIN)
+
+
+enum {
+ SCROLL_VERTICAL,
+ SCROLL_HORIZONTAL,
+ LAST_SIGNAL
+};
+static guint list_item_signals[LAST_SIGNAL] = {0};
+
+
+static void
+dia_list_item_realize (GtkWidget *widget)
+{
+ GdkWindowAttr attributes;
+ gint attributes_mask;
+ GtkAllocation alloc;
+ GdkWindow *window;
+ GtkStyle *style;
+
+ /*GTK_WIDGET_CLASS (parent_class)->realize (widget);*/
+
+ g_return_if_fail (DIA_IS_LIST_ITEM (widget));
+
+ gtk_widget_set_realized (widget, TRUE);
+
+ gtk_widget_get_allocation (widget, &alloc);
+
+ attributes.x = alloc.x;
+ attributes.y = alloc.y;
+ attributes.width = alloc.width;
+ attributes.height = alloc.height;
+ attributes.window_type = GDK_WINDOW_CHILD;
+ attributes.wclass = GDK_INPUT_OUTPUT;
+ attributes.visual = gtk_widget_get_visual (widget);
+ attributes.colormap = gtk_widget_get_colormap (widget);
+ attributes.event_mask = (gtk_widget_get_events (widget) |
+ GDK_EXPOSURE_MASK |
+ GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_KEY_PRESS_MASK |
+ GDK_KEY_RELEASE_MASK);
+
+ attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+ window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
+ gtk_widget_set_window (widget, window);
+ gdk_window_set_user_data (window, widget);
+
+ gtk_widget_style_attach (widget);
+
+ style = gtk_widget_get_style (widget);
+ gdk_window_set_background (window, &style->base[GTK_STATE_NORMAL]);
+}
+
+
+static void
+dia_list_item_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ GtkBin *bin;
+ GtkWidget *child;
+ GtkRequisition child_requisition;
+ GtkStyle *style;
+ gint focus_width;
+ gint focus_pad;
+ int border_width;
+
+ g_return_if_fail (DIA_IS_LIST_ITEM (widget));
+ g_return_if_fail (requisition != NULL);
+
+ bin = GTK_BIN (widget);
+ gtk_widget_style_get (widget,
+ "focus-line-width", &focus_width,
+ "focus-padding", &focus_pad,
+ NULL);
+
+ style = gtk_widget_get_style (widget);
+ border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
+
+ requisition->width = 2 * (border_width + style->xthickness + focus_width + focus_pad - 1);
+ requisition->height = 2 * (border_width + focus_width + focus_pad - 1);
+
+ child = gtk_bin_get_child (bin);
+
+ if (child && gtk_widget_get_visible (child)) {
+ gtk_widget_size_request (child, &child_requisition);
+
+ requisition->width += child_requisition.width;
+ requisition->height += child_requisition.height;
+ }
+}
+
+
+static void
+dia_list_item_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ GtkBin *bin;
+ GtkStyle *style;
+ int border_width;
+ GtkAllocation child_allocation;
+
+ g_return_if_fail (DIA_IS_LIST_ITEM (widget));
+ g_return_if_fail (allocation != NULL);
+
+
+ gtk_widget_set_allocation (widget, allocation);
+
+ style = gtk_widget_get_style (widget);
+ border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
+
+ if (gtk_widget_get_realized (widget)) {
+ gdk_window_move_resize (gtk_widget_get_window (widget),
+ allocation->x, allocation->y,
+ allocation->width, allocation->height);
+ }
+
+ bin = GTK_BIN (widget);
+
+ if (gtk_bin_get_child (bin)) {
+ child_allocation.x = (border_width + style->xthickness);
+ child_allocation.y = border_width;
+ child_allocation.width = allocation->width - child_allocation.x * 2;
+ child_allocation.height = allocation->height - child_allocation.y * 2;
+
+ gtk_widget_size_allocate (gtk_bin_get_child (bin), &child_allocation);
+ }
+}
+
+
+static void
+dia_list_item_style_set (GtkWidget *widget,
+ GtkStyle *previous_style)
+{
+ GtkStyle *style;
+
+ g_return_if_fail (widget != NULL);
+
+ if (previous_style && gtk_widget_get_realized (widget)) {
+ style = gtk_widget_get_style (widget);
+ gdk_window_set_background (gtk_widget_get_window (widget),
+ &style->base[gtk_widget_get_state (widget)]);
+ }
+}
+
+
+static gint
+dia_list_item_expose (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ GtkAllocation alloc;
+ GdkWindow *window;
+ GtkStyle *style;
+
+ g_return_val_if_fail (widget != NULL, FALSE);
+
+ if (gtk_widget_is_drawable (widget)) {
+ window = gtk_widget_get_window (widget);
+ style = gtk_widget_get_style (widget);
+
+ if (gtk_widget_get_state (GTK_WIDGET (widget)) == GTK_STATE_NORMAL) {
+ gdk_window_set_back_pixmap (window, NULL, TRUE);
+ gdk_window_clear_area (window, event->area.x, event->area.y,
+ event->area.width, event->area.height);
+ } else {
+ gtk_paint_flat_box (style, window,
+ gtk_widget_get_state (GTK_WIDGET (widget)), GTK_SHADOW_ETCHED_OUT,
+ &event->area, widget, "listitem",
+ 0, 0, -1, -1);
+ }
+
+ GTK_WIDGET_CLASS (dia_list_item_parent_class)->expose_event (widget, event);
+
+ gtk_widget_get_allocation (widget, &alloc);
+
+ if (gtk_widget_has_focus (widget)) {
+ gtk_paint_focus (style, window, gtk_widget_get_state (widget),
+ NULL, widget, NULL,
+ 0, 0, alloc.width, alloc.height);
+ }
+ }
+
+ return FALSE;
+}
+
+
+static void
+dia_list_item_class_init (DiaListItemClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ GtkBindingSet *binding_set;
+
+ widget_class->realize = dia_list_item_realize;
+ widget_class->size_request = dia_list_item_size_request;
+ widget_class->size_allocate = dia_list_item_size_allocate;
+ widget_class->style_set = dia_list_item_style_set;
+ widget_class->expose_event = dia_list_item_expose;
+
+ klass->scroll_vertical = NULL;
+
+ list_item_signals[SCROLL_VERTICAL] =
+ g_signal_new ("scroll-vertical",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (DiaListItemClass, scroll_vertical),
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 2, GTK_TYPE_SCROLL_TYPE, G_TYPE_DOUBLE);
+
+ binding_set = gtk_binding_set_by_class (klass);
+ gtk_binding_entry_add_signal (binding_set, GDK_Up, 0,
+ "scroll-vertical", 2,
+ G_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD,
+ G_TYPE_DOUBLE, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_KP_Up, 0,
+ "scroll-vertical", 2,
+ G_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD,
+ G_TYPE_DOUBLE, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_Down, 0,
+ "scroll-vertical", 2,
+ G_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD,
+ G_TYPE_DOUBLE, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_KP_Down, 0,
+ "scroll-vertical", 2,
+ G_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD,
+ G_TYPE_DOUBLE, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_Page_Up, 0,
+ "scroll-vertical", 2,
+ G_TYPE_ENUM, GTK_SCROLL_PAGE_BACKWARD,
+ G_TYPE_DOUBLE, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_KP_Page_Up, 0,
+ "scroll-vertical", 2,
+ G_TYPE_ENUM, GTK_SCROLL_PAGE_BACKWARD,
+ G_TYPE_DOUBLE, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_Page_Down, 0,
+ "scroll-vertical", 2,
+ G_TYPE_ENUM, GTK_SCROLL_PAGE_FORWARD,
+ G_TYPE_DOUBLE, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_KP_Page_Down, 0,
+ "scroll-vertical", 2,
+ G_TYPE_ENUM, GTK_SCROLL_PAGE_FORWARD,
+ G_TYPE_DOUBLE, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_Home, GDK_CONTROL_MASK,
+ "scroll-vertical", 2,
+ G_TYPE_ENUM, GTK_SCROLL_JUMP,
+ G_TYPE_DOUBLE, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_KP_Home, GDK_CONTROL_MASK,
+ "scroll-vertical", 2,
+ G_TYPE_ENUM, GTK_SCROLL_JUMP,
+ G_TYPE_DOUBLE, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_End, GDK_CONTROL_MASK,
+ "scroll-vertical", 2,
+ G_TYPE_ENUM, GTK_SCROLL_JUMP,
+ G_TYPE_DOUBLE, 1.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_KP_End, GDK_CONTROL_MASK,
+ "scroll-vertical", 2,
+ G_TYPE_ENUM, GTK_SCROLL_JUMP,
+ G_TYPE_DOUBLE, 1.0);
+}
+
+
+static void
+dia_list_item_init (DiaListItem *list_item)
+{
+ gtk_widget_set_has_window (GTK_WIDGET (list_item), TRUE);
+ gtk_widget_set_can_focus (GTK_WIDGET (list_item), TRUE);
+}
diff --git a/app/dia-list-item.h b/app/dia-list-item.h
new file mode 100644
index 00000000..b41cc1ec
--- /dev/null
+++ b/app/dia-list-item.h
@@ -0,0 +1,50 @@
+/* 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 Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#pragma once
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define DIA_TYPE_LIST_ITEM dia_list_item_get_type ()
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (GtkBin, g_object_unref)
+
+G_DECLARE_DERIVABLE_TYPE (DiaListItem, dia_list_item, DIA, LIST_ITEM, GtkBin)
+
+
+struct _DiaListItemClass {
+ GtkBinClass parent_class;
+
+ void (*select) (DiaListItem *list_item);
+ void (*deselect) (DiaListItem *list_item);
+ void (*scroll_vertical) (DiaListItem *list_item,
+ GtkScrollType scroll_type,
+ gfloat position);
+};
+
+G_END_DECLS
diff --git a/app/dia-list.c b/app/dia-list.c
new file mode 100644
index 00000000..80c45b96
--- /dev/null
+++ b/app/dia-list.c
@@ -0,0 +1,1097 @@
+/* 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 Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+
+#include "dia-list.h"
+#include "dia-list-item.h"
+
+
+typedef struct _DiaListPrivate DiaListPrivate;
+struct _DiaListPrivate
+{
+ GtkContainer container;
+
+ GList *children;
+ DiaListItem *selected;
+
+ GtkWidget *last_focus_child;
+ GtkWidget *undo_focus_child;
+
+ guint htimer;
+ guint vtimer;
+};
+
+
+G_DEFINE_TYPE_WITH_PRIVATE (DiaList, dia_list, GTK_TYPE_CONTAINER)
+
+
+enum {
+ SELECT_CHILD,
+ UNSELECT_CHILD,
+ LAST_SIGNAL
+};
+static guint signals[LAST_SIGNAL] = { 0 };
+
+
+static void
+dia_list_dispose (GObject *object)
+{
+ dia_list_clear_items (DIA_LIST (object), 0, -1);
+
+ G_OBJECT_CLASS (dia_list_parent_class)->dispose (object);
+}
+
+
+static void
+dia_list_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ DiaList *list = DIA_LIST (widget);
+ DiaListPrivate *priv = dia_list_get_instance_private (list);
+ GtkWidget *child;
+ GList *children;
+ int border_width;
+
+ requisition->width = 0;
+ requisition->height = 0;
+
+ children = priv->children;
+ while (children) {
+ child = children->data;
+ children = children->next;
+
+ if (gtk_widget_get_visible (child)) {
+ GtkRequisition child_requisition;
+
+ gtk_widget_size_request (child, &child_requisition);
+
+ requisition->width = MAX (requisition->width,
+ child_requisition.width);
+ requisition->height += child_requisition.height;
+ }
+ }
+
+ border_width = gtk_container_get_border_width (GTK_CONTAINER (list));
+
+ requisition->width += border_width * 2;
+ requisition->height += border_width * 2;
+
+ requisition->width = MAX (requisition->width, 1);
+ requisition->height = MAX (requisition->height, 1);
+}
+
+
+static void
+dia_list_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ DiaList *list = DIA_LIST (widget);
+ DiaListPrivate *priv = dia_list_get_instance_private (list);
+ GtkWidget *child;
+ GtkAllocation child_allocation;
+ GList *children;
+ GdkWindow *window;
+
+ gtk_widget_set_allocation (widget, allocation);
+
+ window = gtk_widget_get_window (widget);
+
+ if (gtk_widget_get_realized (widget)) {
+ gdk_window_move_resize (window,
+ allocation->x, allocation->y,
+ allocation->width, allocation->height);
+ }
+
+ if (priv->children) {
+ int border_width = gtk_container_get_border_width (GTK_CONTAINER (list));
+ child_allocation.x = border_width;
+ child_allocation.y = border_width;
+ child_allocation.width = MAX (1,
+ allocation->width - child_allocation.x * 2);
+
+ children = priv->children;
+
+ while (children) {
+ child = children->data;
+ children = children->next;
+
+ if (gtk_widget_get_visible (child)) {
+ GtkRequisition child_requisition;
+
+ gtk_widget_get_child_requisition (child, &child_requisition);
+
+ child_allocation.height = child_requisition.height;
+
+ gtk_widget_size_allocate (child, &child_allocation);
+
+ child_allocation.y += child_allocation.height;
+ }
+ }
+ }
+}
+
+
+static void
+dia_list_realize (GtkWidget *widget)
+{
+ GtkAllocation alloc;
+ GdkWindowAttr attributes;
+ gint attributes_mask;
+ GdkWindow *window;
+ GtkStyle *style;
+ gtk_widget_set_realized (widget, TRUE);
+
+ gtk_widget_get_allocation (widget, &alloc);
+
+ attributes.window_type = GDK_WINDOW_CHILD;
+ attributes.x = alloc.x;
+ attributes.y = alloc.y;
+ attributes.width = alloc.width;
+ attributes.height = alloc.height;
+ attributes.wclass = GDK_INPUT_OUTPUT;
+ attributes.visual = gtk_widget_get_visual (widget);
+ attributes.colormap = gtk_widget_get_colormap (widget);
+ 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;
+
+
+ window = gdk_window_new (gtk_widget_get_parent_window (widget),
+ &attributes, attributes_mask);
+ gtk_widget_set_window (widget, window);
+ gdk_window_set_user_data (window, widget);
+
+ gtk_widget_style_attach (widget);
+
+ style = gtk_widget_get_style (widget);
+
+ gdk_window_set_background (window,
+ &style->base[GTK_STATE_NORMAL]);
+}
+
+
+static void
+dia_list_unmap (GtkWidget *widget)
+{
+ GdkWindow *window;
+
+ if (!gtk_widget_get_mapped (widget)) {
+ return;
+ }
+
+ gtk_widget_set_mapped (widget, FALSE);
+
+ window = gtk_widget_get_window (widget);
+
+ gdk_window_hide (window);
+}
+
+
+static gboolean
+dia_list_button_press (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ GtkWidget *item;
+
+ if (event->button != 1) {
+ return FALSE;
+ }
+
+ item = gtk_get_event_widget ((GdkEvent*) event);
+
+ while (item && !DIA_IS_LIST_ITEM (item)) {
+ item = gtk_widget_get_parent (item);
+ }
+
+ if (item && (gtk_widget_get_parent (item) == widget)) {
+ if (!gtk_widget_has_focus (item)) {
+ gtk_widget_grab_focus (item);
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static void
+dia_list_style_set (GtkWidget *widget,
+ GtkStyle *previous_style)
+{
+ GtkStyle *style;
+
+ if (previous_style && gtk_widget_get_realized (widget)) {
+ style = gtk_widget_get_style (widget);
+ gdk_window_set_background (gtk_widget_get_window (widget),
+ &style->base[gtk_widget_get_state (widget)]);
+ }
+}
+
+
+static void
+dia_list_add (GtkContainer *container,
+ GtkWidget *widget)
+{
+ GList *item_list;
+
+ g_return_if_fail (DIA_IS_LIST_ITEM (widget));
+
+ item_list = g_list_alloc ();
+ item_list->data = widget;
+
+ dia_list_append_items (DIA_LIST (container), item_list);
+}
+
+
+static void
+dia_list_remove (GtkContainer *container,
+ GtkWidget *widget)
+{
+ GList *item_list;
+
+ g_return_if_fail (container == GTK_CONTAINER (gtk_widget_get_parent (widget)));
+
+ item_list = g_list_alloc ();
+ item_list->data = widget;
+
+ dia_list_remove_items (DIA_LIST (container), item_list);
+
+ g_list_free (item_list);
+}
+
+
+static void
+dia_list_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ DiaList *list = DIA_LIST (container);
+ DiaListPrivate *priv = dia_list_get_instance_private (list);
+ GtkWidget *child;
+ GList *children;
+
+ children = priv->children;
+
+ while (children) {
+ child = children->data;
+ children = children->next;
+
+ (* callback) (child, callback_data);
+ }
+}
+
+
+static GType
+dia_list_child_type (GtkContainer *container)
+{
+ return DIA_TYPE_LIST_ITEM;
+}
+
+
+static void
+dia_list_set_focus_child (GtkContainer *container,
+ GtkWidget *child)
+{
+ DiaList *list;
+ GtkWidget *focus_child;
+ DiaListPrivate *priv;
+
+ g_return_if_fail (DIA_IS_LIST (container));
+
+ if (child) {
+ g_return_if_fail (GTK_IS_WIDGET (child));
+ }
+
+ list = DIA_LIST (container);
+ priv = dia_list_get_instance_private (list);
+
+ focus_child = gtk_container_get_focus_child (container);
+
+ if (child != focus_child) {
+ if (focus_child) {
+ priv->last_focus_child = focus_child;
+ g_clear_object (&focus_child);
+ }
+ GTK_CONTAINER_CLASS (dia_list_parent_class)->set_focus_child (container, child);
+ if (child) {
+ g_object_ref (child);
+ }
+ }
+
+ /* check for v adjustment */
+ if (child) {
+ GtkAdjustment *adjustment;
+
+ adjustment = gtk_container_get_focus_vadjustment (container);
+ if (adjustment) {
+ GtkAllocation alloc;
+
+ gtk_widget_get_allocation (child, &alloc);
+
+ gtk_adjustment_clamp_page (adjustment,
+ alloc.y,
+ (alloc.y +
+ alloc.height));
+ }
+
+ dia_list_select_child (list, DIA_LIST_ITEM (child));
+ }
+}
+
+
+static gboolean
+dia_list_focus (GtkWidget *widget,
+ GtkDirectionType direction)
+{
+ gint return_val = FALSE;
+ GtkContainer *container;
+ GtkWidget *focus_child;
+ DiaListPrivate *priv;
+
+ g_return_val_if_fail (DIA_IS_LIST (widget), FALSE);
+
+ priv = dia_list_get_instance_private (DIA_LIST (widget));
+
+ container = GTK_CONTAINER (widget);
+ focus_child = gtk_container_get_focus_child (container);
+
+ if (focus_child == NULL || !gtk_widget_has_focus (focus_child)) {
+ if (priv->last_focus_child) {
+ gtk_container_set_focus_child (container, priv->last_focus_child);
+ }
+
+ if (GTK_WIDGET_CLASS (dia_list_parent_class)->focus) {
+ return_val = GTK_WIDGET_CLASS (dia_list_parent_class)->focus (widget,
+ direction);
+ }
+ }
+
+ if (!return_val) {
+ focus_child = gtk_container_get_focus_child (GTK_CONTAINER (container));
+
+ if (focus_child) {
+ priv->last_focus_child = focus_child;
+ }
+ }
+
+ return return_val;
+}
+
+
+static void
+dia_list_real_select_child (DiaList *self,
+ DiaListItem *item)
+{
+ DiaListPrivate *priv;
+ DiaListItem *old = NULL;
+
+ g_return_if_fail (DIA_IS_LIST (self));
+ g_return_if_fail (DIA_IS_LIST_ITEM (item));
+
+ priv = dia_list_get_instance_private (self);
+
+ if (priv->selected) {
+ old = g_object_ref (priv->selected);
+ }
+
+ if (g_set_object (&priv->selected, item)) {
+ if (old) {
+ gtk_widget_set_state (GTK_WIDGET (old), GTK_STATE_NORMAL);
+ }
+
+ gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_SELECTED);
+ }
+
+ g_clear_object (&old);
+}
+
+
+static void
+dia_list_real_unselect_child (DiaList *self,
+ DiaListItem *item)
+{
+ DiaListPrivate *priv;
+
+ g_return_if_fail (DIA_IS_LIST (self));
+ g_return_if_fail (DIA_IS_LIST_ITEM (item));
+
+ priv = dia_list_get_instance_private (self);
+
+ g_return_if_fail (priv->selected == item);
+
+ gtk_widget_set_state (GTK_WIDGET (priv->selected), GTK_STATE_NORMAL);
+
+ g_clear_object (&priv->selected);
+}
+
+
+static void
+dia_list_class_init (DiaListClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
+
+ object_class->dispose = dia_list_dispose;
+
+ widget_class->unmap = dia_list_unmap;
+ widget_class->style_set = dia_list_style_set;
+ widget_class->realize = dia_list_realize;
+ widget_class->button_press_event = dia_list_button_press;
+ widget_class->size_request = dia_list_size_request;
+ widget_class->size_allocate = dia_list_size_allocate;
+ widget_class->focus = dia_list_focus;
+
+ container_class->add = dia_list_add;
+ container_class->remove = dia_list_remove;
+ container_class->forall = dia_list_forall;
+ container_class->child_type = dia_list_child_type;
+ container_class->set_focus_child = dia_list_set_focus_child;
+
+ klass->select_child = dia_list_real_select_child;
+ klass->unselect_child = dia_list_real_unselect_child;
+
+ signals[SELECT_CHILD] =
+ g_signal_new ("select-child",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (DiaListClass, select_child),
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 1,
+ DIA_TYPE_LIST_ITEM);
+ signals[UNSELECT_CHILD] =
+ g_signal_new ("unselect-child",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (DiaListClass, unselect_child),
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 1,
+ DIA_TYPE_LIST_ITEM);
+}
+
+
+static void
+dia_list_init (DiaList *list)
+{
+ DiaListPrivate *priv = dia_list_get_instance_private (list);
+
+ priv->children = NULL;
+ priv->selected = NULL;
+
+ priv->last_focus_child = NULL;
+ priv->undo_focus_child = NULL;
+
+ priv->htimer = 0;
+ priv->vtimer = 0;
+}
+
+
+GtkWidget*
+dia_list_new (void)
+{
+ return g_object_new (DIA_TYPE_LIST, NULL);
+}
+
+
+static void
+scroll_vertical (DiaListItem *list_item,
+ GtkScrollType scroll_type,
+ double position,
+ DiaList *list)
+{
+ GtkContainer *container;
+ DiaListPrivate *priv;
+ GList *work;
+ GtkWidget *item;
+ GtkAdjustment *adj;
+ GtkWidget *focus_child;
+ GtkAllocation alloc;
+ gint new_value;
+
+ g_return_if_fail (DIA_IS_LIST (list));
+
+ priv = dia_list_get_instance_private (list);
+
+ container = GTK_CONTAINER (list);
+ focus_child = gtk_container_get_focus_child (container);
+
+ if (focus_child) {
+ work = g_list_find (priv->children, focus_child);
+ } else {
+ work = priv->children;
+ }
+
+ if (!work) {
+ return;
+ }
+
+ switch (scroll_type) {
+ 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_container_get_focus_vadjustment (GTK_CONTAINER (list));
+
+ if (adj) {
+ gboolean correct = FALSE;
+ double value = gtk_adjustment_get_value (adj);
+ double page_size = gtk_adjustment_get_page_size (adj);
+ double lower = gtk_adjustment_get_lower (adj);
+
+ gtk_widget_get_allocation (item, &alloc);
+
+ new_value = value;
+
+ if (alloc.y <= value) {
+ new_value = MAX (alloc.y + alloc.height - page_size, lower);
+ correct = TRUE;
+ }
+
+ if (alloc.y > new_value) {
+ for (; work; work = work->prev) {
+ item = GTK_WIDGET (work->data);
+
+ gtk_widget_get_allocation (item, &alloc);
+
+ if (alloc.y <= new_value &&
+ alloc.y + alloc.height > new_value) {
+ break;
+ }
+ }
+ } else {
+ for (; work; work = work->next) {
+ item = GTK_WIDGET (work->data);
+
+ gtk_widget_get_allocation (item, &alloc);
+
+ if (alloc.y <= new_value &&
+ alloc.y + alloc.height > new_value) {
+ break;
+ }
+ }
+ }
+
+ gtk_widget_get_allocation (item, &alloc);
+
+ if (correct && work && work->next && alloc.y < new_value) {
+ item = work->next->data;
+ }
+ } else {
+ item = priv->children->data;
+ }
+
+ gtk_widget_grab_focus (item);
+ break;
+ case GTK_SCROLL_PAGE_FORWARD:
+ if (!work->next) {
+ return;
+ }
+
+ item = work->data;
+ adj = gtk_container_get_focus_vadjustment (GTK_CONTAINER (list));
+
+ if (adj) {
+ gboolean correct = FALSE;
+ double value = gtk_adjustment_get_value (adj);
+ double upper = gtk_adjustment_get_upper (adj);
+ double page_size = gtk_adjustment_get_page_size (adj);
+
+ new_value = value;
+
+ gtk_widget_get_allocation (item, &alloc);
+
+ if (alloc.y + alloc.height >=
+ value + page_size) {
+ new_value = alloc.y;
+ correct = TRUE;
+ }
+
+ new_value = MIN (new_value + page_size, upper);
+
+ if (alloc.y > new_value) {
+ for (; work; work = work->prev) {
+ item = GTK_WIDGET (work->data);
+
+ gtk_widget_get_allocation (item, &alloc);
+
+ if (alloc.y <= new_value &&
+ alloc.y + alloc.height > new_value) {
+ break;
+ }
+ }
+ } else {
+ for (; work; work = work->next) {
+ item = GTK_WIDGET (work->data);
+
+ gtk_widget_get_allocation (item, &alloc);
+
+ if (alloc.y <= new_value &&
+ alloc.y + alloc.height > new_value) {
+ break;
+ }
+ }
+ }
+
+ gtk_widget_get_allocation (item, &alloc);
+
+ if (correct && work && work->prev &&
+ alloc.y + alloc.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:
+ gtk_widget_get_allocation (GTK_WIDGET (list), &alloc);
+
+ new_value = alloc.height * CLAMP (position, 0, 1);
+
+ for (item = NULL, work = priv->children; work; work = work->next) {
+ item = GTK_WIDGET (work->data);
+
+ gtk_widget_get_allocation (item, &alloc);
+
+ if (alloc.y <= new_value &&
+ alloc.y + alloc.height > new_value) {
+ break;
+ }
+ }
+
+ gtk_widget_grab_focus (item);
+ break;
+ case GTK_SCROLL_STEP_UP:
+ case GTK_SCROLL_STEP_DOWN:
+ case GTK_SCROLL_STEP_LEFT:
+ case GTK_SCROLL_STEP_RIGHT:
+ case GTK_SCROLL_PAGE_UP:
+ case GTK_SCROLL_PAGE_DOWN:
+ case GTK_SCROLL_PAGE_LEFT:
+ case GTK_SCROLL_PAGE_RIGHT:
+ case GTK_SCROLL_START:
+ case GTK_SCROLL_END:
+ case GTK_SCROLL_NONE:
+ default:
+ break;
+ }
+}
+
+
+void
+dia_list_insert_items (DiaList *list,
+ GList *items,
+ int position)
+{
+ GtkWidget *widget;
+ DiaListPrivate *priv;
+ GList *tmp_list;
+ GList *last;
+ int nchildren;
+
+ g_return_if_fail (DIA_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));
+
+ g_signal_connect (widget,
+ "scroll-vertical",
+ G_CALLBACK (scroll_vertical),
+ list);
+ }
+
+ priv = dia_list_get_instance_private (list);
+
+ nchildren = g_list_length (priv->children);
+ if ((position < 0) || (position > nchildren))
+ position = nchildren;
+
+ if (position == nchildren) {
+ if (priv->children) {
+ tmp_list = g_list_last (priv->children);
+ tmp_list->next = items;
+ items->prev = tmp_list;
+ } else {
+ priv->children = items;
+ }
+ } else {
+ tmp_list = g_list_nth (priv->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 == priv->children) {
+ priv->children = items;
+ }
+ }
+
+ if (priv->children && !priv->selected) {
+ widget = priv->children->data;
+ dia_list_select_child (list, DIA_LIST_ITEM (widget));
+ }
+}
+
+
+void
+dia_list_append_items (DiaList *list,
+ GList *items)
+{
+ g_return_if_fail (DIA_IS_LIST (list));
+
+ dia_list_insert_items (list, items, -1);
+}
+
+
+void
+dia_list_prepend_items (DiaList *list,
+ GList *items)
+{
+ g_return_if_fail (DIA_IS_LIST (list));
+
+ dia_list_insert_items (list, items, 0);
+}
+
+
+void
+dia_list_remove_items (DiaList *list,
+ GList *items)
+{
+ GtkWidget *widget;
+ DiaListPrivate *priv;
+ GtkWidget *new_focus_child;
+ GtkWidget *old_focus_child;
+ GtkWidget *focus_child;
+ GtkContainer *container;
+ GList *tmp_list;
+ GList *work;
+ gboolean grab_focus = FALSE;
+
+ g_return_if_fail (DIA_IS_LIST (list));
+
+ priv = dia_list_get_instance_private (list);
+
+ if (!items) {
+ return;
+ }
+
+ container = GTK_CONTAINER (list);
+ focus_child = gtk_container_get_focus_child (container);
+
+ tmp_list = items;
+ while (tmp_list) {
+ widget = tmp_list->data;
+ tmp_list = tmp_list->next;
+
+ if (gtk_widget_get_state (widget) == GTK_STATE_SELECTED) {
+ dia_list_unselect_child (list, DIA_LIST_ITEM (widget));
+ }
+ }
+
+ if (focus_child) {
+ old_focus_child = new_focus_child = focus_child;
+ if (gtk_widget_has_focus (focus_child)) {
+ grab_focus = TRUE;
+ }
+ } else {
+ old_focus_child = new_focus_child = priv->last_focus_child;
+ }
+
+ tmp_list = items;
+ while (tmp_list) {
+ widget = tmp_list->data;
+ tmp_list = tmp_list->next;
+
+ g_object_ref (widget);
+
+ if (widget == new_focus_child) {
+ work = g_list_find (priv->children, widget);
+
+ if (work) {
+ if (work->next) {
+ new_focus_child = work->next->data;
+ } else if (priv->children != work && work->prev) {
+ new_focus_child = work->prev->data;
+ } else {
+ new_focus_child = NULL;
+ }
+ }
+ }
+
+ g_signal_handlers_disconnect_by_data (widget, list);
+ priv->children = g_list_remove (priv->children, widget);
+ gtk_widget_unparent (widget);
+
+ if (widget == priv->undo_focus_child) {
+ priv->undo_focus_child = NULL;
+ }
+
+ if (widget == priv->last_focus_child) {
+ priv->last_focus_child = NULL;
+ }
+
+ g_clear_object (&widget);
+ }
+
+ focus_child = gtk_container_get_focus_child (container);
+
+ if (new_focus_child && new_focus_child != old_focus_child) {
+ if (grab_focus) {
+ gtk_widget_grab_focus (new_focus_child);
+ } else if (focus_child) {
+ gtk_container_set_focus_child (container, new_focus_child);
+ }
+
+ if (!priv->selected) {
+ priv->last_focus_child = new_focus_child;
+ dia_list_select_child (list, DIA_LIST_ITEM (new_focus_child));
+ }
+ }
+
+ if (gtk_widget_get_visible (GTK_WIDGET (list))) {
+ gtk_widget_queue_resize (GTK_WIDGET (list));
+ }
+}
+
+
+void
+dia_list_clear_items (DiaList *list,
+ int start,
+ int end)
+{
+ GtkContainer *container;
+ GtkWidget *widget;
+ DiaListPrivate *priv;
+ GtkWidget *new_focus_child = NULL;
+ GtkWidget *focus_child;
+ GList *start_list;
+ GList *end_list;
+ GList *tmp_list;
+ guint nchildren;
+ gboolean grab_focus = FALSE;
+
+ g_return_if_fail (DIA_IS_LIST (list));
+
+ priv = dia_list_get_instance_private (list);
+
+ nchildren = g_list_length (priv->children);
+
+ if (nchildren == 0) {
+ return;
+ }
+
+ if ((end < 0) || (end > nchildren)) {
+ end = nchildren;
+ }
+
+ if (start >= end) {
+ return;
+ }
+
+ container = GTK_CONTAINER (list);
+
+ start_list = g_list_nth (priv->children, start);
+ end_list = g_list_nth (priv->children, end);
+
+ 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 == priv->children) {
+ priv->children = end_list;
+ }
+
+ focus_child = gtk_container_get_focus_child (container);
+
+ if (focus_child) {
+ if (g_list_find (start_list, focus_child)) {
+ if (start_list->prev) {
+ new_focus_child = start_list->prev->data;
+ } else if (priv->children) {
+ new_focus_child = priv->children->data;
+ }
+
+ if (gtk_widget_has_focus (focus_child)) {
+ grab_focus = TRUE;
+ }
+ }
+ }
+
+ tmp_list = start_list;
+ while (tmp_list) {
+ widget = tmp_list->data;
+ tmp_list = tmp_list->next;
+
+ g_object_ref (widget);
+
+ if (gtk_widget_get_state (widget) == GTK_STATE_SELECTED) {
+ dia_list_unselect_child (list, DIA_LIST_ITEM (widget));
+ }
+
+ g_signal_handlers_disconnect_by_data (widget, list);
+ gtk_widget_unparent (widget);
+
+ if (widget == priv->undo_focus_child) {
+ priv->undo_focus_child = NULL;
+ }
+ if (widget == priv->last_focus_child) {
+ priv->last_focus_child = NULL;
+ }
+
+ g_clear_object (&widget);
+ }
+
+ g_list_free (start_list);
+
+ if (new_focus_child) {
+ if (grab_focus) {
+ gtk_widget_grab_focus (new_focus_child);
+ } else if (focus_child) {
+ gtk_container_set_focus_child (container, new_focus_child);
+ }
+
+ if (!priv->selected) {
+ priv->last_focus_child = new_focus_child;
+ dia_list_select_child (list, DIA_LIST_ITEM (new_focus_child));
+ }
+ }
+
+ if (gtk_widget_get_visible (GTK_WIDGET (list))) {
+ gtk_widget_queue_resize (GTK_WIDGET (list));
+ }
+}
+
+
+void
+dia_list_select_item (DiaList *list,
+ int item)
+{
+ GList *tmp_list;
+ DiaListPrivate *priv;
+
+ g_return_if_fail (DIA_IS_LIST (list));
+
+ priv = dia_list_get_instance_private (list);
+
+ tmp_list = g_list_nth (priv->children, item);
+ if (tmp_list) {
+ dia_list_select_child (list, tmp_list->data);
+ }
+}
+
+
+void
+dia_list_select_child (DiaList *self,
+ DiaListItem *item)
+{
+ g_signal_emit (self, signals[SELECT_CHILD], 0, item);
+}
+
+
+void
+dia_list_unselect_child (DiaList *self,
+ DiaListItem *item)
+{
+ g_signal_emit (self, signals[UNSELECT_CHILD], 0, item);
+}
+
+
+int
+dia_list_child_position (DiaList *self,
+ DiaListItem *item)
+{
+ DiaListPrivate *priv;
+ GList *children;
+ int pos;
+
+ g_return_val_if_fail (DIA_IS_LIST (self), -1);
+ g_return_val_if_fail (DIA_IS_LIST_ITEM (item), -1);
+
+ priv = dia_list_get_instance_private (self);
+
+ pos = 0;
+ children = priv->children;
+
+ while (children) {
+ if (item == children->data) {
+ return pos;
+ }
+
+ pos += 1;
+ children = children->next;
+ }
+
+ return -1;
+}
+
+
+DiaListItem *
+dia_list_get_selected (DiaList *self)
+{
+ DiaListPrivate *priv;
+
+ g_return_val_if_fail (DIA_IS_LIST (self), NULL);
+
+ priv = dia_list_get_instance_private (self);
+
+ return priv->selected;
+}
diff --git a/app/dia-list.h b/app/dia-list.h
new file mode 100644
index 00000000..edd24c24
--- /dev/null
+++ b/app/dia-list.h
@@ -0,0 +1,75 @@
+/* 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 Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#pragma once
+
+#include <gtk/gtk.h>
+
+#include "dia-list-item.h"
+
+G_BEGIN_DECLS
+
+#define DIA_TYPE_LIST dia_list_get_type ()
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (GtkContainer, g_object_unref)
+
+G_DECLARE_DERIVABLE_TYPE (DiaList, dia_list, DIA, LIST, GtkContainer)
+
+
+struct _DiaListClass {
+ GtkContainerClass parent_class;
+
+ void (* select_child) (DiaList *list,
+ DiaListItem *item);
+ void (* unselect_child) (DiaList *list,
+ DiaListItem *item);
+};
+
+
+GtkWidget *dia_list_new (void);
+void dia_list_insert_items (DiaList *self,
+ GList *items,
+ int position);
+void dia_list_append_items (DiaList *self,
+ GList *items);
+void dia_list_prepend_items (DiaList *self,
+ GList *items);
+void dia_list_remove_items (DiaList *self,
+ GList *items);
+void dia_list_clear_items (DiaList *self,
+ int start,
+ int end);
+void dia_list_select_item (DiaList *self,
+ int item);
+void dia_list_select_child (DiaList *self,
+ DiaListItem *item);
+void dia_list_unselect_child (DiaList *self,
+ DiaListItem *item);
+gint dia_list_child_position (DiaList *self,
+ DiaListItem *item);
+DiaListItem *dia_list_get_selected (DiaList *self);
+
+G_END_DECLS
diff --git a/app/layer-editor/dia-layer-widget.c b/app/layer-editor/dia-layer-widget.c
index d66dde95..959fb9da 100644
--- a/app/layer-editor/dia-layer-widget.c
+++ b/app/layer-editor/dia-layer-widget.c
@@ -65,7 +65,7 @@ struct _DiaLayerWidgetPrivate
gboolean shifted;
};
-G_DEFINE_TYPE_WITH_PRIVATE (DiaLayerWidget, dia_layer_widget, GTK_TYPE_LIST_ITEM)
+G_DEFINE_TYPE_WITH_PRIVATE (DiaLayerWidget, dia_layer_widget, DIA_TYPE_LIST_ITEM)
enum {
EXCLUSIVE,
@@ -230,6 +230,7 @@ button_event (GtkWidget *widget,
return FALSE;
}
+
static void
connectable_toggled (GtkToggleButton *widget,
gpointer userdata)
@@ -294,48 +295,6 @@ visible_clicked (GtkToggleButton *widget,
}
}
-static void
-select_callback (GtkWidget *widget, gpointer data)
-{
- DiaLayerWidget *self = DIA_LAYER_WIDGET (widget);
- DiaLayerWidgetPrivate *priv = dia_layer_widget_get_instance_private (self);
- DiagramData *diagram;
-
- g_return_if_fail (priv->layer != NULL);
-
- diagram = dia_layer_get_parent_diagram (priv->layer);
-
- /* Don't deselect if we're selected the active layer. This can happen
- * if the window has been defocused. */
- if (diagram->active_layer != priv->layer) {
- diagram_remove_all_selected (DIA_DIAGRAM (diagram), TRUE);
- }
- diagram_update_extents (DIA_DIAGRAM (diagram));
- data_set_active_layer (diagram, priv->layer);
- diagram_add_update_all (DIA_DIAGRAM (diagram));
- diagram_flush (DIA_DIAGRAM (diagram));
-
- priv->internal_call = TRUE;
- if (priv->connect_off) { /* If the user wants this off, it becomes so */
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->connectable), FALSE);
- } else {
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->connectable), TRUE);
- }
- priv->internal_call = FALSE;
-}
-
-static void
-deselect_callback (GtkWidget *widget, gpointer data)
-{
- DiaLayerWidget *self = DIA_LAYER_WIDGET (widget);
- DiaLayerWidgetPrivate *priv = dia_layer_widget_get_instance_private (self);
-
- priv->internal_call = TRUE;
- /** Set to on if the user has requested so. */
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->connectable),
- priv->connect_on);
- priv->internal_call = FALSE;
-}
static void
dia_layer_widget_init (DiaLayerWidget *self)
@@ -373,8 +332,6 @@ dia_layer_widget_init (DiaLayerWidget *self)
gtk_box_pack_start (GTK_BOX (hbox), priv->visible, FALSE, TRUE, 2);
gtk_widget_show (priv->visible);
- /*gtk_image_new_from_stock(GTK_STOCK_CONNECT,
- GTK_ICON_SIZE_BUTTON), */
priv->connectable =
dia_toggle_button_new_with_icon_names ("dia-connectable",
"dia-connectable-empty");
@@ -403,15 +360,6 @@ dia_layer_widget_init (DiaLayerWidget *self)
gtk_widget_show (hbox);
gtk_container_add (GTK_CONTAINER (self), hbox);
-
- g_signal_connect (G_OBJECT (self),
- "select",
- G_CALLBACK (select_callback),
- NULL);
- g_signal_connect (G_OBJECT (self),
- "deselect",
- G_CALLBACK (deselect_callback),
- NULL);
}
@@ -550,3 +498,54 @@ dia_layer_widget_new (DiaLayer *layer, DiaLayerEditor *editor)
"editor", editor,
NULL);
}
+
+
+void
+dia_layer_widget_select (DiaLayerWidget *self)
+{
+ DiaLayerWidgetPrivate *priv;
+ DiagramData *diagram;
+
+ g_return_if_fail (DIA_IS_LAYER_WIDGET (self));
+
+ priv = dia_layer_widget_get_instance_private (self);
+
+ g_return_if_fail (priv->layer != NULL);
+
+ diagram = dia_layer_get_parent_diagram (priv->layer);
+
+ /* Don't deselect if we're selected the active layer. This can happen
+ * if the window has been defocused. */
+ if (dia_diagram_data_get_active_layer (diagram) != priv->layer) {
+ diagram_remove_all_selected (DIA_DIAGRAM (diagram), TRUE);
+ }
+ diagram_update_extents (DIA_DIAGRAM (diagram));
+ data_set_active_layer (diagram, priv->layer);
+ diagram_add_update_all (DIA_DIAGRAM (diagram));
+ diagram_flush (DIA_DIAGRAM (diagram));
+
+ priv->internal_call = TRUE;
+ if (priv->connect_off) { /* If the user wants this off, it becomes so */
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->connectable), FALSE);
+ } else {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->connectable), TRUE);
+ }
+ priv->internal_call = FALSE;
+}
+
+
+void
+dia_layer_widget_deselect (DiaLayerWidget *self)
+{
+ DiaLayerWidgetPrivate *priv;
+
+ g_return_if_fail (DIA_IS_LAYER_WIDGET (self));
+
+ priv = dia_layer_widget_get_instance_private (self);
+
+ priv->internal_call = TRUE;
+ /** Set to on if the user has requested so. */
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->connectable),
+ priv->connect_on);
+ priv->internal_call = FALSE;
+}
diff --git a/app/layer-editor/dia-layer-widget.h b/app/layer-editor/dia-layer-widget.h
index f6f4dff4..9e0d8989 100644
--- a/app/layer-editor/dia-layer-widget.h
+++ b/app/layer-editor/dia-layer-widget.h
@@ -22,17 +22,16 @@
#include "dia-layer.h"
#include "dia-layer-editor.h"
+#include "dia-list-item.h"
G_BEGIN_DECLS
#define DIA_TYPE_LAYER_WIDGET dia_layer_widget_get_type ()
-G_DEFINE_AUTOPTR_CLEANUP_FUNC (GtkListItem, g_object_unref)
-
-G_DECLARE_DERIVABLE_TYPE (DiaLayerWidget, dia_layer_widget, DIA, LAYER_WIDGET, GtkListItem)
+G_DECLARE_DERIVABLE_TYPE (DiaLayerWidget, dia_layer_widget, DIA, LAYER_WIDGET, DiaListItem)
struct _DiaLayerWidgetClass {
- GtkListItemClass parent;
+ DiaListItemClass parent;
};
GtkWidget *dia_layer_widget_new (DiaLayer *layer,
@@ -46,5 +45,7 @@ DiaLayerEditor *dia_layer_widget_get_editor (DiaLayerWidget *self);
void dia_layer_widget_set_connectable (DiaLayerWidget *self,
gboolean on);
gboolean dia_layer_widget_get_connectable (DiaLayerWidget *self);
+void dia_layer_widget_select (DiaLayerWidget *self);
+void dia_layer_widget_deselect (DiaLayerWidget *self);
G_END_DECLS
diff --git a/app/meson.build b/app/meson.build
index c113bfaa..2a2a92a6 100644
--- a/app/meson.build
+++ b/app/meson.build
@@ -55,6 +55,12 @@ dia_sources = [
'dia-props.c',
'gtkwrapbox.c',
'gtkhwrapbox.c',
+
+ 'dia-list.c',
+ 'dia-list.h',
+ 'dia-list-item.c',
+ 'dia-list-item.h',
+
'cursor.c',
'splash.c',
'recent_files.c',
diff --git a/meson.build b/meson.build
index 20860529..a2019f30 100644
--- a/meson.build
+++ b/meson.build
@@ -79,6 +79,7 @@ add_project_arguments([
'-DGLIB_VERSION_MIN_REQUIRED=@0@'.format(glib_ver),
'-DGLIB_VERSION_MAX_ALLOWED=@0@'.format(glib_ver),
'-DGSEAL_ENABLE',
+ '-DGTK_DISABLE_DEPRECATED',
], language: 'c')
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]