[dia] layer-editor: merge DiaListItem and DiaLayerWidget



commit 5105f70a966490e8be6767a97ee54044e07b2fe6
Author: Zander Brown <zbrown gnome org>
Date:   Sun Apr 5 01:44:13 2020 +0100

    layer-editor: merge DiaListItem and DiaLayerWidget
    
    Since DiaList[Item] is only intended to be used in the layer editor
    merge DiaListItem into DiaLayerWidget instead of extending
    
    Also make DiaList less generic

 app/dia-list-item.c                 | 301 ------------------------------------
 app/dia-list-item.h                 |  50 ------
 app/dia-list.h                      |  75 ---------
 app/layer-editor/dia-layer-editor.c | 181 ++++++++++------------
 app/layer-editor/dia-layer-widget.c | 252 +++++++++++++++++++++++++++++-
 app/layer-editor/dia-layer-widget.h |   7 +-
 app/{ => layer-editor}/dia-list.c   | 185 ++++++++--------------
 app/layer-editor/dia-list.h         |  70 +++++++++
 app/meson.build                     |   7 +-
 9 files changed, 469 insertions(+), 659 deletions(-)
---
diff --git a/app/layer-editor/dia-layer-editor.c b/app/layer-editor/dia-layer-editor.c
index 4c41e1e1..4cea78a6 100644
--- a/app/layer-editor/dia-layer-editor.c
+++ b/app/layer-editor/dia-layer-editor.c
@@ -27,6 +27,7 @@
 #include "dia-layer-editor.h"
 #include "dia-layer-properties.h"
 #include "dia-layer.h"
+#include "dia-list.h"
 #include "layer_dialog.h"
 
 typedef struct _ButtonData ButtonData;
@@ -131,41 +132,22 @@ dia_layer_editor_class_init (DiaLayerEditorClass *klass)
 
 static void rename_layer (GtkWidget *widget, DiaLayerEditor *self);
 
+
 static gint
-list_event (GtkWidget      *widget,
-            GdkEvent       *event,
-            DiaLayerEditor *self)
+list_button_press (GtkWidget      *widget,
+                   GdkEvent       *event,
+                   DiaLayerEditor *self)
 {
-  GdkEventKey *kevent;
   GtkWidget *event_widget;
   DiaLayerWidget *layer_widget;
 
   event_widget = gtk_get_event_widget (event);
 
-  if (GTK_IS_LIST_ITEM (event_widget)) {
+  if (DIA_IS_LAYER_WIDGET (event_widget)) {
     layer_widget = DIA_LAYER_WIDGET (event_widget);
 
-    switch (event->type) {
-      case GDK_2BUTTON_PRESS:
-        rename_layer (GTK_WIDGET (layer_widget), self);
-        return TRUE;
-
-      case GDK_KEY_PRESS:
-        kevent = (GdkEventKey *) event;
-        switch (kevent->keyval) {
-          case GDK_Up:
-            /* printf ("up arrow\n"); */
-            break;
-          case GDK_Down:
-            /* printf ("down arrow\n"); */
-            break;
-          default:
-            return FALSE;
-        }
-        return TRUE;
-
-      default:
-        break;
+    if (event->type == GDK_2BUTTON_PRESS) {
+      rename_layer (GTK_WIDGET (layer_widget), self);
     }
   }
 
@@ -188,13 +170,13 @@ exclusive_connectable (DiaLayerWidget *layer_row,
   for (i = 0; i < data_layer_count (DIA_DIAGRAM_DATA (priv->diagram)); i++) {
     layer = data_layer_get_nth (DIA_DIAGRAM_DATA (priv->diagram), i);
 
-    if (dia_layer_widget_get_layer (DIA_LAYER_WIDGET (layer_row)) != layer) {
+    if (dia_layer_widget_get_layer (layer_row) != layer) {
       connectable |= dia_layer_is_connectable (layer);
     }
   }
 
   /*  Now, toggle the connectability for all layers except the specified one  */
-  list = GTK_LIST (priv->list)->children;
+  list = gtk_container_get_children (GTK_CONTAINER (priv->list));
   while (list) {
     lw = DIA_LAYER_WIDGET (list->data);
     if (lw != layer_row) {
@@ -215,7 +197,7 @@ new_layer (GtkWidget *widget, DiaLayerEditor *self)
   DiaLayerEditorPrivate *priv = dia_layer_editor_get_instance_private (self);
   DiaLayer *layer;
   Diagram *dia;
-  GtkWidget *selected;
+  DiaLayerWidget *selected;
   GList *list = NULL;
   GtkWidget *layer_widget;
   int pos;
@@ -224,15 +206,19 @@ new_layer (GtkWidget *widget, DiaLayerEditor *self)
   dia = priv->diagram;
 
   if (dia != NULL) {
-    gchar* new_layer_name = g_strdup_printf (_("New layer %d"),
-                                             next_layer_num++);
+    char* new_layer_name = g_strdup_printf (_("New layer %d"),
+                                            next_layer_num++);
     layer = dia_layer_new (new_layer_name, dia->data);
 
-    g_assert (GTK_LIST (priv->list)->selection != NULL);
-    selected = GTK_LIST (priv->list)->selection->data;
-    pos = gtk_list_child_position (GTK_LIST (priv->list), selected);
+    selected = dia_list_get_selected (DIA_LIST (priv->list));
+
+    g_return_if_fail (selected != NULL);
+
+    pos = dia_list_child_position (DIA_LIST (priv->list), selected);
 
-    data_add_layer_at (dia->data, layer, dia->data->layers->len - pos);
+    data_add_layer_at (DIA_DIAGRAM_DATA (dia),
+                       layer,
+                       data_layer_count (DIA_DIAGRAM_DATA (dia)) - pos);
 
     diagram_add_update_all (dia);
     diagram_flush (dia);
@@ -246,14 +232,18 @@ new_layer (GtkWidget *widget, DiaLayerEditor *self)
 
     list = g_list_prepend (list, layer_widget);
 
-    gtk_list_insert_items (GTK_LIST (priv->list), list, pos);
+    dia_list_insert_items (DIA_LIST (priv->list), list, pos);
 
-    gtk_list_select_item (GTK_LIST (priv->list), pos);
+    dia_list_select_item (DIA_LIST (priv->list), pos);
 
-    dia_layer_change_new (dia, layer, TYPE_ADD_LAYER, dia->data->layers->len - pos);
+    dia_layer_change_new (dia,
+                          layer,
+                          TYPE_ADD_LAYER,
+                          data_layer_count (DIA_DIAGRAM_DATA (dia)) - pos);
     undo_set_transactionpoint (dia->undo);
 
-    g_free (new_layer_name);
+    g_clear_pointer (&new_layer_name, g_free);
+    g_clear_object (&layer);
   }
 }
 
@@ -272,12 +262,12 @@ rename_layer (GtkWidget *widget, DiaLayerEditor *self)
     return;
   }
 
-  layer = dia->data->active_layer;
+  layer = dia_diagram_data_get_active_layer (DIA_DIAGRAM_DATA (dia));
 
   dlg = g_object_new (DIA_TYPE_LAYER_PROPERTIES,
-                     "layer", layer,
-                     "visible", TRUE,
-                     NULL);
+                      "layer", layer,
+                      "visible", TRUE,
+                      NULL);
   gtk_widget_show (dlg);
 }
 
@@ -287,34 +277,36 @@ delete_layer (GtkWidget *widget, DiaLayerEditor *self)
 {
   DiaLayerEditorPrivate *priv = dia_layer_editor_get_instance_private (self);
   Diagram *dia;
-  GtkWidget *selected;
+  DiaLayerWidget *selected;
   DiaLayer *layer;
   int pos;
 
   dia = priv->diagram;
 
-  if ((dia != NULL) && (dia->data->layers->len > 1)) {
-    g_assert (GTK_LIST (priv->list)->selection != NULL);
-    selected = GTK_LIST (priv->list)->selection->data;
 
-    layer = dia->data->active_layer;
+  if ((dia != NULL) && (data_layer_count (DIA_DIAGRAM_DATA (dia)) > 1)) {
+    selected = dia_list_get_selected (DIA_LIST (priv->list));
 
-    data_remove_layer (dia->data, layer);
-    diagram_add_update_all (dia);
-    diagram_flush (dia);
+    g_return_if_fail (selected != NULL);
 
-    pos = gtk_list_child_position (GTK_LIST (priv->list), selected);
-    gtk_container_remove (GTK_CONTAINER (priv->list), selected);
+    layer = dia_diagram_data_get_active_layer (DIA_DIAGRAM_DATA (dia));
+
+    pos = dia_list_child_position (DIA_LIST (priv->list), selected);
+    gtk_container_remove (GTK_CONTAINER (priv->list), GTK_WIDGET (selected));
 
     dia_layer_change_new (dia, layer, TYPE_DELETE_LAYER,
-                          dia->data->layers->len - pos);
+                          data_layer_count (DIA_DIAGRAM_DATA (dia)) - pos);
     undo_set_transactionpoint (dia->undo);
 
+    data_remove_layer (dia->data, layer);
+    diagram_add_update_all (dia);
+    diagram_flush (dia);
+
     if (--pos < 0) {
       pos = 0;
     }
 
-    gtk_list_select_item (GTK_LIST (priv->list), pos);
+    dia_list_select_item (DIA_LIST (priv->list), pos);
   }
 }
 
@@ -325,35 +317,36 @@ raise_layer (GtkWidget *widget, DiaLayerEditor *self)
   DiaLayerEditorPrivate *priv = dia_layer_editor_get_instance_private (self);
   DiaLayer *layer;
   Diagram *dia;
-  GtkWidget *selected;
+  DiaLayerWidget *selected;
   GList *list = NULL;
   int pos;
 
   dia = priv->diagram;
 
-  if ((dia != NULL) && (dia->data->layers->len > 1)) {
-    g_assert (GTK_LIST (priv->list)->selection != NULL);
-    selected = GTK_LIST (priv->list)->selection->data;
+  if ((dia != NULL) && (data_layer_count (DIA_DIAGRAM_DATA (dia)) > 1)) {
+    selected = dia_list_get_selected (DIA_LIST (priv->list));
 
-    pos = gtk_list_child_position (GTK_LIST (priv->list), selected);
+    g_return_if_fail (selected != NULL);
+
+    pos = dia_list_child_position (DIA_LIST (priv->list), selected);
 
     if (pos > 0) {
-      layer = dia_layer_widget_get_layer (DIA_LAYER_WIDGET (selected));
-      data_raise_layer (dia->data, layer);
+      layer = dia_layer_widget_get_layer (selected);
+      data_raise_layer (DIA_DIAGRAM_DATA (dia), layer);
 
       list = g_list_prepend (list, selected);
 
       g_object_ref (selected);
 
-      gtk_list_remove_items (GTK_LIST (priv->list),
+      dia_list_remove_items (DIA_LIST (priv->list),
                              list);
 
-      gtk_list_insert_items (GTK_LIST (priv->list),
+      dia_list_insert_items (DIA_LIST (priv->list),
                              list, pos - 1);
 
-      g_object_unref (selected);
+      g_clear_object (&selected);
 
-      gtk_list_select_item (GTK_LIST (priv->list), pos-1);
+      dia_list_select_item (DIA_LIST (priv->list), pos-1);
 
       diagram_add_update_all (dia);
       diagram_flush (dia);
@@ -371,35 +364,36 @@ lower_layer (GtkWidget *widget, DiaLayerEditor *self)
   DiaLayerEditorPrivate *priv = dia_layer_editor_get_instance_private (self);
   DiaLayer *layer;
   Diagram *dia;
-  GtkWidget *selected;
+  DiaLayerWidget *selected;
   GList *list = NULL;
   int pos;
 
   dia = priv->diagram;
 
-  if ((dia != NULL) && (dia->data->layers->len > 1)) {
-    g_assert (GTK_LIST (priv->list)->selection != NULL);
-    selected = GTK_LIST (priv->list)->selection->data;
+  if ((dia != NULL) && (data_layer_count (DIA_DIAGRAM_DATA (dia)) > 1)) {
+    selected = dia_list_get_selected (DIA_LIST (priv->list));
+
+    g_return_if_fail (selected != NULL);
 
-    pos = gtk_list_child_position (GTK_LIST (priv->list), selected);
+    pos = dia_list_child_position (DIA_LIST (priv->list), selected);
 
-    if (pos < dia->data->layers->len-1) {
-      layer = dia_layer_widget_get_layer (DIA_LAYER_WIDGET (selected));
-      data_lower_layer (dia->data, layer);
+    if (pos < data_layer_count (DIA_DIAGRAM_DATA (dia)) - 1) {
+      layer = dia_layer_widget_get_layer (selected);
+      data_lower_layer (DIA_DIAGRAM_DATA (dia), layer);
 
       list = g_list_prepend (list, selected);
 
       g_object_ref (selected);
 
-      gtk_list_remove_items (GTK_LIST (priv->list),
+      dia_list_remove_items (DIA_LIST (priv->list),
                              list);
 
-      gtk_list_insert_items (GTK_LIST (priv->list),
+      dia_list_insert_items (DIA_LIST (priv->list),
                              list, pos + 1);
 
-      g_object_unref (selected);
+      g_clear_object (&selected);
 
-      gtk_list_select_item (GTK_LIST (priv->list), pos+1);
+      dia_list_select_item (DIA_LIST (priv->list), pos+1);
 
       diagram_add_update_all (dia);
       diagram_flush (dia);
@@ -442,16 +436,16 @@ dia_layer_editor_init (DiaLayerEditor *self)
                                   GTK_POLICY_AUTOMATIC);
   gtk_box_pack_start (GTK_BOX (self), scrolled_win, TRUE, TRUE, 2);
 
-  priv->list = gtk_list_new ();
+  priv->list = dia_list_new ();
+
   gtk_widget_show (priv->list);
-  gtk_list_set_selection_mode (GTK_LIST (priv->list), GTK_SELECTION_BROWSE);
   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), priv->list);
   gtk_container_set_focus_vadjustment (GTK_CONTAINER (priv->list),
                                        gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW 
(scrolled_win)));
 
   g_signal_connect (G_OBJECT (priv->list),
-                    "event",
-                    G_CALLBACK (list_event),
+                    "button-press-event",
+                    G_CALLBACK (list_button_press),
                     self);
 
   // inline-toolbar
@@ -492,21 +486,6 @@ dia_layer_editor_new (void)
 }
 
 
-/*
- * Used to avoid writing to possibly already deleted layer in
- * dia_layer_widget_connectable_toggled(). Must be called before
- * e.g. gtk_list_clear_items() cause that will emit the toggled
- * signal to last focus widget. See bug #329096
- */
-static void
-_layer_widget_clear_layer (GtkWidget *widget, gpointer user_data)
-{
-  DiaLayerWidget *lw = DIA_LAYER_WIDGET (widget);
-
-  dia_layer_widget_set_layer (lw, NULL);
-}
-
-
 void
 dia_layer_editor_set_diagram (DiaLayerEditor *self,
                               Diagram        *dia)
@@ -532,11 +511,9 @@ dia_layer_editor_set_diagram (DiaLayerEditor *self,
 
   priv->diagram = g_object_ref (dia);
 
-  active_layer = DIA_DIAGRAM_DATA (dia)->active_layer;
+  active_layer = dia_diagram_data_get_active_layer (DIA_DIAGRAM_DATA (dia));
 
-  gtk_container_foreach (GTK_CONTAINER (priv->list),
-                         _layer_widget_clear_layer, NULL);
-  gtk_list_clear_items (GTK_LIST (priv->list), 0, -1);
+  dia_list_clear_items (DIA_LIST (priv->list), 0, -1);
 
   sel_pos = 0;
   for (i = data_layer_count (DIA_DIAGRAM_DATA (dia)) - 1, j = 0; i >= 0; i--, j++) {
@@ -553,7 +530,7 @@ dia_layer_editor_set_diagram (DiaLayerEditor *self,
     }
   }
 
-  gtk_list_select_item (GTK_LIST (priv->list), sel_pos);
+  dia_list_select_item (DIA_LIST (priv->list), sel_pos);
 
   g_object_notify_by_pspec (G_OBJECT (self), pspecs[PROP_DIAGRAM]);
 }
diff --git a/app/layer-editor/dia-layer-widget.c b/app/layer-editor/dia-layer-widget.c
index 959fb9da..62870958 100644
--- a/app/layer-editor/dia-layer-widget.c
+++ b/app/layer-editor/dia-layer-widget.c
@@ -17,6 +17,7 @@
  */
 
 #include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
 
 #include "intl.h"
 
@@ -65,10 +66,11 @@ struct _DiaLayerWidgetPrivate
   gboolean shifted;
 };
 
-G_DEFINE_TYPE_WITH_PRIVATE (DiaLayerWidget, dia_layer_widget, DIA_TYPE_LIST_ITEM)
+G_DEFINE_TYPE_WITH_PRIVATE (DiaLayerWidget, dia_layer_widget, GTK_TYPE_BIN)
 
 enum {
   EXCLUSIVE,
+  SCROLL_VERTICAL,
   LAST_SIGNAL
 };
 
@@ -148,15 +150,198 @@ dia_layer_widget_finalize (GObject *object)
 }
 
 
+static void
+dia_layer_widget_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_LAYER_WIDGET (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_layer_widget_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_LAYER_WIDGET (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_layer_widget_size_allocate (GtkWidget     *widget,
+                                GtkAllocation *allocation)
+{
+  GtkBin *bin;
+  GtkStyle *style;
+  int border_width;
+  GtkAllocation child_allocation;
+
+  g_return_if_fail (DIA_IS_LAYER_WIDGET (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_layer_widget_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 int
+dia_layer_widget_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_layer_widget_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_layer_widget_class_init (DiaLayerWidgetClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+  GtkBindingSet *binding_set;
 
   object_class->set_property = dia_layer_widget_set_property;
   object_class->get_property = dia_layer_widget_get_property;
   object_class->finalize = dia_layer_widget_finalize;
 
+  widget_class->realize = dia_layer_widget_realize;
+  widget_class->size_request = dia_layer_widget_size_request;
+  widget_class->size_allocate = dia_layer_widget_size_allocate;
+  widget_class->style_set = dia_layer_widget_style_set;
+  widget_class->expose_event = dia_layer_widget_expose;
+
   signals[EXCLUSIVE] =
     g_signal_new ("exclusive",
                   G_TYPE_FROM_CLASS (klass),
@@ -167,6 +352,14 @@ dia_layer_widget_class_init (DiaLayerWidgetClass *klass)
                   NULL,
                   G_TYPE_NONE, 0);
 
+  signals[SCROLL_VERTICAL] =
+    g_signal_new ("scroll-vertical",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                  0,
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE, 2, GTK_TYPE_SCROLL_TYPE, G_TYPE_DOUBLE);
+
   /**
    * DiaLayerWidget:layer:
    *
@@ -210,6 +403,56 @@ dia_layer_widget_class_init (DiaLayerWidgetClass *klass)
                           G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
 
   g_object_class_install_properties (object_class, LAST_LW_PROP, lw_pspecs);
+
+  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);
 }
 
 
@@ -302,6 +545,9 @@ dia_layer_widget_init (DiaLayerWidget *self)
   DiaLayerWidgetPrivate *priv = dia_layer_widget_get_instance_private (self);
   GtkWidget *hbox;
 
+  gtk_widget_set_has_window (GTK_WIDGET (self), TRUE);
+  gtk_widget_set_can_focus (GTK_WIDGET (self), TRUE);
+
   hbox = gtk_hbox_new (FALSE, 0);
 
   priv->internal_call = FALSE;
@@ -412,8 +658,8 @@ dia_layer_widget_set_layer (DiaLayerWidget *self,
 
     gtk_widget_set_sensitive (GTK_WIDGET (self), TRUE);
 
-  g_object_notify_by_pspec (G_OBJECT (self), lw_pspecs[LW_PROP_LAYER]);
-}
+    g_object_notify_by_pspec (G_OBJECT (self), lw_pspecs[LW_PROP_LAYER]);
+  }
 }
 
 
diff --git a/app/layer-editor/dia-layer-widget.h b/app/layer-editor/dia-layer-widget.h
index 9e0d8989..378d346e 100644
--- a/app/layer-editor/dia-layer-widget.h
+++ b/app/layer-editor/dia-layer-widget.h
@@ -22,16 +22,17 @@
 
 #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_DECLARE_DERIVABLE_TYPE (DiaLayerWidget, dia_layer_widget, DIA, LAYER_WIDGET, DiaListItem)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (GtkBin, g_object_unref)
+
+G_DECLARE_DERIVABLE_TYPE (DiaLayerWidget, dia_layer_widget, DIA, LAYER_WIDGET, GtkBin)
 
 struct _DiaLayerWidgetClass {
-  DiaListItemClass parent;
+  GtkBinClass parent_class;
 };
 
 GtkWidget      *dia_layer_widget_new             (DiaLayer       *layer,
diff --git a/app/dia-list.c b/app/layer-editor/dia-list.c
similarity index 89%
rename from app/dia-list.c
rename to app/layer-editor/dia-list.c
index 80c45b96..e09a8075 100644
--- a/app/dia-list.c
+++ b/app/layer-editor/dia-list.c
@@ -29,7 +29,7 @@
 #include <gtk/gtk.h>
 
 #include "dia-list.h"
-#include "dia-list-item.h"
+#include "dia-layer-widget.h"
 
 
 typedef struct _DiaListPrivate DiaListPrivate;
@@ -38,27 +38,15 @@ struct _DiaListPrivate
   GtkContainer container;
 
   GList *children;
-  DiaListItem *selected;
+  DiaLayerWidget *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)
 {
@@ -225,7 +213,7 @@ dia_list_button_press (GtkWidget      *widget,
 
   item = gtk_get_event_widget ((GdkEvent*) event);
 
-  while (item && !DIA_IS_LIST_ITEM (item)) {
+  while (item && !DIA_IS_LAYER_WIDGET (item)) {
     item = gtk_widget_get_parent (item);
   }
 
@@ -261,7 +249,7 @@ dia_list_add (GtkContainer *container,
 {
   GList *item_list;
 
-  g_return_if_fail (DIA_IS_LIST_ITEM (widget));
+  g_return_if_fail (DIA_IS_LAYER_WIDGET (widget));
 
   item_list = g_list_alloc ();
   item_list->data = widget;
@@ -312,7 +300,7 @@ dia_list_forall (GtkContainer  *container,
 static GType
 dia_list_child_type (GtkContainer *container)
 {
-  return DIA_TYPE_LIST_ITEM;
+  return DIA_TYPE_LAYER_WIDGET;
 }
 
 
@@ -362,7 +350,7 @@ dia_list_set_focus_child (GtkContainer *container,
                                  alloc.height));
     }
 
-    dia_list_select_child (list, DIA_LIST_ITEM (child));
+    dia_list_select_child (list, DIA_LAYER_WIDGET (child));
   }
 }
 
@@ -406,53 +394,6 @@ dia_list_focus (GtkWidget        *widget,
 }
 
 
-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)
 {
@@ -475,26 +416,6 @@ dia_list_class_init (DiaListClass *klass)
   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);
 }
 
 
@@ -507,14 +428,10 @@ dia_list_init (DiaList *list)
   priv->selected = NULL;
 
   priv->last_focus_child = NULL;
-  priv->undo_focus_child = NULL;
-
-  priv->htimer = 0;
-  priv->vtimer = 0;
 }
 
 
-GtkWidget*
+GtkWidget *
 dia_list_new (void)
 {
   return g_object_new (DIA_TYPE_LIST, NULL);
@@ -522,10 +439,10 @@ dia_list_new (void)
 
 
 static void
-scroll_vertical (DiaListItem   *list_item,
-                 GtkScrollType  scroll_type,
-                 double         position,
-                 DiaList       *list)
+scroll_vertical (DiaLayerWidget *list_item,
+                 GtkScrollType   scroll_type,
+                 double          position,
+                 DiaList        *list)
 {
   GtkContainer *container;
   DiaListPrivate *priv;
@@ -782,14 +699,14 @@ dia_list_insert_items (DiaList *list,
 
   if (priv->children && !priv->selected) {
     widget = priv->children->data;
-    dia_list_select_child (list, DIA_LIST_ITEM (widget));
+    dia_list_select_child (list, DIA_LAYER_WIDGET (widget));
   }
 }
 
 
 void
 dia_list_append_items (DiaList *list,
-                           GList   *items)
+                       GList   *items)
 {
   g_return_if_fail (DIA_IS_LIST (list));
 
@@ -799,7 +716,7 @@ dia_list_append_items (DiaList *list,
 
 void
 dia_list_prepend_items (DiaList *list,
-                            GList      *items)
+                        GList   *items)
 {
   g_return_if_fail (DIA_IS_LIST (list));
 
@@ -838,7 +755,7 @@ dia_list_remove_items (DiaList *list,
     tmp_list = tmp_list->next;
 
     if (gtk_widget_get_state (widget) == GTK_STATE_SELECTED) {
-      dia_list_unselect_child (list, DIA_LIST_ITEM (widget));
+      dia_list_unselect_child (list, DIA_LAYER_WIDGET (widget));
     }
   }
 
@@ -876,10 +793,6 @@ dia_list_remove_items (DiaList *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;
     }
@@ -898,7 +811,7 @@ dia_list_remove_items (DiaList *list,
 
     if (!priv->selected) {
       priv->last_focus_child = new_focus_child;
-      dia_list_select_child (list, DIA_LIST_ITEM (new_focus_child));
+      dia_list_select_child (list, DIA_LAYER_WIDGET (new_focus_child));
     }
   }
 
@@ -910,8 +823,8 @@ dia_list_remove_items (DiaList *list,
 
 void
 dia_list_clear_items (DiaList *list,
-                          int         start,
-                          int         end)
+                      int         start,
+                      int         end)
 {
   GtkContainer *container;
   GtkWidget *widget;
@@ -984,15 +897,12 @@ dia_list_clear_items (DiaList *list,
     g_object_ref (widget);
 
     if (gtk_widget_get_state (widget) == GTK_STATE_SELECTED) {
-      dia_list_unselect_child (list, DIA_LIST_ITEM (widget));
+      dia_list_unselect_child (list, DIA_LAYER_WIDGET (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;
     }
@@ -1011,7 +921,7 @@ dia_list_clear_items (DiaList *list,
 
     if (!priv->selected) {
       priv->last_focus_child = new_focus_child;
-      dia_list_select_child (list, DIA_LIST_ITEM (new_focus_child));
+      dia_list_select_child (list, DIA_LAYER_WIDGET (new_focus_child));
     }
   }
 
@@ -1040,31 +950,66 @@ dia_list_select_item (DiaList *list,
 
 
 void
-dia_list_select_child (DiaList     *self,
-                       DiaListItem *item)
+dia_list_select_child (DiaList        *self,
+                       DiaLayerWidget *item)
 {
-  g_signal_emit (self, signals[SELECT_CHILD], 0, item);
+  DiaListPrivate *priv;
+  DiaLayerWidget *old = NULL;
+
+  g_return_if_fail (DIA_IS_LIST (self));
+  g_return_if_fail (DIA_IS_LAYER_WIDGET (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);
+
+    dia_layer_widget_select (item);
+  }
+
+  g_clear_object (&old);
 }
 
 
 void
-dia_list_unselect_child (DiaList     *self,
-                         DiaListItem *item)
+dia_list_unselect_child (DiaList        *self,
+                         DiaLayerWidget *item)
 {
-  g_signal_emit (self, signals[UNSELECT_CHILD], 0, item);
+  DiaListPrivate *priv;
+
+  g_return_if_fail (DIA_IS_LIST (self));
+  g_return_if_fail (DIA_IS_LAYER_WIDGET (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);
+
+  dia_layer_widget_deselect (item);
 }
 
 
 int
-dia_list_child_position (DiaList     *self,
-                         DiaListItem *item)
+dia_list_child_position (DiaList        *self,
+                         DiaLayerWidget *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);
+  g_return_val_if_fail (DIA_IS_LAYER_WIDGET (item), -1);
 
   priv = dia_list_get_instance_private (self);
 
@@ -1084,7 +1029,7 @@ dia_list_child_position (DiaList     *self,
 }
 
 
-DiaListItem *
+DiaLayerWidget *
 dia_list_get_selected (DiaList *self)
 {
   DiaListPrivate *priv;
diff --git a/app/layer-editor/dia-list.h b/app/layer-editor/dia-list.h
new file mode 100644
index 00000000..76b6b125
--- /dev/null
+++ b/app/layer-editor/dia-list.h
@@ -0,0 +1,70 @@
+/* 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-layer-widget.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;
+};
+
+
+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,
+                                         DiaLayerWidget *item);
+void            dia_list_unselect_child (DiaList        *self,
+                                         DiaLayerWidget *item);
+int             dia_list_child_position (DiaList        *self,
+                                         DiaLayerWidget *item);
+DiaLayerWidget *dia_list_get_selected   (DiaList        *self);
+
+G_END_DECLS
diff --git a/app/meson.build b/app/meson.build
index 2a2a92a6..083eb137 100644
--- a/app/meson.build
+++ b/app/meson.build
@@ -11,6 +11,8 @@ dia_sources = [
     'dia-change.h',
     'object_ops.c',
 
+    'layer-editor/dia-list.c',
+    'layer-editor/dia-list.h',
     'layer-editor/dia-layer-widget.c',
     'layer-editor/dia-layer-widget.h',
     'layer-editor/dia-layer-editor.c',
@@ -56,11 +58,6 @@ dia_sources = [
     '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',



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]