[dia/dia-next: 35/59] Merge DiaArrowChooser/DiaArrowSelector



commit f484bb17aa7560294bf1f35d67895c5518550660
Author: Zander Brown <zbrown gnome org>
Date:   Sat Dec 29 03:03:15 2018 +0000

    Merge DiaArrowChooser/DiaArrowSelector

 app/toolbox.c                     |  20 +-
 data/dia-arrow-chooser-popover.ui |  87 +++++++
 lib/Makefile.am                   |   5 +-
 lib/dia-line-style-selector.c     | 107 ++++----
 lib/diaarrowchooser.c             | 478 -----------------------------------
 lib/diaarrowchooser.h             |  99 --------
 lib/diaarrowselector.c            | 214 ----------------
 lib/libdia.def                    |   8 -
 lib/prop_attr.c                   |  12 +-
 lib/widgets.h                     |  14 --
 lib/widgets/dia-arrow-chooser.c   | 508 ++++++++++++++++++++++++++++++++++++++
 lib/widgets/dia-arrow-chooser.h   |  75 ++++++
 12 files changed, 744 insertions(+), 883 deletions(-)
---
diff --git a/app/toolbox.c b/app/toolbox.c
index 50ab4df3..0c9eba52 100644
--- a/app/toolbox.c
+++ b/app/toolbox.c
@@ -20,13 +20,13 @@
 
 #include <gtk/gtk.h>
 
-#include "diaarrowchooser.h"
 #include "diadynamicmenu.h"
 #include "attributes.h"
 #include "sheet.h"
 #include "dia-colour-area.h"
 #include "dia-line-width-area.h"
 #include "widgets/dia-sheet-chooser.h"
+#include "widgets/dia-arrow-chooser.h"
 #include "intl.h"
 #include "message.h"
 #include "object.h"
@@ -444,15 +444,17 @@ create_color_area (DiaToolbox *self)
 }
 
 static void
-change_start_arrow_style(Arrow arrow, gpointer user_data)
+change_start_arrow_style (DiaArrowChooser *chooser, gpointer user_data)
 {
-  attributes_set_default_start_arrow(arrow);
+  attributes_set_default_start_arrow (dia_arrow_chooser_get_arrow (chooser));
 }
+
 static void
-change_end_arrow_style(Arrow arrow, gpointer user_data)
+change_end_arrow_style (DiaArrowChooser *chooser, gpointer user_data)
 {
-  attributes_set_default_end_arrow(arrow);
+  attributes_set_default_end_arrow (dia_arrow_chooser_get_arrow (chooser));
 }
+
 static void
 change_line_style(DiaLineStyleSelector *selector, gpointer user_data)
 {
@@ -479,7 +481,9 @@ create_lineprops_area (DiaToolbox *self)
   gtk_box_pack_end (GTK_BOX (self), box, FALSE, FALSE, 0);
   gtk_widget_show (box);
 
-  chooser = dia_arrow_chooser_new (TRUE, change_start_arrow_style, NULL);
+  chooser = dia_arrow_chooser_new (TRUE);
+  g_signal_connect (G_OBJECT (chooser), "value-changed",
+                    G_CALLBACK (change_start_arrow_style), NULL);
   gtk_container_add (GTK_CONTAINER (box), chooser);
   arrow.width = persistence_register_real ("start-arrow-width", DEFAULT_ARROW_WIDTH);
   arrow.length = persistence_register_real ("start-arrow-length", DEFAULT_ARROW_LENGTH);
@@ -501,7 +505,9 @@ create_lineprops_area (DiaToolbox *self)
   dia_line_style_selector_set_line_style (DIA_LINE_STYLE_SELECTOR (chooser), style, dash_length);
   gtk_widget_show (chooser);
 
-  chooser = dia_arrow_chooser_new (FALSE, change_end_arrow_style, NULL);
+  chooser = dia_arrow_chooser_new (FALSE);
+  g_signal_connect (G_OBJECT (chooser), "value-changed",
+                    G_CALLBACK (change_end_arrow_style), NULL);
   gtk_container_add (GTK_CONTAINER (box), chooser);
   arrow.width = persistence_register_real ("end-arrow-width", DEFAULT_ARROW_WIDTH);
   arrow.length = persistence_register_real ("end-arrow-length", DEFAULT_ARROW_LENGTH);
diff --git a/data/dia-arrow-chooser-popover.ui b/data/dia-arrow-chooser-popover.ui
new file mode 100644
index 00000000..21d2cb35
--- /dev/null
+++ b/data/dia-arrow-chooser-popover.ui
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface>
+  <requires lib="gtk+" version="3.20"/>
+  <template class="DiaArrowChooserPopover" parent="GtkPopover">
+    <property name="can_focus">False</property>
+    <child>
+      <object class="GtkBox">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_left">8</property>
+        <property name="margin_right">8</property>
+        <property name="margin_top">8</property>
+        <property name="margin_bottom">8</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">16</property>
+        <child>
+          <object class="GtkScrolledWindow">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="shadow_type">etched-in</property>
+            <property name="min_content_width">150</property>
+            <property name="max_content_width">150</property>
+            <property name="max_content_height">200</property>
+            <property name="propagate_natural_width">True</property>
+            <property name="propagate_natural_height">True</property>
+            <child>
+              <object class="GtkViewport">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="shadow_type">none</property>
+                <child>
+                  <object class="GtkListBox" id="list">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                  </object>
+                </child>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="size_box">
+            <property name="visible">True</property>
+            <property name="sensitive">False</property>
+            <property name="can_focus">False</property>
+            <property name="spacing">16</property>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Size</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="DiaSizeSelector" id="size">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="pack_type">end</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/lib/Makefile.am b/lib/Makefile.am
index bd9692bb..7b65fd30 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -189,9 +189,8 @@ libdia_la_SOURCES =  \
                autoroute.h \
                parent.c \
                parent.h \
-               diaarrowchooser.h \
-               diaarrowchooser.c \
-               diaarrowselector.c \
+               widgets/dia-arrow-chooser.h \
+               widgets/dia-arrow-chooser.c \
                diacolorselector.c \
                dia-line-style-selector-popover.c \
                dia-line-style-selector.c \
diff --git a/lib/dia-line-style-selector.c b/lib/dia-line-style-selector.c
index 77051d32..865f0b9d 100644
--- a/lib/dia-line-style-selector.c
+++ b/lib/dia-line-style-selector.c
@@ -38,58 +38,62 @@ dia_line_preview_draw (GtkWidget *widget, cairo_t *ctx)
   gint width, height;
   double dash[6];
   int length;
+  GdkRGBA fg;
+  GtkStyleContext *context = gtk_widget_get_style_context (widget);
+
+  gtk_style_context_get_color (context, gtk_widget_get_state_flags (widget), &fg);
+  gdk_cairo_set_source_rgba (ctx, &fg);
 
   gtk_widget_get_allocation (widget, &alloc);
 
-  if (gtk_widget_is_drawable (widget)) {
-    width = alloc.width;
-    height = alloc.height;
-    length = line->length * 20;
-
-    cairo_set_line_cap (ctx, CAIRO_LINE_CAP_BUTT);
-    cairo_set_line_join (ctx, CAIRO_LINE_JOIN_MITER);
-
-    /* Adapted from DiaCairoRenderer, TODO: Avoid duplication */
-    switch (line->lstyle) {
-      case LINESTYLE_DEFAULT:
-      case LINESTYLE_SOLID:
-        cairo_set_dash (ctx, NULL, 0, 0);
-        break;
-      case LINESTYLE_DASHED:
-        dash[0] = length;
-        dash[1] = length;
-        cairo_set_dash (ctx, dash, 2, 0);
-        break;
-      case LINESTYLE_DASH_DOT:
-        dash[0] = length;
-        dash[1] = length * 0.45;
-        dash[2] = length * 0.1;
-        dash[3] = length * 0.45;
-        cairo_set_dash (ctx, dash, 4, 0);
-        break;
-      case LINESTYLE_DASH_DOT_DOT:
-        dash[0] = length;
-        dash[1] = length * (0.8/3);
-        dash[2] = length * 0.1;
-        dash[3] = length * (0.8/3);
-        dash[4] = length * 0.1;
-        dash[5] = length * (0.8/3);
-        cairo_set_dash (ctx, dash, 6, 0);
-        break;
-      case LINESTYLE_DOTTED:
-        dash[0] = length * 0.1;
-        dash[1] = length * 0.1;
-        cairo_set_dash (ctx, dash, 2, 0);
-        break;
-      default:
-        g_warning("DiaLinePreview : Unsupported line style specified!");
-    }
-
-    cairo_move_to (ctx, 0, height / 2);
-    cairo_line_to (ctx, width, height / 2);
-    cairo_stroke (ctx);
+  width = alloc.width;
+  height = alloc.height;
+  length = line->length * 20;
+
+  cairo_set_line_cap (ctx, CAIRO_LINE_CAP_BUTT);
+  cairo_set_line_join (ctx, CAIRO_LINE_JOIN_MITER);
+
+  /* Adapted from DiaCairoRenderer, TODO: Avoid duplication */
+  switch (line->lstyle) {
+    case LINESTYLE_DEFAULT:
+    case LINESTYLE_SOLID:
+      cairo_set_dash (ctx, NULL, 0, 0);
+      break;
+    case LINESTYLE_DASHED:
+      dash[0] = length;
+      dash[1] = length;
+      cairo_set_dash (ctx, dash, 2, 0);
+      break;
+    case LINESTYLE_DASH_DOT:
+      dash[0] = length;
+      dash[1] = length * 0.45;
+      dash[2] = length * 0.1;
+      dash[3] = length * 0.45;
+      cairo_set_dash (ctx, dash, 4, 0);
+      break;
+    case LINESTYLE_DASH_DOT_DOT:
+      dash[0] = length;
+      dash[1] = length * (0.8/3);
+      dash[2] = length * 0.1;
+      dash[3] = length * (0.8/3);
+      dash[4] = length * 0.1;
+      dash[5] = length * (0.8/3);
+      cairo_set_dash (ctx, dash, 6, 0);
+      break;
+    case LINESTYLE_DOTTED:
+      dash[0] = length * 0.1;
+      dash[1] = length * 0.1;
+      cairo_set_dash (ctx, dash, 2, 0);
+      break;
+    default:
+      g_warning("DiaLinePreview : Unsupported line style specified!");
   }
-  return TRUE;
+
+  cairo_move_to (ctx, 0, height / 2);
+  cairo_line_to (ctx, width, height / 2);
+  cairo_stroke (ctx);
+
+  return FALSE;
 }
 
 static void
@@ -105,7 +109,7 @@ static void
 dia_line_preview_init (DiaLinePreview *self)
 {
   gtk_widget_set_has_window (GTK_WIDGET (self), FALSE);
-  gtk_widget_set_size_request (GTK_WIDGET (self), -1, 16);
+  gtk_widget_set_size_request (GTK_WIDGET (self), -1, 24);
 
   self->lstyle = LINESTYLE_SOLID;
   self->length = 1; /* For clarity we default quite big */
@@ -187,7 +191,6 @@ static void
 dia_line_style_selector_init (DiaLineStyleSelector *self)
 {
   GtkWidget *box;
-  GtkWidget *arrow;
   DiaLineStyleSelectorPrivate *priv = dia_line_style_selector_get_instance_private (self);
 
   box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 16);
@@ -197,10 +200,6 @@ dia_line_style_selector_init (DiaLineStyleSelector *self)
   priv->preview = dia_line_preview_new (DEFAULT_LINESTYLE);
   gtk_widget_show (priv->preview);
   gtk_box_pack_start (GTK_BOX (box), priv->preview, TRUE, TRUE, 0);
-
-  arrow = gtk_image_new_from_icon_name ("pan-down-symbolic", GTK_ICON_SIZE_BUTTON);
-  gtk_widget_show (arrow);
-  gtk_box_pack_end (GTK_BOX (box), arrow, FALSE, FALSE, 0);
  
   priv->popover = dia_line_style_selector_popover_new ();
   dia_line_style_selector_popover_set_line_style (DIA_LINE_STYLE_SELECTOR_POPOVER (priv->popover),
diff --git a/lib/libdia.def b/lib/libdia.def
index 4af8a80d..ebd01da9 100644
--- a/lib/libdia.def
+++ b/lib/libdia.def
@@ -184,14 +184,6 @@ EXPORTS
  dia_alignment_selector_get_alignment
  dia_alignment_selector_new
  dia_alignment_selector_set_alignment
- dia_arrow_chooser_new
- dia_arrow_chooser_set_arrow
- dia_arrow_chooser_get_arrow_type
- dia_arrow_chooser_get_type
- dia_arrow_selector_get_arrow
- dia_arrow_selector_get_type
- dia_arrow_selector_new
- dia_arrow_selector_set_arrow
  dia_assert_true
  dia_color_selector_get_color
 ; dia_color_selector_get_type
diff --git a/lib/prop_attr.c b/lib/prop_attr.c
index 8f0369b2..bc69e5a6 100644
--- a/lib/prop_attr.c
+++ b/lib/prop_attr.c
@@ -31,7 +31,7 @@
 #include "widgets.h"
 #include "properties.h"
 #include "propinternals.h"
-#include "diaarrowchooser.h"
+#include "widgets/dia-arrow-chooser.h"
 #include "diafontselector.h"
 
 /***************************/
@@ -172,7 +172,7 @@ arrowprop_copy(ArrowProperty *src)
 static WIDGET *
 arrowprop_get_widget(ArrowProperty *prop, PropDialog *dialog)
 {
-  GtkWidget *ret = dia_arrow_selector_new();
+  GtkWidget *ret = dia_arrow_chooser_new (FALSE);
   prophandler_connect(&prop->common, G_OBJECT(ret), "value-changed");
   return ret;
 }
@@ -180,14 +180,14 @@ arrowprop_get_widget(ArrowProperty *prop, PropDialog *dialog)
 static void 
 arrowprop_reset_widget(ArrowProperty *prop, WIDGET *widget)
 {
-  dia_arrow_selector_set_arrow(DIA_ARROW_SELECTOR(widget),
-                               prop->arrow_data);
+  dia_arrow_chooser_set_arrow (DIA_ARROW_CHOOSER (widget),
+                               &prop->arrow_data);
 }
 
 static void 
-arrowprop_set_from_widget(ArrowProperty *prop, WIDGET *widget) 
+arrowprop_set_from_widget (ArrowProperty *prop, WIDGET *widget) 
 {
-  prop->arrow_data = dia_arrow_selector_get_arrow(DIA_ARROW_SELECTOR(widget));
+  prop->arrow_data = dia_arrow_chooser_get_arrow (DIA_ARROW_CHOOSER (widget));
 }
 
 static void 
diff --git a/lib/widgets.h b/lib/widgets.h
index e1517c27..aeaba571 100644
--- a/lib/widgets.h
+++ b/lib/widgets.h
@@ -46,24 +46,10 @@ void       dia_color_selector_set_color (GtkWidget *cs,
 
 
 /* DiaArrowSelector */
-#define DIA_TYPE_ARROW_SELECTOR           (dia_arrow_selector_get_type())
-#define DIA_ARROW_SELECTOR(obj)           (G_TYPE_CHECK_INSTANCE_CAST (obj, dia_arrow_selector_get_type (), 
DiaArrowSelector))
-#define DIA_ARROW_SELECTOR_CLASS(klass)   (G_TYPE_CHECK_CLASS_CAST (klass, dia_arrow_selector_get_type (), 
DiaArrowSelectorClass))
-#define DIA_IS_ARROW_SELECTOR(obj)        (G_TYPE_CHECK_TYPE (obj, dia_arrow_selector_get_type ()))
-#define DIA_ARROW_SELECTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DIA_TYPE_ARROW_SELECTOR, 
DiaArrowSelectorClass))
-
 #define DEFAULT_ARROW ARROW_NONE
 #define DEFAULT_ARROW_LENGTH DEFAULT_ARROW_SIZE
 #define DEFAULT_ARROW_WIDTH DEFAULT_ARROW_SIZE
 
-
-GType    dia_arrow_selector_get_type        (void);
-GtkWidget* dia_arrow_selector_new           (void);
-Arrow      dia_arrow_selector_get_arrow     (DiaArrowSelector *as);
-void       dia_arrow_selector_set_arrow     (DiaArrowSelector *as,
-                                            Arrow arrow);
-
-
 /* DiaFileSelector: */
 #define DIAFILESELECTOR(obj)          G_TYPE_CHECK_INSTANCE_CAST (obj, dia_file_selector_get_type (), 
DiaFileSelector)
 #define DIAFILESELECTOR_CLASS(klass)  G_TYPE_CHECK_CLASS_CAST (klass, dia_file_selector_get_type (), 
DiaFileSelectorClass)
diff --git a/lib/widgets/dia-arrow-chooser.c b/lib/widgets/dia-arrow-chooser.c
new file mode 100644
index 00000000..38385c6d
--- /dev/null
+++ b/lib/widgets/dia-arrow-chooser.c
@@ -0,0 +1,508 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * diarrowchooser.c -- Copyright (C) 1999 James Henstridge.
+ *                     Copyright (C) 2004 Hubert Figuiere
+ *
+ * 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.
+ */
+
+/** \file diaarrowchooser.c  A widget to choose arrowhead.  This only select arrowhead, not width  and 
height. 
+ * \ingroup diawidgets
+ */
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include "intl.h"
+#include "widgets.h"
+#include "dia-arrow-chooser.h"
+#include "renderer/diacairo.h"
+#include "dia_dirs.h"
+
+/* --------------- DiaArrowPreview -------------------------------- */
+static void dia_arrow_preview_set(DiaArrowPreview *arrow, 
+                                  ArrowType atype, gboolean left);
+static gint dia_arrow_preview_draw       (GtkWidget             *widget,
+                                          cairo_t               *ctx);
+
+G_DEFINE_TYPE (DiaArrowPreview, dia_arrow_preview, GTK_TYPE_WIDGET)
+
+/** Initialize class information for the arrow preview class.
+ * @param class The class object to initialize/
+ */
+static void
+dia_arrow_preview_class_init(DiaArrowPreviewClass *class)
+{
+  GtkWidgetClass *widget_class;
+
+  widget_class = GTK_WIDGET_CLASS (class);
+  widget_class->draw = dia_arrow_preview_draw;
+}
+
+/** Initialize an arrow preview widget.
+ * @param arrow The widget to initialize.
+ */
+static void
+dia_arrow_preview_init (DiaArrowPreview *self)
+{
+  gtk_widget_set_has_window (GTK_WIDGET (self), FALSE);
+  gtk_widget_set_size_request (GTK_WIDGET (self), -1, 24);
+
+  self->atype = ARROW_NONE;
+  self->left = TRUE;
+}
+
+/** Create a new arrow preview widget.
+ * @param atype The type of arrow to start out selected with.
+ * @param left If TRUE, this preview will point to the left.
+ * @return A new widget.
+ */
+GtkWidget *
+dia_arrow_preview_new(ArrowType atype, gboolean left)
+{
+  DiaArrowPreview *arrow = g_object_new(DIA_TYPE_ARROW_PREVIEW, NULL);
+
+  arrow->atype = atype;
+  arrow->left = left;
+  return GTK_WIDGET(arrow);
+}
+
+/** Set the values shown by an arrow preview widget.
+ * @param arrow Preview widget to change.
+ * @param atype New arrow type to use.
+ * @param left If TRUE, the preview should point to the left.
+ */
+static void
+dia_arrow_preview_set(DiaArrowPreview *arrow, ArrowType atype, gboolean left)
+{
+  if (arrow->atype != atype || arrow->left != left) {
+    arrow->atype = atype;
+    arrow->left = left;
+    if (gtk_widget_is_drawable(GTK_WIDGET(arrow)))
+      gtk_widget_queue_draw(GTK_WIDGET(arrow));
+  }
+}
+
+/** Expose handle for the arrow preview widget.
+ * @param widget The widget to display.
+ * @param event The event that caused the call.
+ * @return TRUE always.
+ * The expose handler gets called when the Arrow needs to be drawn.
+ */
+static gboolean
+dia_arrow_preview_draw (GtkWidget *widget, cairo_t *ctx)
+{
+  Point from, to;
+  Point move_arrow, move_line, arrow_head;
+  DiaCairoRenderer *renderer;
+  DiaArrowPreview *arrow = DIA_ARROW_PREVIEW(widget);
+  Arrow arrow_type;
+  gint width, height;
+  GtkAllocation alloc;
+  int linewidth = 2;
+  DiaRendererClass *renderer_ops;
+  GtkStyleContext *context = gtk_widget_get_style_context (widget);
+
+  gtk_widget_get_allocation (widget, &alloc);
+
+  width = alloc.width;
+  height = alloc.height;
+
+  to.y = from.y = height/2;
+  if (arrow->left) {
+    from.x = width-linewidth;
+    to.x = 0;
+  } else {
+    from.x = 0;
+    to.x = width-linewidth;
+  }
+
+  /* here we must do some acrobaticts and construct Arrow type
+    * variable
+    */
+  arrow_type.type = arrow->atype;
+  arrow_type.length = .75*((real)height-linewidth); 
+  arrow_type.width = .75*((real)height-linewidth);
+  
+  /* and here we calculate new arrow start and end of line points */
+  calculate_arrow_point(&arrow_type, &from, &to,
+                        &move_arrow, &move_line,
+      linewidth);
+  arrow_head = to;
+  point_add(&arrow_head, &move_arrow);
+  point_add(&to, &move_line);
+
+  renderer = g_object_new (DIA_TYPE_CAIRO_RENDERER, NULL);
+  renderer->with_alpha = TRUE;
+  renderer->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+
+  renderer_ops = DIA_RENDERER_GET_CLASS (renderer);
+  renderer_ops->begin_render(DIA_RENDERER (renderer), NULL);
+  renderer_ops->set_linewidth(DIA_RENDERER (renderer), linewidth);
+  {
+    GdkRGBA fg;
+    GdkRGBA bg = { 0, 0, 0, 0 };
+    /* the text colors are the best approximation to what we had */
+    gtk_style_context_get_color (context, gtk_widget_get_state_flags (widget), &fg);
+
+
+    renderer_ops->draw_line(DIA_RENDERER (renderer), &from, &to, &fg);
+    arrow_draw (DIA_RENDERER (renderer), arrow_type.type, 
+                &arrow_head, &from, 
+                arrow_type.length, 
+                arrow_type.width,
+                linewidth, &fg, &bg);
+  }
+  renderer_ops->end_render(DIA_RENDERER (renderer));
+
+  cairo_set_source_surface (ctx, renderer->surface, 0, 0);
+  cairo_paint (ctx);
+
+  g_object_unref(renderer);
+
+  return FALSE;
+}
+
+typedef struct _DiaArrowChooserPopoverPrivate DiaArrowChooserPopoverPrivate;
+
+struct _DiaArrowChooserPopoverPrivate {
+  GtkWidget *list;
+  GtkWidget *size;
+  GtkWidget *size_box;
+
+  Arrow arrow;
+  gboolean left;
+};
+
+G_DEFINE_TYPE_WITH_CODE (DiaArrowChooserPopover, dia_arrow_chooser_popover, GTK_TYPE_POPOVER,
+                         G_ADD_PRIVATE (DiaArrowChooserPopover))
+
+enum {
+  DAC_POP_VALUE_CHANGED,
+  DAC_POP_LAST_SIGNAL
+};
+
+static guint dac_pop_signals[DAC_POP_LAST_SIGNAL] = { 0 };
+
+enum {
+  DAC_POP_PROP_LEFT = 1,
+  DAC_POP_N_PROPS
+};
+static GParamSpec* dac_pop_properties[DAC_POP_N_PROPS];
+
+GtkWidget *
+dia_arrow_chooser_popover_new (gboolean left)
+{
+  return g_object_new (DIA_TYPE_ARROW_CHOOSER_POPOVER,
+                       "left", left,
+                       NULL);
+}
+
+static void
+dia_arrow_chooser_popover_set_property (GObject      *object,
+                                        guint         property_id,
+                                        const GValue *value,
+                                        GParamSpec   *pspec)
+{
+  DiaArrowChooserPopover *self = DIA_ARROW_CHOOSER_POPOVER (object);
+  DiaArrowChooserPopoverPrivate *priv = dia_arrow_chooser_popover_get_instance_private (self);
+  switch (property_id) {
+    case DAC_POP_PROP_LEFT:
+      priv->left = g_value_get_boolean (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+  }
+}
+
+static void
+dia_arrow_chooser_popover_class_init (DiaArrowChooserPopoverClass *klass)
+{
+  GFile *template_file;
+  GBytes *template;
+  GError *err = NULL;
+  GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->set_property = dia_arrow_chooser_popover_set_property;
+
+  dac_pop_properties[DAC_POP_PROP_LEFT] =
+    g_param_spec_boolean ("left",
+                          "Is left",
+                          "Does the arrow point left",
+                          TRUE,
+                          G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);
+
+  g_object_class_install_properties (object_class,
+                                     DAC_POP_N_PROPS,
+                                     dac_pop_properties);
+
+  dac_pop_signals[DAC_POP_VALUE_CHANGED] = g_signal_new ("value-changed",
+                                                         G_TYPE_FROM_CLASS (klass),
+                                                         G_SIGNAL_RUN_FIRST,
+                                                         0, NULL, NULL, NULL,
+                                                         G_TYPE_NONE, 0);
+
+  /* TODO: Use GResource */
+  template_file = g_file_new_for_path (build_ui_filename ("ui/dia-arrow-chooser-popover.ui"));
+  template = g_file_load_bytes (template_file, NULL, NULL, &err);
+
+  if (err)
+    g_critical ("Failed to load template: %s", err->message);
+
+  gtk_widget_class_set_template (widget_class, template);
+  gtk_widget_class_bind_template_child_private (widget_class, DiaArrowChooserPopover, list);
+  gtk_widget_class_bind_template_child_private (widget_class, DiaArrowChooserPopover, size);
+  gtk_widget_class_bind_template_child_private (widget_class, DiaArrowChooserPopover, size_box);
+
+  g_object_unref (template_file);
+}
+
+static void
+row_selected (GtkListBox             *box,
+              GtkListBoxRow          *row,
+              DiaArrowChooserPopover *self)
+{
+  DiaArrowChooserPopoverPrivate *priv = dia_arrow_chooser_popover_get_instance_private (self);
+  ArrowType atype = arrow_type_from_index (gtk_list_box_row_get_index (row));
+
+  if (priv->arrow.type != atype) {
+    priv->arrow.type = atype;
+    dia_arrow_chooser_popover_set_arrow (self, &priv->arrow);
+  }
+
+  gtk_widget_set_sensitive (GTK_WIDGET (priv->size_box),
+                            g_ascii_strcasecmp (arrow_get_name_from_type (atype), "None") != 0);
+}
+
+static void
+size_changed (DiaSizeSelector        *selector,
+              DiaArrowChooserPopover *self)
+{
+  DiaArrowChooserPopoverPrivate *priv = dia_arrow_chooser_popover_get_instance_private (self);
+
+  dia_size_selector_get_size (DIA_SIZE_SELECTOR (priv->size), &priv->arrow.width, &priv->arrow.length);
+
+  dia_arrow_chooser_popover_set_arrow (self, &priv->arrow);
+}
+
+static void
+dia_arrow_chooser_popover_init (DiaArrowChooserPopover *self)
+{
+  DiaArrowChooserPopoverPrivate *priv = dia_arrow_chooser_popover_get_instance_private (self);
+
+  priv->arrow.type = ARROW_NONE;
+  priv->arrow.length = DEFAULT_ARROW_LENGTH;
+  priv->arrow.width = DEFAULT_ARROW_WIDTH;
+
+  gtk_widget_init_template (GTK_WIDGET (self));
+
+  /* although from ARROW_NONE to MAX_ARROW_TYPE-1 this is sorted by *index* to keep the order consistent 
with earlier releases */
+  for (int i = ARROW_NONE; i < MAX_ARROW_TYPE; ++i) {
+    ArrowType arrow_type = arrow_type_from_index (i);
+    GtkWidget *ar = dia_arrow_preview_new (arrow_type, priv->left);
+    /* TODO: Don't gettext here */
+    gtk_widget_set_tooltip_text (ar, gettext (arrow_get_name_from_type (arrow_type)));
+    gtk_widget_show (ar);
+    gtk_list_box_insert (GTK_LIST_BOX (priv->list), ar, i);
+  }
+
+  g_signal_connect (G_OBJECT (priv->list), "row-selected",
+                    G_CALLBACK (row_selected), self);
+
+  g_signal_connect (G_OBJECT (priv->size), "value-changed",
+                    G_CALLBACK (size_changed), self);
+}
+
+Arrow
+dia_arrow_chooser_popover_get_arrow (DiaArrowChooserPopover *self)
+{
+  DiaArrowChooserPopoverPrivate *priv = dia_arrow_chooser_popover_get_instance_private (self);
+
+  return priv->arrow;
+}
+
+void
+dia_arrow_chooser_popover_set_arrow (DiaArrowChooserPopover *self,
+                                     Arrow                  *arrow)
+{
+  DiaArrowChooserPopoverPrivate *priv = dia_arrow_chooser_popover_get_instance_private (self);
+
+  priv->arrow.type = arrow->type;
+  priv->arrow.width = arrow->width;
+  priv->arrow.length = arrow->length;
+
+  dia_size_selector_set_size (DIA_SIZE_SELECTOR (priv->size), arrow->width, arrow->length);
+  gtk_list_box_select_row (GTK_LIST_BOX (priv->list),
+                           gtk_list_box_get_row_at_index (GTK_LIST_BOX (priv->list),
+                                                          arrow_index_from_type (arrow->type)));
+
+  g_signal_emit (G_OBJECT (self),
+                 dac_pop_signals[DAC_POP_VALUE_CHANGED], 0);
+}
+
+/* ------- Code for DiaArrowChooser ----------------------- */
+
+typedef struct _DiaArrowChooserPrivate DiaArrowChooserPrivate;
+
+struct _DiaArrowChooserPrivate {
+  gboolean left;
+
+  GtkWidget *preview;
+  GtkWidget *popover;
+};
+
+G_DEFINE_TYPE_WITH_CODE (DiaArrowChooser, dia_arrow_chooser, GTK_TYPE_MENU_BUTTON,
+                         G_ADD_PRIVATE (DiaArrowChooser))
+
+enum {
+    DAC_VALUE_CHANGED,
+    DAC_LAST_SIGNAL
+};
+
+static guint dac_signals[DAC_LAST_SIGNAL] = { 0 };
+
+enum {
+  DAC_PROP_LEFT = 1,
+  DAC_N_PROPS
+};
+static GParamSpec* dac_properties[DAC_N_PROPS];
+
+static void
+dia_arrow_chooser_set_property (GObject      *object,
+                                guint         property_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+  DiaArrowChooser *self = DIA_ARROW_CHOOSER (object);
+  DiaArrowChooserPrivate *priv = dia_arrow_chooser_get_instance_private (self);
+  switch (property_id) {
+    case DAC_PROP_LEFT:
+      priv->left = g_value_get_boolean (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+  }
+}
+
+/** Initialize class information for the arrow choose.
+ * @param class Class structure to initialize private fields of.
+ */
+static void
+dia_arrow_chooser_class_init (DiaArrowChooserClass *class)
+{
+  GObjectClass   *object_class = G_OBJECT_CLASS (class);
+
+  object_class->set_property = dia_arrow_chooser_set_property;
+
+  dac_properties[DAC_PROP_LEFT] =
+    g_param_spec_boolean ("left",
+                          "Is left",
+                          "Does the arrow point left",
+                          TRUE,
+                          G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);
+
+  g_object_class_install_properties (object_class,
+                                     DAC_N_PROPS,
+                                     dac_properties);
+
+  dac_signals[DAC_VALUE_CHANGED] = g_signal_new ("value-changed",
+                                                 G_TYPE_FROM_CLASS (class),
+                                                 G_SIGNAL_RUN_FIRST,
+                                                 0, NULL, NULL, NULL,
+                                                 G_TYPE_NONE, 0);
+
+  /* Just in case it's not registered when using GtkBuilder */
+  g_type_ensure (dia_size_selector_get_type ());
+}
+
+static void
+value_changed (DiaArrowChooserPopover *popover,
+               DiaArrowChooser        *chooser)
+{
+  DiaArrowChooserPrivate *priv = dia_arrow_chooser_get_instance_private (chooser);
+  Arrow arrow = dia_arrow_chooser_popover_get_arrow (popover);
+
+  dia_arrow_preview_set (DIA_ARROW_PREVIEW (priv->preview), arrow.type, priv->left);
+
+  g_signal_emit (G_OBJECT (chooser), dac_signals[DAC_VALUE_CHANGED], 0);
+}
+
+/** Initialize an arrow choose object.
+ * @param arrow Newly allocated arrow choose object.
+ */
+static void
+dia_arrow_chooser_init (DiaArrowChooser *self)
+{
+  DiaArrowChooserPrivate *priv = dia_arrow_chooser_get_instance_private (self);
+  GtkWidget *wid;
+
+  wid = dia_arrow_preview_new (ARROW_NONE, priv->left);
+  gtk_container_add (GTK_CONTAINER (self), wid);
+  gtk_widget_show (wid);
+  priv->preview = wid;
+
+  priv->popover = dia_arrow_chooser_popover_new (priv->left);
+  g_signal_connect (G_OBJECT (priv->popover), "value-changed",
+                    G_CALLBACK (value_changed), self);
+  gtk_menu_button_set_popover (GTK_MENU_BUTTON (self), priv->popover);
+}
+
+/** Create a new arrow chooser object.
+ * @param left If TRUE, this chooser will point its arrowheads to the left.
+ * @return A new DiaArrowChooser widget.
+ */
+GtkWidget *
+dia_arrow_chooser_new (gboolean left)
+{
+  return g_object_new (DIA_TYPE_ARROW_CHOOSER,
+                       "left", left,
+                       NULL);
+}
+
+/** Set the type of arrow shown by the arrow chooser.  If the arrow type
+ * changes, the callback function will be called.
+ * @param chooser The chooser to update.
+ * @param arrow The arrow type and dimensions the chooser will dispaly.
+ * Should it be called as well when the dimensions change?
+ */
+void
+dia_arrow_chooser_set_arrow (DiaArrowChooser *self, Arrow *arrow)
+{
+  DiaArrowChooserPrivate *priv = dia_arrow_chooser_get_instance_private (self);
+
+  dia_arrow_chooser_popover_set_arrow (DIA_ARROW_CHOOSER_POPOVER (priv->popover),
+                                       arrow);
+}
+
+/** Get the currently selected arrow type from an arrow chooser.
+ * @param arrow An arrow chooser to query.
+ * @return The arrow type that is currently selected in the chooser.
+ */
+ArrowType
+dia_arrow_chooser_get_arrow_type (DiaArrowChooser *self)
+{
+  return dia_arrow_chooser_get_arrow(self).type;
+}
+
+Arrow
+dia_arrow_chooser_get_arrow (DiaArrowChooser *self)
+{
+  DiaArrowChooserPrivate *priv = dia_arrow_chooser_get_instance_private (self);
+
+  return dia_arrow_chooser_popover_get_arrow (DIA_ARROW_CHOOSER_POPOVER (priv->popover));
+}
diff --git a/lib/widgets/dia-arrow-chooser.h b/lib/widgets/dia-arrow-chooser.h
new file mode 100644
index 00000000..15207187
--- /dev/null
+++ b/lib/widgets/dia-arrow-chooser.h
@@ -0,0 +1,75 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * diarrowchooser.h -- Copyright (C) 1999 James Henstridge.
+ *                     Copyright (C) 2004 Hubert Figuiere
+ *
+ * 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.
+ */
+
+#ifndef _DIAARROWCHOOSER_H_
+#define _DIAARROWCHOOSER_H_
+
+#include <gtk/gtk.h>
+
+#include "arrows.h"
+#include "diatypes.h"
+
+
+/* --------------- DiaArrowPreview -------------------------------- */
+
+#define DIA_TYPE_ARROW_PREVIEW (dia_arrow_preview_get_type ())
+G_DECLARE_FINAL_TYPE (DiaArrowPreview, dia_arrow_preview, DIA, ARROW_PREVIEW, GtkWidget)
+
+struct _DiaArrowPreview
+{
+  GtkWidget misc;
+  ArrowType atype;
+  gboolean left;
+};
+
+GtkWidget *dia_arrow_preview_new (ArrowType atype, gboolean left);
+
+
+/* ------- Code for DiaArrowChooser ----------------------- */
+
+#define DIA_TYPE_ARROW_CHOOSER_POPOVER (dia_arrow_chooser_popover_get_type ())
+G_DECLARE_DERIVABLE_TYPE (DiaArrowChooserPopover, dia_arrow_chooser_popover, DIA, ARROW_CHOOSER_POPOVER, 
GtkPopover)
+
+struct _DiaArrowChooserPopoverClass {
+  GtkPopoverClass parent_class;
+};
+
+GtkWidget *dia_arrow_chooser_popover_new                  (gboolean                left);
+void       dia_arrow_chooser_popover_set_arrow            (DiaArrowChooserPopover *chooser,
+                                                           Arrow                  *arrow);
+Arrow      dia_arrow_chooser_popover_get_arrow            (DiaArrowChooserPopover *chooser);
+
+
+#define DIA_TYPE_ARROW_CHOOSER (dia_arrow_chooser_get_type ())
+G_DECLARE_DERIVABLE_TYPE (DiaArrowChooser, dia_arrow_chooser, DIA, ARROW_CHOOSER, GtkMenuButton)
+
+struct _DiaArrowChooserClass
+{
+  GtkMenuButtonClass parent_class;
+};
+
+GtkWidget *dia_arrow_chooser_new            (gboolean         left);
+void       dia_arrow_chooser_set_arrow      (DiaArrowChooser *chooser,
+                                             Arrow           *arrow);
+Arrow      dia_arrow_chooser_get_arrow      (DiaArrowChooser *chooser);
+ArrowType  dia_arrow_chooser_get_arrow_type (DiaArrowChooser *chooser);
+
+#endif /* _DIAARROWCHOOSER_H_ */


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