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

gEDA-cvs: pcb.git: branch: master updated (728f350268e134ca116a6f79577843db7b18e82c)



The branch, master has been updated
       via  728f350268e134ca116a6f79577843db7b18e82c (commit)
       via  73591e0e0e4c2abc764a2a8be503a44da1ca86f4 (commit)
       via  352a088d8c506ef0407cb9c88844bf4033576eb0 (commit)
      from  acf8d00db4a90b555d768341a97453914b7b4aec (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


=========
 Summary
=========

 src/Makefile.am                                    |   12 +-
 ...isibility.c => ghid-cell-renderer-visibility.c} |  118 ++++++++++----------
 src/hid/gtk/ghid-cell-renderer-visibility.h        |   24 ++++
 .../{gtk-pcb-coord-entry.c => ghid-coord-entry.c}  |   76 +++++++-------
 src/hid/gtk/ghid-coord-entry.h                     |   35 ++++++
 ...-pcb-layer-selector.c => ghid-layer-selector.c} |  118 ++++++++++----------
 src/hid/gtk/ghid-layer-selector.h                  |   45 ++++++++
 src/hid/gtk/gtk-pcb-cell-renderer-visibility.h     |   24 ----
 src/hid/gtk/gtk-pcb-coord-entry.h                  |   35 ------
 src/hid/gtk/gtk-pcb-layer-selector.h               |   45 --------
 src/hid/gtk/gui-config.c                           |    8 +-
 src/hid/gtk/gui-dialog-print.c                     |    6 +-
 src/hid/gtk/gui-dialog-size.c                      |   28 +++---
 src/hid/gtk/gui-top-window.c                       |   84 +++++++-------
 src/hid/gtk/gui-utils.c                            |   17 ++--
 src/hid/gtk/gui.h                                  |    6 +-
 16 files changed, 340 insertions(+), 341 deletions(-)
 rename src/hid/gtk/{gtk-pcb-cell-renderer-visibility.c => ghid-cell-renderer-visibility.c} (61%)
 create mode 100644 src/hid/gtk/ghid-cell-renderer-visibility.h
 rename src/hid/gtk/{gtk-pcb-coord-entry.c => ghid-coord-entry.c} (76%)
 create mode 100644 src/hid/gtk/ghid-coord-entry.h
 rename src/hid/gtk/{gtk-pcb-layer-selector.c => ghid-layer-selector.c} (87%)
 create mode 100644 src/hid/gtk/ghid-layer-selector.h
 delete mode 100644 src/hid/gtk/gtk-pcb-cell-renderer-visibility.h
 delete mode 100644 src/hid/gtk/gtk-pcb-coord-entry.h
 delete mode 100644 src/hid/gtk/gtk-pcb-layer-selector.h


=================
 Commit Messages
=================

commit 728f350268e134ca116a6f79577843db7b18e82c
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Rename GtkPcbCoordEntry to GHidCoordEntry

:100644 100644 00e7453... 4b66ac7... M	src/Makefile.am
:000000 100644 0000000... a49ceca... A	src/hid/gtk/ghid-coord-entry.c
:000000 100644 0000000... e90c9f9... A	src/hid/gtk/ghid-coord-entry.h
:100644 000000 233dc9b... 0000000... D	src/hid/gtk/gtk-pcb-coord-entry.c
:100644 000000 3827ccf... 0000000... D	src/hid/gtk/gtk-pcb-coord-entry.h
:100644 100644 215f16a... 88bf547... M	src/hid/gtk/gui-config.c
:100644 100644 71b078f... ce98f13... M	src/hid/gtk/gui-dialog-print.c
:100644 100644 27c0336... 8cc9185... M	src/hid/gtk/gui-dialog-size.c
:100644 100644 a36057b... e9008c6... M	src/hid/gtk/gui-utils.c
:100644 100644 ad2a112... 30ff593... M	src/hid/gtk/gui.h

commit 73591e0e0e4c2abc764a2a8be503a44da1ca86f4
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Rename GtkPcbLayerSelector to GHidLayerSelector

:100644 100644 f4bba29... 00e7453... M	src/Makefile.am
:000000 100644 0000000... 06dc8cd... A	src/hid/gtk/ghid-layer-selector.c
:000000 100644 0000000... bfeffe9... A	src/hid/gtk/ghid-layer-selector.h
:100644 000000 1067aeb... 0000000... D	src/hid/gtk/gtk-pcb-layer-selector.c
:100644 000000 27b0de9... 0000000... D	src/hid/gtk/gtk-pcb-layer-selector.h
:100644 100644 26e0030... 9d170c8... M	src/hid/gtk/gui-top-window.c

commit 352a088d8c506ef0407cb9c88844bf4033576eb0
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Rename GtkPcbCellRendererVisibility to GHidCellRendererVisibility

:100644 100644 d4c37e0... f4bba29... M	src/Makefile.am
:000000 100644 0000000... 2e07c67... A	src/hid/gtk/ghid-cell-renderer-visibility.c
:000000 100644 0000000... be08fae... A	src/hid/gtk/ghid-cell-renderer-visibility.h
:100644 000000 9e8593c... 0000000... D	src/hid/gtk/gtk-pcb-cell-renderer-visibility.c
:100644 000000 212c4a4... 0000000... D	src/hid/gtk/gtk-pcb-cell-renderer-visibility.h
:100644 100644 c8c9849... 1067aeb... M	src/hid/gtk/gtk-pcb-layer-selector.c

=========
 Changes
=========

commit 728f350268e134ca116a6f79577843db7b18e82c
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Rename GtkPcbCoordEntry to GHidCoordEntry

diff --git a/src/Makefile.am b/src/Makefile.am
index 00e7453..4b66ac7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -270,8 +270,8 @@ libgtk_a_CPPFLAGS = -I./hid/gtk
 LIBGTK_SRCS = \
 	dolists.h \
 	hid/hidint.h \
-	hid/gtk/gtk-pcb-coord-entry.c \
-	hid/gtk/gtk-pcb-coord-entry.h \
+	hid/gtk/ghid-coord-entry.c \
+	hid/gtk/ghid-coord-entry.h \
 	hid/gtk/ghid-layer-selector.c \
 	hid/gtk/ghid-layer-selector.h \
 	hid/gtk/ghid-cell-renderer-visibility.c \
diff --git a/src/hid/gtk/ghid-coord-entry.c b/src/hid/gtk/ghid-coord-entry.c
new file mode 100644
index 0000000..a49ceca
--- /dev/null
+++ b/src/hid/gtk/ghid-coord-entry.c
@@ -0,0 +1,312 @@
+/*! \file <gtk-pcb-coord-entry.c>
+ *  \brief Implementation of GHidCoordEntry widget
+ *  \par Description
+ *  This widget is a modified spinbox for the user to enter
+ *  pcb coords. It is assigned a default unit (for display),
+ *  but this can be changed by the user by typing a new one
+ *  or right-clicking on the box.
+ *
+ *  Internally, it keeps track of its value in pcb coords.
+ *  From the user's perspective, it uses natural human units.
+ */
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "gtkhid.h"
+#include "gui.h"
+#include "pcb-printf.h"
+
+#include "ghid-coord-entry.h"
+
+enum {
+  UNIT_CHANGE_SIGNAL,
+  LAST_SIGNAL
+};
+
+static guint ghid_coord_entry_signals[LAST_SIGNAL] = { 0 };
+
+struct _GHidCoordEntry
+{
+  GtkSpinButton parent;
+
+  Coord min_value;
+  Coord max_value;
+  Coord value;
+
+  enum ce_step_size step_size;
+  const Unit *unit;
+};
+
+struct _GHidCoordEntryClass
+{
+  GtkSpinButtonClass parent_class;
+
+  void (* change_unit) (GHidCoordEntry *, const Unit *);
+};
+
+/* SIGNAL HANDLERS */
+/*! \brief Callback for "Change Unit" menu click */
+static void
+menu_item_activate_cb (GtkMenuItem *item, GHidCoordEntry *ce)
+{
+  const char *text = gtk_menu_item_get_label (item);
+  const Unit *unit = get_unit_struct (text);
+  
+  g_signal_emit (ce, ghid_coord_entry_signals[UNIT_CHANGE_SIGNAL], 0, unit);
+}
+
+/*! \brief Callback for context menu creation */
+static void
+ghid_coord_entry_popup_cb (GHidCoordEntry *ce, GtkMenu *menu, gpointer data)
+{
+  int i, n;
+  const Unit *unit_list;
+  GtkWidget *menu_item, *submenu;
+
+  /* Build submenu */
+  n = get_n_units ();
+  unit_list = get_unit_list ();
+
+  submenu = gtk_menu_new ();
+  for (i = 0; i < n; ++i)
+    {
+      menu_item = gtk_menu_item_new_with_label (unit_list[i].suffix);
+      g_signal_connect (G_OBJECT (menu_item), "activate",
+                        G_CALLBACK (menu_item_activate_cb), ce);
+      gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menu_item);
+      gtk_widget_show (menu_item);
+    }
+
+  /* Add submenu to menu */
+  menu_item = gtk_separator_menu_item_new ();
+  gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item);
+  gtk_widget_show (menu_item);
+
+  menu_item = gtk_menu_item_new_with_label (_("Change Units"));
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), submenu);
+  gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item);
+  gtk_widget_show (menu_item);
+}
+
+/*! \brief Callback for user output */
+static gboolean
+ghid_coord_entry_output_cb (GHidCoordEntry *ce, gpointer data)
+{
+  GtkAdjustment *adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (ce));
+  double value = gtk_adjustment_get_value (adj);
+  gchar *text;
+
+  text = pcb_g_strdup_printf ("%.*f %s", ce->unit->default_prec, value, ce->unit->suffix);
+  gtk_entry_set_text (GTK_ENTRY (ce), text);
+  g_free (text);
+   
+  return TRUE;
+}
+
+/*! \brief Callback for user input */
+static gboolean
+ghid_coord_text_changed_cb (GHidCoordEntry *entry, gpointer data)
+{
+  const char *text;
+  char *suffix;
+  const Unit *new_unit;
+  double value;
+
+  /* Check if units have changed */
+  text = gtk_entry_get_text (GTK_ENTRY (entry));
+  value = strtod (text, &suffix);
+  new_unit = get_unit_struct (suffix);
+  if (new_unit && new_unit != entry->unit)
+    {
+      entry->value = unit_to_coord (new_unit, value);
+      g_signal_emit (entry, ghid_coord_entry_signals[UNIT_CHANGE_SIGNAL], 0, new_unit);
+    }
+
+  return FALSE;
+}
+
+/*! \brief Callback for change in value (input or ^v clicks) */
+static gboolean
+ghid_coord_value_changed_cb (GHidCoordEntry *ce, gpointer data)
+{
+  GtkAdjustment *adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (ce));
+
+  /* Re-calculate internal value */
+  double value = gtk_adjustment_get_value (adj);
+  ce->value = unit_to_coord (ce->unit, value);
+  /* Handle potential unit changes */
+  ghid_coord_text_changed_cb (ce, data);
+
+  return FALSE;
+}
+
+/*! \brief Change the unit used by a coord entry
+ *
+ *  \param [in] ce         The entry to be acted on
+ *  \parin [in] new_unit   The new unit to be used
+ */
+static void
+ghid_coord_entry_change_unit (GHidCoordEntry *ce, const Unit *new_unit)
+{
+  double climb_rate = 0.0;
+  GtkAdjustment *adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (ce));
+
+  ce->unit = new_unit;
+  /* Re-calculate min/max values for spinbox */
+  gtk_adjustment_configure (adj, coord_to_unit (new_unit, ce->value),
+                                 coord_to_unit (new_unit, ce->min_value),
+                                 coord_to_unit (new_unit, ce->max_value),
+                                 ce->unit->step_small,
+                                 ce->unit->step_medium,
+                                 0.0);
+
+  switch (ce->step_size)
+    {
+    case CE_TINY: climb_rate = new_unit->step_tiny; break;
+    case CE_SMALL: climb_rate = new_unit->step_small; break;
+    case CE_MEDIUM: climb_rate = new_unit->step_medium; break;
+    case CE_LARGE: climb_rate = new_unit->step_large; break;
+    }
+  gtk_spin_button_configure (GTK_SPIN_BUTTON (ce), adj, climb_rate,
+                             new_unit->default_prec + strlen (new_unit->suffix));
+}
+
+/* CONSTRUCTOR */
+static void
+ghid_coord_entry_init (GHidCoordEntry *ce)
+{
+  /* Hookup signal handlers */
+  g_signal_connect (G_OBJECT (ce), "focus_out_event",
+                    G_CALLBACK (ghid_coord_text_changed_cb), NULL);
+  g_signal_connect (G_OBJECT (ce), "value_changed",
+                    G_CALLBACK (ghid_coord_value_changed_cb), NULL);
+  g_signal_connect (G_OBJECT (ce), "populate_popup",
+                    G_CALLBACK (ghid_coord_entry_popup_cb), NULL);
+  g_signal_connect (G_OBJECT (ce), "output",
+                    G_CALLBACK (ghid_coord_entry_output_cb), NULL);
+}
+
+static void
+ghid_coord_entry_class_init (GHidCoordEntryClass *klass)
+{
+  klass->change_unit = ghid_coord_entry_change_unit;
+
+  /* GtkAutoComplete *ce : the object acted on */
+  /* const Unit *new_unit: the new unit that was set */
+  ghid_coord_entry_signals[UNIT_CHANGE_SIGNAL] =
+    g_signal_new ("change-unit",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                  G_STRUCT_OFFSET (GHidCoordEntryClass, change_unit),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE,
+                  1, G_TYPE_POINTER);
+
+}
+
+/* PUBLIC FUNCTIONS */
+GType
+ghid_coord_entry_get_type (void)
+{
+  static GType ce_type = 0;
+
+  if (!ce_type)
+    {
+      const GTypeInfo ce_info =
+      {
+	sizeof (GHidCoordEntryClass),
+	NULL, /* base_init */
+	NULL, /* base_finalize */
+	(GClassInitFunc) ghid_coord_entry_class_init,
+	NULL, /* class_finalize */
+	NULL, /* class_data */
+	sizeof (GHidCoordEntry),
+	0,    /* n_preallocs */
+	(GInstanceInitFunc) ghid_coord_entry_init,
+      };
+
+      ce_type = g_type_register_static (GTK_TYPE_SPIN_BUTTON,
+                                        "GHidCoordEntry",
+                                        &ce_info,
+                                        0);
+    }
+
+  return ce_type;
+}
+
+/*! \brief Create a new GHidCoordEntry
+ *
+ *  \param [in] min_val    The minimum allowed value, in pcb coords
+ *  \param [in] max_val    The maximum allowed value, in pcb coords
+ *  \param [in] value      The default value, in pcb coords
+ *  \param [in] unit       The default unit
+ *  \param [in] step_size  How large the default increments should be
+ *
+ *  \return a freshly-allocated GHidCoordEntry
+ */
+GtkWidget *
+ghid_coord_entry_new (Coord min_val, Coord max_val, Coord value,
+                         const Unit *unit, enum ce_step_size step_size)
+{
+  /* Setup spinbox min/max values */
+  double small_step, big_step;
+  GtkAdjustment *adj;
+  GHidCoordEntry *ce = g_object_new (GHID_COORD_ENTRY_TYPE, NULL);
+
+  ce->unit = unit;
+  ce->min_value = min_val;
+  ce->max_value = max_val;
+  ce->value = value;
+
+  ce->step_size = step_size;
+  switch (step_size)
+    {
+    case CE_TINY:
+      small_step = unit->step_tiny;
+      big_step   = unit->step_small;
+      break;
+    case CE_SMALL:
+      small_step = unit->step_small;
+      big_step   = unit->step_medium;
+      break;
+    case CE_MEDIUM:
+      small_step = unit->step_medium;
+      big_step   = unit->step_large;
+      break;
+    case CE_LARGE:
+      small_step = unit->step_large;
+      big_step   = unit->step_huge;
+      break;
+    default:
+      small_step = big_step = 0;
+      break;
+    }
+
+  adj = GTK_ADJUSTMENT (gtk_adjustment_new (coord_to_unit (unit, value),
+                                            coord_to_unit (unit, min_val),
+                                            coord_to_unit (unit, max_val),
+                                            small_step, big_step, 0.0));
+  gtk_spin_button_configure (GTK_SPIN_BUTTON (ce), adj, small_step,
+                             unit->default_prec + strlen (unit->suffix));
+  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (ce), FALSE);
+
+  return GTK_WIDGET (ce);
+}
+
+/*! \brief Gets a GHidCoordEntry's value, in pcb coords */
+Coord
+ghid_coord_entry_get_value (GHidCoordEntry *ce)
+{
+  return ce->value;
+}
+
+/*! \brief Sets a GHidCoordEntry's value, in pcb coords */
+void
+ghid_coord_entry_set_value (GHidCoordEntry *ce, Coord val)
+{
+  gtk_spin_button_set_value (GTK_SPIN_BUTTON (ce),
+                             coord_to_unit (ce->unit, val));
+}
+
diff --git a/src/hid/gtk/ghid-coord-entry.h b/src/hid/gtk/ghid-coord-entry.h
new file mode 100644
index 0000000..e90c9f9
--- /dev/null
+++ b/src/hid/gtk/ghid-coord-entry.h
@@ -0,0 +1,35 @@
+/* This is the modified GtkSpinbox used for entering Coords.
+ * Hopefully it can be used as a template whenever we migrate the
+ * rest of the Gtk HID to use GObjects and GtkWidget subclassing.
+ */
+#ifndef GHID_COORD_ENTRY_H__
+#define GHID_COORD_ENTRY_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS  /* keep c++ happy */
+
+#define GHID_COORD_ENTRY_TYPE            (ghid_coord_entry_get_type ())
+#define GHID_COORD_ENTRY(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GHID_COORD_ENTRY_TYPE, GHidCoordEntry))
+#define GHID_COORD_ENTRY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GHID_COORD_ENTRY_TYPE, GHidCoordEntryClass))
+#define IS_GHID_COORD_ENTRY(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GHID_COORD_ENTRY_TYPE))
+#define IS_GHID_COORD_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GHID_COORD_ENTRY_TYPE))
+
+typedef struct _GHidCoordEntry       GHidCoordEntry;
+typedef struct _GHidCoordEntryClass  GHidCoordEntryClass;
+
+/* Step sizes */
+enum ce_step_size { CE_TINY, CE_SMALL, CE_MEDIUM, CE_LARGE };
+
+GType ghid_coord_entry_get_type (void);
+GtkWidget* ghid_coord_entry_new (Coord min_val, Coord max_val, Coord value,
+                                 const Unit *unit, enum ce_step_size step_size);
+void ghid_coord_entry_add_entry (GHidCoordEntry *ce, const gchar *name, const gchar *desc);
+gchar *ghid_coord_entry_get_last_command (GHidCoordEntry *ce);
+
+Coord ghid_coord_entry_get_value (GHidCoordEntry *ce);
+void ghid_coord_entry_set_value (GHidCoordEntry *ce, Coord val);
+
+G_END_DECLS  /* keep c++ happy */
+#endif
diff --git a/src/hid/gtk/gtk-pcb-coord-entry.c b/src/hid/gtk/gtk-pcb-coord-entry.c
deleted file mode 100644
index 233dc9b..0000000
--- a/src/hid/gtk/gtk-pcb-coord-entry.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/*! \file <gtk-pcb-coord-entry.c>
- *  \brief Implementation of GtkPcbCoordEntry widget
- *  \par Description
- *  This widget is a modified spinbox for the user to enter
- *  pcb coords. It is assigned a default unit (for display),
- *  but this can be changed by the user by typing a new one
- *  or right-clicking on the box.
- *
- *  Internally, it keeps track of its value in pcb coords.
- *  From the user's perspective, it uses natural human units.
- */
-
-#include <glib.h>
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-#include "gtkhid.h"
-#include "gui.h"
-#include "pcb-printf.h"
-
-#include "gtk-pcb-coord-entry.h"
-
-enum {
-  UNIT_CHANGE_SIGNAL,
-  LAST_SIGNAL
-};
-
-static guint gtk_pcb_coord_entry_signals[LAST_SIGNAL] = { 0 };
-
-struct _GtkPcbCoordEntry
-{
-  GtkSpinButton parent;
-
-  Coord min_value;
-  Coord max_value;
-  Coord value;
-
-  enum ce_step_size step_size;
-  const Unit *unit;
-};
-
-struct _GtkPcbCoordEntryClass
-{
-  GtkSpinButtonClass parent_class;
-
-  void (* change_unit) (GtkPcbCoordEntry *, const Unit *);
-};
-
-/* SIGNAL HANDLERS */
-/*! \brief Callback for "Change Unit" menu click */
-static void
-menu_item_activate_cb (GtkMenuItem *item, GtkPcbCoordEntry *ce)
-{
-  const char *text = gtk_menu_item_get_label (item);
-  const Unit *unit = get_unit_struct (text);
-  
-  g_signal_emit (ce, gtk_pcb_coord_entry_signals[UNIT_CHANGE_SIGNAL], 0, unit);
-}
-
-/*! \brief Callback for context menu creation */
-static void
-gtk_pcb_coord_entry_popup_cb (GtkPcbCoordEntry *ce, GtkMenu *menu, gpointer data)
-{
-  int i, n;
-  const Unit *unit_list;
-  GtkWidget *menu_item, *submenu;
-
-  /* Build submenu */
-  n = get_n_units ();
-  unit_list = get_unit_list ();
-
-  submenu = gtk_menu_new ();
-  for (i = 0; i < n; ++i)
-    {
-      menu_item = gtk_menu_item_new_with_label (unit_list[i].suffix);
-      g_signal_connect (G_OBJECT (menu_item), "activate",
-                        G_CALLBACK (menu_item_activate_cb), ce);
-      gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menu_item);
-      gtk_widget_show (menu_item);
-    }
-
-  /* Add submenu to menu */
-  menu_item = gtk_separator_menu_item_new ();
-  gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item);
-  gtk_widget_show (menu_item);
-
-  menu_item = gtk_menu_item_new_with_label (_("Change Units"));
-  gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), submenu);
-  gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item);
-  gtk_widget_show (menu_item);
-}
-
-/*! \brief Callback for user output */
-static gboolean
-gtk_pcb_coord_entry_output_cb (GtkPcbCoordEntry *ce, gpointer data)
-{
-  GtkAdjustment *adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (ce));
-  double value = gtk_adjustment_get_value (adj);
-  gchar *text;
-
-  text = pcb_g_strdup_printf ("%.*f %s", ce->unit->default_prec, value, ce->unit->suffix);
-  gtk_entry_set_text (GTK_ENTRY (ce), text);
-  g_free (text);
-   
-  return TRUE;
-}
-
-/*! \brief Callback for user input */
-static gboolean
-gtk_pcb_coord_text_changed_cb (GtkPcbCoordEntry *entry, gpointer data)
-{
-  const char *text;
-  char *suffix;
-  const Unit *new_unit;
-  double value;
-
-  /* Check if units have changed */
-  text = gtk_entry_get_text (GTK_ENTRY (entry));
-  value = strtod (text, &suffix);
-  new_unit = get_unit_struct (suffix);
-  if (new_unit && new_unit != entry->unit)
-    {
-      entry->value = unit_to_coord (new_unit, value);
-      g_signal_emit (entry, gtk_pcb_coord_entry_signals[UNIT_CHANGE_SIGNAL], 0, new_unit);
-    }
-
-  return FALSE;
-}
-
-/*! \brief Callback for change in value (input or ^v clicks) */
-static gboolean
-gtk_pcb_coord_value_changed_cb (GtkPcbCoordEntry *ce, gpointer data)
-{
-  GtkAdjustment *adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (ce));
-
-  /* Re-calculate internal value */
-  double value = gtk_adjustment_get_value (adj);
-  ce->value = unit_to_coord (ce->unit, value);
-  /* Handle potential unit changes */
-  gtk_pcb_coord_text_changed_cb (ce, data);
-
-  return FALSE;
-}
-
-/*! \brief Change the unit used by a coord entry
- *
- *  \param [in] ce         The entry to be acted on
- *  \parin [in] new_unit   The new unit to be used
- */
-static void
-gtk_pcb_coord_entry_change_unit (GtkPcbCoordEntry *ce, const Unit *new_unit)
-{
-  double climb_rate = 0.0;
-  GtkAdjustment *adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (ce));
-
-  ce->unit = new_unit;
-  /* Re-calculate min/max values for spinbox */
-  gtk_adjustment_configure (adj, coord_to_unit (new_unit, ce->value),
-                                 coord_to_unit (new_unit, ce->min_value),
-                                 coord_to_unit (new_unit, ce->max_value),
-                                 ce->unit->step_small,
-                                 ce->unit->step_medium,
-                                 0.0);
-
-  switch (ce->step_size)
-    {
-    case CE_TINY: climb_rate = new_unit->step_tiny; break;
-    case CE_SMALL: climb_rate = new_unit->step_small; break;
-    case CE_MEDIUM: climb_rate = new_unit->step_medium; break;
-    case CE_LARGE: climb_rate = new_unit->step_large; break;
-    }
-  gtk_spin_button_configure (GTK_SPIN_BUTTON (ce), adj, climb_rate,
-                             new_unit->default_prec + strlen (new_unit->suffix));
-}
-
-/* CONSTRUCTOR */
-static void
-gtk_pcb_coord_entry_init (GtkPcbCoordEntry *ce)
-{
-  /* Hookup signal handlers */
-  g_signal_connect (G_OBJECT (ce), "focus_out_event",
-                    G_CALLBACK (gtk_pcb_coord_text_changed_cb), NULL);
-  g_signal_connect (G_OBJECT (ce), "value_changed",
-                    G_CALLBACK (gtk_pcb_coord_value_changed_cb), NULL);
-  g_signal_connect (G_OBJECT (ce), "populate_popup",
-                    G_CALLBACK (gtk_pcb_coord_entry_popup_cb), NULL);
-  g_signal_connect (G_OBJECT (ce), "output",
-                    G_CALLBACK (gtk_pcb_coord_entry_output_cb), NULL);
-}
-
-static void
-gtk_pcb_coord_entry_class_init (GtkPcbCoordEntryClass *klass)
-{
-  klass->change_unit = gtk_pcb_coord_entry_change_unit;
-
-  /* GtkAutoComplete *ce : the object acted on */
-  /* const Unit *new_unit: the new unit that was set */
-  gtk_pcb_coord_entry_signals[UNIT_CHANGE_SIGNAL] =
-    g_signal_new ("change-unit",
-                  G_TYPE_FROM_CLASS (klass),
-                  G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                  G_STRUCT_OFFSET (GtkPcbCoordEntryClass, change_unit),
-                  NULL, NULL,
-                  g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE,
-                  1, G_TYPE_POINTER);
-
-}
-
-/* PUBLIC FUNCTIONS */
-GType
-gtk_pcb_coord_entry_get_type (void)
-{
-  static GType ce_type = 0;
-
-  if (!ce_type)
-    {
-      const GTypeInfo ce_info =
-      {
-	sizeof (GtkPcbCoordEntryClass),
-	NULL, /* base_init */
-	NULL, /* base_finalize */
-	(GClassInitFunc) gtk_pcb_coord_entry_class_init,
-	NULL, /* class_finalize */
-	NULL, /* class_data */
-	sizeof (GtkPcbCoordEntry),
-	0,    /* n_preallocs */
-	(GInstanceInitFunc) gtk_pcb_coord_entry_init,
-      };
-
-      ce_type = g_type_register_static (GTK_TYPE_SPIN_BUTTON,
-                                        "GtkPcbCoordEntry",
-                                        &ce_info,
-                                        0);
-    }
-
-  return ce_type;
-}
-
-/*! \brief Create a new GtkPcbCoordEntry
- *
- *  \param [in] min_val    The minimum allowed value, in pcb coords
- *  \param [in] max_val    The maximum allowed value, in pcb coords
- *  \param [in] value      The default value, in pcb coords
- *  \param [in] unit       The default unit
- *  \param [in] step_size  How large the default increments should be
- *
- *  \return a freshly-allocated GtkPcbCoordEntry
- */
-GtkWidget *
-gtk_pcb_coord_entry_new (Coord min_val, Coord max_val, Coord value,
-                         const Unit *unit, enum ce_step_size step_size)
-{
-  /* Setup spinbox min/max values */
-  double small_step, big_step;
-  GtkAdjustment *adj;
-  GtkPcbCoordEntry *ce = g_object_new (GTK_PCB_COORD_ENTRY_TYPE, NULL);
-
-  ce->unit = unit;
-  ce->min_value = min_val;
-  ce->max_value = max_val;
-  ce->value = value;
-
-  ce->step_size = step_size;
-  switch (step_size)
-    {
-    case CE_TINY:
-      small_step = unit->step_tiny;
-      big_step   = unit->step_small;
-      break;
-    case CE_SMALL:
-      small_step = unit->step_small;
-      big_step   = unit->step_medium;
-      break;
-    case CE_MEDIUM:
-      small_step = unit->step_medium;
-      big_step   = unit->step_large;
-      break;
-    case CE_LARGE:
-      small_step = unit->step_large;
-      big_step   = unit->step_huge;
-      break;
-    default:
-      small_step = big_step = 0;
-      break;
-    }
-
-  adj = GTK_ADJUSTMENT (gtk_adjustment_new (coord_to_unit (unit, value),
-                                            coord_to_unit (unit, min_val),
-                                            coord_to_unit (unit, max_val),
-                                            small_step, big_step, 0.0));
-  gtk_spin_button_configure (GTK_SPIN_BUTTON (ce), adj, small_step,
-                             unit->default_prec + strlen (unit->suffix));
-  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (ce), FALSE);
-
-  return GTK_WIDGET (ce);
-}
-
-/*! \brief Gets a GtkPcbCoordEntry's value, in pcb coords */
-Coord
-gtk_pcb_coord_entry_get_value (GtkPcbCoordEntry *ce)
-{
-  return ce->value;
-}
-
-/*! \brief Sets a GtkPcbCoordEntry's value, in pcb coords */
-void
-gtk_pcb_coord_entry_set_value (GtkPcbCoordEntry *ce, Coord val)
-{
-  gtk_spin_button_set_value (GTK_SPIN_BUTTON (ce),
-                             coord_to_unit (ce->unit, val));
-}
-
diff --git a/src/hid/gtk/gtk-pcb-coord-entry.h b/src/hid/gtk/gtk-pcb-coord-entry.h
deleted file mode 100644
index 3827ccf..0000000
--- a/src/hid/gtk/gtk-pcb-coord-entry.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* This is the modified GtkSpinbox used for entering Coords.
- * Hopefully it can be used as a template whenever we migrate the
- * rest of the Gtk HID to use GObjects and GtkWidget subclassing.
- */
-#ifndef GTK_PCB_COORD_ENTRY_H__
-#define GTK_PCB_COORD_ENTRY_H__
-
-#include <glib.h>
-#include <glib-object.h>
-
-G_BEGIN_DECLS  /* keep c++ happy */
-
-#define GTK_PCB_COORD_ENTRY_TYPE            (gtk_pcb_coord_entry_get_type ())
-#define GTK_PCB_COORD_ENTRY(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_PCB_COORD_ENTRY_TYPE, GtkPcbCoordEntry))
-#define GTK_PCB_COORD_ENTRY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_PCB_COORD_ENTRY_TYPE, GtkPcbCoordEntryClass))
-#define IS_GTK_PCB_COORD_ENTRY(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_PCB_COORD_ENTRY_TYPE))
-#define IS_GTK_PCB_COORD_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_PCB_COORD_ENTRY_TYPE))
-
-typedef struct _GtkPcbCoordEntry       GtkPcbCoordEntry;
-typedef struct _GtkPcbCoordEntryClass  GtkPcbCoordEntryClass;
-
-/* Step sizes */
-enum ce_step_size { CE_TINY, CE_SMALL, CE_MEDIUM, CE_LARGE };
-
-GType gtk_pcb_coord_entry_get_type (void);
-GtkWidget* gtk_pcb_coord_entry_new (Coord min_val, Coord max_val, Coord value,
-                                    const Unit *unit, enum ce_step_size step_size);
-void gtk_pcb_coord_entry_add_entry (GtkPcbCoordEntry *ce, const gchar *name, const gchar *desc);
-gchar *gtk_pcb_coord_entry_get_last_command (GtkPcbCoordEntry *ce);
-
-Coord gtk_pcb_coord_entry_get_value (GtkPcbCoordEntry *ce);
-void gtk_pcb_coord_entry_set_value (GtkPcbCoordEntry *ce, Coord val);
-
-G_END_DECLS  /* keep c++ happy */
-#endif
diff --git a/src/hid/gtk/gui-config.c b/src/hid/gtk/gui-config.c
index 215f16a..88bf547 100644
--- a/src/hid/gtk/gui-config.c
+++ b/src/hid/gtk/gui-config.c
@@ -1011,9 +1011,9 @@ text_spin_button_cb (GtkSpinButton * spin, void * dst)
 }
 
 static void
-coord_entry_cb (GtkPcbCoordEntry * ce, void * dst)
+coord_entry_cb (GHidCoordEntry * ce, void * dst)
 {
-  *(Coord *) dst = gtk_pcb_coord_entry_get_value (ce);
+  *(Coord *) dst = ghid_coord_entry_get_value (ce);
   ghidgui->config_modified = TRUE;
 }
 
@@ -1139,9 +1139,9 @@ config_sizes_tab_create (GtkWidget * tab_vbox)
 static GtkWidget *config_increments_vbox, *config_increments_tab_vbox;
 
 static void
-increment_spin_button_cb (GtkPcbCoordEntry * ce, void * dst)
+increment_spin_button_cb (GHidCoordEntry * ce, void * dst)
 {
-  *(Coord *)dst = gtk_pcb_coord_entry_get_value (ce);
+  *(Coord *)dst = ghid_coord_entry_get_value (ce);
   ghidgui->config_modified = TRUE;
 }
 
diff --git a/src/hid/gtk/gui-dialog-print.c b/src/hid/gtk/gui-dialog-print.c
index 71b078f..ce98f13 100644
--- a/src/hid/gtk/gui-dialog-print.c
+++ b/src/hid/gtk/gui-dialog-print.c
@@ -174,9 +174,9 @@ ghid_attribute_dialog (HID_Attribute * attrs,
 	  hbox = gtk_hbox_new (FALSE, 4);
 	  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
 
-	  entry = gtk_pcb_coord_entry_new (attrs[j].min_val, attrs[j].max_val,
-	                                   attrs[j].default_val.coord_value,
-	                                   Settings.grid_unit, CE_SMALL);
+	  entry = ghid_coord_entry_new (attrs[j].min_val, attrs[j].max_val,
+	                                attrs[j].default_val.coord_value,
+	                                Settings.grid_unit, CE_SMALL);
 	  gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
 	  if(attrs[j].default_val.str_value != NULL)
 	    gtk_entry_set_text (GTK_ENTRY (entry),
diff --git a/src/hid/gtk/gui-dialog-size.c b/src/hid/gtk/gui-dialog-size.c
index 27c0336..8cc9185 100644
--- a/src/hid/gtk/gui-dialog-size.c
+++ b/src/hid/gtk/gui-dialog-size.c
@@ -85,32 +85,32 @@ make_route_string(RouteStyleType * rs)
 }
 
 static void
-via_hole_cb (GtkPcbCoordEntry * entry, gpointer data)
+via_hole_cb (GHidCoordEntry * entry, gpointer data)
 {
   SizesDialog * sd = (SizesDialog *)data;
   gdouble via_hole_size, via_size;
 
-  via_hole_size = gtk_pcb_coord_entry_get_value (entry);
-  via_size = gtk_pcb_coord_entry_get_value
-               (GTK_PCB_COORD_ENTRY (sd->via_size_coord_entry));
+  via_hole_size = ghid_coord_entry_get_value (entry);
+  via_size = ghid_coord_entry_get_value
+               (GHID_COORD_ENTRY (sd->via_size_coord_entry));
 
   if (via_size < via_hole_size + MIN_PINORVIACOPPER)
-    gtk_pcb_coord_entry_set_value (GTK_PCB_COORD_ENTRY (sd->via_size_coord_entry),
+    ghid_coord_entry_set_value (GHID_COORD_ENTRY (sd->via_size_coord_entry),
 			           via_hole_size + MIN_PINORVIACOPPER);
 }
 
 static void
-via_size_cb (GtkPcbCoordEntry * entry, gpointer data)
+via_size_cb (GHidCoordEntry * entry, gpointer data)
 {
   SizesDialog * sd = (SizesDialog *)data;
   gdouble via_hole_size, via_size;
 
-  via_size = gtk_pcb_coord_entry_get_value (entry);
-  via_hole_size = gtk_pcb_coord_entry_get_value
-                    (GTK_PCB_COORD_ENTRY (sd->via_hole_coord_entry));
+  via_size = ghid_coord_entry_get_value (entry);
+  via_hole_size = ghid_coord_entry_get_value
+                    (GHID_COORD_ENTRY (sd->via_hole_coord_entry));
 
   if (via_hole_size > via_size - MIN_PINORVIACOPPER)
-    gtk_pcb_coord_entry_set_value (GTK_PCB_COORD_ENTRY (sd->via_hole_coord_entry),
+    ghid_coord_entry_set_value (GHID_COORD_ENTRY (sd->via_hole_coord_entry),
 			           via_size - MIN_PINORVIACOPPER);
 }
 
@@ -261,16 +261,16 @@ ghid_route_style_dialog (gint index, RouteStyleType * temp_rst)
 	rst = &rst_buf;
 
       rst->Thick =
-	gtk_pcb_coord_entry_get_value (GTK_PCB_COORD_ENTRY
+	ghid_coord_entry_get_value (GHID_COORD_ENTRY
 				        (sd->line_width_coord_entry));
       rst->Hole =
-	gtk_pcb_coord_entry_get_value (GTK_PCB_COORD_ENTRY
+	ghid_coord_entry_get_value (GHID_COORD_ENTRY
 				        (sd->via_hole_coord_entry));
       rst->Diameter =
-	gtk_pcb_coord_entry_get_value (GTK_PCB_COORD_ENTRY
+	ghid_coord_entry_get_value (GHID_COORD_ENTRY
 				        (sd->via_size_coord_entry));
       rst->Keepaway =
-	gtk_pcb_coord_entry_get_value (GTK_PCB_COORD_ENTRY
+	ghid_coord_entry_get_value (GHID_COORD_ENTRY
 				        (sd->clearance_coord_entry));
 
       if (index < NUM_STYLES && !set_temp1 && !set_temp2)
diff --git a/src/hid/gtk/gui-utils.c b/src/hid/gtk/gui-utils.c
index a36057b..e9008c6 100644
--- a/src/hid/gtk/gui-utils.c
+++ b/src/hid/gtk/gui-utils.c
@@ -33,7 +33,6 @@
 #endif
 
 #include "gui.h"
-#include "gtk-pcb-coord-entry.h"
 #include <gdk/gdkkeysyms.h>
 
 #ifdef HAVE_LIBDMALLOC
@@ -273,11 +272,11 @@ ghid_button_connected (GtkWidget * box, GtkWidget ** button,
 void
 ghid_coord_entry (GtkWidget * box, GtkWidget ** coord_entry, Coord value,
 		  Coord low, Coord high,  enum ce_step_size step_size,
-		  gint width, void (*cb_func) (GtkPcbCoordEntry *, gpointer),
+		  gint width, void (*cb_func) (GHidCoordEntry *, gpointer),
 		  gpointer data, gboolean right_align, gchar * string)
 {
   GtkWidget *hbox = NULL, *label, *entry_widget;
-  GtkPcbCoordEntry *entry;
+  GHidCoordEntry *entry;
 
   if (string && box)
     {
@@ -286,12 +285,12 @@ ghid_coord_entry (GtkWidget * box, GtkWidget ** coord_entry, Coord value,
       box = hbox;
     }
 
-  entry_widget = gtk_pcb_coord_entry_new (low, high, value, Settings.grid_unit, step_size);
+  entry_widget = ghid_coord_entry_new (low, high, value, Settings.grid_unit, step_size);
   if (coord_entry)
     *coord_entry = entry_widget;
   if (width > 0)
     gtk_widget_set_size_request (entry_widget, width, -1);
-  entry = GTK_PCB_COORD_ENTRY (entry_widget);
+  entry = GHID_COORD_ENTRY (entry_widget);
   if (data == NULL)
     data = (gpointer) entry;
   if (cb_func)
@@ -368,21 +367,21 @@ void
 ghid_table_coord_entry (GtkWidget * table, gint row, gint column,
 			GtkWidget ** coord_entry, Coord value,
 			Coord low, Coord high, enum ce_step_size step_size,
-			gint width, void (*cb_func) (GtkPcbCoordEntry *, gpointer),
+			gint width, void (*cb_func) (GHidCoordEntry *, gpointer),
 			gpointer data, gboolean right_align, gchar * string)
 {
   GtkWidget *label, *entry_widget;
-  GtkPcbCoordEntry *entry;
+  GHidCoordEntry *entry;
 
   if (!table)
     return;
 
-  entry_widget = gtk_pcb_coord_entry_new (low, high, value, Settings.grid_unit, step_size);
+  entry_widget = ghid_coord_entry_new (low, high, value, Settings.grid_unit, step_size);
   if (coord_entry)
     *coord_entry = entry_widget;
   if (width > 0)
     gtk_widget_set_size_request (entry_widget, width, -1);
-  entry = GTK_PCB_COORD_ENTRY (entry_widget);
+  entry = GHID_COORD_ENTRY (entry_widget);
   if (data == NULL)
     data = (gpointer) entry;
   if (cb_func)
diff --git a/src/hid/gtk/gui.h b/src/hid/gtk/gui.h
index ad2a112..30ff593 100644
--- a/src/hid/gtk/gui.h
+++ b/src/hid/gtk/gui.h
@@ -36,7 +36,7 @@
 #include <sys/stat.h>
 
 #include <gtk/gtk.h>
-#include "gtk-pcb-coord-entry.h"
+#include "ghid-coord-entry.h"
 #include "gui-pinout-preview.h"
 
 
@@ -371,7 +371,7 @@ void ghid_button_connected (GtkWidget * box, GtkWidget ** button,
 			    gpointer data, gchar * string);
 void ghid_coord_entry (GtkWidget * box, GtkWidget ** coord_entry, Coord value,
 		       Coord low, Coord high,  enum ce_step_size step_size,
-		       gint width, void (*cb_func) (GtkPcbCoordEntry *, gpointer),
+		       gint width, void (*cb_func) (GHidCoordEntry *, gpointer),
 		       gpointer data, gboolean right_align, gchar * string);
 void ghid_spin_button (GtkWidget * box, GtkWidget ** spin_button,
 		       gfloat value, gfloat low, gfloat high, gfloat step0,
@@ -381,7 +381,7 @@ void ghid_spin_button (GtkWidget * box, GtkWidget ** spin_button,
 void ghid_table_coord_entry (GtkWidget * table, gint row, gint column,
 		 	    GtkWidget ** coord_entry, Coord value,
 			    Coord low, Coord high, enum ce_step_size, gint width,
-			    void (*cb_func) (GtkPcbCoordEntry *, gpointer), gpointer data,
+			    void (*cb_func) (GHidCoordEntry *, gpointer), gpointer data,
 			    gboolean right_align, gchar * string);
 void ghid_table_spin_button (GtkWidget * box, gint row, gint column,
 			     GtkWidget ** spin_button, gfloat value,

commit 73591e0e0e4c2abc764a2a8be503a44da1ca86f4
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Rename GtkPcbLayerSelector to GHidLayerSelector

diff --git a/src/Makefile.am b/src/Makefile.am
index f4bba29..00e7453 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -272,8 +272,8 @@ LIBGTK_SRCS = \
 	hid/hidint.h \
 	hid/gtk/gtk-pcb-coord-entry.c \
 	hid/gtk/gtk-pcb-coord-entry.h \
-	hid/gtk/gtk-pcb-layer-selector.c \
-	hid/gtk/gtk-pcb-layer-selector.h \
+	hid/gtk/ghid-layer-selector.c \
+	hid/gtk/ghid-layer-selector.h \
 	hid/gtk/ghid-cell-renderer-visibility.c \
 	hid/gtk/ghid-cell-renderer-visibility.h \
 	hid/gtk/gtkhid-main.c \
diff --git a/src/hid/gtk/ghid-layer-selector.c b/src/hid/gtk/ghid-layer-selector.c
new file mode 100644
index 0000000..06dc8cd
--- /dev/null
+++ b/src/hid/gtk/ghid-layer-selector.c
@@ -0,0 +1,815 @@
+/*! \file <gtk-pcb-layer-selector.c>
+ *  \brief Implementation of GHidLayerSelector widget
+ *  \par Description
+ *  This widget is the layer selector on the left side of the Gtk
+ *  GUI. It also describes (in XML) the relevant sections of the
+ *  menu for layer selection and visibility toggling, and makes
+ *  sure these stay in sync.
+ */
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
+#include "gtkhid.h"
+#include "gui.h"
+#include "pcb-printf.h"
+
+#include "ghid-layer-selector.h"
+#include "ghid-cell-renderer-visibility.h"
+
+#define INITIAL_ACTION_MAX	40
+
+/* Forward dec'ls */
+static void ghid_layer_selector_finalize (GObject *object);
+
+/*! \brief Signals exposed by the widget */
+enum {
+  SELECT_LAYER_SIGNAL,
+  TOGGLE_LAYER_SIGNAL,
+  LAST_SIGNAL
+};
+
+/*! \brief Columns used for internal data store */
+enum {
+  INDEX_COL,
+  USER_ID_COL,
+  VISIBLE_COL,
+  COLOR_COL,
+  TEXT_COL,
+  FONT_COL,
+  ACTIVATABLE_COL,
+  SEPARATOR_COL,
+  N_COLS
+};
+
+static GtkTreeView *ghid_layer_selector_parent_class;
+static guint ghid_layer_selector_signals[LAST_SIGNAL] = { 0 };
+
+struct _GHidLayerSelector
+{
+  GtkTreeView parent;
+
+  GtkListStore *list_store;
+  GtkTreeSelection *selection;
+  GtkTreeViewColumn *visibility_column;
+
+  GtkActionGroup *action_group;
+
+  GtkToggleAction **view_actions;
+  GtkRadioAction  **pick_actions;
+  GtkTreeRowReference **rows;
+  GSList *radio_group;
+  int max_actions;
+  int n_actions;
+
+  gboolean last_activatable;
+};
+
+struct _GHidLayerSelectorClass
+{
+  GtkTreeViewClass parent_class;
+
+  void (* select_layer) (GHidLayerSelector *, gint);
+  void (* toggle_layer) (GHidLayerSelector *, gint);
+};
+
+/*! \brief Flip the visibility state of a given layer 
+ *  \par Function Description
+ *  Changes the internal toggle state and menu checkbox state
+ *  of the layer pointed to by iter. Emits a toggle-layer signal.
+ *  ALL internal visibility-flipping needs to go through this
+ *  function. Otherwise a signal will not be emitted and it is
+ *  likely that pcb will become inconsistent with the selector.
+ *
+ *  \param [in] ls    The selector to be acted on
+ *  \param [in] iter  A GtkTreeIter pointed at the relevant layer
+ */
+static void
+toggle_visibility (GHidLayerSelector *ls, GtkTreeIter *iter)
+{
+  gint idx;
+  gboolean toggle;
+  gtk_tree_model_get (GTK_TREE_MODEL (ls->list_store), iter,
+                     VISIBLE_COL, &toggle, INDEX_COL, &idx, -1);
+  gtk_list_store_set (ls->list_store, iter, VISIBLE_COL, !toggle, -1);
+  gtk_toggle_action_set_active (ls->view_actions[idx], !toggle);
+}
+
+/*! \brief Decide if a GtkListStore entry is a layer or separator */
+static gboolean
+tree_view_separator_func (GtkTreeModel *model, GtkTreeIter *iter,
+                          gpointer data)
+{
+  gboolean ret_val;
+  gtk_tree_model_get (model, iter, SEPARATOR_COL, &ret_val, -1);
+  return ret_val;
+}
+
+/*! \brief Decide if a GtkListStore entry may be selected */
+static gboolean
+tree_selection_func (GtkTreeSelection *selection, GtkTreeModel *model,
+                     GtkTreePath *path, gboolean selected, gpointer data)
+{
+  GtkTreeIter iter;
+
+  if (gtk_tree_model_get_iter (model, &iter, path))
+    {
+      gboolean activatable;
+      gtk_tree_model_get (model, &iter, ACTIVATABLE_COL, &activatable, -1);
+      return activatable;
+    }
+
+  return FALSE;
+}
+
+/* SIGNAL HANDLERS */
+/*! \brief Callback for mouse-click: toggle visibility */
+static gboolean
+button_press_cb (GHidLayerSelector *ls, GdkEventButton *event)
+{
+  /* Handle visibility independently to prevent changing the active
+   *  layer, which will happen if we let this event propagate.  */
+  GtkTreeViewColumn *column;
+  GtkTreePath *path;
+  if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (ls),
+                                     event->x, event->y,
+                                     &path, &column, NULL, NULL))
+    {
+      GtkTreeIter iter;
+      gtk_tree_model_get_iter (GTK_TREE_MODEL (ls->list_store), &iter, path);
+      if (column == ls->visibility_column)
+        {
+          toggle_visibility (ls, &iter);
+          return TRUE; 
+        }
+    }
+  return FALSE;
+}
+
+/*! \brief Callback for layer selection change: sync menu */
+static void
+selection_changed_cb (GtkTreeSelection *selection, GHidLayerSelector *ls)
+{
+  GtkTreeIter iter;
+  if (gtk_tree_selection_get_selected (selection, NULL, &iter))
+    {
+      gint idx;
+      gtk_tree_model_get (GTK_TREE_MODEL (ls->list_store), &iter,
+                          INDEX_COL, &idx, -1);
+      if (ls->pick_actions[0])
+        gtk_radio_action_set_current_value (ls->pick_actions[0], idx);
+    }
+}
+
+/*! \brief Callback for menu actions: sync layer selection list, emit signal */
+static void
+menu_view_cb (GtkToggleAction *action, GtkTreeRowReference *rref)
+{
+  GHidLayerSelector *ls;
+  GtkTreeModel *model = gtk_tree_row_reference_get_model (rref);
+  GtkTreePath *path = gtk_tree_row_reference_get_path (rref);
+  gboolean state = gtk_toggle_action_get_active (action);
+  GtkTreeIter iter;
+  gint user_id;
+
+  gtk_tree_model_get_iter (model, &iter, path);
+  gtk_list_store_set (GTK_LIST_STORE (model), &iter, VISIBLE_COL, state, -1);
+  gtk_tree_model_get (model, &iter, USER_ID_COL, &user_id, -1);
+
+  ls = g_object_get_data (G_OBJECT (model), "layer-selector");
+  g_signal_emit (ls, ghid_layer_selector_signals[TOGGLE_LAYER_SIGNAL],
+                 0, user_id);
+}
+
+/*! \brief Callback for menu actions: sync layer selection list, emit signal */
+static void
+menu_pick_cb (GtkRadioAction *action, GtkTreeRowReference *rref)
+{
+  GHidLayerSelector *ls;
+  GtkTreeModel *model = gtk_tree_row_reference_get_model (rref);
+  GtkTreePath *path = gtk_tree_row_reference_get_path (rref);
+  GtkTreeIter iter;
+  gint user_id;
+
+  gtk_tree_model_get_iter (model, &iter, path);
+  gtk_tree_model_get (model, &iter, USER_ID_COL, &user_id, -1);
+
+  ls = g_object_get_data (G_OBJECT (model), "layer-selector");
+  gtk_tree_selection_select_path (ls->selection, path);
+  g_signal_emit (ls, ghid_layer_selector_signals[SELECT_LAYER_SIGNAL],
+                 0, user_id);
+}
+
+/* CONSTRUCTOR */
+static void
+ghid_layer_selector_init (GHidLayerSelector *ls)
+{
+  /* Hookup signal handlers */
+}
+
+static void
+ghid_layer_selector_class_init (GHidLayerSelectorClass *klass)
+{
+  GObjectClass *object_class = (GObjectClass *) klass;
+
+  ghid_layer_selector_signals[SELECT_LAYER_SIGNAL] =
+    g_signal_new ("select-layer",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                  G_STRUCT_OFFSET (GHidLayerSelectorClass, select_layer),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__INT, G_TYPE_NONE,
+                  1, G_TYPE_INT);
+  ghid_layer_selector_signals[TOGGLE_LAYER_SIGNAL] =
+    g_signal_new ("toggle-layer",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                  G_STRUCT_OFFSET (GHidLayerSelectorClass, toggle_layer),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__INT, G_TYPE_NONE,
+                  1, G_TYPE_INT);
+
+  object_class->finalize = ghid_layer_selector_finalize;
+}
+
+/*! \brief Clean up object before garbage collection
+ */
+static void
+ghid_layer_selector_finalize (GObject *object)
+{
+  int i;
+  GHidLayerSelector *ls = (GHidLayerSelector *) object;
+
+  g_object_unref (ls->action_group);
+  g_free (ls->view_actions);
+  g_free (ls->pick_actions);
+  for (i = 0; i < ls->n_actions; ++i)
+    if (ls->rows[i])
+      gtk_tree_row_reference_free (ls->rows[i]);
+  g_free (ls->rows);
+
+  G_OBJECT_CLASS (ghid_layer_selector_parent_class)->finalize (object);
+}
+
+/* PUBLIC FUNCTIONS */
+GType
+ghid_layer_selector_get_type (void)
+{
+  static GType ls_type = 0;
+
+  if (!ls_type)
+    {
+      const GTypeInfo ls_info =
+      {
+	sizeof (GHidLayerSelectorClass),
+	NULL, /* base_init */
+	NULL, /* base_finalize */
+	(GClassInitFunc) ghid_layer_selector_class_init,
+	NULL, /* class_finalize */
+	NULL, /* class_data */
+	sizeof (GHidLayerSelector),
+	0,    /* n_preallocs */
+	(GInstanceInitFunc) ghid_layer_selector_init,
+      };
+
+      ls_type = g_type_register_static (GTK_TYPE_TREE_VIEW,
+                                        "GHidLayerSelector",
+                                        &ls_info,
+                                        0);
+    }
+
+  return ls_type;
+}
+
+/*! \brief Create a new GHidLayerSelector
+ *
+ *  \return a freshly-allocated GHidLayerSelector.
+ */
+GtkWidget *
+ghid_layer_selector_new (void)
+{
+  GtkCellRenderer *renderer1 = ghid_cell_renderer_visibility_new ();
+  GtkCellRenderer *renderer2 = gtk_cell_renderer_text_new ();
+  GtkTreeViewColumn *opacity_col =
+      gtk_tree_view_column_new_with_attributes ("", renderer1,
+                                                "active", VISIBLE_COL,
+                                                "color", COLOR_COL, NULL);
+  GtkTreeViewColumn *name_col =
+      gtk_tree_view_column_new_with_attributes ("", renderer2,
+                                                "text", TEXT_COL,
+                                                "font", FONT_COL,
+                                                "sensitive", VISIBLE_COL, NULL);
+
+  GHidLayerSelector *ls = g_object_new (GHID_LAYER_SELECTOR_TYPE, NULL);
+
+  /* action index, active, color, text, font, is_separator */
+  ls->list_store = gtk_list_store_new (N_COLS, G_TYPE_INT, G_TYPE_INT,
+                                       G_TYPE_BOOLEAN, G_TYPE_STRING,
+                                       G_TYPE_STRING, G_TYPE_STRING,
+                                       G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
+  gtk_tree_view_insert_column (GTK_TREE_VIEW (ls), opacity_col, -1);
+  gtk_tree_view_insert_column (GTK_TREE_VIEW (ls), name_col, -1);
+  gtk_tree_view_set_model (GTK_TREE_VIEW (ls), GTK_TREE_MODEL (ls->list_store));
+  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (ls), FALSE);
+
+  ls->last_activatable = TRUE;
+  ls->visibility_column = opacity_col;
+  ls->selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (ls));
+  ls->action_group = gtk_action_group_new ("LayerSelector");
+  ls->n_actions = 0;
+  ls->max_actions = INITIAL_ACTION_MAX;
+  ls->view_actions = g_malloc0 (ls->max_actions * sizeof (*ls->view_actions));
+  ls->pick_actions = g_malloc0 (ls->max_actions * sizeof (*ls->pick_actions));
+  ls->rows = g_malloc0 (ls->max_actions * sizeof (*ls->rows));
+
+  gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW (ls),
+                                        tree_view_separator_func,
+                                        NULL, NULL);
+  gtk_tree_selection_set_select_function (ls->selection, tree_selection_func,
+                                          NULL, NULL);
+  gtk_tree_selection_set_mode (ls->selection, GTK_SELECTION_BROWSE);
+
+  g_object_set_data (G_OBJECT (ls->list_store), "layer-selector", ls);
+  g_signal_connect (ls, "button_press_event",
+                    G_CALLBACK (button_press_cb), NULL);
+  g_signal_connect (ls->selection, "changed",
+                    G_CALLBACK (selection_changed_cb), ls);
+
+  g_object_ref (ls->action_group);
+
+  return GTK_WIDGET (ls);
+}
+
+/*! \brief Add a layer to a GHidLayerSelector.
+ *  \par Function Description
+ *  This function adds an entry to a GHidLayerSelector, which will
+ *  appear in the layer-selection list as well as visibility and selection
+ *  menus (assuming this is a selectable layer). For the first 20 layers,
+ *  keyboard accelerators will be added for selection/visibility toggling.
+ *
+ *  If the user_id passed already exists in the layer selector, that layer
+ *  will have its data overwritten with the new stuff.
+ *
+ *  \param [in] ls            The selector to be acted on
+ *  \param [in] user_id       An ID used to identify the layer; will be passed to selection/visibility callbacks
+ *  \param [in] name          The name of the layer; will be used on selector and menus
+ *  \param [in] color_string  The color of the layer on selector
+ *  \param [in] visibile      Whether the layer is visible
+ *  \param [in] activatable   Whether the layer appears in menus and can be selected
+ */
+void
+ghid_layer_selector_add_layer (GHidLayerSelector *ls,
+                               gint user_id,
+                               const gchar *name,
+                               const gchar *color_string,
+                               gboolean visible,
+                               gboolean activatable)
+{
+  gchar *pname, *vname, *paccel, *vaccel;
+  gboolean new_iter = TRUE;
+  gboolean last_activatable = TRUE;
+  GtkTreePath *path;
+  GtkTreeIter iter;
+
+  /* Look for existing layer with this ID */
+  if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (ls->list_store), &iter))
+    do
+      {
+        gboolean is_sep, active;
+        gint read_id;
+        gtk_tree_model_get (GTK_TREE_MODEL (ls->list_store),
+                            &iter, USER_ID_COL, &read_id,
+                            SEPARATOR_COL, &is_sep,
+                            ACTIVATABLE_COL, &active, -1);
+        if (!is_sep)
+          {
+            last_activatable = active;
+            if(read_id == user_id)
+              {
+                new_iter = FALSE;
+                break;
+              }
+          }
+      }
+    while (gtk_tree_model_iter_next (GTK_TREE_MODEL (ls->list_store), &iter));
+
+  /* Handle separator addition */
+  if (new_iter)
+    {
+      if (activatable != last_activatable)
+        {
+          /* Add separator between activatable/non-activatable boundaries */
+          gtk_list_store_append (ls->list_store, &iter);
+          gtk_list_store_set (ls->list_store, &iter,
+                              SEPARATOR_COL, TRUE, -1);
+        }
+      /* Create new layer */
+      gtk_list_store_append (ls->list_store, &iter);
+      gtk_list_store_set (ls->list_store, &iter,
+                          INDEX_COL, ls->n_actions,
+                          USER_ID_COL, user_id,
+                          VISIBLE_COL, visible,
+                          COLOR_COL, color_string,
+                          TEXT_COL, name,
+                          FONT_COL, activatable ? NULL : "Italic",
+                          ACTIVATABLE_COL, activatable,
+                          SEPARATOR_COL, FALSE,
+                          -1);
+    }
+  else
+    gtk_list_store_set (ls->list_store, &iter,
+                        VISIBLE_COL, visible,
+                        COLOR_COL, color_string,
+                        TEXT_COL, name,
+                        FONT_COL, activatable ? NULL : "Italic",
+                        ACTIVATABLE_COL, activatable,
+                        -1);
+
+  /* Unless we're adding new actions, we're done now */
+  if (!new_iter)
+    return;
+
+  if (activatable && ls->n_actions == 0)
+    gtk_tree_selection_select_iter (ls->selection, &iter);
+
+  /* Allocate new actions if necessary */
+  if (ls->n_actions == ls->max_actions)
+    {
+      void *tmp[2];
+      ls->max_actions *= 2;
+      tmp[0] = g_realloc (ls->view_actions,
+                          ls->max_actions * sizeof (*ls->view_actions));
+      tmp[1] = g_realloc (ls->pick_actions,
+                          ls->max_actions * sizeof (*ls->pick_actions));
+      tmp[2] = g_realloc (ls->rows,
+                          ls->max_actions * sizeof (*ls->rows));
+      if (tmp[0] == NULL || tmp[1] == NULL || tmp[2] == NULL)
+        g_critical ("realloc failed allocating new actions");
+      else
+        {
+          ls->view_actions = tmp[0];
+          ls->pick_actions = tmp[1];
+          ls->rows = tmp[2];
+        }
+    }
+
+  /* -- Setup new actions -- */
+  vname = g_strdup_printf ("LayerView%d", ls->n_actions);
+  pname = g_strdup_printf ("LayerPick%d", ls->n_actions);
+  vaccel = NULL;
+  paccel = NULL;
+
+  /* Determine keyboard accelerators */
+  if (ls->n_actions < 10)
+    {
+      /* Map 1-0 to actions 1-10 (with '0' meaning 10) */
+      int i = (ls->n_actions + 1) % 10;
+      vaccel = g_strdup_printf ("<Ctrl>%d", i);
+      paccel = g_strdup_printf ("%d", i);
+    }
+  else
+    {
+      /* Map 1-0 to actions 11-20 (with '0' meaning 10) */
+      int i = (ls->n_actions + 1) % 10;
+      vaccel = g_strdup_printf ("<Alt><Ctrl>%d", i);
+      paccel = g_strdup_printf ("<Alt>%d", i);
+    }
+
+  /* Create row reference for actions */
+  path = gtk_tree_model_get_path (GTK_TREE_MODEL (ls->list_store), &iter);
+  ls->rows[ls->n_actions] = gtk_tree_row_reference_new
+                              (GTK_TREE_MODEL (ls->list_store), path);
+  gtk_tree_path_free (path);
+
+  /* Create selection action */
+  if (activatable)
+    {
+      ls->pick_actions[ls->n_actions]
+        = gtk_radio_action_new (pname, name, NULL, NULL, ls->n_actions);
+      gtk_radio_action_set_group (ls->pick_actions[ls->n_actions],
+                                  ls->radio_group);
+      ls->radio_group
+         = gtk_radio_action_get_group (ls->pick_actions[ls->n_actions]);
+      gtk_action_group_add_action_with_accel
+        (ls->action_group,
+         GTK_ACTION (ls->pick_actions[ls->n_actions]),
+         paccel);
+      g_signal_connect (ls->pick_actions[ls->n_actions], "toggled",
+                        G_CALLBACK (menu_pick_cb), ls->rows[ls->n_actions]);
+    }
+  else
+    ls->pick_actions[ls->n_actions] = NULL;
+
+  /* Create visibility action */
+  ls->view_actions[ls->n_actions] = gtk_toggle_action_new (vname, name,
+                                                           NULL, NULL);
+  gtk_toggle_action_set_active (ls->view_actions[ls->n_actions], visible);
+
+  gtk_action_group_add_action_with_accel
+    (ls->action_group,
+     GTK_ACTION (ls->view_actions[ls->n_actions]),
+     vaccel);
+  g_signal_connect (ls->view_actions[ls->n_actions], "toggled",
+                    G_CALLBACK (menu_view_cb), ls->rows[ls->n_actions]);
+
+  /* cleanup */
+  if (vaccel)
+    {
+      g_free (vaccel);
+      g_free (paccel); 
+    }
+  g_free (vname);
+  g_free (pname);
+
+  ls->n_actions++;
+}
+
+/*! \brief Get the "Current Layer" menu description of a layer selector
+ *  \par Function Description
+ *  Returns the XML content used by Gtk in building the layer-selection
+ *  part of the menu. This is a radio-button list describing which layer
+ *  is active.
+ *
+ *  \param [in] ls            The selector to be acted on
+ *
+ *  \return the requested XML
+ */
+gchar *
+ghid_layer_selector_get_pick_xml (GHidLayerSelector *ls)
+{
+  int i;
+  GString *str = g_string_new ("");
+
+  for (i = 0; i < ls->n_actions; ++i)
+    if (ls->pick_actions[i])
+      g_string_append_printf (str, "<menuitem action=\"LayerPick%d\" />\n", i);
+
+  return g_string_free (str, FALSE);
+}
+
+/*! \brief Get the "Shown Layers" menu description of a layer selector
+ *  \par Function Description
+ *  Returns the XML content used by Gtk in building the layer-selection
+ *  part of the menu. This is a toggle-button list describing which layer(s)
+ *  are visible.
+ *
+ *  \param [in] ls            The selector to be acted on
+ *
+ *  \return the requested XML
+ */
+gchar *
+ghid_layer_selector_get_view_xml (GHidLayerSelector *ls)
+{
+  int i;
+  GString *str = g_string_new ("");
+
+  for (i = 0; i < ls->n_actions; ++i)
+    if (ls->view_actions[i])
+      g_string_append_printf (str, "<menuitem action=\"LayerView%d\" />\n", i);
+
+  return g_string_free (str, FALSE);
+}
+
+/*! \brief Get the GtkActionGroup containing accelerators, etc, of a layer selector
+ *  \par Function Description
+ *  Returns the GtkActionGroup containing the toggle and radio buttons used
+ *  in the menu. Also contains the accelerators. This action group should be
+ *  added to the main UI. See Gtk docs for details.
+ *
+ *  \param [in] ls            The selector to be acted on
+ *
+ *  \return the action group of the selector
+ */
+GtkActionGroup *
+ghid_layer_selector_get_action_group (GHidLayerSelector *ls)
+{
+  return ls->action_group;
+}
+
+/*! \brief used internally */
+static gboolean
+toggle_foreach_func (GtkTreeModel *model, GtkTreePath *path,
+                     GtkTreeIter *iter, gpointer data)
+{
+  gint id;
+  GHidLayerSelector *ls = g_object_get_data (G_OBJECT (model),
+                                               "layer-selector");
+  
+  gtk_tree_model_get (model, iter, USER_ID_COL, &id, -1);
+  if (id == *(gint *) data)
+    {
+      toggle_visibility (ls, iter);
+      return TRUE;
+    }
+  return FALSE;
+}
+
+/*! \brief Toggle a layer's visibility
+ *  \par Function Description
+ *  Toggle the layer indicated by user_id, emitting a layer-toggle signal.
+ *
+ *  \param [in] ls       The selector to be acted on
+ *  \param [in] user_id  The ID of the layer to be affected
+ */
+void
+ghid_layer_selector_toggle_layer (GHidLayerSelector *ls, gint user_id)
+{
+  gtk_tree_model_foreach (GTK_TREE_MODEL (ls->list_store),
+                          toggle_foreach_func, &user_id);
+}
+
+/*! \brief used internally */
+static gboolean
+select_foreach_func (GtkTreeModel *model, GtkTreePath *path,
+                     GtkTreeIter *iter, gpointer data)
+{
+  gint id;
+  GHidLayerSelector *ls = g_object_get_data (G_OBJECT (model),
+                                               "layer-selector");
+  
+  gtk_tree_model_get (model, iter, USER_ID_COL, &id, -1);
+  if (id == *(gint *) data)
+    {
+      gtk_tree_selection_select_path (ls->selection, path);
+      return TRUE;
+    }
+  return FALSE;
+}
+
+/*! \brief Select a layer
+ *  \par Function Description
+ *  Select the layer indicated by user_id, emitting a layer-select signal.
+ *
+ *  \param [in] ls       The selector to be acted on
+ *  \param [in] user_id  The ID of the layer to be affected
+ */
+void
+ghid_layer_selector_select_layer (GHidLayerSelector *ls, gint user_id)
+{
+  gtk_tree_model_foreach (GTK_TREE_MODEL (ls->list_store),
+                          select_foreach_func, &user_id);
+}
+
+/*! \brief Selects the next visible layer
+ *  \par Function Description
+ *  Used to ensure hidden layers are not active; if the active layer is
+ *  visible, this function is a noop. Otherwise, it will look for the
+ *  next layer that IS visible, and select that. Failing that, it will
+ *  return FALSE.
+ *
+ *  \param [in] ls       The selector to be acted on
+ *
+ *  \return TRUE on success, FALSE if all selectable layers are hidden
+ */
+gboolean
+ghid_layer_selector_select_next_visible (GHidLayerSelector *ls)
+{
+  GtkTreeIter iter;
+  if (gtk_tree_selection_get_selected (ls->selection, NULL, &iter))
+    {
+      /* Scan forward, looking for selectable iter */
+      do
+        {
+          gboolean visible, activatable;
+          gtk_tree_model_get (GTK_TREE_MODEL (ls->list_store),
+                              &iter, VISIBLE_COL, &visible,
+                              ACTIVATABLE_COL, &activatable, -1);
+          if (visible && activatable)
+            {
+              gtk_tree_selection_select_iter (ls->selection, &iter);
+              return TRUE;
+            }
+        }
+      while (gtk_tree_model_iter_next (GTK_TREE_MODEL (ls->list_store), &iter));
+      /* Move iter to start, and repeat. */
+      gtk_tree_model_get_iter_first (GTK_TREE_MODEL (ls->list_store), &iter);
+      do
+        {
+          gboolean visible, activatable;
+          gtk_tree_model_get (GTK_TREE_MODEL (ls->list_store),
+                              &iter, VISIBLE_COL, &visible,
+                              ACTIVATABLE_COL, &activatable, -1);
+          if (visible && activatable)
+            {
+              gtk_tree_selection_select_iter (ls->selection, &iter);
+              return TRUE;
+            }
+        }
+      while (gtk_tree_model_iter_next (GTK_TREE_MODEL (ls->list_store), &iter));
+      /* If we get here, nothing is selectable, so fail. */
+    }
+  return FALSE;
+}
+
+/*! \brief Makes the selected layer visible
+ *  \par Function Description
+ *  Used to ensure hidden layers are not active; un-hides the currently
+ *  selected layer.
+ *
+ *  \param [in] ls       The selector to be acted on
+ */
+void
+ghid_layer_selector_make_selected_visible (GHidLayerSelector *ls)
+{
+  GtkTreeIter iter;
+  if (gtk_tree_selection_get_selected (ls->selection, NULL, &iter))
+    {
+      gboolean visible;
+      gtk_tree_model_get (GTK_TREE_MODEL (ls->list_store),
+                          &iter, VISIBLE_COL, &visible, -1);
+      if (!visible)
+        toggle_visibility (ls, &iter);
+    }
+}
+
+/*! \brief Sets the colors of all layers in a layer-selector
+ *  \par Function Description
+ *  Updates the colors of a layer selector via a callback mechanism:
+ *  the user_id of each layer is passed to the callback function,
+ *  which returns a color string to update the layer's color, or NULL
+ *  to leave it alone.
+ *
+ *  \param [in] ls       The selector to be acted on
+ *  \param [in] callback Takes the user_id of the layer and returns a color string
+ */
+void
+ghid_layer_selector_update_colors (GHidLayerSelector *ls,
+                                   const gchar *(*callback)(int user_id))
+{
+  GtkTreeIter iter;
+  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (ls->list_store), &iter);
+  do
+    {
+      gint user_id;
+      const gchar *new_color;
+      gtk_tree_model_get (GTK_TREE_MODEL (ls->list_store),
+                          &iter, USER_ID_COL, &user_id, -1);
+      new_color = callback (user_id);
+      if (new_color != NULL)
+        gtk_list_store_set (ls->list_store, &iter, COLOR_COL, new_color, -1);
+    }
+  while (gtk_tree_model_iter_next (GTK_TREE_MODEL (ls->list_store), &iter));
+}
+
+/*! \brief Deletes layers from a layer selector
+ *  \par Function Description
+ *  Deletes layers according to a callback function: a return value of TRUE
+ *  means delete, FALSE means leave it alone. Do not try to delete all layers
+ *  using this function; with nothing left to select, pcb will likely go into
+ *  an infinite recursion between hid_action() and g_signal().
+ *
+ *  Separators will be deleted if the layer AFTER them is deleted.
+ *
+ *  \param [in] ls       The selector to be acted on
+ *  \param [in] callback Takes the user_id of the layer and returns a boolean
+ */
+void
+ghid_layer_selector_delete_layers (GHidLayerSelector *ls,
+                                   gboolean (*callback)(int user_id))
+{
+  GtkTreeIter iter, last_iter;
+  gboolean needs_inc;
+  gboolean was_separator = FALSE;
+  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (ls->list_store), &iter);
+  do
+    {
+      gboolean sep;
+      gint user_id, idx;
+      gtk_tree_model_get (GTK_TREE_MODEL (ls->list_store),
+                          &iter, USER_ID_COL, &user_id,
+                          INDEX_COL, &idx, SEPARATOR_COL, &sep, -1);
+      /* gtk_list_store_remove will increment the iter for us, so we
+       *  don't want to do it again in the loop condition */
+      needs_inc = TRUE;
+      if (!sep && callback (user_id))
+        {
+          if (gtk_list_store_remove (ls->list_store, &iter))
+            {
+              if (ls->view_actions[idx])
+                gtk_action_group_remove_action (ls->action_group,
+                                                GTK_ACTION (ls->view_actions[idx]));
+              if (ls->pick_actions[idx])
+                gtk_action_group_remove_action (ls->action_group,
+                                                GTK_ACTION (ls->pick_actions[idx]));
+              gtk_tree_row_reference_free (ls->rows[idx]);
+              ls->view_actions[idx] = NULL;
+              ls->pick_actions[idx] = NULL;
+              ls->rows[idx] = NULL;
+              needs_inc = FALSE;
+            }
+          else
+            return;
+          if (was_separator)
+            gtk_list_store_remove (ls->list_store, &last_iter);
+        }
+      last_iter = iter;
+      was_separator = sep;
+    }
+  while (!needs_inc ||
+         gtk_tree_model_iter_next (GTK_TREE_MODEL (ls->list_store), &iter));
+}
+
+
+
diff --git a/src/hid/gtk/ghid-layer-selector.h b/src/hid/gtk/ghid-layer-selector.h
new file mode 100644
index 0000000..bfeffe9
--- /dev/null
+++ b/src/hid/gtk/ghid-layer-selector.h
@@ -0,0 +1,45 @@
+#ifndef GHID_LAYER_SELECTOR_H__
+#define GHID_LAYER_SELECTOR_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS  /* keep c++ happy */
+
+#define GHID_LAYER_SELECTOR_TYPE            (ghid_layer_selector_get_type ())
+#define GHID_LAYER_SELECTOR(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GHID_LAYER_SELECTOR_TYPE, GHidLayerSelector))
+#define GHID_LAYER_SELECTOR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GHID_LAYER_SELECTOR_TYPE, GHidLayerSelectorClass))
+#define IS_GHID_LAYER_SELECTOR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GHID_LAYER_SELECTOR_TYPE))
+#define IS_GHID_LAYER_SELECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GHID_LAYER_SELECTOR_TYPE))
+
+typedef struct _GHidLayerSelector       GHidLayerSelector;
+typedef struct _GHidLayerSelectorClass  GHidLayerSelectorClass;
+
+GType ghid_layer_selector_get_type (void);
+GtkWidget* ghid_layer_selector_new (void);
+
+void ghid_layer_selector_add_layer (GHidLayerSelector *ls,
+                                    gint user_id,
+                                    const gchar *name,
+                                    const gchar *color_string,
+                                    gboolean visible,
+                                    gboolean activatable);
+GtkAccelGroup *ghid_layer_selector_get_accel_group (GHidLayerSelector *ls);
+gchar *ghid_layer_selector_get_pick_xml (GHidLayerSelector *ls);
+gchar *ghid_layer_selector_get_view_xml (GHidLayerSelector *ls);
+GtkActionGroup *ghid_layer_selector_get_action_group (GHidLayerSelector *ls);
+
+void ghid_layer_selector_toggle_layer (GHidLayerSelector *ls, 
+                                       gint user_id);
+void ghid_layer_selector_select_layer (GHidLayerSelector *ls, 
+                                       gint user_id);
+gboolean ghid_layer_selector_select_next_visible (GHidLayerSelector *ls);
+void ghid_layer_selector_make_selected_visible (GHidLayerSelector *ls);
+void ghid_layer_selector_update_colors (GHidLayerSelector *ls,
+                                        const gchar *(*callback)(int user_id));
+void ghid_layer_selector_delete_layers (GHidLayerSelector *ls,
+                                        gboolean (*callback)(int user_id));
+
+G_END_DECLS  /* keep c++ happy */
+#endif
diff --git a/src/hid/gtk/gtk-pcb-layer-selector.c b/src/hid/gtk/gtk-pcb-layer-selector.c
deleted file mode 100644
index 1067aeb..0000000
--- a/src/hid/gtk/gtk-pcb-layer-selector.c
+++ /dev/null
@@ -1,815 +0,0 @@
-/*! \file <gtk-pcb-layer-selector.c>
- *  \brief Implementation of GtkPcbLayerSelector widget
- *  \par Description
- *  This widget is the layer selector on the left side of the Gtk
- *  GUI. It also describes (in XML) the relevant sections of the
- *  menu for layer selection and visibility toggling, and makes
- *  sure these stay in sync.
- */
-
-#include <glib.h>
-#include <glib-object.h>
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-
-#include "gtkhid.h"
-#include "gui.h"
-#include "pcb-printf.h"
-
-#include "gtk-pcb-layer-selector.h"
-#include "ghid-cell-renderer-visibility.h"
-
-#define INITIAL_ACTION_MAX	40
-
-/* Forward dec'ls */
-static void gtk_pcb_layer_selector_finalize (GObject *object);
-
-/*! \brief Signals exposed by the widget */
-enum {
-  SELECT_LAYER_SIGNAL,
-  TOGGLE_LAYER_SIGNAL,
-  LAST_SIGNAL
-};
-
-/*! \brief Columns used for internal data store */
-enum {
-  INDEX_COL,
-  USER_ID_COL,
-  VISIBLE_COL,
-  COLOR_COL,
-  TEXT_COL,
-  FONT_COL,
-  ACTIVATABLE_COL,
-  SEPARATOR_COL,
-  N_COLS
-};
-
-static GtkTreeView *gtk_pcb_layer_selector_parent_class;
-static guint gtk_pcb_layer_selector_signals[LAST_SIGNAL] = { 0 };
-
-struct _GtkPcbLayerSelector
-{
-  GtkTreeView parent;
-
-  GtkListStore *list_store;
-  GtkTreeSelection *selection;
-  GtkTreeViewColumn *visibility_column;
-
-  GtkActionGroup *action_group;
-
-  GtkToggleAction **view_actions;
-  GtkRadioAction  **pick_actions;
-  GtkTreeRowReference **rows;
-  GSList *radio_group;
-  int max_actions;
-  int n_actions;
-
-  gboolean last_activatable;
-};
-
-struct _GtkPcbLayerSelectorClass
-{
-  GtkTreeViewClass parent_class;
-
-  void (* select_layer) (GtkPcbLayerSelector *, gint);
-  void (* toggle_layer) (GtkPcbLayerSelector *, gint);
-};
-
-/*! \brief Flip the visibility state of a given layer 
- *  \par Function Description
- *  Changes the internal toggle state and menu checkbox state
- *  of the layer pointed to by iter. Emits a toggle-layer signal.
- *  ALL internal visibility-flipping needs to go through this
- *  function. Otherwise a signal will not be emitted and it is
- *  likely that pcb will become inconsistent with the selector.
- *
- *  \param [in] ls    The selector to be acted on
- *  \param [in] iter  A GtkTreeIter pointed at the relevant layer
- */
-static void
-toggle_visibility (GtkPcbLayerSelector *ls, GtkTreeIter *iter)
-{
-  gint idx;
-  gboolean toggle;
-  gtk_tree_model_get (GTK_TREE_MODEL (ls->list_store), iter,
-                     VISIBLE_COL, &toggle, INDEX_COL, &idx, -1);
-  gtk_list_store_set (ls->list_store, iter, VISIBLE_COL, !toggle, -1);
-  gtk_toggle_action_set_active (ls->view_actions[idx], !toggle);
-}
-
-/*! \brief Decide if a GtkListStore entry is a layer or separator */
-static gboolean
-tree_view_separator_func (GtkTreeModel *model, GtkTreeIter *iter,
-                          gpointer data)
-{
-  gboolean ret_val;
-  gtk_tree_model_get (model, iter, SEPARATOR_COL, &ret_val, -1);
-  return ret_val;
-}
-
-/*! \brief Decide if a GtkListStore entry may be selected */
-static gboolean
-tree_selection_func (GtkTreeSelection *selection, GtkTreeModel *model,
-                     GtkTreePath *path, gboolean selected, gpointer data)
-{
-  GtkTreeIter iter;
-
-  if (gtk_tree_model_get_iter (model, &iter, path))
-    {
-      gboolean activatable;
-      gtk_tree_model_get (model, &iter, ACTIVATABLE_COL, &activatable, -1);
-      return activatable;
-    }
-
-  return FALSE;
-}
-
-/* SIGNAL HANDLERS */
-/*! \brief Callback for mouse-click: toggle visibility */
-static gboolean
-button_press_cb (GtkPcbLayerSelector *ls, GdkEventButton *event)
-{
-  /* Handle visibility independently to prevent changing the active
-   *  layer, which will happen if we let this event propagate.  */
-  GtkTreeViewColumn *column;
-  GtkTreePath *path;
-  if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (ls),
-                                     event->x, event->y,
-                                     &path, &column, NULL, NULL))
-    {
-      GtkTreeIter iter;
-      gtk_tree_model_get_iter (GTK_TREE_MODEL (ls->list_store), &iter, path);
-      if (column == ls->visibility_column)
-        {
-          toggle_visibility (ls, &iter);
-          return TRUE; 
-        }
-    }
-  return FALSE;
-}
-
-/*! \brief Callback for layer selection change: sync menu */
-static void
-selection_changed_cb (GtkTreeSelection *selection, GtkPcbLayerSelector *ls)
-{
-  GtkTreeIter iter;
-  if (gtk_tree_selection_get_selected (selection, NULL, &iter))
-    {
-      gint idx;
-      gtk_tree_model_get (GTK_TREE_MODEL (ls->list_store), &iter,
-                          INDEX_COL, &idx, -1);
-      if (ls->pick_actions[0])
-        gtk_radio_action_set_current_value (ls->pick_actions[0], idx);
-    }
-}
-
-/*! \brief Callback for menu actions: sync layer selection list, emit signal */
-static void
-menu_view_cb (GtkToggleAction *action, GtkTreeRowReference *rref)
-{
-  GtkPcbLayerSelector *ls;
-  GtkTreeModel *model = gtk_tree_row_reference_get_model (rref);
-  GtkTreePath *path = gtk_tree_row_reference_get_path (rref);
-  gboolean state = gtk_toggle_action_get_active (action);
-  GtkTreeIter iter;
-  gint user_id;
-
-  gtk_tree_model_get_iter (model, &iter, path);
-  gtk_list_store_set (GTK_LIST_STORE (model), &iter, VISIBLE_COL, state, -1);
-  gtk_tree_model_get (model, &iter, USER_ID_COL, &user_id, -1);
-
-  ls = g_object_get_data (G_OBJECT (model), "layer-selector");
-  g_signal_emit (ls, gtk_pcb_layer_selector_signals[TOGGLE_LAYER_SIGNAL],
-                 0, user_id);
-}
-
-/*! \brief Callback for menu actions: sync layer selection list, emit signal */
-static void
-menu_pick_cb (GtkRadioAction *action, GtkTreeRowReference *rref)
-{
-  GtkPcbLayerSelector *ls;
-  GtkTreeModel *model = gtk_tree_row_reference_get_model (rref);
-  GtkTreePath *path = gtk_tree_row_reference_get_path (rref);
-  GtkTreeIter iter;
-  gint user_id;
-
-  gtk_tree_model_get_iter (model, &iter, path);
-  gtk_tree_model_get (model, &iter, USER_ID_COL, &user_id, -1);
-
-  ls = g_object_get_data (G_OBJECT (model), "layer-selector");
-  gtk_tree_selection_select_path (ls->selection, path);
-  g_signal_emit (ls, gtk_pcb_layer_selector_signals[SELECT_LAYER_SIGNAL],
-                 0, user_id);
-}
-
-/* CONSTRUCTOR */
-static void
-gtk_pcb_layer_selector_init (GtkPcbLayerSelector *ls)
-{
-  /* Hookup signal handlers */
-}
-
-static void
-gtk_pcb_layer_selector_class_init (GtkPcbLayerSelectorClass *klass)
-{
-  GObjectClass *object_class = (GObjectClass *) klass;
-
-  gtk_pcb_layer_selector_signals[SELECT_LAYER_SIGNAL] =
-    g_signal_new ("select-layer",
-                  G_TYPE_FROM_CLASS (klass),
-                  G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                  G_STRUCT_OFFSET (GtkPcbLayerSelectorClass, select_layer),
-                  NULL, NULL,
-                  g_cclosure_marshal_VOID__INT, G_TYPE_NONE,
-                  1, G_TYPE_INT);
-  gtk_pcb_layer_selector_signals[TOGGLE_LAYER_SIGNAL] =
-    g_signal_new ("toggle-layer",
-                  G_TYPE_FROM_CLASS (klass),
-                  G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                  G_STRUCT_OFFSET (GtkPcbLayerSelectorClass, toggle_layer),
-                  NULL, NULL,
-                  g_cclosure_marshal_VOID__INT, G_TYPE_NONE,
-                  1, G_TYPE_INT);
-
-  object_class->finalize = gtk_pcb_layer_selector_finalize;
-}
-
-/*! \brief Clean up object before garbage collection
- */
-static void
-gtk_pcb_layer_selector_finalize (GObject *object)
-{
-  int i;
-  GtkPcbLayerSelector *ls = (GtkPcbLayerSelector *) object;
-
-  g_object_unref (ls->action_group);
-  g_free (ls->view_actions);
-  g_free (ls->pick_actions);
-  for (i = 0; i < ls->n_actions; ++i)
-    if (ls->rows[i])
-      gtk_tree_row_reference_free (ls->rows[i]);
-  g_free (ls->rows);
-
-  G_OBJECT_CLASS (gtk_pcb_layer_selector_parent_class)->finalize (object);
-}
-
-/* PUBLIC FUNCTIONS */
-GType
-gtk_pcb_layer_selector_get_type (void)
-{
-  static GType ls_type = 0;
-
-  if (!ls_type)
-    {
-      const GTypeInfo ls_info =
-      {
-	sizeof (GtkPcbLayerSelectorClass),
-	NULL, /* base_init */
-	NULL, /* base_finalize */
-	(GClassInitFunc) gtk_pcb_layer_selector_class_init,
-	NULL, /* class_finalize */
-	NULL, /* class_data */
-	sizeof (GtkPcbLayerSelector),
-	0,    /* n_preallocs */
-	(GInstanceInitFunc) gtk_pcb_layer_selector_init,
-      };
-
-      ls_type = g_type_register_static (GTK_TYPE_TREE_VIEW,
-                                        "GtkPcbLayerSelector",
-                                        &ls_info,
-                                        0);
-    }
-
-  return ls_type;
-}
-
-/*! \brief Create a new GtkPcbLayerSelector
- *
- *  \return a freshly-allocated GtkPcbLayerSelector.
- */
-GtkWidget *
-gtk_pcb_layer_selector_new (void)
-{
-  GtkCellRenderer *renderer1 = ghid_cell_renderer_visibility_new ();
-  GtkCellRenderer *renderer2 = gtk_cell_renderer_text_new ();
-  GtkTreeViewColumn *opacity_col =
-      gtk_tree_view_column_new_with_attributes ("", renderer1,
-                                                "active", VISIBLE_COL,
-                                                "color", COLOR_COL, NULL);
-  GtkTreeViewColumn *name_col =
-      gtk_tree_view_column_new_with_attributes ("", renderer2,
-                                                "text", TEXT_COL,
-                                                "font", FONT_COL,
-                                                "sensitive", VISIBLE_COL, NULL);
-
-  GtkPcbLayerSelector *ls = g_object_new (GTK_PCB_LAYER_SELECTOR_TYPE, NULL);
-
-  /* action index, active, color, text, font, is_separator */
-  ls->list_store = gtk_list_store_new (N_COLS, G_TYPE_INT, G_TYPE_INT,
-                                       G_TYPE_BOOLEAN, G_TYPE_STRING,
-                                       G_TYPE_STRING, G_TYPE_STRING,
-                                       G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
-  gtk_tree_view_insert_column (GTK_TREE_VIEW (ls), opacity_col, -1);
-  gtk_tree_view_insert_column (GTK_TREE_VIEW (ls), name_col, -1);
-  gtk_tree_view_set_model (GTK_TREE_VIEW (ls), GTK_TREE_MODEL (ls->list_store));
-  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (ls), FALSE);
-
-  ls->last_activatable = TRUE;
-  ls->visibility_column = opacity_col;
-  ls->selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (ls));
-  ls->action_group = gtk_action_group_new ("LayerSelector");
-  ls->n_actions = 0;
-  ls->max_actions = INITIAL_ACTION_MAX;
-  ls->view_actions = g_malloc0 (ls->max_actions * sizeof (*ls->view_actions));
-  ls->pick_actions = g_malloc0 (ls->max_actions * sizeof (*ls->pick_actions));
-  ls->rows = g_malloc0 (ls->max_actions * sizeof (*ls->rows));
-
-  gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW (ls),
-                                        tree_view_separator_func,
-                                        NULL, NULL);
-  gtk_tree_selection_set_select_function (ls->selection, tree_selection_func,
-                                          NULL, NULL);
-  gtk_tree_selection_set_mode (ls->selection, GTK_SELECTION_BROWSE);
-
-  g_object_set_data (G_OBJECT (ls->list_store), "layer-selector", ls);
-  g_signal_connect (ls, "button_press_event",
-                    G_CALLBACK (button_press_cb), NULL);
-  g_signal_connect (ls->selection, "changed",
-                    G_CALLBACK (selection_changed_cb), ls);
-
-  g_object_ref (ls->action_group);
-
-  return GTK_WIDGET (ls);
-}
-
-/*! \brief Add a layer to a GtkPcbLayerSelector.
- *  \par Function Description
- *  This function adds an entry to a GtkPcbLayerSelector, which will
- *  appear in the layer-selection list as well as visibility and selection
- *  menus (assuming this is a selectable layer). For the first 20 layers,
- *  keyboard accelerators will be added for selection/visibility toggling.
- *
- *  If the user_id passed already exists in the layer selector, that layer
- *  will have its data overwritten with the new stuff.
- *
- *  \param [in] ls            The selector to be acted on
- *  \param [in] user_id       An ID used to identify the layer; will be passed to selection/visibility callbacks
- *  \param [in] name          The name of the layer; will be used on selector and menus
- *  \param [in] color_string  The color of the layer on selector
- *  \param [in] visibile      Whether the layer is visible
- *  \param [in] activatable   Whether the layer appears in menus and can be selected
- */
-void
-gtk_pcb_layer_selector_add_layer (GtkPcbLayerSelector *ls,
-                                  gint user_id,
-                                  const gchar *name,
-                                  const gchar *color_string,
-                                  gboolean visible,
-                                  gboolean activatable)
-{
-  gchar *pname, *vname, *paccel, *vaccel;
-  gboolean new_iter = TRUE;
-  gboolean last_activatable = TRUE;
-  GtkTreePath *path;
-  GtkTreeIter iter;
-
-  /* Look for existing layer with this ID */
-  if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (ls->list_store), &iter))
-    do
-      {
-        gboolean is_sep, active;
-        gint read_id;
-        gtk_tree_model_get (GTK_TREE_MODEL (ls->list_store),
-                            &iter, USER_ID_COL, &read_id,
-                            SEPARATOR_COL, &is_sep,
-                            ACTIVATABLE_COL, &active, -1);
-        if (!is_sep)
-          {
-            last_activatable = active;
-            if(read_id == user_id)
-              {
-                new_iter = FALSE;
-                break;
-              }
-          }
-      }
-    while (gtk_tree_model_iter_next (GTK_TREE_MODEL (ls->list_store), &iter));
-
-  /* Handle separator addition */
-  if (new_iter)
-    {
-      if (activatable != last_activatable)
-        {
-          /* Add separator between activatable/non-activatable boundaries */
-          gtk_list_store_append (ls->list_store, &iter);
-          gtk_list_store_set (ls->list_store, &iter,
-                              SEPARATOR_COL, TRUE, -1);
-        }
-      /* Create new layer */
-      gtk_list_store_append (ls->list_store, &iter);
-      gtk_list_store_set (ls->list_store, &iter,
-                          INDEX_COL, ls->n_actions,
-                          USER_ID_COL, user_id,
-                          VISIBLE_COL, visible,
-                          COLOR_COL, color_string,
-                          TEXT_COL, name,
-                          FONT_COL, activatable ? NULL : "Italic",
-                          ACTIVATABLE_COL, activatable,
-                          SEPARATOR_COL, FALSE,
-                          -1);
-    }
-  else
-    gtk_list_store_set (ls->list_store, &iter,
-                        VISIBLE_COL, visible,
-                        COLOR_COL, color_string,
-                        TEXT_COL, name,
-                        FONT_COL, activatable ? NULL : "Italic",
-                        ACTIVATABLE_COL, activatable,
-                        -1);
-
-  /* Unless we're adding new actions, we're done now */
-  if (!new_iter)
-    return;
-
-  if (activatable && ls->n_actions == 0)
-    gtk_tree_selection_select_iter (ls->selection, &iter);
-
-  /* Allocate new actions if necessary */
-  if (ls->n_actions == ls->max_actions)
-    {
-      void *tmp[2];
-      ls->max_actions *= 2;
-      tmp[0] = g_realloc (ls->view_actions,
-                          ls->max_actions * sizeof (*ls->view_actions));
-      tmp[1] = g_realloc (ls->pick_actions,
-                          ls->max_actions * sizeof (*ls->pick_actions));
-      tmp[2] = g_realloc (ls->rows,
-                          ls->max_actions * sizeof (*ls->rows));
-      if (tmp[0] == NULL || tmp[1] == NULL || tmp[2] == NULL)
-        g_critical ("realloc failed allocating new actions");
-      else
-        {
-          ls->view_actions = tmp[0];
-          ls->pick_actions = tmp[1];
-          ls->rows = tmp[2];
-        }
-    }
-
-  /* -- Setup new actions -- */
-  vname = g_strdup_printf ("LayerView%d", ls->n_actions);
-  pname = g_strdup_printf ("LayerPick%d", ls->n_actions);
-  vaccel = NULL;
-  paccel = NULL;
-
-  /* Determine keyboard accelerators */
-  if (ls->n_actions < 10)
-    {
-      /* Map 1-0 to actions 1-10 (with '0' meaning 10) */
-      int i = (ls->n_actions + 1) % 10;
-      vaccel = g_strdup_printf ("<Ctrl>%d", i);
-      paccel = g_strdup_printf ("%d", i);
-    }
-  else
-    {
-      /* Map 1-0 to actions 11-20 (with '0' meaning 10) */
-      int i = (ls->n_actions + 1) % 10;
-      vaccel = g_strdup_printf ("<Alt><Ctrl>%d", i);
-      paccel = g_strdup_printf ("<Alt>%d", i);
-    }
-
-  /* Create row reference for actions */
-  path = gtk_tree_model_get_path (GTK_TREE_MODEL (ls->list_store), &iter);
-  ls->rows[ls->n_actions] = gtk_tree_row_reference_new
-                              (GTK_TREE_MODEL (ls->list_store), path);
-  gtk_tree_path_free (path);
-
-  /* Create selection action */
-  if (activatable)
-    {
-      ls->pick_actions[ls->n_actions]
-        = gtk_radio_action_new (pname, name, NULL, NULL, ls->n_actions);
-      gtk_radio_action_set_group (ls->pick_actions[ls->n_actions],
-                                  ls->radio_group);
-      ls->radio_group
-         = gtk_radio_action_get_group (ls->pick_actions[ls->n_actions]);
-      gtk_action_group_add_action_with_accel
-        (ls->action_group,
-         GTK_ACTION (ls->pick_actions[ls->n_actions]),
-         paccel);
-      g_signal_connect (ls->pick_actions[ls->n_actions], "toggled",
-                        G_CALLBACK (menu_pick_cb), ls->rows[ls->n_actions]);
-    }
-  else
-    ls->pick_actions[ls->n_actions] = NULL;
-
-  /* Create visibility action */
-  ls->view_actions[ls->n_actions] = gtk_toggle_action_new (vname, name,
-                                                           NULL, NULL);
-  gtk_toggle_action_set_active (ls->view_actions[ls->n_actions], visible);
-
-  gtk_action_group_add_action_with_accel
-    (ls->action_group,
-     GTK_ACTION (ls->view_actions[ls->n_actions]),
-     vaccel);
-  g_signal_connect (ls->view_actions[ls->n_actions], "toggled",
-                    G_CALLBACK (menu_view_cb), ls->rows[ls->n_actions]);
-
-  /* cleanup */
-  if (vaccel)
-    {
-      g_free (vaccel);
-      g_free (paccel); 
-    }
-  g_free (vname);
-  g_free (pname);
-
-  ls->n_actions++;
-}
-
-/*! \brief Get the "Current Layer" menu description of a layer selector
- *  \par Function Description
- *  Returns the XML content used by Gtk in building the layer-selection
- *  part of the menu. This is a radio-button list describing which layer
- *  is active.
- *
- *  \param [in] ls            The selector to be acted on
- *
- *  \return the requested XML
- */
-gchar *
-gtk_pcb_layer_selector_get_pick_xml (GtkPcbLayerSelector *ls)
-{
-  int i;
-  GString *str = g_string_new ("");
-
-  for (i = 0; i < ls->n_actions; ++i)
-    if (ls->pick_actions[i])
-      g_string_append_printf (str, "<menuitem action=\"LayerPick%d\" />\n", i);
-
-  return g_string_free (str, FALSE);
-}
-
-/*! \brief Get the "Shown Layers" menu description of a layer selector
- *  \par Function Description
- *  Returns the XML content used by Gtk in building the layer-selection
- *  part of the menu. This is a toggle-button list describing which layer(s)
- *  are visible.
- *
- *  \param [in] ls            The selector to be acted on
- *
- *  \return the requested XML
- */
-gchar *
-gtk_pcb_layer_selector_get_view_xml (GtkPcbLayerSelector *ls)
-{
-  int i;
-  GString *str = g_string_new ("");
-
-  for (i = 0; i < ls->n_actions; ++i)
-    if (ls->view_actions[i])
-      g_string_append_printf (str, "<menuitem action=\"LayerView%d\" />\n", i);
-
-  return g_string_free (str, FALSE);
-}
-
-/*! \brief Get the GtkActionGroup containing accelerators, etc, of a layer selector
- *  \par Function Description
- *  Returns the GtkActionGroup containing the toggle and radio buttons used
- *  in the menu. Also contains the accelerators. This action group should be
- *  added to the main UI. See Gtk docs for details.
- *
- *  \param [in] ls            The selector to be acted on
- *
- *  \return the action group of the selector
- */
-GtkActionGroup *
-gtk_pcb_layer_selector_get_action_group (GtkPcbLayerSelector *ls)
-{
-  return ls->action_group;
-}
-
-/*! \brief used internally */
-static gboolean
-toggle_foreach_func (GtkTreeModel *model, GtkTreePath *path,
-                     GtkTreeIter *iter, gpointer data)
-{
-  gint id;
-  GtkPcbLayerSelector *ls = g_object_get_data (G_OBJECT (model),
-                                               "layer-selector");
-  
-  gtk_tree_model_get (model, iter, USER_ID_COL, &id, -1);
-  if (id == *(gint *) data)
-    {
-      toggle_visibility (ls, iter);
-      return TRUE;
-    }
-  return FALSE;
-}
-
-/*! \brief Toggle a layer's visibility
- *  \par Function Description
- *  Toggle the layer indicated by user_id, emitting a layer-toggle signal.
- *
- *  \param [in] ls       The selector to be acted on
- *  \param [in] user_id  The ID of the layer to be affected
- */
-void
-gtk_pcb_layer_selector_toggle_layer (GtkPcbLayerSelector *ls, gint user_id)
-{
-  gtk_tree_model_foreach (GTK_TREE_MODEL (ls->list_store),
-                          toggle_foreach_func, &user_id);
-}
-
-/*! \brief used internally */
-static gboolean
-select_foreach_func (GtkTreeModel *model, GtkTreePath *path,
-                     GtkTreeIter *iter, gpointer data)
-{
-  gint id;
-  GtkPcbLayerSelector *ls = g_object_get_data (G_OBJECT (model),
-                                               "layer-selector");
-  
-  gtk_tree_model_get (model, iter, USER_ID_COL, &id, -1);
-  if (id == *(gint *) data)
-    {
-      gtk_tree_selection_select_path (ls->selection, path);
-      return TRUE;
-    }
-  return FALSE;
-}
-
-/*! \brief Select a layer
- *  \par Function Description
- *  Select the layer indicated by user_id, emitting a layer-select signal.
- *
- *  \param [in] ls       The selector to be acted on
- *  \param [in] user_id  The ID of the layer to be affected
- */
-void
-gtk_pcb_layer_selector_select_layer (GtkPcbLayerSelector *ls, gint user_id)
-{
-  gtk_tree_model_foreach (GTK_TREE_MODEL (ls->list_store),
-                          select_foreach_func, &user_id);
-}
-
-/*! \brief Selects the next visible layer
- *  \par Function Description
- *  Used to ensure hidden layers are not active; if the active layer is
- *  visible, this function is a noop. Otherwise, it will look for the
- *  next layer that IS visible, and select that. Failing that, it will
- *  return FALSE.
- *
- *  \param [in] ls       The selector to be acted on
- *
- *  \return TRUE on success, FALSE if all selectable layers are hidden
- */
-gboolean
-gtk_pcb_layer_selector_select_next_visible (GtkPcbLayerSelector *ls)
-{
-  GtkTreeIter iter;
-  if (gtk_tree_selection_get_selected (ls->selection, NULL, &iter))
-    {
-      /* Scan forward, looking for selectable iter */
-      do
-        {
-          gboolean visible, activatable;
-          gtk_tree_model_get (GTK_TREE_MODEL (ls->list_store),
-                              &iter, VISIBLE_COL, &visible,
-                              ACTIVATABLE_COL, &activatable, -1);
-          if (visible && activatable)
-            {
-              gtk_tree_selection_select_iter (ls->selection, &iter);
-              return TRUE;
-            }
-        }
-      while (gtk_tree_model_iter_next (GTK_TREE_MODEL (ls->list_store), &iter));
-      /* Move iter to start, and repeat. */
-      gtk_tree_model_get_iter_first (GTK_TREE_MODEL (ls->list_store), &iter);
-      do
-        {
-          gboolean visible, activatable;
-          gtk_tree_model_get (GTK_TREE_MODEL (ls->list_store),
-                              &iter, VISIBLE_COL, &visible,
-                              ACTIVATABLE_COL, &activatable, -1);
-          if (visible && activatable)
-            {
-              gtk_tree_selection_select_iter (ls->selection, &iter);
-              return TRUE;
-            }
-        }
-      while (gtk_tree_model_iter_next (GTK_TREE_MODEL (ls->list_store), &iter));
-      /* If we get here, nothing is selectable, so fail. */
-    }
-  return FALSE;
-}
-
-/*! \brief Makes the selected layer visible
- *  \par Function Description
- *  Used to ensure hidden layers are not active; un-hides the currently
- *  selected layer.
- *
- *  \param [in] ls       The selector to be acted on
- */
-void
-gtk_pcb_layer_selector_make_selected_visible (GtkPcbLayerSelector *ls)
-{
-  GtkTreeIter iter;
-  if (gtk_tree_selection_get_selected (ls->selection, NULL, &iter))
-    {
-      gboolean visible;
-      gtk_tree_model_get (GTK_TREE_MODEL (ls->list_store),
-                          &iter, VISIBLE_COL, &visible, -1);
-      if (!visible)
-        toggle_visibility (ls, &iter);
-    }
-}
-
-/*! \brief Sets the colors of all layers in a layer-selector
- *  \par Function Description
- *  Updates the colors of a layer selector via a callback mechanism:
- *  the user_id of each layer is passed to the callback function,
- *  which returns a color string to update the layer's color, or NULL
- *  to leave it alone.
- *
- *  \param [in] ls       The selector to be acted on
- *  \param [in] callback Takes the user_id of the layer and returns a color string
- */
-void
-gtk_pcb_layer_selector_update_colors (GtkPcbLayerSelector *ls,
-                                      const gchar *(*callback)(int user_id))
-{
-  GtkTreeIter iter;
-  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (ls->list_store), &iter);
-  do
-    {
-      gint user_id;
-      const gchar *new_color;
-      gtk_tree_model_get (GTK_TREE_MODEL (ls->list_store),
-                          &iter, USER_ID_COL, &user_id, -1);
-      new_color = callback (user_id);
-      if (new_color != NULL)
-        gtk_list_store_set (ls->list_store, &iter, COLOR_COL, new_color, -1);
-    }
-  while (gtk_tree_model_iter_next (GTK_TREE_MODEL (ls->list_store), &iter));
-}
-
-/*! \brief Deletes layers from a layer selector
- *  \par Function Description
- *  Deletes layers according to a callback function: a return value of TRUE
- *  means delete, FALSE means leave it alone. Do not try to delete all layers
- *  using this function; with nothing left to select, pcb will likely go into
- *  an infinite recursion between hid_action() and g_signal().
- *
- *  Separators will be deleted if the layer AFTER them is deleted.
- *
- *  \param [in] ls       The selector to be acted on
- *  \param [in] callback Takes the user_id of the layer and returns a boolean
- */
-void
-gtk_pcb_layer_selector_delete_layers (GtkPcbLayerSelector *ls,
-                                      gboolean (*callback)(int user_id))
-{
-  GtkTreeIter iter, last_iter;
-  gboolean needs_inc;
-  gboolean was_separator = FALSE;
-  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (ls->list_store), &iter);
-  do
-    {
-      gboolean sep;
-      gint user_id, idx;
-      gtk_tree_model_get (GTK_TREE_MODEL (ls->list_store),
-                          &iter, USER_ID_COL, &user_id,
-                          INDEX_COL, &idx, SEPARATOR_COL, &sep, -1);
-      /* gtk_list_store_remove will increment the iter for us, so we
-       *  don't want to do it again in the loop condition */
-      needs_inc = TRUE;
-      if (!sep && callback (user_id))
-        {
-          if (gtk_list_store_remove (ls->list_store, &iter))
-            {
-              if (ls->view_actions[idx])
-                gtk_action_group_remove_action (ls->action_group,
-                                                GTK_ACTION (ls->view_actions[idx]));
-              if (ls->pick_actions[idx])
-                gtk_action_group_remove_action (ls->action_group,
-                                                GTK_ACTION (ls->pick_actions[idx]));
-              gtk_tree_row_reference_free (ls->rows[idx]);
-              ls->view_actions[idx] = NULL;
-              ls->pick_actions[idx] = NULL;
-              ls->rows[idx] = NULL;
-              needs_inc = FALSE;
-            }
-          else
-            return;
-          if (was_separator)
-            gtk_list_store_remove (ls->list_store, &last_iter);
-        }
-      last_iter = iter;
-      was_separator = sep;
-    }
-  while (!needs_inc ||
-         gtk_tree_model_iter_next (GTK_TREE_MODEL (ls->list_store), &iter));
-}
-
-
-
diff --git a/src/hid/gtk/gtk-pcb-layer-selector.h b/src/hid/gtk/gtk-pcb-layer-selector.h
deleted file mode 100644
index 27b0de9..0000000
--- a/src/hid/gtk/gtk-pcb-layer-selector.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef GTK_PCB_LAYER_SELECTOR_H__
-#define GTK_PCB_LAYER_SELECTOR_H__
-
-#include <glib.h>
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS  /* keep c++ happy */
-
-#define GTK_PCB_LAYER_SELECTOR_TYPE            (gtk_pcb_layer_selector_get_type ())
-#define GTK_PCB_LAYER_SELECTOR(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_PCB_LAYER_SELECTOR_TYPE, GtkPcbLayerSelector))
-#define GTK_PCB_LAYER_SELECTOR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_PCB_LAYER_SELECTOR_TYPE, GtkPcbLayerSelectorClass))
-#define IS_GTK_PCB_LAYER_SELECTOR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_PCB_LAYER_SELECTOR_TYPE))
-#define IS_GTK_PCB_LAYER_SELECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_PCB_LAYER_SELECTOR_TYPE))
-
-typedef struct _GtkPcbLayerSelector       GtkPcbLayerSelector;
-typedef struct _GtkPcbLayerSelectorClass  GtkPcbLayerSelectorClass;
-
-GType gtk_pcb_layer_selector_get_type (void);
-GtkWidget* gtk_pcb_layer_selector_new (void);
-
-void gtk_pcb_layer_selector_add_layer (GtkPcbLayerSelector *ls,
-                                       gint user_id,
-                                       const gchar *name,
-                                       const gchar *color_string,
-                                       gboolean visible,
-                                       gboolean activatable);
-GtkAccelGroup *gtk_pcb_layer_selector_get_accel_group (GtkPcbLayerSelector *ls);
-gchar *gtk_pcb_layer_selector_get_pick_xml (GtkPcbLayerSelector *ls);
-gchar *gtk_pcb_layer_selector_get_view_xml (GtkPcbLayerSelector *ls);
-GtkActionGroup *gtk_pcb_layer_selector_get_action_group (GtkPcbLayerSelector *ls);
-
-void gtk_pcb_layer_selector_toggle_layer (GtkPcbLayerSelector *ls, 
-                                          gint user_id);
-void gtk_pcb_layer_selector_select_layer (GtkPcbLayerSelector *ls, 
-                                          gint user_id);
-gboolean gtk_pcb_layer_selector_select_next_visible (GtkPcbLayerSelector *ls);
-void gtk_pcb_layer_selector_make_selected_visible (GtkPcbLayerSelector *ls);
-void gtk_pcb_layer_selector_update_colors (GtkPcbLayerSelector *ls,
-                                           const gchar *(*callback)(int user_id));
-void gtk_pcb_layer_selector_delete_layers (GtkPcbLayerSelector *ls,
-                                           gboolean (*callback)(int user_id));
-
-G_END_DECLS  /* keep c++ happy */
-#endif
diff --git a/src/hid/gtk/gui-top-window.c b/src/hid/gtk/gui-top-window.c
index 26e0030..9d170c8 100644
--- a/src/hid/gtk/gui-top-window.c
+++ b/src/hid/gtk/gui-top-window.c
@@ -82,7 +82,7 @@ a zoom in/out.
 #include <locale.h>
 #endif
 
-#include "gtk-pcb-layer-selector.h"
+#include "ghid-layer-selector.h"
 #include "gtkhid.h"
 #include "gui.h"
 #include "hid.h"
@@ -677,9 +677,9 @@ layer_process (gchar **color_string, char **text, int *set, int i)
     }
 }
 
-/*! \brief Callback for GtkPcbLayerSelector layer selection */
+/*! \brief Callback for GHidLayerSelector layer selection */
 static void
-layer_selector_select_callback (GtkPcbLayerSelector *ls, int layer, gpointer d)
+layer_selector_select_callback (GHidLayerSelector *ls, int layer, gpointer d)
 {
   gboolean active;
   layer_process (NULL, NULL, &active, layer);
@@ -691,14 +691,14 @@ layer_selector_select_callback (GtkPcbLayerSelector *ls, int layer, gpointer d)
     ChangeGroupVisibility (layer, true, true);
 
   /* Ensure layer is turned on */
-  gtk_pcb_layer_selector_make_selected_visible (ls);
+  ghid_layer_selector_make_selected_visible (ls);
 
   ghid_invalidate_all ();
 }
 
-/*! \brief Callback for GtkPcbLayerSelector layer toggling */
+/*! \brief Callback for GHidLayerSelector layer toggling */
 static void
-layer_selector_toggle_callback (GtkPcbLayerSelector *ls, int layer, gpointer d)
+layer_selector_toggle_callback (GHidLayerSelector *ls, int layer, gpointer d)
 {
   gboolean redraw = FALSE;
   gboolean active;
@@ -748,8 +748,8 @@ layer_selector_toggle_callback (GtkPcbLayerSelector *ls, int layer, gpointer d)
    *  (or its group). In this case, select a different one if we
    *  can. If we can't, turn the original layer back on.
    */
-  if (!gtk_pcb_layer_selector_select_next_visible (ls))
-    gtk_pcb_layer_selector_toggle_layer (ls, layer);
+  if (!ghid_layer_selector_select_next_visible (ls))
+    ghid_layer_selector_toggle_layer (ls, layer);
 
   if (redraw)
     ghid_invalidate_all();
@@ -838,8 +838,8 @@ make_top_menubar (GtkWidget * hbox, GHidPort * port)
   ghidgui->main_actions = actions;
 
   make_menu_actions (actions, port);
-  layer_actions = gtk_pcb_layer_selector_get_action_group
-          (GTK_PCB_LAYER_SELECTOR (ghidgui->layer_selector));
+  layer_actions = ghid_layer_selector_get_action_group
+          (GHID_LAYER_SELECTOR (ghidgui->layer_selector));
  
   gtk_ui_manager_insert_action_group (ui, actions, 0);
   gtk_ui_manager_insert_action_group (ui, layer_actions, 0);
@@ -996,32 +996,32 @@ make_cursor_position_labels (GtkWidget * hbox, GHidPort * port)
 static void
 make_virtual_layer_buttons (GtkWidget *layer_selector)
 {
-  GtkPcbLayerSelector *layersel = GTK_PCB_LAYER_SELECTOR (layer_selector);
+  GHidLayerSelector *layersel = GHID_LAYER_SELECTOR (layer_selector);
   gchar *text;
   gchar *color_string;
   gboolean active;
  
   layer_process (&color_string, &text, &active, LAYER_BUTTON_SILK);
-  gtk_pcb_layer_selector_add_layer (layersel, LAYER_BUTTON_SILK,
-                                    text, color_string, active, TRUE);
+  ghid_layer_selector_add_layer (layersel, LAYER_BUTTON_SILK,
+                                 text, color_string, active, TRUE);
   layer_process (&color_string, &text, &active, LAYER_BUTTON_RATS);
-  gtk_pcb_layer_selector_add_layer (layersel, LAYER_BUTTON_RATS,
-                                    text, color_string, active, TRUE);
+  ghid_layer_selector_add_layer (layersel, LAYER_BUTTON_RATS,
+                                 text, color_string, active, TRUE);
   layer_process (&color_string, &text, &active, LAYER_BUTTON_PINS);
-  gtk_pcb_layer_selector_add_layer (layersel, LAYER_BUTTON_PINS,
-                                    text, color_string, active, FALSE);
+  ghid_layer_selector_add_layer (layersel, LAYER_BUTTON_PINS,
+                                 text, color_string, active, FALSE);
   layer_process (&color_string, &text, &active, LAYER_BUTTON_VIAS);
-  gtk_pcb_layer_selector_add_layer (layersel, LAYER_BUTTON_VIAS,
-                                    text, color_string, active, FALSE);
+  ghid_layer_selector_add_layer (layersel, LAYER_BUTTON_VIAS,
+                                 text, color_string, active, FALSE);
   layer_process (&color_string, &text, &active, LAYER_BUTTON_FARSIDE);
-  gtk_pcb_layer_selector_add_layer (layersel, LAYER_BUTTON_FARSIDE,
-                                    text, color_string, active, FALSE);
+  ghid_layer_selector_add_layer (layersel, LAYER_BUTTON_FARSIDE,
+                                 text, color_string, active, FALSE);
   layer_process (&color_string, &text, &active, LAYER_BUTTON_MASK);
-  gtk_pcb_layer_selector_add_layer (layersel, LAYER_BUTTON_MASK,
-                                    text, color_string, active, FALSE);
+  ghid_layer_selector_add_layer (layersel, LAYER_BUTTON_MASK,
+                                 text, color_string, active, FALSE);
 }
 
-/*! \brief callback for gtk_pcb_layer_selector_update_colors */
+/*! \brief callback for ghid_layer_selector_update_colors */
 const gchar *
 get_layer_color (gint layer)
 {
@@ -1034,8 +1034,8 @@ get_layer_color (gint layer)
 void
 ghid_layer_buttons_color_update (void)
 {
-  gtk_pcb_layer_selector_update_colors
-    (GTK_PCB_LAYER_SELECTOR (ghidgui->layer_selector), get_layer_color);
+  ghid_layer_selector_update_colors
+    (GHID_LAYER_SELECTOR (ghidgui->layer_selector), get_layer_color);
   pcb_colors_from_settings (PCB);
 }
  
@@ -1051,13 +1051,13 @@ make_layer_buttons (GtkWidget *layersel)
   for (i = 0; i < max_copper_layer; ++i)
     {
       layer_process (&color_string, &text, &active, i);
-      gtk_pcb_layer_selector_add_layer (GTK_PCB_LAYER_SELECTOR (layersel), i,
-                                        text, color_string, active, TRUE);
+      ghid_layer_selector_add_layer (GHID_LAYER_SELECTOR (layersel), i,
+                                     text, color_string, active, TRUE);
     }
 }
 
 
-/*! \brief callback for gtk_pcb_layer_selector_delete_layers */
+/*! \brief callback for ghid_layer_selector_delete_layers */
 gboolean
 get_layer_delete (gint layer)
 {
@@ -1074,8 +1074,8 @@ ghid_layer_buttons_update (void)
 {
   gint layer;
 
-  gtk_pcb_layer_selector_delete_layers
-    (GTK_PCB_LAYER_SELECTOR (ghidgui->layer_selector),
+  ghid_layer_selector_delete_layers
+    (GHID_LAYER_SELECTOR (ghidgui->layer_selector),
      get_layer_delete);
   make_layer_buttons (ghidgui->layer_selector);
   make_virtual_layer_buttons (ghidgui->layer_selector);
@@ -1088,8 +1088,8 @@ ghid_layer_buttons_update (void)
   else
     layer = LayerStack[0];
 
-  gtk_pcb_layer_selector_select_layer
-    (GTK_PCB_LAYER_SELECTOR (ghidgui->layer_selector), layer);
+  ghid_layer_selector_select_layer
+    (GHID_LAYER_SELECTOR (ghidgui->layer_selector), layer);
 }
 
 
@@ -1485,7 +1485,7 @@ ghid_build_pcb_top_window (void)
   gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
 
   /* Build layer menus */
-  ghidgui->layer_selector = gtk_pcb_layer_selector_new ();
+  ghidgui->layer_selector = ghid_layer_selector_new ();
   make_layer_buttons (ghidgui->layer_selector);
   make_virtual_layer_buttons (ghidgui->layer_selector);
   g_signal_connect (G_OBJECT (ghidgui->layer_selector), "select_layer",
@@ -2167,8 +2167,8 @@ ToggleView (int argc, char **argv, Coord x, Coord y)
   /* Now that we've figured out which toggle button ought to control
    * this layer, simply hit the button and let the pre-existing code deal
    */
-  gtk_pcb_layer_selector_toggle_layer
-    (GTK_PCB_LAYER_SELECTOR (ghidgui->layer_selector), l);
+  ghid_layer_selector_toggle_layer
+    (GHID_LAYER_SELECTOR (ghidgui->layer_selector), l);
   in_toggle_view = 0;
   return 0;
 }
@@ -2207,8 +2207,8 @@ SelectLayer (int argc, char **argv, Coord x, Coord y)
   /* Now that we've figured out which radio button ought to select
    * this layer, simply hit the button and let the pre-existing code deal
    */
-  gtk_pcb_layer_selector_select_layer
-    (GTK_PCB_LAYER_SELECTOR (ghidgui->layer_selector), newl);
+  ghid_layer_selector_select_layer
+    (GHID_LAYER_SELECTOR (ghidgui->layer_selector), newl);
 
   return 0;
 }
@@ -2906,15 +2906,15 @@ add_resource_to_menu (const char * menu, const Resource * node, int indent)
 	  {
 	    if (strcmp (node->v[i].value, "@layerview") == 0)
 	      {
-                gchar *tmp = gtk_pcb_layer_selector_get_view_xml
-                  (GTK_PCB_LAYER_SELECTOR (ghidgui->layer_selector));
+                gchar *tmp = ghid_layer_selector_get_view_xml
+                  (GHID_LAYER_SELECTOR (ghidgui->layer_selector));
                 ghid_ui_info_append (tmp);
                 g_free (tmp);
 	      }
 	    else if (strcmp (node->v[i].value, "@layerpick") == 0)
 	      {
-                gchar *tmp = gtk_pcb_layer_selector_get_pick_xml
-                  (GTK_PCB_LAYER_SELECTOR (ghidgui->layer_selector));
+                gchar *tmp = ghid_layer_selector_get_pick_xml
+                  (GHID_LAYER_SELECTOR (ghidgui->layer_selector));
                 ghid_ui_info_append (tmp);
                 g_free (tmp);
 	      }

commit 352a088d8c506ef0407cb9c88844bf4033576eb0
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Rename GtkPcbCellRendererVisibility to GHidCellRendererVisibility

diff --git a/src/Makefile.am b/src/Makefile.am
index d4c37e0..f4bba29 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -274,8 +274,8 @@ LIBGTK_SRCS = \
 	hid/gtk/gtk-pcb-coord-entry.h \
 	hid/gtk/gtk-pcb-layer-selector.c \
 	hid/gtk/gtk-pcb-layer-selector.h \
-	hid/gtk/gtk-pcb-cell-renderer-visibility.c \
-	hid/gtk/gtk-pcb-cell-renderer-visibility.h \
+	hid/gtk/ghid-cell-renderer-visibility.c \
+	hid/gtk/ghid-cell-renderer-visibility.h \
 	hid/gtk/gtkhid-main.c \
 	hid/gtk/gtkhid.h \
 	hid/gtk/gui.h \
diff --git a/src/hid/gtk/ghid-cell-renderer-visibility.c b/src/hid/gtk/ghid-cell-renderer-visibility.c
new file mode 100644
index 0000000..2e07c67
--- /dev/null
+++ b/src/hid/gtk/ghid-cell-renderer-visibility.c
@@ -0,0 +1,295 @@
+/*! \file <gtk-pcb-cell-render-visibility.c>
+ *  \brief Implementation of GtkCellRenderer for layer visibility toggler
+ *  \par More Information
+ *  For details on the functions implemented here, see the Gtk
+ *  documentation for the GtkCellRenderer object, which defines
+ *  the interface we are implementing.
+ */
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "gtkhid.h"
+#include "gui.h"
+
+#include "ghid-cell-renderer-visibility.h"
+
+enum {
+  TOGGLED,
+  LAST_SIGNAL
+};
+static guint toggle_cell_signals[LAST_SIGNAL] = { 0 };
+
+enum {
+  PROP_ACTIVE = 1,
+  PROP_COLOR
+};
+
+struct _GHidCellRendererVisibility
+{
+  GtkCellRenderer parent;
+
+  gboolean active;
+  gchar *color;
+};
+
+struct _GHidCellRendererVisibilityClass
+{
+  GtkCellRendererClass parent_class;
+
+  void (* toggled) (GHidCellRendererVisibility *cell, const gchar *path);
+};
+
+/* RENDERER FUNCTIONS */
+/*! \brief Calculates the window area the renderer will use */
+static void
+ghid_cell_renderer_visibility_get_size (GtkCellRenderer *cell,
+                                        GtkWidget       *widget,
+                                        GdkRectangle    *cell_area,
+                                        gint            *x_offset,
+                                        gint            *y_offset,
+                                        gint            *width,
+                                        gint            *height)
+{
+  GtkStyle *style = gtk_widget_get_style (widget);
+  gint w, h;
+
+  w = VISIBILITY_TOGGLE_SIZE + 2 * (cell->xpad + style->xthickness);
+  h = VISIBILITY_TOGGLE_SIZE + 2 * (cell->ypad + style->ythickness);
+
+  if (width)
+    *width = w;
+  if (height)
+    *height = h;
+
+  if (cell_area)
+    {
+      if (x_offset)
+        {
+          gint xalign = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
+                          ? 1.0 - cell->xalign
+                          : cell->xalign;
+          *x_offset = MAX (0, xalign * (cell_area->width - w));
+        }
+      if (y_offset)
+        *y_offset = MAX(0, cell->yalign * (cell_area->height - h));
+    }
+}
+
+/*! \brief Actually renders the swatch */
+static void
+ghid_cell_renderer_visibility_render (GtkCellRenderer      *cell,
+                                      GdkWindow            *window,
+                                      GtkWidget            *widget,
+                                      GdkRectangle         *background_area,
+                                      GdkRectangle         *cell_area,
+                                      GdkRectangle         *expose_area,
+                                      GtkCellRendererState  flags)
+{
+  GHidCellRendererVisibility *pcb_cell;
+  GdkRectangle toggle_rect;
+  GdkRectangle draw_rect;
+
+  pcb_cell = GHID_CELL_RENDERER_VISIBILITY (cell);
+  ghid_cell_renderer_visibility_get_size (cell, widget, cell_area,
+                                          &toggle_rect.x,
+                                          &toggle_rect.y,
+                                          &toggle_rect.width,
+                                          &toggle_rect.height);
+
+  toggle_rect.x      += cell_area->x + cell->xpad;
+  toggle_rect.y      += cell_area->y + cell->ypad;
+  toggle_rect.width  -= cell->xpad * 2;
+  toggle_rect.height -= cell->ypad * 2;
+
+  if (toggle_rect.width <= 0 || toggle_rect.height <= 0)
+    return;
+
+  if (gdk_rectangle_intersect (expose_area, cell_area, &draw_rect))
+    {
+      GdkColor color;
+      cairo_t *cr = gdk_cairo_create (window);
+      if (expose_area)
+        {
+          gdk_cairo_rectangle (cr, expose_area);
+          cairo_clip (cr);
+        }
+      cairo_set_line_width (cr, 1);
+
+      cairo_rectangle (cr, toggle_rect.x + 0.5, toggle_rect.y + 0.5,
+                           toggle_rect.width - 1, toggle_rect.height - 1);
+      cairo_set_source_rgb (cr, 1, 1, 1);
+      cairo_fill_preserve (cr);
+      cairo_set_source_rgb (cr, 0, 0, 0);
+      cairo_stroke (cr);
+
+      gdk_color_parse (pcb_cell->color, &color);
+      gdk_cairo_set_source_color (cr, &color);
+      if (pcb_cell->active)
+        cairo_rectangle (cr, toggle_rect.x + 0.5, toggle_rect.y + 0.5,
+                             toggle_rect.width - 1, toggle_rect.height - 1);
+      else
+        {
+          cairo_move_to (cr, toggle_rect.x + 1, toggle_rect.y + 1);
+          cairo_rel_line_to (cr, toggle_rect.width / 2, 0);
+          cairo_rel_line_to (cr, -toggle_rect.width / 2, toggle_rect.width / 2);
+          cairo_close_path (cr);
+        }
+      cairo_fill (cr);
+
+      cairo_destroy (cr);
+    }
+}
+
+/*! \brief Toggless the swatch */
+static gint
+ghid_cell_renderer_visibility_activate (GtkCellRenderer      *cell,
+                                        GdkEvent             *event,
+                                        GtkWidget            *widget,
+                                        const gchar          *path,
+                                        GdkRectangle         *background_area,
+                                        GdkRectangle         *cell_area,
+                                        GtkCellRendererState  flags)
+{
+  g_signal_emit (cell, toggle_cell_signals[TOGGLED], 0, path);
+  return TRUE;
+}
+
+/* Setter/Getter */
+static void
+ghid_cell_renderer_visibility_get_property (GObject     *object,
+                                            guint        param_id,
+                                            GValue      *value,
+                                            GParamSpec  *pspec)
+{
+  GHidCellRendererVisibility *pcb_cell =
+    GHID_CELL_RENDERER_VISIBILITY (object);
+
+  switch (param_id)
+    {
+    case PROP_ACTIVE:
+      g_value_set_boolean (value, pcb_cell->active);
+      break;
+    case PROP_COLOR:
+      g_value_set_string (value, pcb_cell->color);
+      break;
+    }
+}
+
+static void
+ghid_cell_renderer_visibility_set_property (GObject      *object,
+                                               guint         param_id,
+                                               const GValue *value,
+                                               GParamSpec   *pspec)
+{
+  GHidCellRendererVisibility *pcb_cell =
+    GHID_CELL_RENDERER_VISIBILITY (object);
+
+  switch (param_id)
+    {
+    case PROP_ACTIVE:
+      pcb_cell->active = g_value_get_boolean (value);
+      break;
+    case PROP_COLOR:
+      g_free (pcb_cell->color);
+      pcb_cell->color = g_value_dup_string (value);
+      break;
+    }
+}
+
+
+/* CONSTRUCTOR */
+static void
+ghid_cell_renderer_visibility_init (GHidCellRendererVisibility *ls)
+{
+  g_object_set (ls, "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);
+}
+
+static void
+ghid_cell_renderer_visibility_class_init (GHidCellRendererVisibilityClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (klass);
+
+  object_class->get_property = ghid_cell_renderer_visibility_get_property;
+  object_class->set_property = ghid_cell_renderer_visibility_set_property;
+
+  cell_class->get_size = ghid_cell_renderer_visibility_get_size;
+  cell_class->render   = ghid_cell_renderer_visibility_render;
+  cell_class->activate = ghid_cell_renderer_visibility_activate;
+
+  g_object_class_install_property (object_class, PROP_ACTIVE,
+                                   g_param_spec_boolean ("active",
+                                                         _("Visibility state"),
+                                                         _("Visibility of the layer"),
+                                                         FALSE,
+                                                         G_PARAM_READWRITE));
+  g_object_class_install_property (object_class, PROP_COLOR,
+                                   g_param_spec_string ("color",
+                                                         _("Layer color"),
+                                                         _("Layer color"),
+                                                         FALSE,
+                                                         G_PARAM_READWRITE));
+
+
+ /**
+  * GHidCellRendererVisibility::toggled:
+  * @cell_renderer: the object which received the signal
+  * @path: string representation of #GtkTreePath describing the 
+  *        event location
+  *
+  * The ::toggled signal is emitted when the cell is toggled. 
+  **/
+  toggle_cell_signals[TOGGLED] =
+    g_signal_new (_("toggled"),
+                  G_OBJECT_CLASS_TYPE (object_class),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GHidCellRendererVisibilityClass, toggled),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__STRING,
+                  G_TYPE_NONE, 1,
+                  G_TYPE_STRING);
+}
+
+/* PUBLIC FUNCTIONS */
+GType
+ghid_cell_renderer_visibility_get_type (void)
+{
+  static GType ls_type = 0;
+
+  if (!ls_type)
+    {
+      const GTypeInfo ls_info =
+      {
+	sizeof (GHidCellRendererVisibilityClass),
+	NULL, /* base_init */
+	NULL, /* base_finalize */
+	(GClassInitFunc) ghid_cell_renderer_visibility_class_init,
+	NULL, /* class_finalize */
+	NULL, /* class_data */
+	sizeof (GHidCellRendererVisibility),
+	0,    /* n_preallocs */
+	(GInstanceInitFunc) ghid_cell_renderer_visibility_init,
+      };
+
+      ls_type = g_type_register_static (GTK_TYPE_CELL_RENDERER,
+                                        "GHidCellRendererVisibility",
+                                        &ls_info,
+                                        0);
+    }
+
+  return ls_type;
+}
+
+GtkCellRenderer *
+ghid_cell_renderer_visibility_new (void)
+{
+  GHidCellRendererVisibility *rv =
+    g_object_new (GHID_CELL_RENDERER_VISIBILITY_TYPE, NULL);
+
+  rv->active = FALSE;
+
+  return GTK_CELL_RENDERER (rv);
+}
+
diff --git a/src/hid/gtk/ghid-cell-renderer-visibility.h b/src/hid/gtk/ghid-cell-renderer-visibility.h
new file mode 100644
index 0000000..be08fae
--- /dev/null
+++ b/src/hid/gtk/ghid-cell-renderer-visibility.h
@@ -0,0 +1,24 @@
+#ifndef GHID_CELL_RENDERER_VISIBILITY_H__
+#define GHID_CELL_RENDERER_VISIBILITY_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS  /* keep c++ happy */
+
+#define VISIBILITY_TOGGLE_SIZE	16
+
+#define GHID_CELL_RENDERER_VISIBILITY_TYPE            (ghid_cell_renderer_visibility_get_type ())
+#define GHID_CELL_RENDERER_VISIBILITY(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GHID_CELL_RENDERER_VISIBILITY_TYPE, GHidCellRendererVisibility))
+#define GHID_CELL_RENDERER_VISIBILITY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GHID_CELL_RENDERER_VISIBILITY_TYPE, GHidCellRendererVisibilityClass))
+#define IS_GHID_CELL_RENDERER_VISIBILITY(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GHID_CELL_RENDERER_VISIBILITY_TYPE))
+#define IS_GHID_CELL_RENDERER_VISIBILITY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GHID_CELL_RENDERER_VISIBILITY_TYPE))
+
+typedef struct _GHidCellRendererVisibility       GHidCellRendererVisibility;
+typedef struct _GHidCellRendererVisibilityClass  GHidCellRendererVisibilityClass;
+
+GType ghid_cell_renderer_visibility_get_type (void);
+GtkCellRenderer *ghid_cell_renderer_visibility_new (void);
+
+G_END_DECLS  /* keep c++ happy */
+#endif
diff --git a/src/hid/gtk/gtk-pcb-cell-renderer-visibility.c b/src/hid/gtk/gtk-pcb-cell-renderer-visibility.c
deleted file mode 100644
index 9e8593c..0000000
--- a/src/hid/gtk/gtk-pcb-cell-renderer-visibility.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*! \file <gtk-pcb-cell-render-visibility.c>
- *  \brief Implementation of GtkCellRenderer for layer visibility toggler
- *  \par More Information
- *  For details on the functions implemented here, see the Gtk
- *  documentation for the GtkCellRenderer object, which defines
- *  the interface we are implementing.
- */
-
-#include <glib.h>
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-#include "gtkhid.h"
-#include "gui.h"
-
-#include "gtk-pcb-cell-renderer-visibility.h"
-
-enum {
-  TOGGLED,
-  LAST_SIGNAL
-};
-static guint toggle_cell_signals[LAST_SIGNAL] = { 0 };
-
-enum {
-  PROP_ACTIVE = 1,
-  PROP_COLOR
-};
-
-struct _GtkPcbCellRendererVisibility
-{
-  GtkCellRenderer parent;
-
-  gboolean active;
-  gchar *color;
-};
-
-struct _GtkPcbCellRendererVisibilityClass
-{
-  GtkCellRendererClass parent_class;
-
-  void (* toggled) (GtkPcbCellRendererVisibility *cell, const gchar *path);
-};
-
-/* RENDERER FUNCTIONS */
-/*! \brief Calculates the window area the renderer will use */
-static void
-gtk_pcb_cell_renderer_visibility_get_size (GtkCellRenderer *cell,
-                                           GtkWidget       *widget,
-                                           GdkRectangle    *cell_area,
-                                           gint            *x_offset,
-                                           gint            *y_offset,
-                                           gint            *width,
-                                           gint            *height)
-{
-  GtkStyle *style = gtk_widget_get_style (widget);
-  gint w, h;
-
-  w = VISIBILITY_TOGGLE_SIZE + 2 * (cell->xpad + style->xthickness);
-  h = VISIBILITY_TOGGLE_SIZE + 2 * (cell->ypad + style->ythickness);
-
-  if (width)
-    *width = w;
-  if (height)
-    *height = h;
-
-  if (cell_area)
-    {
-      if (x_offset)
-        {
-          gint xalign = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
-                          ? 1.0 - cell->xalign
-                          : cell->xalign;
-          *x_offset = MAX (0, xalign * (cell_area->width - w));
-        }
-      if (y_offset)
-        *y_offset = MAX(0, cell->yalign * (cell_area->height - h));
-    }
-}
-
-/*! \brief Actually renders the swatch */
-static void
-gtk_pcb_cell_renderer_visibility_render (GtkCellRenderer      *cell,
-                                         GdkWindow            *window,
-                                         GtkWidget            *widget,
-                                         GdkRectangle         *background_area,
-                                         GdkRectangle         *cell_area,
-                                         GdkRectangle         *expose_area,
-                                         GtkCellRendererState  flags)
-{
-  GtkPcbCellRendererVisibility *pcb_cell;
-  GdkRectangle toggle_rect;
-  GdkRectangle draw_rect;
-
-  pcb_cell = GTK_PCB_CELL_RENDERER_VISIBILITY (cell);
-  gtk_pcb_cell_renderer_visibility_get_size (cell, widget, cell_area,
-                                             &toggle_rect.x,
-                                             &toggle_rect.y,
-                                             &toggle_rect.width,
-                                             &toggle_rect.height);
-
-  toggle_rect.x      += cell_area->x + cell->xpad;
-  toggle_rect.y      += cell_area->y + cell->ypad;
-  toggle_rect.width  -= cell->xpad * 2;
-  toggle_rect.height -= cell->ypad * 2;
-
-  if (toggle_rect.width <= 0 || toggle_rect.height <= 0)
-    return;
-
-  if (gdk_rectangle_intersect (expose_area, cell_area, &draw_rect))
-    {
-      GdkColor color;
-      cairo_t *cr = gdk_cairo_create (window);
-      if (expose_area)
-        {
-          gdk_cairo_rectangle (cr, expose_area);
-          cairo_clip (cr);
-        }
-      cairo_set_line_width (cr, 1);
-
-      cairo_rectangle (cr, toggle_rect.x + 0.5, toggle_rect.y + 0.5,
-                           toggle_rect.width - 1, toggle_rect.height - 1);
-      cairo_set_source_rgb (cr, 1, 1, 1);
-      cairo_fill_preserve (cr);
-      cairo_set_source_rgb (cr, 0, 0, 0);
-      cairo_stroke (cr);
-
-      gdk_color_parse (pcb_cell->color, &color);
-      gdk_cairo_set_source_color (cr, &color);
-      if (pcb_cell->active)
-        cairo_rectangle (cr, toggle_rect.x + 0.5, toggle_rect.y + 0.5,
-                             toggle_rect.width - 1, toggle_rect.height - 1);
-      else
-        {
-          cairo_move_to (cr, toggle_rect.x + 1, toggle_rect.y + 1);
-          cairo_rel_line_to (cr, toggle_rect.width / 2, 0);
-          cairo_rel_line_to (cr, -toggle_rect.width / 2, toggle_rect.width / 2);
-          cairo_close_path (cr);
-        }
-      cairo_fill (cr);
-
-      cairo_destroy (cr);
-    }
-}
-
-/*! \brief Toggless the swatch */
-static gint
-gtk_pcb_cell_renderer_visibility_activate (GtkCellRenderer      *cell,
-                                           GdkEvent             *event,
-                                           GtkWidget            *widget,
-                                           const gchar          *path,
-                                           GdkRectangle         *background_area,
-                                           GdkRectangle         *cell_area,
-                                           GtkCellRendererState  flags)
-{
-  g_signal_emit (cell, toggle_cell_signals[TOGGLED], 0, path);
-  return TRUE;
-}
-
-/* Setter/Getter */
-static void
-gtk_pcb_cell_renderer_visibility_get_property (GObject     *object,
-                                               guint        param_id,
-                                               GValue      *value,
-                                               GParamSpec  *pspec)
-{
-  GtkPcbCellRendererVisibility *pcb_cell =
-    GTK_PCB_CELL_RENDERER_VISIBILITY (object);
-
-  switch (param_id)
-    {
-    case PROP_ACTIVE:
-      g_value_set_boolean (value, pcb_cell->active);
-      break;
-    case PROP_COLOR:
-      g_value_set_string (value, pcb_cell->color);
-      break;
-    }
-}
-
-static void
-gtk_pcb_cell_renderer_visibility_set_property (GObject      *object,
-                                               guint         param_id,
-                                               const GValue *value,
-                                               GParamSpec   *pspec)
-{
-  GtkPcbCellRendererVisibility *pcb_cell =
-    GTK_PCB_CELL_RENDERER_VISIBILITY (object);
-
-  switch (param_id)
-    {
-    case PROP_ACTIVE:
-      pcb_cell->active = g_value_get_boolean (value);
-      break;
-    case PROP_COLOR:
-      g_free (pcb_cell->color);
-      pcb_cell->color = g_value_dup_string (value);
-      break;
-    }
-}
-
-
-/* CONSTRUCTOR */
-static void
-gtk_pcb_cell_renderer_visibility_init (GtkPcbCellRendererVisibility *ls)
-{
-  g_object_set (ls, "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);
-}
-
-static void
-gtk_pcb_cell_renderer_visibility_class_init (GtkPcbCellRendererVisibilityClass *klass)
-{
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
-  GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (klass);
-
-  object_class->get_property = gtk_pcb_cell_renderer_visibility_get_property;
-  object_class->set_property = gtk_pcb_cell_renderer_visibility_set_property;
-
-  cell_class->get_size = gtk_pcb_cell_renderer_visibility_get_size;
-  cell_class->render   = gtk_pcb_cell_renderer_visibility_render;
-  cell_class->activate = gtk_pcb_cell_renderer_visibility_activate;
-
-  g_object_class_install_property (object_class, PROP_ACTIVE,
-                                   g_param_spec_boolean ("active",
-                                                         _("Visibility state"),
-                                                         _("Visibility of the layer"),
-                                                         FALSE,
-                                                         G_PARAM_READWRITE));
-  g_object_class_install_property (object_class, PROP_COLOR,
-                                   g_param_spec_string ("color",
-                                                         _("Layer color"),
-                                                         _("Layer color"),
-                                                         FALSE,
-                                                         G_PARAM_READWRITE));
-
-
- /**
-  * GtkPcbCellRendererVisibility::toggled:
-  * @cell_renderer: the object which received the signal
-  * @path: string representation of #GtkTreePath describing the 
-  *        event location
-  *
-  * The ::toggled signal is emitted when the cell is toggled. 
-  **/
-  toggle_cell_signals[TOGGLED] =
-    g_signal_new (_("toggled"),
-                  G_OBJECT_CLASS_TYPE (object_class),
-                  G_SIGNAL_RUN_LAST,
-                  G_STRUCT_OFFSET (GtkPcbCellRendererVisibilityClass, toggled),
-                  NULL, NULL,
-                  g_cclosure_marshal_VOID__STRING,
-                  G_TYPE_NONE, 1,
-                  G_TYPE_STRING);
-}
-
-/* PUBLIC FUNCTIONS */
-GType
-gtk_pcb_cell_renderer_visibility_get_type (void)
-{
-  static GType ls_type = 0;
-
-  if (!ls_type)
-    {
-      const GTypeInfo ls_info =
-      {
-	sizeof (GtkPcbCellRendererVisibilityClass),
-	NULL, /* base_init */
-	NULL, /* base_finalize */
-	(GClassInitFunc) gtk_pcb_cell_renderer_visibility_class_init,
-	NULL, /* class_finalize */
-	NULL, /* class_data */
-	sizeof (GtkPcbCellRendererVisibility),
-	0,    /* n_preallocs */
-	(GInstanceInitFunc) gtk_pcb_cell_renderer_visibility_init,
-      };
-
-      ls_type = g_type_register_static (GTK_TYPE_CELL_RENDERER,
-                                        "GtkPcbCellRendererVisibility",
-                                        &ls_info,
-                                        0);
-    }
-
-  return ls_type;
-}
-
-GtkCellRenderer *
-gtk_pcb_cell_renderer_visibility_new (void)
-{
-  GtkPcbCellRendererVisibility *rv =
-    g_object_new (GTK_PCB_CELL_RENDERER_VISIBILITY_TYPE, NULL);
-
-  rv->active = FALSE;
-
-  return GTK_CELL_RENDERER (rv);
-}
-
diff --git a/src/hid/gtk/gtk-pcb-cell-renderer-visibility.h b/src/hid/gtk/gtk-pcb-cell-renderer-visibility.h
deleted file mode 100644
index 212c4a4..0000000
--- a/src/hid/gtk/gtk-pcb-cell-renderer-visibility.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef GTK_PCB_CELL_RENDERER_VISIBILITY_H__
-#define GTK_PCB_CELL_RENDERER_VISIBILITY_H__
-
-#include <glib.h>
-#include <glib-object.h>
-
-G_BEGIN_DECLS  /* keep c++ happy */
-
-#define VISIBILITY_TOGGLE_SIZE	16
-
-#define GTK_PCB_CELL_RENDERER_VISIBILITY_TYPE            (gtk_pcb_cell_renderer_visibility_get_type ())
-#define GTK_PCB_CELL_RENDERER_VISIBILITY(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_PCB_CELL_RENDERER_VISIBILITY_TYPE, GtkPcbCellRendererVisibility))
-#define GTK_PCB_CELL_RENDERER_VISIBILITY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_PCB_CELL_RENDERER_VISIBILITY_TYPE, GtkPcbCellRendererVisibilityClass))
-#define IS_GTK_PCB_CELL_RENDERER_VISIBILITY(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_PCB_CELL_RENDERER_VISIBILITY_TYPE))
-#define IS_GTK_PCB_CELL_RENDERER_VISIBILITY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_PCB_CELL_RENDERER_VISIBILITY_TYPE))
-
-typedef struct _GtkPcbCellRendererVisibility       GtkPcbCellRendererVisibility;
-typedef struct _GtkPcbCellRendererVisibilityClass  GtkPcbCellRendererVisibilityClass;
-
-GType gtk_pcb_cell_renderer_visibility_get_type (void);
-GtkCellRenderer *gtk_pcb_cell_renderer_visibility_new (void);
-
-G_END_DECLS  /* keep c++ happy */
-#endif
diff --git a/src/hid/gtk/gtk-pcb-layer-selector.c b/src/hid/gtk/gtk-pcb-layer-selector.c
index c8c9849..1067aeb 100644
--- a/src/hid/gtk/gtk-pcb-layer-selector.c
+++ b/src/hid/gtk/gtk-pcb-layer-selector.c
@@ -17,7 +17,7 @@
 #include "pcb-printf.h"
 
 #include "gtk-pcb-layer-selector.h"
-#include "gtk-pcb-cell-renderer-visibility.h"
+#include "ghid-cell-renderer-visibility.h"
 
 #define INITIAL_ACTION_MAX	40
 
@@ -290,7 +290,7 @@ gtk_pcb_layer_selector_get_type (void)
 GtkWidget *
 gtk_pcb_layer_selector_new (void)
 {
-  GtkCellRenderer *renderer1 = gtk_pcb_cell_renderer_visibility_new ();
+  GtkCellRenderer *renderer1 = ghid_cell_renderer_visibility_new ();
   GtkCellRenderer *renderer2 = gtk_cell_renderer_text_new ();
   GtkTreeViewColumn *opacity_col =
       gtk_tree_view_column_new_with_attributes ("", renderer1,




_______________________________________________
geda-cvs mailing list
geda-cvs@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-cvs