[dia] arrow-selector: use GtkComboBox



commit 5f2e661269259bc46c529bbebafd738c8032676a
Author: Zander Brown <zbrown gnome org>
Date:   Mon Nov 25 01:24:27 2019 +0000

    arrow-selector: use GtkComboBox
    
    Implement a simple CellRenderer based on DiaArrowPreview so we can use a GtkComoboBox instead of 
OptionMenu
    
    Arrow becomes a simple GBoxed

 lib/arrows.c                  |  28 ++++
 lib/arrows.h                  |  79 ++++++-----
 lib/dia-arrow-cell-renderer.c | 312 ++++++++++++++++++++++++++++++++++++++++++
 lib/dia-arrow-cell-renderer.h |  42 ++++++
 lib/diaarrowselector.c        | 215 +++++++++++++++++------------
 lib/meson.build               |   2 +
 6 files changed, 553 insertions(+), 125 deletions(-)
---
diff --git a/lib/arrows.c b/lib/arrows.c
index d1cf42be..9171c834 100644
--- a/lib/arrows.c
+++ b/lib/arrows.c
@@ -84,6 +84,34 @@ calculate_diamond (Point       *poly/*[4]*/,
                    real         length,
                    real         width);
 
+
+G_DEFINE_BOXED_TYPE (Arrow, dia_arrow, dia_arrow_copy, dia_arrow_free)
+
+
+Arrow *
+dia_arrow_copy (Arrow *self)
+{
+  Arrow *new;
+
+  g_return_val_if_fail (self != NULL, NULL);
+
+  new = g_new0 (Arrow, 1);
+
+  new->type = self->type;
+  new->length = self->length;
+  new->width = self->width;
+
+  return new;
+}
+
+
+void
+dia_arrow_free (Arrow *self)
+{
+  g_free (self);
+}
+
+
 /**
  * calculate_arrow_point:
  * @arrow: An arrow to calculate adjustments for.  The arrow type
diff --git a/lib/arrows.h b/lib/arrows.h
index 3419d56f..6e268f0c 100644
--- a/lib/arrows.h
+++ b/lib/arrows.h
@@ -142,41 +142,46 @@ struct _Arrow {
   real      width;
 };
 
+#define DIA_TYPE_ARROW (dia_arrow_get_type ())
 
-void          arrow_draw              (DiaRenderer *renderer,
-                                       ArrowType    type,
-                                       Point       *to,
-                                       Point       *from,
-                                       real         length,
-                                       real         width,
-                                       real         linewidth,
-                                       Color       *fg_color,
-                                       Color       *bg_color);
-void          arrow_bbox              (const Arrow *self,
-                                       real         line_width,
-                                       const Point *to,
-                                       const Point *from,
-                                       DiaRectangle *rect);
-void          calculate_arrow_point   (const Arrow *arrow,
-                                       const Point *to,
-                                       const Point *from,
-                                       Point       *move_arrow,
-                                       Point       *move_line,
-                                       real         linewidth);
-void          save_arrow              (ObjectNode   obj_node,
-                                       Arrow       *arrow,
-                                       gchar       *type_attribute,
-                                       gchar       *length_attribute,
-                                       gchar       *width_attribute,
-                                       DiaContext  *ctx);
-void         load_arrow               (ObjectNode   obj_node,
-                                       Arrow       *arrow,
-                                       gchar       *type_attribute,
-                                       gchar       *length_attribute,
-                                       gchar       *width_attribute,
-                                       DiaContext  *ctx);
-ArrowType    arrow_type_from_name     (const gchar *name);
-gint         arrow_index_from_type    (ArrowType    atype);
-ArrowType    arrow_type_from_index    (gint         index);
-const gchar *arrow_get_name_from_type (ArrowType    type);
-GList       *get_arrow_names          (void);
+
+Arrow        *dia_arrow_copy           (Arrow       *self);
+void          dia_arrow_free           (Arrow       *self);
+GType         dia_arrow_get_type       (void);
+void          arrow_draw               (DiaRenderer *renderer,
+                                        ArrowType    type,
+                                        Point       *to,
+                                        Point       *from,
+                                        real         length,
+                                        real         width,
+                                        real         linewidth,
+                                        Color       *fg_color,
+                                        Color       *bg_color);
+void          arrow_bbox               (const Arrow *self,
+                                        real         line_width,
+                                        const Point *to,
+                                        const Point *from,
+                                        DiaRectangle *rect);
+void          calculate_arrow_point    (const Arrow *arrow,
+                                        const Point *to,
+                                        const Point *from,
+                                        Point       *move_arrow,
+                                        Point       *move_line,
+                                        real         linewidth);
+void          save_arrow               (ObjectNode   obj_node,
+                                        Arrow       *arrow,
+                                        gchar       *type_attribute,
+                                        gchar       *length_attribute,
+                                        gchar       *width_attribute,
+                                        DiaContext  *ctx);
+void          load_arrow               (ObjectNode   obj_node,
+                                        Arrow       *arrow,
+                                        gchar       *type_attribute,
+                                        gchar       *length_attribute,
+                                        gchar       *width_attribute,
+                                        DiaContext  *ctx);
+ArrowType     arrow_type_from_name     (const gchar *name);
+gint          arrow_index_from_type    (ArrowType    atype);
+ArrowType     arrow_type_from_index    (gint         index);
+const gchar  *arrow_get_name_from_type (ArrowType    type);
+GList        *get_arrow_names          (void);
diff --git a/lib/dia-arrow-cell-renderer.c b/lib/dia-arrow-cell-renderer.c
new file mode 100644
index 00000000..f31d6a4a
--- /dev/null
+++ b/lib/dia-arrow-cell-renderer.c
@@ -0,0 +1,312 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright © 2019 Zander Brown <zbrown gnome org>
+ */
+
+#include <config.h>
+#include "intl.h"
+#include <gtk/gtk.h>
+#include "dia-arrow-cell-renderer.h"
+#include "renderer/diacairo.h"
+#include "diarenderer.h"
+#include "arrows.h"
+
+#define ARROW_LINEWIDTH 2
+
+typedef struct _DiaArrowCellRendererPrivate DiaArrowCellRendererPrivate;
+struct _DiaArrowCellRendererPrivate {
+  DiaRenderer *renderer;
+  Arrow       *arrow;
+  gboolean     point_left;
+};
+
+
+G_DEFINE_TYPE_WITH_PRIVATE (DiaArrowCellRenderer, dia_arrow_cell_renderer, GTK_TYPE_CELL_RENDERER)
+
+
+enum {
+  PROP_0,
+  PROP_ARROW,
+  PROP_RENDERER,
+  PROP_POINT_LEFT,
+  LAST_PROP
+};
+static GParamSpec *pspecs[LAST_PROP] = { NULL, };
+
+
+static void
+dia_arrow_cell_renderer_get_property (GObject    *object,
+                                      guint       param_id,
+                                      GValue     *value,
+                                      GParamSpec *pspec)
+{
+  DiaArrowCellRenderer *self = DIA_ARROW_CELL_RENDERER (object);
+  DiaArrowCellRendererPrivate *priv = dia_arrow_cell_renderer_get_instance_private (self);
+
+  switch (param_id) {
+    case PROP_RENDERER:
+      g_value_set_object (value, priv->renderer);
+      break;
+
+    case PROP_ARROW:
+      g_value_set_boxed (value, priv->arrow);
+      break;
+
+    case PROP_POINT_LEFT:
+      g_value_set_boolean (value, priv->point_left);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+      break;
+  }
+}
+
+
+static void
+dia_arrow_cell_renderer_set_property (GObject      *object,
+                                          guint         param_id,
+                                          const GValue *value,
+                                          GParamSpec   *pspec)
+{
+  DiaArrowCellRenderer *self = DIA_ARROW_CELL_RENDERER (object);
+  DiaArrowCellRendererPrivate *priv = dia_arrow_cell_renderer_get_instance_private (self);
+
+  switch (param_id) {
+    case PROP_RENDERER:
+      g_clear_object (&priv->renderer);
+      priv->renderer = g_value_dup_object (value);
+      break;
+
+    case PROP_ARROW:
+      g_clear_pointer (&priv->arrow, dia_arrow_free);
+      priv->arrow = g_value_dup_boxed (value);
+      break;
+
+    case PROP_POINT_LEFT:
+      priv->point_left = g_value_get_boolean (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+      break;
+    }
+}
+
+
+static void
+dia_arrow_cell_renderer_finalize (GObject *object)
+{
+  DiaArrowCellRenderer *self = DIA_ARROW_CELL_RENDERER (object);
+  DiaArrowCellRendererPrivate *priv = dia_arrow_cell_renderer_get_instance_private (self);
+
+  g_clear_object (&priv->renderer);
+  g_clear_pointer (&priv->arrow, dia_arrow_free);
+
+  G_OBJECT_CLASS (dia_arrow_cell_renderer_parent_class)->finalize (object);
+}
+
+
+static void
+dia_arrow_cell_renderer_get_size (GtkCellRenderer *cell,
+                                  GtkWidget       *widget,
+                                  GdkRectangle    *cell_area,
+                                  gint            *x_offset,
+                                  gint            *y_offset,
+                                  gint            *width,
+                                  gint            *height)
+{
+  gint calc_width;
+  gint calc_height;
+  int  xpad;
+  int  ypad;
+
+  gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
+
+  calc_width  = (gint) xpad * 2 + 40;
+  calc_height = (gint) ypad * 2 + 20;
+
+  if (x_offset) *x_offset = 0;
+  if (y_offset) *y_offset = 0;
+
+  if (width)  *width  = calc_width;
+  if (height) *height = calc_height;
+}
+
+
+static void
+dia_arrow_cell_renderer_render (GtkCellRenderer      *cell,
+                                GdkWindow            *window,
+                                GtkWidget            *widget,
+                                GdkRectangle         *background_area,
+                                GdkRectangle         *cell_area,
+                                GdkRectangle         *expose_area,
+                                GtkCellRendererState  flags)
+{
+  DiaArrowCellRenderer *self = DIA_ARROW_CELL_RENDERER (cell);
+  DiaArrowCellRendererPrivate *priv = dia_arrow_cell_renderer_get_instance_private (self);
+  Point from, to;
+  Point move_arrow, move_line, arrow_head;
+  gint width, height;
+  gint x, y;
+  cairo_t *ctx;
+  int xpad, ypad;
+  Arrow tmp_arrow;
+  Color colour_fg;
+  Color colour_bg = { 0.0, 0.0, 0.0, 0.0 };
+  GtkStyle *style = gtk_widget_get_style (widget);
+  GdkColor fg = style->text[gtk_widget_get_state(widget)];
+
+  GDK_COLOR_TO_DIA (fg, colour_fg);
+
+  gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
+
+  ctx = gdk_cairo_create (GDK_DRAWABLE (window));
+
+  g_return_if_fail (DIA_CAIRO_IS_RENDERER (priv->renderer));
+
+  width = cell_area->width - xpad * 2;
+  height = cell_area->height - ypad * 2;
+  x = (cell_area->x + xpad);
+  y = (cell_area->y + ypad);
+
+  to.y = from.y = height/2;
+  if (priv->point_left) {
+    from.x = width - ARROW_LINEWIDTH;
+    to.x = 0;
+  } else {
+    from.x = 0;
+    to.x = width - ARROW_LINEWIDTH;
+  }
+
+  /* here we must do some acrobaticts and construct Arrow type
+    * variable
+    */
+  tmp_arrow.type = priv->arrow->type;
+  tmp_arrow.length = .75 * ((double) height - ARROW_LINEWIDTH);
+  tmp_arrow.width = .75 * ((double) height - ARROW_LINEWIDTH);
+
+  /* and here we calculate new arrow start and end of line points */
+  calculate_arrow_point (&tmp_arrow,
+                         &from, &to,
+                         &move_arrow,
+                         &move_line,
+                         ARROW_LINEWIDTH);
+  arrow_head = to;
+  point_add (&arrow_head, &move_arrow);
+  point_add (&to, &move_line);
+
+  dia_renderer_begin_render (DIA_RENDERER (priv->renderer), NULL);
+  dia_renderer_set_linewidth (DIA_RENDERER (priv->renderer),
+                              ARROW_LINEWIDTH);
+
+  dia_renderer_draw_line (DIA_RENDERER (priv->renderer),
+                          &from,
+                          &to,
+                          &colour_fg);
+  arrow_draw (DIA_RENDERER (priv->renderer),
+              tmp_arrow.type,
+              &arrow_head,
+              &from,
+              tmp_arrow.length,
+              tmp_arrow.width,
+              ARROW_LINEWIDTH,
+              &colour_fg,
+              &colour_bg);
+
+  dia_renderer_end_render (DIA_RENDERER (priv->renderer));
+
+  cairo_set_source_surface (ctx, DIA_CAIRO_RENDERER (priv->renderer)->surface, x, y);
+  cairo_paint (ctx);
+}
+
+
+static void
+dia_arrow_cell_renderer_class_init (DiaArrowCellRendererClass *klass)
+{
+  GObjectClass         *object_class = G_OBJECT_CLASS (klass);
+  GtkCellRendererClass *cell_class   = GTK_CELL_RENDERER_CLASS (klass);
+
+  object_class->set_property = dia_arrow_cell_renderer_set_property;
+  object_class->get_property = dia_arrow_cell_renderer_get_property;
+  object_class->finalize = dia_arrow_cell_renderer_finalize;
+
+  cell_class->get_size = dia_arrow_cell_renderer_get_size;
+  cell_class->render = dia_arrow_cell_renderer_render;
+
+  /**
+   * DiaArrowCellRenderer:renderer:
+   *
+   * Since: 0.98
+   */
+  pspecs[PROP_RENDERER] =
+    g_param_spec_object ("renderer",
+                         "Renderer",
+                         "Renderer to draw arrows",
+                         DIA_TYPE_RENDERER,
+                         G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+
+  /**
+   * DiaArrowCellRenderer:arrow:
+   *
+   * Since: 0.98
+   */
+  pspecs[PROP_ARROW] =
+    g_param_spec_boxed ("arrow",
+                        "Arrow",
+                        "Arrow to draw",
+                        DIA_TYPE_ARROW,
+                        G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+
+  /**
+   * DiaArrowCellRenderer:point-left:
+   *
+   * Since: 0.98
+   */
+  pspecs[PROP_POINT_LEFT] =
+    g_param_spec_boolean ("point-left",
+                          "Point Left",
+                          "Arrow to should be pointing to the left",
+                          FALSE,
+                          G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+
+  g_object_class_install_properties (object_class, LAST_PROP, pspecs);
+}
+
+
+static void
+dia_arrow_cell_renderer_init (DiaArrowCellRenderer *self)
+{
+  DiaArrowCellRendererPrivate *priv = dia_arrow_cell_renderer_get_instance_private (self);
+
+  priv->point_left = FALSE;
+
+  priv->renderer = g_object_new (DIA_CAIRO_TYPE_RENDERER, NULL);
+
+  DIA_CAIRO_RENDERER (priv->renderer)->surface = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA, 
NULL);
+  DIA_CAIRO_RENDERER (priv->renderer)->with_alpha = TRUE;
+}
+
+
+GtkCellRenderer *
+dia_arrow_cell_renderer_new (void)
+{
+  return g_object_new (DIA_TYPE_ARROW_CELL_RENDERER, NULL);
+}
diff --git a/lib/dia-arrow-cell-renderer.h b/lib/dia-arrow-cell-renderer.h
new file mode 100644
index 00000000..88d3e535
--- /dev/null
+++ b/lib/dia-arrow-cell-renderer.h
@@ -0,0 +1,42 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright © 2019 Zander Brown <zbrown gnome org>
+ */
+
+#include <gtk/gtk.h>
+
+#pragma once
+
+G_BEGIN_DECLS
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (GtkCellRenderer, g_object_unref)
+
+#define DIA_TYPE_ARROW_CELL_RENDERER dia_arrow_cell_renderer_get_type ()
+G_DECLARE_DERIVABLE_TYPE (DiaArrowCellRenderer, dia_arrow_cell_renderer, DIA, ARROW_CELL_RENDERER, 
GtkCellRenderer)
+
+struct _DiaArrowCellRendererClass {
+  GtkCellRendererClass parent_class;
+};
+
+
+GtkCellRenderer *dia_arrow_cell_renderer_new (void);
+
+
+G_END_DECLS
diff --git a/lib/diaarrowselector.c b/lib/diaarrowselector.c
index 9812f09f..8ad7a4d8 100644
--- a/lib/diaarrowselector.c
+++ b/lib/diaarrowselector.c
@@ -24,10 +24,17 @@
 #include "widgets.h"
 #include "arrows.h"
 #include "diaarrowchooser.h"
-#include "diadynamicmenu.h"
+#include "dia-arrow-cell-renderer.h"
 
 /************* DiaArrowSelector: ***************/
 
+
+enum {
+  COL_ARROW,
+  N_COL
+};
+
+
 /* FIXME: Should these structs be in widgets.h instead? */
 struct _DiaArrowSelector
 {
@@ -36,8 +43,11 @@ struct _DiaArrowSelector
   GtkHBox *sizebox;
   GtkLabel *sizelabel;
   DiaSizeSelector *size;
-  
-  GtkWidget *omenu;
+
+  GtkWidget    *combo;
+  GtkListStore *arrow_store;
+
+  ArrowType     looking_for;
 };
 
 struct _DiaArrowSelectorClass
@@ -45,6 +55,8 @@ struct _DiaArrowSelectorClass
   GtkVBoxClass parent_class;
 };
 
+G_DEFINE_TYPE (DiaArrowSelector, dia_arrow_selector, GTK_TYPE_VBOX)
+
 enum {
     DAS_VALUE_CHANGED,
     DAS_LAST_SIGNAL
@@ -63,28 +75,41 @@ dia_arrow_selector_class_init (DiaArrowSelectorClass *class)
                     g_cclosure_marshal_VOID__VOID,
                     G_TYPE_NONE, 0);
 }
-  
+
+
 static void
-set_size_sensitivity(DiaArrowSelector *as)
+set_size_sensitivity (DiaArrowSelector *as)
 {
-  int state;
-  gchar *entryname = dia_dynamic_menu_get_entry(DIA_DYNAMIC_MENU(as->omenu));
+  GtkTreeIter iter;
+
+  if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (as->combo), &iter)) {
+    Arrow *active = NULL;
+
+    gtk_tree_model_get (GTK_TREE_MODEL (as->arrow_store),
+                        &iter,
+                        COL_ARROW, &active,
+                        -1);
 
-  state = (entryname != NULL) && (0 != g_ascii_strcasecmp(entryname, "None"));
-  g_free(entryname);
+    gtk_widget_set_sensitive (GTK_WIDGET (as->sizelabel), active->type != ARROW_NONE);
+    gtk_widget_set_sensitive (GTK_WIDGET (as->size), active->type != ARROW_NONE);
 
-  gtk_widget_set_sensitive(GTK_WIDGET(as->sizelabel), state);
-  gtk_widget_set_sensitive(GTK_WIDGET(as->size), state);
+    dia_arrow_free (active);
+  } else {
+    gtk_widget_set_sensitive (GTK_WIDGET (as->sizelabel), FALSE);
+    gtk_widget_set_sensitive (GTK_WIDGET (as->size), FALSE);
+  }
 }
 
+
 static void
-arrow_type_change_callback(DiaDynamicMenu *ddm, gpointer userdata)
+arrow_type_change_callback (GtkComboBox *widget, gpointer userdata)
 {
-  set_size_sensitivity(DIA_ARROW_SELECTOR(userdata));
-  g_signal_emit(DIA_ARROW_SELECTOR(userdata),
-               das_signals[DAS_VALUE_CHANGED], 0);
+  set_size_sensitivity (DIA_ARROW_SELECTOR (userdata));
+  g_signal_emit (DIA_ARROW_SELECTOR (userdata),
+                 das_signals[DAS_VALUE_CHANGED], 0);
 }
 
+
 static void
 arrow_size_change_callback(DiaSizeSelector *size, gpointer userdata)
 {
@@ -92,47 +117,44 @@ arrow_size_change_callback(DiaSizeSelector *size, gpointer userdata)
                das_signals[DAS_VALUE_CHANGED], 0);
 }
 
-static GtkWidget *
-create_arrow_menu_item(DiaDynamicMenu *ddm, gchar *name)
-{
-  ArrowType atype = arrow_type_from_name(name);
-  GtkWidget *item = gtk_menu_item_new();
-  GtkWidget *preview;
-
-  preview = dia_arrow_preview_new(atype, FALSE);
-
-  gtk_widget_show(preview);
-  gtk_container_add(GTK_CONTAINER(item), preview);
-  gtk_widget_show(item);
-  return item;
-}
 
 static void
-dia_arrow_selector_init (DiaArrowSelector *as,
-                        gpointer g_class)
+dia_arrow_selector_init (DiaArrowSelector *as)
 {
-  GtkWidget *omenu;
   GtkWidget *box;
   GtkWidget *label;
   GtkWidget *size;
-  
-  GList *arrow_names = get_arrow_names();
-  as->omenu = 
-  omenu = dia_dynamic_menu_new_listbased(create_arrow_menu_item,
-                                        as,
-                                        _("More arrows"),
-                                        arrow_names,
-                                        "arrow-menu");
-  dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(omenu), "None");
-  dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(omenu), "Lines");
-  dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(omenu), "Filled Concave");
-
-  gtk_box_pack_start(GTK_BOX(as), omenu, FALSE, TRUE, 0);
-  gtk_widget_show(omenu);
-
-  g_signal_connect(DIA_DYNAMIC_MENU(omenu),
-                  "value-changed", G_CALLBACK(arrow_type_change_callback),
-                  as);
+  GtkTreeIter iter;
+  GtkCellRenderer *renderer;
+
+  as->arrow_store = gtk_list_store_new (N_COL, DIA_TYPE_ARROW);
+
+  for (int i = ARROW_NONE; i < MAX_ARROW_TYPE; ++i) {
+    ArrowType arrow_type = arrow_type_from_index (i);
+    Arrow arrow = { arrow_type, 0.5, 0.5 };
+
+    gtk_list_store_append (as->arrow_store, &iter);
+    gtk_list_store_set (as->arrow_store,
+                        &iter,
+                        COL_ARROW, &arrow,
+                        -1);
+  }
+
+  as->combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (as->arrow_store));
+  g_signal_connect (as->combo,
+                    "changed",
+                    G_CALLBACK (arrow_type_change_callback),
+                    as);
+
+  renderer = dia_arrow_cell_renderer_new ();
+  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (as->combo), renderer, TRUE);
+  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (as->combo),
+                                  renderer,
+                                  "arrow", COL_ARROW,
+                                  NULL);
+
+  gtk_box_pack_start (GTK_BOX (as), as->combo, FALSE, TRUE, 0);
+  gtk_widget_show (as->combo);
 
   box = gtk_hbox_new(FALSE,0);
   as->sizebox = GTK_HBOX(box);
@@ -155,57 +177,74 @@ dia_arrow_selector_init (DiaArrowSelector *as,
   gtk_widget_show(box);
 }
 
-GType
-dia_arrow_selector_get_type        (void)
-{
-  static GType dfs_type = 0;
-
-  if (!dfs_type) {
-    static const GTypeInfo dfs_info = {
-      sizeof (DiaArrowSelectorClass),
-      (GBaseInitFunc) NULL,
-      (GBaseFinalizeFunc) NULL,
-      (GClassInitFunc) dia_arrow_selector_class_init,
-      NULL, /* class_finalize */
-      NULL, /* class_data */
-      sizeof (DiaArrowSelector),
-      0,    /* n_preallocs */
-      (GInstanceInitFunc)dia_arrow_selector_init,  /* init */
-    };
-    
-    dfs_type = g_type_register_static (GTK_TYPE_VBOX,
-                                      "DiaArrowSelector",
-                                      &dfs_info, 0);
-  }
-  
-  return dfs_type;
-}
 
 GtkWidget *
-dia_arrow_selector_new ()
+dia_arrow_selector_new (void)
 {
-  return GTK_WIDGET ( g_object_new (DIA_TYPE_ARROW_SELECTOR, NULL));
+  return g_object_new (DIA_TYPE_ARROW_SELECTOR, NULL);
 }
 
 
-Arrow 
-dia_arrow_selector_get_arrow(DiaArrowSelector *as)
+Arrow
+dia_arrow_selector_get_arrow (DiaArrowSelector *as)
 {
   Arrow at;
-  gchar *arrowname = dia_dynamic_menu_get_entry(DIA_DYNAMIC_MENU(as->omenu));
+  GtkTreeIter iter;
+
+  if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (as->combo), &iter)) {
+    Arrow *active = NULL;
+
+    gtk_tree_model_get (GTK_TREE_MODEL (as->arrow_store),
+                        &iter,
+                        COL_ARROW, &active,
+                        -1);
+
+    at.type = active->type;
+
+    dia_arrow_free (active);
+  } else {
+    at.type = ARROW_NONE;
+  }
+
+  dia_size_selector_get_size (as->size, &at.width, &at.length);
 
-  at.type = arrow_type_from_name(arrowname);
-  g_free(arrowname);
-  dia_size_selector_get_size(as->size, &at.width, &at.length);
   return at;
 }
 
+
+static gboolean
+set_type (GtkTreeModel *model,
+          GtkTreePath  *path,
+          GtkTreeIter  *iter,
+          gpointer      data)
+{
+  DiaArrowSelector *self = DIA_ARROW_SELECTOR (data);
+  Arrow *arrow;
+  gboolean res = FALSE;
+
+  gtk_tree_model_get (model,
+                      iter,
+                      COL_ARROW, &arrow,
+                      -1);
+
+  res = arrow->type == self->looking_for;
+  if (res) {
+    gtk_combo_box_set_active_iter (GTK_COMBO_BOX (self->combo), iter);
+  }
+
+  dia_arrow_free (arrow);
+
+  return res;
+}
+
+
 void
 dia_arrow_selector_set_arrow (DiaArrowSelector *as,
-                             Arrow arrow)
+                              Arrow             arrow)
 {
-  dia_dynamic_menu_select_entry(DIA_DYNAMIC_MENU(as->omenu),
-                               arrow_get_name_from_type(arrow.type));
-  set_size_sensitivity(as);
-  dia_size_selector_set_size(DIA_SIZE_SELECTOR(as->size), arrow.width, arrow.length);
+  as->looking_for = arrow.type;
+  gtk_tree_model_foreach (GTK_TREE_MODEL (as->arrow_store), set_type, as);
+  as->looking_for = ARROW_NONE;
+
+  dia_size_selector_set_size (DIA_SIZE_SELECTOR (as->size), arrow.width, arrow.length);
 }
diff --git a/lib/meson.build b/lib/meson.build
index 776b21e7..d80c3295 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -152,6 +152,8 @@ libdia_sources = stdprop_sources + [
     'dialib.c',
     'diacontext.c',
     'diacellrendererenum.c',
+    'dia-arrow-cell-renderer.c',
+    'dia-arrow-cell-renderer.h',
 ]
 
 gnome = import('gnome')


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