summaryrefslogtreecommitdiffstats
path: root/include/ganv
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2022-07-14 15:38:58 -0400
committerDavid Robillard <d@drobilla.net>2022-08-13 18:17:45 -0400
commitc83478ea0a19cc7fdf6e2cc228ed3697990732fe (patch)
treec6910dc1cc0b110d4f75d7e4dd918037687d3bb2 /include/ganv
parent03b1626676f596d78df9de718e3e079e8269f5cc (diff)
downloadganv-c83478ea0a19cc7fdf6e2cc228ed3697990732fe.tar.gz
ganv-c83478ea0a19cc7fdf6e2cc228ed3697990732fe.tar.bz2
ganv-c83478ea0a19cc7fdf6e2cc228ed3697990732fe.zip
Move public headers to conventional include directory
Diffstat (limited to 'include/ganv')
-rw-r--r--include/ganv/Box.hpp59
-rw-r--r--include/ganv/Canvas.hpp164
-rw-r--r--include/ganv/Circle.hpp78
-rw-r--r--include/ganv/Edge.hpp94
-rw-r--r--include/ganv/Item.hpp92
-rw-r--r--include/ganv/Module.hpp134
-rw-r--r--include/ganv/Node.hpp120
-rw-r--r--include/ganv/Port.hpp78
-rw-r--r--include/ganv/box.h87
-rw-r--r--include/ganv/canvas.h647
-rw-r--r--include/ganv/circle.h88
-rw-r--r--include/ganv/edge.h136
-rw-r--r--include/ganv/ganv.h30
-rw-r--r--include/ganv/ganv.hpp26
-rw-r--r--include/ganv/group.h63
-rw-r--r--include/ganv/item.h188
-rw-r--r--include/ganv/module.h103
-rw-r--r--include/ganv/node.h186
-rw-r--r--include/ganv/port.h110
-rw-r--r--include/ganv/text.h59
-rw-r--r--include/ganv/types.h26
-rw-r--r--include/ganv/types.hpp30
-rw-r--r--include/ganv/widget.h62
-rw-r--r--include/ganv/wrap.hpp140
24 files changed, 2800 insertions, 0 deletions
diff --git a/include/ganv/Box.hpp b/include/ganv/Box.hpp
new file mode 100644
index 0000000..fe24622
--- /dev/null
+++ b/include/ganv/Box.hpp
@@ -0,0 +1,59 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2015 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GANV_BOX_HPP
+#define GANV_BOX_HPP
+
+#include "ganv/Node.hpp"
+#include "ganv/box.h"
+#include "ganv/node.h"
+#include "ganv/types.h"
+#include "ganv/wrap.hpp"
+
+#include <glib.h>
+
+namespace Ganv {
+
+class Canvas;
+
+class Box : public Node
+{
+public:
+ Box(Canvas* canvas, GanvBox* gobj)
+ : Node(canvas, GANV_NODE(gobj))
+ {}
+
+ RW_PROPERTY(gboolean, beveled)
+
+ METHODRET0(ganv_box, double, get_x1)
+ METHODRET0(ganv_box, double, get_y1)
+ METHODRET0(ganv_box, double, get_x2)
+ METHODRET0(ganv_box, double, get_y2)
+ METHODRET0(ganv_box, double, get_width)
+ METHOD1(ganv_box, set_width, double, width)
+ METHODRET0(ganv_box, double, get_height)
+ METHOD1(ganv_box, set_height, double, height)
+
+ double get_border_width() const override {
+ return ganv_box_get_border_width(gobj());
+ }
+
+ GanvBox* gobj() { return GANV_BOX(_gobj); }
+ const GanvBox* gobj() const { return GANV_BOX(_gobj); }
+};
+
+} // namespace Ganv
+
+#endif // GANV_BOX_HPP
diff --git a/include/ganv/Canvas.hpp b/include/ganv/Canvas.hpp
new file mode 100644
index 0000000..350a6e7
--- /dev/null
+++ b/include/ganv/Canvas.hpp
@@ -0,0 +1,164 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2015 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GANV_CANVAS_HPP
+#define GANV_CANVAS_HPP
+
+#include "ganv/canvas.h"
+#include "ganv/item.h"
+#include "ganv/types.h"
+#include "ganv/wrap.hpp"
+
+#include <cairo.h>
+#include <gdk/gdk.h>
+#include <glib.h>
+#include <gtkmm/layout.h>
+#include <sigc++/signal.h>
+
+/** Ganv namespace, everything is defined under this.
+ *
+ * @ingroup Ganv
+ */
+namespace Ganv {
+
+class Edge;
+class Item;
+class Node;
+
+/** @defgroup Ganv Ganv
+ *
+ * A canvas widget for graph-like UIs.
+ */
+
+/** The 'master' canvas widget which contains all other objects.
+ *
+ * Applications must override some virtual methods to make the widget actually
+ * do anything (e.g. connect).
+ *
+ * @ingroup Ganv
+ */
+class Canvas
+{
+public:
+ Canvas(double width, double height);
+
+ Canvas(const Canvas&) = delete;
+ Canvas& operator=(const Canvas&) = delete;
+
+ Canvas(Canvas&&) = delete;
+ Canvas& operator=(Canvas&&) = delete;
+
+ virtual ~Canvas();
+
+ GanvItem* root() { return ganv_canvas_root(gobj()); }
+
+ METHOD0(ganv_canvas, clear)
+ METHODRET0(ganv_canvas, gboolean, empty)
+ METHOD2(ganv_canvas, get_size, double*, width, double*, height)
+ METHOD2(ganv_canvas, resize, double, width, double, height)
+ METHOD4(ganv_canvas, set_scroll_region, double, x1, double, y1, double, x2, double, y2)
+ METHOD4(ganv_canvas, get_scroll_region, double*, x1, double*, y1, double*, x2, double*, y2)
+ METHOD1(ganv_canvas, set_center_scroll_region, gboolean, c)
+ METHODRET0(ganv_canvas, gboolean, get_center_scroll_region)
+ METHOD2(ganv_canvas, scroll_to, int, x, int, y)
+
+ void get_scroll_offsets(int& cx, int& cy) const {
+ ganv_canvas_get_scroll_offsets(gobj(), &cx, &cy);
+ }
+
+ METHOD1(ganv_canvas, w2c_affine, cairo_matrix_t*, matrix)
+ METHOD4(ganv_canvas, w2c, double, wx, double, wy, int*, cx, int*, cy)
+ METHOD4(ganv_canvas, w2c_d, double, wx, double, wy, double*, cx, double*, cy)
+ METHOD4(ganv_canvas, c2w, int, cx, int, cy, double*, wx, double*, wy)
+ METHOD4(ganv_canvas, window_to_world, double, winx, double, winy, double*, worldx, double*, worldy)
+ METHOD4(ganv_canvas, world_to_window, double, worldx, double, worldy, double*, winx, double*, winy)
+
+ Item* get_item_at(double x, double y) const;
+ Edge* get_edge(Node* tail, Node* head) const;
+ void remove_edge_between(Node* tail, Node* head);
+ void remove_edge(Edge* edge);
+
+ METHOD0(ganv_canvas, arrange)
+ METHODRET2(ganv_canvas, int, export_image, const char*, filename, bool, draw_background)
+ METHOD1(ganv_canvas, export_dot, const char*, filename)
+ METHODRET0(ganv_canvas, gboolean, supports_sprung_layout)
+ METHODRET1(ganv_canvas, gboolean, set_sprung_layout, gboolean, sprung_layout)
+ METHOD2(ganv_canvas, for_each_node, GanvNodeFunc, f, void*, data)
+ METHOD2(ganv_canvas, for_each_selected_node, GanvNodeFunc, f, void*, data)
+ METHOD2(ganv_canvas, for_each_edge, GanvEdgeFunc, f, void*, data)
+ METHOD3(ganv_canvas, for_each_edge_from,
+ const GanvNode*, tail,
+ GanvEdgeFunc, f,
+ void*, data)
+ METHOD3(ganv_canvas, for_each_edge_to,
+ const GanvNode*, head,
+ GanvEdgeFunc, f,
+ void*, data)
+ METHOD3(ganv_canvas, for_each_edge_on,
+ const GanvNode*, node,
+ GanvEdgeFunc, f,
+ void*, data)
+ METHOD2(ganv_canvas, for_each_selected_edge, GanvEdgeFunc, f, void*, data)
+
+ METHOD0(ganv_canvas, select_all)
+ METHOD0(ganv_canvas, clear_selection)
+ METHODRET0(ganv_canvas, double, get_zoom)
+ METHOD1(ganv_canvas, set_zoom, double, pix_per_unit)
+ METHOD0(ganv_canvas, zoom_full)
+ METHODRET0(ganv_canvas, double, get_default_font_size)
+ METHODRET0(ganv_canvas, double, get_font_size)
+ METHOD1(ganv_canvas, set_font_size, double, points)
+ METHOD0(ganv_canvas, get_move_cursor)
+ METHOD2(ganv_canvas, move_contents_to, double, x, double, y)
+
+ RW_PROPERTY(gboolean, locked)
+ RW_PROPERTY(double, width)
+ RW_PROPERTY(double, height)
+ RW_PROPERTY(GanvDirection, direction)
+
+ void set_port_order(GanvPortOrderFunc port_cmp, void* data) {
+ ganv_canvas_set_port_order(gobj(), port_cmp, data);
+ }
+
+ Gtk::Layout& widget() {
+ return *Glib::wrap(&_gobj->layout);
+ }
+
+ GQuark wrapper_key();
+
+ GanvCanvas* gobj() { return GANV_CANVAS(_gobj); }
+ const GanvCanvas* gobj() const { return GANV_CANVAS(_gobj); }
+
+ sigc::signal<bool, GdkEvent*> signal_event;
+ sigc::signal<void, Node*, Node*> signal_connect;
+ sigc::signal<void, Node*, Node*> signal_disconnect;
+
+private:
+ GanvCanvas* const _gobj;
+};
+
+} // namespace Ganv
+
+namespace Glib {
+
+static inline Ganv::Canvas*
+wrap(GanvCanvas* canvas)
+{
+ return static_cast<Ganv::Canvas*>(ganv_canvas_get_wrapper(canvas));
+}
+
+} // namespace Glib
+
+#endif // GANV_CANVAS_HPP
diff --git a/include/ganv/Circle.hpp b/include/ganv/Circle.hpp
new file mode 100644
index 0000000..b60b89d
--- /dev/null
+++ b/include/ganv/Circle.hpp
@@ -0,0 +1,78 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2013 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GANV_CIRCLE_HPP
+#define GANV_CIRCLE_HPP
+
+#include "ganv/Canvas.hpp"
+#include "ganv/Node.hpp"
+#include "ganv/circle.h"
+#include "ganv/item.h"
+#include "ganv/node.h"
+#include "ganv/wrap.hpp"
+
+#include <glib.h>
+
+#include <cstdint>
+#include <string>
+
+GANV_GLIB_WRAP(Circle)
+
+namespace Ganv {
+
+/** An elliptical Item which is Node.
+ *
+ * Unlike a Module, this doesn't contain ports, but is directly joinable itself
+ * (think your classic circles 'n' lines diagram, ala FSM).
+ *
+ * @ingroup Ganv
+ */
+class Circle : public Node
+{
+public:
+ static const uint32_t FILL_COLOUR = 0x1E2224FF;
+ static const uint32_t BORDER_COLOUR = 0xD3D7CFFF;
+
+ Circle(Canvas& canvas,
+ const std::string& name,
+ double x,
+ double y)
+ : Node(&canvas,
+ GANV_NODE(
+ ganv_item_new(
+ GANV_ITEM(canvas.root()),
+ ganv_circle_get_type(),
+ "x", x,
+ "y", y,
+ "can-tail", TRUE,
+ "can-head", TRUE,
+ "fill-color", FILL_COLOUR,
+ "border-color", BORDER_COLOUR,
+ "label", name.c_str(),
+ "draggable", TRUE,
+ nullptr)))
+ {}
+
+ RW_PROPERTY(double, radius)
+ RW_PROPERTY(double, radius_ems)
+ RW_PROPERTY(gboolean, fit_label)
+
+ GanvCircle* gobj() { return GANV_CIRCLE(_gobj); }
+ const GanvCircle* gobj() const { return GANV_CIRCLE(_gobj); }
+};
+
+} // namespace Ganv
+
+#endif // GANV_CIRCLE_HPP
diff --git a/include/ganv/Edge.hpp b/include/ganv/Edge.hpp
new file mode 100644
index 0000000..a0d9a7c
--- /dev/null
+++ b/include/ganv/Edge.hpp
@@ -0,0 +1,94 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2015 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GANV_EDGE_HPP
+#define GANV_EDGE_HPP
+
+#include "ganv/Canvas.hpp"
+#include "ganv/Item.hpp"
+#include "ganv/Node.hpp"
+#include "ganv/edge.h"
+#include "ganv/item.h"
+#include "ganv/types.h"
+#include "ganv/wrap.hpp"
+
+#include <glib-object.h>
+#include <glib.h>
+
+#include <cstdint>
+
+GANV_GLIB_WRAP(Edge)
+
+namespace Ganv {
+
+/** A edge (line) between two Node objects.
+ *
+ * @ingroup Ganv
+ */
+class Edge : public Item
+{
+public:
+ Edge(Canvas& canvas,
+ Node* tail,
+ Node* head,
+ uint32_t color = 0,
+ bool show_arrowhead = false,
+ bool curved = true)
+ : Item(GANV_ITEM(ganv_edge_new(canvas.gobj(),
+ tail->gobj(),
+ head->gobj(),
+ "color", color,
+ "curved", static_cast<gboolean>(curved),
+ "arrowhead", static_cast<gboolean>(show_arrowhead),
+ nullptr)))
+ {}
+
+ explicit Edge(GanvEdge* gobj)
+ : Item(GANV_ITEM(gobj))
+ {}
+
+ Edge(const Edge&) = delete;
+ Edge& operator=(const Edge& other) = delete;
+
+ Edge(Edge&&) = delete;
+ Edge& operator=(Edge&&) = delete;
+
+ ~Edge() override {
+ if (_gobj && ganv_item_get_parent(_gobj)) {
+ g_object_unref(_gobj);
+ }
+ }
+
+ gboolean is_within(double x1, double y1, double x2, double y2) const {
+ return ganv_edge_is_within(gobj(), x1, y1, x2, y2);
+ }
+
+ RW_PROPERTY(gboolean, constraining)
+ RW_PROPERTY(gboolean, curved)
+ RW_PROPERTY(gboolean, selected)
+ RW_PROPERTY(gboolean, highlighted)
+ RW_PROPERTY(guint, color)
+ RW_PROPERTY(gdouble, handle_radius)
+
+ METHODRETWRAP0(ganv_edge, Node*, get_tail)
+ METHODRETWRAP0(ganv_edge, Node*, get_head)
+
+ GanvEdge* gobj() { return reinterpret_cast<GanvEdge*>(_gobj); }
+ const GanvEdge* gobj() const { return reinterpret_cast<GanvEdge*>(_gobj); }
+};
+
+} // namespace Ganv
+
+#endif // GANV_EDGE_HPP
diff --git a/include/ganv/Item.hpp b/include/ganv/Item.hpp
new file mode 100644
index 0000000..e6b690c
--- /dev/null
+++ b/include/ganv/Item.hpp
@@ -0,0 +1,92 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2015 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GANV_ITEM_HPP
+#define GANV_ITEM_HPP
+
+#include "ganv/Canvas.hpp"
+#include "ganv/item.h"
+#include "ganv/wrap.hpp"
+
+#include <gdk/gdk.h>
+#include <glib-object.h>
+#include <glib.h>
+#include <gobject/gclosure.h>
+#include <gtk/gtk.h>
+#include <sigc++/signal.h>
+#include <sigc++/trackable.h>
+
+GANV_GLIB_WRAP(Item)
+
+namespace Ganv {
+
+/** An item on the canvas.
+ */
+class Item : public sigc::trackable {
+public:
+ explicit Item(GanvItem* gobj)
+ : _gobj(gobj)
+ {
+ ganv_item_set_wrapper(gobj, this);
+ if (gobj && ganv_item_get_parent(gobj)) {
+ g_signal_connect(
+ G_OBJECT(_gobj), "event", G_CALLBACK(on_item_event), this);
+ }
+ }
+
+ Item(const Item&) = delete;
+ Item& operator=(const Item&) = delete;
+
+ Item(Item&&) = delete;
+ Item& operator=(Item&&) = delete;
+
+ virtual ~Item() {
+ gtk_object_destroy(GTK_OBJECT(_gobj));
+ }
+
+ RW_PROPERTY(double, x)
+ RW_PROPERTY(double, y)
+
+ METHOD0(ganv_item, raise)
+ METHOD0(ganv_item, lower)
+ METHOD2(ganv_item, move, double, dx, double, dy)
+ METHOD0(ganv_item, show)
+ METHOD0(ganv_item, hide)
+ METHOD2(ganv_item, i2w, double*, x, double*, y)
+ METHOD2(ganv_item, w2i, double*, x, double*, y)
+ METHOD0(ganv_item, grab_focus)
+
+ Canvas* canvas() const {
+ return Glib::wrap(ganv_item_get_canvas(_gobj));
+ }
+
+ GanvItem* gobj() const { return _gobj; }
+
+ SIGNAL1(event, GdkEvent*)
+ SIGNAL1(click, GdkEventButton*)
+
+protected:
+ GanvItem* const _gobj;
+
+private:
+ static gboolean on_item_event(GanvItem*, GdkEvent* ev, void* item)
+ {
+ return static_cast<Item*>(item)->signal_event().emit(ev);
+ }
+};
+
+} // namespace Ganv
+
+#endif // GANV_ITEM_HPP
diff --git a/include/ganv/Module.hpp b/include/ganv/Module.hpp
new file mode 100644
index 0000000..8beea60
--- /dev/null
+++ b/include/ganv/Module.hpp
@@ -0,0 +1,134 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2015 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GANV_MODULE_HPP
+#define GANV_MODULE_HPP
+
+#include "ganv/Box.hpp"
+#include "ganv/Canvas.hpp"
+#include "ganv/Port.hpp"
+#include "ganv/box.h"
+#include "ganv/item.h"
+#include "ganv/module.h"
+#include "ganv/types.h"
+#include "ganv/wrap.hpp"
+
+#include <glib.h>
+#include <gtkmm/widget.h>
+
+#include <string>
+
+GANV_GLIB_WRAP(Module)
+
+namespace Ganv {
+
+/** A rectangular Item which can hold a Port.
+ *
+ * @ingroup Ganv
+ */
+class Module : public Box
+{
+public:
+ Module(Canvas& canvas,
+ const std::string& name,
+ double x = 0,
+ double y = 0,
+ bool show_title = true)
+ : Box(&canvas,
+ GANV_BOX(ganv_item_new(GANV_ITEM(canvas.root()),
+ ganv_module_get_type(),
+ "x", x,
+ "y", y,
+ "can-tail", FALSE,
+ "can-head", FALSE,
+ "radius-tl", 4.0,
+ "radius-tr", 4.0,
+ "radius-br", 4.0,
+ "radius-bl", 4.0,
+ "border-width", 2.0,
+ "label", name.c_str(),
+ "draggable", TRUE,
+ nullptr)))
+ {
+ (void)show_title;
+ }
+
+ template<typename P, typename C>
+ class iterator_base {
+ public:
+ iterator_base(GanvModule* m, guint i) : _module(m), _index(i) {}
+ template<typename T, typename U>
+ explicit iterator_base(const iterator_base<T, U>& i)
+ : _module(i._module)
+ , _index(i._index)
+ {}
+ P* operator*() const {
+ return Glib::wrap(ganv_module_get_port(_module, _index));
+ }
+ P* operator->() const {
+ return Glib::wrap(ganv_module_get_port(_module, _index));
+ }
+ iterator_base operator++(int) const {
+ return iterator_base<P, C>(_index + 1);
+ }
+ iterator_base& operator++() {
+ ++_index; return *this;
+ }
+ bool operator==(const iterator_base<P, C>& i) const {
+ return _index == i._index;
+ }
+ bool operator!=(const iterator_base<P, C>& i) const {
+ return _index != i._index;
+ }
+ private:
+ template<typename T, typename U> friend class iterator_base;
+ GanvModule* _module;
+ guint _index;
+ };
+
+ using iterator = iterator_base<Port, GanvPort>;
+ using const_iterator = iterator_base<const Port, const GanvPort>;
+
+ iterator begin() { return {gobj(), 0}; }
+ iterator end() { return {gobj(), num_ports()}; }
+ iterator back() { return {gobj(), num_ports() - 1}; }
+ const_iterator begin() const { return {const_cast<GanvModule*>(gobj()), 0}; }
+ const_iterator end() const { return {const_cast<GanvModule*>(gobj()), num_ports()}; }
+ const_iterator back() const { return {const_cast<GanvModule*>(gobj()), num_ports() - 1}; }
+
+ void embed(Gtk::Widget* widget) {
+ ganv_module_embed(gobj(), widget ? widget->gobj() : nullptr);
+ }
+
+ Port* get_port(guint index) {
+ return Glib::wrap(ganv_module_get_port(gobj(), index));
+ }
+
+ METHOD2(ganv_module, for_each_port, GanvPortFunc, f, void*, data)
+
+ METHODRET0(ganv_module, guint, num_ports)
+
+ RW_PROPERTY(gboolean, stacked)
+
+ METHODRET0(ganv_module, double, get_empty_port_breadth)
+ METHODRET0(ganv_module, double, get_empty_port_depth)
+
+ GanvModule* gobj() { return GANV_MODULE(_gobj); }
+ const GanvModule* gobj() const { return GANV_MODULE(_gobj); }
+};
+
+} // namespace Ganv
+
+#endif // GANV_MODULE_HPP
diff --git a/include/ganv/Node.hpp b/include/ganv/Node.hpp
new file mode 100644
index 0000000..7980566
--- /dev/null
+++ b/include/ganv/Node.hpp
@@ -0,0 +1,120 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2015 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GANV_NODE_HPP
+#define GANV_NODE_HPP
+
+#include "ganv/Item.hpp"
+#include "ganv/item.h"
+#include "ganv/node.h"
+#include "ganv/types.h"
+#include "ganv/wrap.hpp"
+
+#include <glib-object.h>
+#include <glib.h>
+#include <glibmm/object.h>
+#include <gobject/gclosure.h>
+#include <sigc++/signal.h>
+
+GANV_GLIB_WRAP(Node) // IWYU pragma: keep
+
+namespace Ganv {
+
+class Canvas;
+
+/** An object a Edge can connect to.
+ */
+class Node : public Item {
+public:
+ Node(Canvas*, GanvNode* gobj)
+ : Item(GANV_ITEM(g_object_ref(gobj)))
+ {
+ g_signal_connect(gobj, "moved", G_CALLBACK(on_moved), this);
+ CONNECT_PROP_SIGNAL(gobj, selected, on_notify_bool, &Node::on_selected)
+ }
+
+ Node(const Node&) = delete;
+ Node& operator=(const Node&) = delete;
+
+ Node(Node&&) = delete;
+ Node& operator=(Node&&) = delete;
+
+ ~Node() override {
+ g_object_unref(_gobj);
+ }
+
+ RW_PROPERTY(gboolean, can_tail)
+ RW_PROPERTY(gboolean, can_head)
+ RW_PROPERTY(gboolean, is_source)
+
+ gboolean is_within(double x1, double y1, double x2, double y2) const {
+ return ganv_node_is_within(gobj(), x1, y1, x2, y2);
+ }
+
+ RW_PROPERTY(const char*, label)
+ RW_PROPERTY(double, border_width)
+ RW_PROPERTY(double, dash_length)
+ RW_PROPERTY(double, dash_offset)
+ RW_PROPERTY(guint, fill_color)
+ RW_PROPERTY(guint, border_color)
+ RW_PROPERTY(gboolean, selected)
+ RW_PROPERTY(gboolean, highlighted)
+ RW_PROPERTY(gboolean, draggable)
+ RW_PROPERTY(gboolean, grabbed)
+
+ RW_OBJECT_PROPERTY(Node*, partner)
+
+ GanvNode* gobj() { return GANV_NODE(_gobj); }
+ const GanvNode* gobj() const { return GANV_NODE(_gobj); }
+
+ void move(const double dx, const double dy) override {
+ ganv_node_move(gobj(), dx, dy);
+ }
+
+ METHOD2(ganv_node, move_to, double, x, double, y)
+
+ METHOD0(ganv_node, disconnect)
+
+ sigc::signal<void, double, double>& signal_moved() {
+ return _signal_moved;
+ }
+
+private:
+ sigc::signal<void, double, double> _signal_moved;
+
+ static void on_moved(GanvNode* node, double x, double y) {
+ Glib::wrap(node)->_signal_moved.emit(x, y);
+ }
+
+ /* GCC 4.6 can't handle this
+ template<typename T>
+ static void on_notify(GObject* gobj, GParamSpec* pspec, gpointer signal) {
+ T value;
+ g_object_get(gobj, g_param_spec_get_name(pspec), &value, nullptr);
+ ((sigc::signal<bool, T>*)signal)->emit(value);
+ }
+ */
+ static void on_notify_bool(GObject* gobj,
+ GParamSpec* pspec,
+ gpointer signal) {
+ gboolean value = FALSE;
+ g_object_get(gobj, g_param_spec_get_name(pspec), &value, nullptr);
+ static_cast<sigc::signal<bool, gboolean>*>(signal)->emit(value);
+ }
+};
+
+} // namespace Ganv
+
+#endif // GANV_NODE_HPP
diff --git a/include/ganv/Port.hpp b/include/ganv/Port.hpp
new file mode 100644
index 0000000..c665b08
--- /dev/null
+++ b/include/ganv/Port.hpp
@@ -0,0 +1,78 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2014 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GANV_PORT_HPP
+#define GANV_PORT_HPP
+
+#include "ganv/Box.hpp"
+#include "ganv/port.h"
+#include "ganv/types.h"
+#include "ganv/wrap.hpp"
+
+#include <glib.h>
+#include <sigc++/signal.h>
+
+#include <cstdint>
+#include <string>
+
+GANV_GLIB_WRAP(Port)
+
+namespace Ganv {
+
+class Module;
+
+/** A port on a Module.
+ *
+ * This is a group that contains both the label and rectangle for a port.
+ *
+ * @ingroup Ganv
+ */
+class Port : public Box
+{
+public:
+ Port(Module& module,
+ const std::string& name,
+ bool is_input,
+ uint32_t color);
+
+ RW_PROPERTY(gboolean, is_controllable)
+
+ METHODRET0(ganv_port, gboolean, is_input)
+ METHODRET0(ganv_port, gboolean, is_output)
+
+ METHODRET0(ganv_port, double, get_natural_width)
+ METHODRET0(ganv_port, float, get_control_value)
+ METHODRET0(ganv_port, float, get_control_min)
+ METHODRET0(ganv_port, float, get_control_max)
+ METHOD0(ganv_port, show_control)
+ METHOD0(ganv_port, hide_control)
+ METHOD1(ganv_port, set_control_is_toggle, gboolean, is_toggle)
+ METHOD1(ganv_port, set_control_is_integer, gboolean, is_integer)
+ METHOD1(ganv_port, set_control_value, float, value)
+ METHOD1(ganv_port, set_control_min, float, min)
+ METHOD1(ganv_port, set_control_max, float, max)
+ METHOD1(ganv_port, set_value_label, const char*, str)
+
+ sigc::signal<void, double> signal_value_changed;
+
+ Module* get_module() const;
+
+ GanvPort* gobj() { return GANV_PORT(_gobj); }
+ const GanvPort* gobj() const { return GANV_PORT(_gobj); }
+};
+
+} // namespace Ganv
+
+#endif // GANV_PORT_HPP
diff --git a/include/ganv/box.h b/include/ganv/box.h
new file mode 100644
index 0000000..11e0662
--- /dev/null
+++ b/include/ganv/box.h
@@ -0,0 +1,87 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2014 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// IWYU pragma: no_include "ganv-private.h"
+
+#ifndef GANV_BOX_H
+#define GANV_BOX_H
+
+#include "ganv/node.h"
+#include "ganv/types.h"
+
+#include <glib-object.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GANV_TYPE_BOX (ganv_box_get_type())
+#define GANV_BOX(obj) (GTK_CHECK_CAST((obj), GANV_TYPE_BOX, GanvBox))
+#define GANV_BOX_CLASS(klass) (GTK_CHECK_CLASS_CAST((klass), GANV_TYPE_BOX, GanvBoxClass))
+#define GANV_IS_BOX(obj) (GTK_CHECK_TYPE((obj), GANV_TYPE_BOX))
+#define GANV_IS_BOX_CLASS(klass) (GTK_CHECK_CLASS_TYPE((klass), GANV_TYPE_BOX))
+#define GANV_BOX_GET_CLASS(obj) (GTK_CHECK_GET_CLASS((obj), GANV_TYPE_BOX, GanvBoxClass))
+
+struct _GanvBoxClass;
+
+typedef struct _GanvBoxClass GanvBoxClass;
+typedef struct _GanvBoxPrivate GanvBoxPrivate;
+
+struct _GanvBox {
+ GanvNode node;
+ GanvBoxPrivate* impl;
+};
+
+/**
+ * GanvBoxClass:
+ * @parent_class: Node superclass.
+ * @set_width: Set the width of the box.
+ * @set_height: Set the height of the box.
+ */
+struct _GanvBoxClass {
+ GanvNodeClass parent_class;
+
+ void (*set_width)(GanvBox* box,
+ double width);
+
+ void (*set_height)(GanvBox* box,
+ double height);
+
+ /* Reserved for future expansion */
+ gpointer spare_vmethods[4];
+};
+
+GType ganv_box_get_type(void) G_GNUC_CONST;
+double ganv_box_get_x1(const GanvBox* box);
+double ganv_box_get_y1(const GanvBox* box);
+double ganv_box_get_x2(const GanvBox* box);
+double ganv_box_get_y2(const GanvBox* box);
+double ganv_box_get_width(const GanvBox* box);
+void ganv_box_set_width(GanvBox* box, double width);
+double ganv_box_get_height(const GanvBox* box);
+void ganv_box_set_height(GanvBox* box, double height);
+double ganv_box_get_border_width(const GanvBox* box);
+
+/**
+ * ganv_box_normalize:
+ * @box: The box to normalize.
+ *
+ * Normalize the box coordinates such that x1 < x2 and y1 < y2.
+ */
+void ganv_box_normalize(GanvBox* box);
+
+G_END_DECLS
+
+#endif /* GANV_BOX_H */
diff --git a/include/ganv/canvas.h b/include/ganv/canvas.h
new file mode 100644
index 0000000..ca50b21
--- /dev/null
+++ b/include/ganv/canvas.h
@@ -0,0 +1,647 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2015 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GANV_CANVAS_H
+#define GANV_CANVAS_H
+
+#include "ganv/item.h"
+#include "ganv/types.h"
+
+#include <cairo.h>
+#include <gdk/gdk.h>
+#include <glib-object.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GANV_TYPE_CANVAS (ganv_canvas_get_type())
+#define GANV_CANVAS(obj) (GTK_CHECK_CAST((obj), GANV_TYPE_CANVAS, GanvCanvas))
+#define GANV_CANVAS_CLASS(klass) (GTK_CHECK_CLASS_CAST((klass), GANV_TYPE_CANVAS, GanvCanvasClass))
+#define GANV_IS_CANVAS(obj) (GTK_CHECK_TYPE((obj), GANV_TYPE_CANVAS))
+#define GANV_IS_CANVAS_CLASS(klass) (GTK_CHECK_CLASS_TYPE((klass), GANV_TYPE_CANVAS))
+#define GANV_CANVAS_GET_CLASS(obj) (GTK_CHECK_GET_CLASS((obj), GANV_TYPE_CANVAS, GanvCanvasClass))
+
+struct _GanvCanvasClass;
+
+typedef struct GanvCanvasImpl GanvCanvasPrivate;
+typedef struct _GanvCanvasClass GanvCanvasClass;
+
+/**
+ * GanvDirection:
+ * @GANV_DIRECTION_DOWN: Signal flows from top to bottom.
+ * @GANV_DIRECTION_RIGHT: Signal flows from left to right.
+ *
+ * Specifies the direction of signal flow on the canvas, which affects the
+ * appearance of modules and how the canvas is auto-arranged.
+ */
+typedef enum {
+ GANV_DIRECTION_DOWN,
+ GANV_DIRECTION_RIGHT
+} GanvDirection;
+
+struct _GanvCanvas {
+ GtkLayout layout;
+ GanvCanvasPrivate* impl;
+};
+
+struct _GanvCanvasClass {
+ GtkLayoutClass parent_class;
+
+ /* Reserved for future expansion */
+ gpointer spare_vmethods[4];
+};
+
+GType ganv_canvas_get_type(void) G_GNUC_CONST;
+
+/**
+ * GanvEdgeFunc:
+ * @edge: Canvas edge.
+ * @data: User callback data.
+ *
+ * A node function that takes a user data argument (for callbacks).
+ *
+ * Note that in the Gtk world it is considered safe to cast a function to a
+ * function with more arguments and call the resulting pointer, so functions
+ * like ganv_edge_select can safely be used where a GanvEdgeFunc is expected.
+ */
+typedef void (*GanvEdgeFunc)(GanvEdge* edge, void* data);
+
+/**
+ * GanvNodeFunc:
+ * @node: Canvas node.
+ * @data: User callback data.
+ *
+ * A node function that takes a user data argument (for callbacks).
+ *
+ * Note that in the Gtk world it is considered safe to cast a function to a
+ * function with more arguments and call the resulting pointer, so functions
+ * like ganv_node_select can safely be used where a GanvNodeFunc is expected.
+ */
+typedef void (*GanvNodeFunc)(GanvNode* node, void* data);
+
+/**
+ * GanvPortOrderFunc:
+ * @lhs: Left-hand port to compare.
+ * @rhs: Right-hand port to compare.
+ * @data: User callback data.
+ *
+ * A function to compare two ports.
+ */
+typedef int (*GanvPortOrderFunc)(const GanvPort* lhs, const GanvPort* rhs, void* data);
+
+/**
+ * ganv_canvas_new:
+ *
+ * Return value: A newly-created canvas.
+ */
+GanvCanvas*
+ganv_canvas_new(double width, double height);
+
+/**
+ * ganv_canvas_set_wrapper:
+ *
+ * Set the opaque wrapper object for the canvas.
+ */
+void
+ganv_canvas_set_wrapper(GanvCanvas* canvas, void* wrapper);
+
+/**
+ * ganv_canvas_get_wrapper:
+ *
+ * Return an opaque pointer to the wrapper for the canvas.
+ */
+void*
+ganv_canvas_get_wrapper(GanvCanvas* canvas);
+
+/**
+ * ganv_canvas_clear:
+ *
+ * Remove all items from the canvas.
+ */
+void
+ganv_canvas_clear(GanvCanvas* canvas);
+
+/**
+ * ganv_canvas_empty:
+ *
+ * Return value: True if there are no items on the canvas.
+ */
+gboolean
+ganv_canvas_empty(const GanvCanvas* canvas);
+
+/**
+ * ganv_canvas_get_size:
+ *
+ * Gets the width and height of the canvas.
+ */
+void
+ganv_canvas_get_size(GanvCanvas* canvas, double* width, double* height);
+
+/**
+ * ganv_canvas_resize:
+ *
+ * Resize the canvas to the given dimensions.
+ */
+void
+ganv_canvas_resize(GanvCanvas* canvas, double width, double height);
+
+/**
+ * ganv_canvas_root:
+ * @canvas: A canvas.
+ *
+ * Return value: (transfer none): The root group of the canvas.
+ */
+GanvItem*
+ganv_canvas_root(GanvCanvas* canvas);
+
+/**
+ * ganv_canvas_set_scroll_region:
+ * @canvas: A canvas.
+ * @x1: Leftmost limit of the scrolling region.
+ * @y1: Upper limit of the scrolling region.
+ * @x2: Rightmost limit of the scrolling region.
+ * @y2: Lower limit of the scrolling region.
+ *
+ * Sets the scrolling region of a canvas to the specified rectangle. The
+ * canvas will then be able to scroll only within this region. The view of the
+ * canvas is adjusted as appropriate to display as much of the new region as
+ * possible.
+ */
+void
+ganv_canvas_set_scroll_region(GanvCanvas* canvas,
+ double x1, double y1, double x2, double y2);
+
+/**
+ * ganv_canvas_get_scroll_region:
+ * @canvas: A canvas.
+ * @x1: Leftmost limit of the scrolling region (return value).
+ * @y1: Upper limit of the scrolling region (return value).
+ * @x2: Rightmost limit of the scrolling region (return value).
+ * @y2: Lower limit of the scrolling region (return value).
+ *
+ * Queries the scrolling region of a canvas.
+ */
+void
+ganv_canvas_get_scroll_region(GanvCanvas* canvas,
+ double* x1, double* y1, double* x2, double* y2);
+
+/**
+ * ganv_canvas_set_center_scroll_region:
+ * @canvas: A canvas.
+ * @center_scroll_region: Whether to center the scrolling region in the canvas
+ * window when it is smaller than the canvas' allocation.
+ *
+ * When the scrolling region of the canvas is smaller than the canvas window,
+ * e.g. the allocation of the canvas, it can be either centered on the window
+ * or simply made to be on the upper-left corner on the window. This function
+ * lets you configure this property.
+ */
+void
+ganv_canvas_set_center_scroll_region(GanvCanvas* canvas,
+ gboolean center_scroll_region);
+
+/**
+ * ganv_canvas_get_center_scroll_region:
+ * @canvas: A canvas.
+ *
+ * Returns whether the canvas is set to center the scrolling region in the
+ * window if the former is smaller than the canvas' allocation.
+ *
+ * Returns: Whether the scroll region is being centered in the canvas window.
+ */
+gboolean
+ganv_canvas_get_center_scroll_region(const GanvCanvas* canvas);
+
+/**
+ * ganv_canvas_scroll_to:
+ * @canvas: A canvas.
+ * @cx: Horizontal scrolling offset in canvas pixel units.
+ * @cy: Vertical scrolling offset in canvas pixel units.
+ *
+ * Makes a canvas scroll to the specified offsets, given in canvas pixel units.
+ * The canvas will adjust the view so that it is not outside the scrolling
+ * region. This function is typically not used, as it is better to hook
+ * scrollbars to the canvas layout's scrolling adjusments.
+ */
+void
+ganv_canvas_scroll_to(GanvCanvas* canvas, int cx, int cy);
+
+/**
+ * ganv_canvas_get_scroll_offsets:
+ * @canvas: A canvas.
+ * @cx: Horizontal scrolling offset (return value).
+ * @cy: Vertical scrolling offset (return value).
+ *
+ * Queries the scrolling offsets of a canvas. The values are returned in canvas
+ * pixel units.
+ */
+void
+ganv_canvas_get_scroll_offsets(const GanvCanvas* canvas, int* cx, int* cy);
+
+/**
+ * ganv_canvas_w2c_affine:
+ * @canvas: A canvas.
+ * @matrix: An affine transformation matrix (return value).
+ *
+ * Gets the affine transform that converts from world coordinates to canvas
+ * pixel coordinates.
+ */
+void
+ganv_canvas_w2c_affine(GanvCanvas* canvas, cairo_matrix_t* matrix);
+
+/**
+ * ganv_canvas_w2c:
+ * @canvas: A canvas.
+ * @wx: World X coordinate.
+ * @wy: World Y coordinate.
+ * @cx: X pixel coordinate (return value).
+ * @cy: Y pixel coordinate (return value).
+ *
+ * Converts world coordinates into canvas pixel coordinates.
+ */
+void
+ganv_canvas_w2c(GanvCanvas* canvas, double wx, double wy, int* cx, int* cy);
+
+/**
+ * ganv_canvas_w2c_d:
+ * @canvas: A canvas.
+ * @wx: World X coordinate.
+ * @wy: World Y coordinate.
+ * @cx: X pixel coordinate (return value).
+ * @cy: Y pixel coordinate (return value).
+ *
+ * Converts world coordinates into canvas pixel coordinates. This version
+ * uses floating point coordinates for greater precision.
+ */
+void
+ganv_canvas_w2c_d(GanvCanvas* canvas,
+ double wx,
+ double wy,
+ double* cx,
+ double* cy);
+
+/**
+ * ganv_canvas_c2w:
+ * @canvas: A canvas.
+ * @cx: Canvas pixel X coordinate.
+ * @cy: Canvas pixel Y coordinate.
+ * @wx: X world coordinate (return value).
+ * @wy: Y world coordinate (return value).
+ *
+ * Converts canvas pixel coordinates to world coordinates.
+ */
+void
+ganv_canvas_c2w(GanvCanvas* canvas, int cx, int cy, double* wx, double* wy);
+
+/**
+ * ganv_canvas_window_to_world:
+ * @canvas: A canvas.
+ * @winx: Window-relative X coordinate.
+ * @winy: Window-relative Y coordinate.
+ * @worldx: X world coordinate (return value).
+ * @worldy: Y world coordinate (return value).
+ *
+ * Converts window-relative coordinates into world coordinates. You can use
+ * this when you need to convert mouse coordinates into world coordinates, for
+ * example.
+ */
+void
+ganv_canvas_window_to_world(GanvCanvas* canvas,
+ double winx,
+ double winy,
+ double* worldx,
+ double* worldy);
+
+/**
+ * ganv_canvas_world_to_window:
+ * @canvas: A canvas.
+ * @worldx: World X coordinate.
+ * @worldy: World Y coordinate.
+ * @winx: X window-relative coordinate.
+ * @winy: Y window-relative coordinate.
+ *
+ * Converts world coordinates into window-relative coordinates.
+ */
+void
+ganv_canvas_world_to_window(GanvCanvas* canvas,
+ double worldx,
+ double worldy,
+ double* winx,
+ double* winy);
+
+/**
+ * ganv_canvas_get_item_at:
+ * @canvas: A canvas.
+ * @x: X position in world coordinates.
+ * @y: Y position in world coordinates.
+ *
+ * Looks for the item that is under the specified position, which must be
+ * specified in world coordinates.
+ *
+ * Returns: (transfer none): The sought item, or NULL if no item is at the
+ * specified coordinates.
+ */
+GanvItem*
+ganv_canvas_get_item_at(GanvCanvas* canvas, double x, double y);
+
+/**
+ * ganv_canvas_get_edge:
+ *
+ * Get the edge between two nodes, or NULL if none exists.
+ *
+ * Return value: (transfer none): The root group of @canvas.
+ */
+GanvEdge*
+ganv_canvas_get_edge(GanvCanvas* canvas,
+ GanvNode* tail,
+ GanvNode* head);
+
+/**
+ * ganv_canvas_remove_edge:
+ *
+ * Remove @edge from the canvas.
+ */
+void
+ganv_canvas_remove_edge(GanvCanvas* canvas,
+ GanvEdge* edge);
+
+/**
+ * ganv_canvas_remove_edge_between:
+ *
+ * Remove the edge from @tail to @head if one exists.
+ */
+void
+ganv_canvas_remove_edge_between(GanvCanvas* canvas,
+ GanvNode* tail,
+ GanvNode* head);
+
+/**
+ * ganv_canvas_get_direction:
+ *
+ * Return the direction of signal flow.
+ */
+GanvDirection
+ganv_canvas_get_direction(GanvCanvas* canvas);
+
+/**
+ * ganv_canvas_set_direction:
+ *
+ * Set the direction of signal flow.
+ */
+void
+ganv_canvas_set_direction(GanvCanvas* canvas, GanvDirection dir);
+
+/**
+ * ganv_canvas_arrange:
+ *
+ * Automatically arrange the canvas contents.
+ */
+void
+ganv_canvas_arrange(GanvCanvas* canvas);
+
+/**
+ * ganv_canvas_export_image:
+ *
+ * Draw the canvas to an image file. The file type is determined by extension,
+ * currently supported: pdf, ps, svg, dot.
+ *
+ * Returns: 0 on success.
+ */
+int
+ganv_canvas_export_image(GanvCanvas* canvas,
+ const char* filename,
+ gboolean draw_background);
+
+/**
+ * ganv_canvas_export_dot:
+ *
+ * Write a Graphviz DOT description of the canvas to a file.
+ */
+void
+ganv_canvas_export_dot(GanvCanvas* canvas, const char* filename);
+
+/**
+ * ganv_canvas_supports_sprung_layout:
+ *
+ * Returns: true iff ganv is compiled with sprung layout support.
+ */
+gboolean
+ganv_canvas_supports_sprung_layout(const GanvCanvas* canvas);
+
+/**
+ * ganv_canvas_set_sprung_layout:
+ *
+ * Enable or disable "live" force-directed canvas layout.
+ *
+ * Returns: true iff sprung layout was enabled.
+ */
+gboolean
+ganv_canvas_set_sprung_layout(GanvCanvas* canvas, gboolean sprung_layout);
+
+/**
+ * ganv_canvas_get_locked:
+ *
+ * Return true iff the canvas is locked and nodes may not move.
+ */
+gboolean
+ganv_canvas_get_locked(const GanvCanvas* canvas);
+
+/**
+ * ganv_canvas_for_each_node:
+ * @canvas: The canvas.
+ * @f: (scope call): A function to call on every node on @canvas.
+ * @data: Data to pass to @f.
+ */
+void
+ganv_canvas_for_each_node(GanvCanvas* canvas,
+ GanvNodeFunc f,
+ void* data);
+
+/**
+ * ganv_canvas_for_each_selected_node:
+ * @canvas: The canvas.
+ * @f: (scope call): A function to call on every selected node on @canvas.
+ * @data: Data to pass to @f.
+ */
+void
+ganv_canvas_for_each_selected_node(GanvCanvas* canvas,
+ GanvNodeFunc f,
+ void* data);
+
+/**
+ * ganv_canvas_for_each_edge:
+ * @canvas: The canvas.
+ * @f: (scope call): A function to call on every edge on @canvas.
+ * @data: Data to pass to @f.
+ */
+void
+ganv_canvas_for_each_edge(GanvCanvas* canvas,
+ GanvEdgeFunc f,
+ void* data);
+
+/**
+ * ganv_canvas_for_each_edge_from:
+ * @canvas: The canvas.
+ * @tail: The tail to enumerate every edge for.
+ * @f: (scope call): A function to call on every edge leaving @tail.
+ */
+void
+ganv_canvas_for_each_edge_from(GanvCanvas* canvas,
+ const GanvNode* tail,
+ GanvEdgeFunc f,
+ void* data);
+
+/**
+ * ganv_canvas_for_each_edge_to:
+ * @canvas: The canvas.
+ * @head: The head to enumerate every edge for.
+ * @f: (scope call): A function to call on every edge entering @head.
+ */
+void
+ganv_canvas_for_each_edge_to(GanvCanvas* canvas,
+ const GanvNode* head,
+ GanvEdgeFunc f,
+ void* data);
+
+/**
+ * ganv_canvas_for_each_edge_on:
+ * @canvas: The canvas.
+ * @node: The node to enumerate every edge for.
+ * @f: (scope call): A function to call on every edge attached to @node.
+ */
+void
+ganv_canvas_for_each_edge_on(GanvCanvas* canvas,
+ const GanvNode* node,
+ GanvEdgeFunc f,
+ void* data);
+
+/**
+ * ganv_canvas_for_each_selected_edge:
+ * @canvas: The canvas.
+ * @f: (scope call): A function to call on every edge attached to @node.
+ * @data: Data to pass to @f.
+ */
+void
+ganv_canvas_for_each_selected_edge(GanvCanvas* canvas,
+ GanvEdgeFunc f,
+ void* data);
+
+/**
+ * ganv_canvas_select_all:
+ *
+ * Select all items on the canvas.
+ */
+void
+ganv_canvas_select_all(GanvCanvas* canvas);
+
+/**
+ * ganv_canvas_clear_selection:
+ *
+ * Deselect any selected items on the canvas.
+ */
+void
+ganv_canvas_clear_selection(GanvCanvas* canvas);
+
+/**
+ * ganv_canvas_get_zoom:
+ *
+ * Return the current zoom factor (pixels per unit).
+ */
+double
+ganv_canvas_get_zoom(const GanvCanvas* canvas);
+
+/**
+ * ganv_canvas_set_zoom:
+ * @canvas: A canvas.
+ * @zoom: The number of pixels that correspond to one canvas unit.
+ *
+ * The anchor point for zooming, i.e. the point that stays fixed and all others
+ * zoom inwards or outwards from it, depends on whether the canvas is set to
+ * center the scrolling region or not. You can control this using the
+ * ganv_canvas_set_center_scroll_region() function. If the canvas is set to
+ * center the scroll region, then the center of the canvas window is used as
+ * the anchor point for zooming. Otherwise, the upper-left corner of the
+ * canvas window is used as the anchor point.
+ */
+void
+ganv_canvas_set_zoom(GanvCanvas* canvas, double zoom);
+
+/**
+ * ganv_canvas_zoom_full:
+ *
+ * Zoom so all canvas contents are visible.
+ */
+void
+ganv_canvas_zoom_full(GanvCanvas* canvas);
+
+/**
+ * ganv_canvas_get_default_font_size:
+ *
+ * Get the default font size in points.
+ */
+double
+ganv_canvas_get_default_font_size(const GanvCanvas* canvas);
+
+/**
+ * ganv_canvas_get_font_size:
+ *
+ * Get the current font size in points.
+ */
+double
+ganv_canvas_get_font_size(const GanvCanvas* canvas);
+
+/**
+ * ganv_canvas_set_font_size:
+ *
+ * Set the current font size in points.
+ */
+void
+ganv_canvas_set_font_size(GanvCanvas* canvas, double points);
+
+/**
+ * ganv_canvas_get_move_cursor:
+ *
+ * Return the cursor to use while dragging canvas objects.
+ */
+GdkCursor*
+ganv_canvas_get_move_cursor(const GanvCanvas* canvas);
+
+/**
+ * ganv_canvas_move_contents_to:
+ *
+ * Shift all canvas contents so the top-left object is at (x, y).
+ */
+void
+ganv_canvas_move_contents_to(GanvCanvas* canvas, double x, double y);
+
+/**
+ * ganv_canvas_set_port_order:
+ * @canvas: The canvas to set the default port order on.
+ * @port_cmp: (scope call): Port comparison function.
+ * @data: Data to be passed to order.
+ *
+ * Set a comparator function to use as the default order for ports on modules.
+ * If left unset, ports are shown in the order they are added.
+ */
+void
+ganv_canvas_set_port_order(GanvCanvas* canvas,
+ GanvPortOrderFunc port_cmp,
+ void* data);
+
+
+G_END_DECLS
+
+#endif /* GANV_CANVAS_H */
diff --git a/include/ganv/circle.h b/include/ganv/circle.h
new file mode 100644
index 0000000..23bfa2d
--- /dev/null
+++ b/include/ganv/circle.h
@@ -0,0 +1,88 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2014 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// IWYU pragma: no_include "ganv-private.h"
+
+#ifndef GANV_CIRCLE_H
+#define GANV_CIRCLE_H
+
+#include "ganv/node.h"
+#include "ganv/types.h"
+
+#include <glib-object.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GANV_TYPE_CIRCLE (ganv_circle_get_type())
+#define GANV_CIRCLE(obj) (GTK_CHECK_CAST((obj), GANV_TYPE_CIRCLE, GanvCircle))
+#define GANV_CIRCLE_CLASS(klass) (GTK_CHECK_CLASS_CAST((klass), GANV_TYPE_CIRCLE, GanvCircleClass))
+#define GANV_IS_CIRCLE(obj) (GTK_CHECK_TYPE((obj), GANV_TYPE_CIRCLE))
+#define GANV_IS_CIRCLE_CLASS(klass) (GTK_CHECK_CLASS_TYPE((klass), GANV_TYPE_CIRCLE))
+#define GANV_CIRCLE_GET_CLASS(obj) (GTK_CHECK_GET_CLASS((obj), GANV_TYPE_CIRCLE, GanvCircleClass))
+
+struct _GanvCircle;
+struct _GanvCircleClass;
+
+typedef struct _GanvCircle GanvCircle;
+typedef struct _GanvCircleClass GanvCircleClass;
+typedef struct _GanvCirclePrivate GanvCirclePrivate;
+
+/**
+ * GanvCircle:
+ *
+ * A circular #GanvNode. A #GanvCircle is a leaf, that is, it does not contain
+ * any child nodes (though, like any #GanvNode, it may have a label).
+ */
+struct _GanvCircle {
+ GanvNode node;
+ GanvCirclePrivate* impl;
+};
+
+struct _GanvCircleClass {
+ GanvNodeClass parent_class;
+
+ /* Reserved for future expansion */
+ gpointer spare_vmethods[4];
+};
+
+GType ganv_circle_get_type(void) G_GNUC_CONST;
+
+GanvCircle*
+ganv_circle_new(GanvCanvas* canvas,
+ const char* first_prop_name, ...);
+
+double
+ganv_circle_get_radius(const GanvCircle* circle);
+
+void
+ganv_circle_set_radius(GanvCircle* circle, double radius);
+
+double
+ganv_circle_get_radius_ems(const GanvCircle* circle);
+
+void
+ganv_circle_set_radius_ems(GanvCircle* circle, double radius);
+
+gboolean
+ganv_circle_get_fit_label(const GanvCircle* circle);
+
+void
+ganv_circle_set_fit_label(GanvCircle* circle, gboolean fit_label);
+
+G_END_DECLS
+
+#endif /* GANV_CIRCLE_H */
diff --git a/include/ganv/edge.h b/include/ganv/edge.h
new file mode 100644
index 0000000..8bf8ad0
--- /dev/null
+++ b/include/ganv/edge.h
@@ -0,0 +1,136 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2015 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// IWYU pragma: no_include "ganv-private.h"
+
+#ifndef GANV_EDGE_H
+#define GANV_EDGE_H
+
+#include "ganv/item.h"
+#include "ganv/types.h"
+
+#include <glib-object.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GANV_TYPE_EDGE (ganv_edge_get_type())
+#define GANV_EDGE(obj) (GTK_CHECK_CAST((obj), GANV_TYPE_EDGE, GanvEdge))
+#define GANV_EDGE_CLASS(klass) (GTK_CHECK_CLASS_CAST((klass), GANV_TYPE_EDGE, GanvEdgeClass))
+#define GANV_IS_EDGE(obj) (GTK_CHECK_TYPE((obj), GANV_TYPE_EDGE))
+#define GANV_IS_EDGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE((klass), GANV_TYPE_EDGE))
+#define GANV_EDGE_GET_CLASS(obj) (GTK_CHECK_GET_CLASS((obj), GANV_TYPE_EDGE, GanvEdgeClass))
+
+struct _GanvEdgeClass;
+
+typedef struct _GanvEdgeClass GanvEdgeClass;
+typedef struct _GanvEdgePrivate GanvEdgePrivate;
+
+struct _GanvEdge {
+ GanvItem item;
+ GanvEdgePrivate* impl;
+};
+
+struct _GanvEdgeClass {
+ GanvItemClass parent_class;
+
+ /* Reserved for future expansion */
+ gpointer spare_vmethods[4];
+};
+
+GType ganv_edge_get_type(void) G_GNUC_CONST;
+
+GanvEdge*
+ganv_edge_new(GanvCanvas* canvas,
+ GanvNode* tail,
+ GanvNode* head,
+ const char* first_prop_name, ...);
+
+gboolean
+ganv_edge_is_within(const GanvEdge* edge,
+ double x1,
+ double y1,
+ double x2,
+ double y2);
+
+gboolean
+ganv_edge_get_curved(const GanvEdge* edge);
+
+void
+ganv_edge_set_curved(GanvEdge* edge, gboolean curved);
+
+gboolean
+ganv_edge_get_constraining(const GanvEdge* edge);
+
+void
+ganv_edge_set_constraining(GanvEdge* edge, gboolean constraining);
+
+void
+ganv_edge_set_selected(GanvEdge* edge, gboolean selected);
+
+void
+ganv_edge_set_highlighted(GanvEdge* edge, gboolean highlighted);
+
+void
+ganv_edge_select(GanvEdge* edge);
+
+void
+ganv_edge_unselect(GanvEdge* edge);
+
+void
+ganv_edge_highlight(GanvEdge* edge);
+
+void
+ganv_edge_unhighlight(GanvEdge* edge);
+
+/**
+ * ganv_edge_disconnect:
+ *
+ * Disconnect the edge. This will disconnect the edge just as if it had been
+ * disconnected by the user via the canvas. The canvas disconnect signal will
+ * be emitted, allowing the application to control disconnect logic.
+ */
+void
+ganv_edge_disconnect(GanvEdge* edge);
+
+/**
+ * ganv_edge_remove:
+ *
+ * Remove the edge from the canvas. This will only remove the edge visually,
+ * it will not emit the canvas disconnect signal to notify the application.
+ */
+void
+ganv_edge_remove(GanvEdge* edge);
+
+/**
+ * ganv_edge_get_tail:
+ *
+ * Return value: (transfer none): The tail of `edge`.
+ */
+GanvNode*
+ganv_edge_get_tail(const GanvEdge* edge);
+
+/**
+ * ganv_edge_get_head:
+ *
+ * Return value: (transfer none): The head of `edge`.
+ */
+GanvNode*
+ganv_edge_get_head(const GanvEdge* edge);
+
+G_END_DECLS
+
+#endif /* GANV_EDGE_H */
diff --git a/include/ganv/ganv.h b/include/ganv/ganv.h
new file mode 100644
index 0000000..f86165f
--- /dev/null
+++ b/include/ganv/ganv.h
@@ -0,0 +1,30 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2016 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GANV_GANV_H
+#define GANV_GANV_H
+
+#include "ganv/box.h" // IWYU pragma: export
+#include "ganv/canvas.h" // IWYU pragma: export
+#include "ganv/circle.h" // IWYU pragma: export
+#include "ganv/edge.h" // IWYU pragma: export
+#include "ganv/group.h" // IWYU pragma: export
+#include "ganv/module.h" // IWYU pragma: export
+#include "ganv/node.h" // IWYU pragma: export
+#include "ganv/port.h" // IWYU pragma: export
+#include "ganv/text.h" // IWYU pragma: export
+#include "ganv/types.h" // IWYU pragma: export
+
+#endif /* GANV_GANV_H */
diff --git a/include/ganv/ganv.hpp b/include/ganv/ganv.hpp
new file mode 100644
index 0000000..3e3f259
--- /dev/null
+++ b/include/ganv/ganv.hpp
@@ -0,0 +1,26 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2015 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GANV_GANV_HPP
+#define GANV_GANV_HPP
+
+#include "ganv/Canvas.hpp" // IWYU pragma: export
+#include "ganv/Circle.hpp" // IWYU pragma: export
+#include "ganv/Edge.hpp" // IWYU pragma: export
+#include "ganv/Module.hpp" // IWYU pragma: export
+#include "ganv/Node.hpp" // IWYU pragma: export
+#include "ganv/Port.hpp" // IWYU pragma: export
+
+#endif // GANV_GANV_HPP
diff --git a/include/ganv/group.h b/include/ganv/group.h
new file mode 100644
index 0000000..72efa3c
--- /dev/null
+++ b/include/ganv/group.h
@@ -0,0 +1,63 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2014 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// IWYU pragma: no_include "ganv-private.h"
+
+#ifndef GANV_GROUP_H
+#define GANV_GROUP_H
+
+#include "ganv/item.h"
+
+#include <glib-object.h>
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+/* Based on GnomeCanvasGroup, by Federico Mena <federico@nuclecu.unam.mx>
+ * and Raph Levien <raph@gimp.org>
+ * Copyright 1997-2000 Free Software Foundation
+ */
+
+#define GANV_TYPE_GROUP (ganv_group_get_type())
+#define GANV_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GANV_TYPE_GROUP, GanvGroup))
+#define GANV_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GANV_TYPE_GROUP, GanvGroupClass))
+#define GANV_IS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GANV_TYPE_GROUP))
+#define GANV_IS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GANV_TYPE_GROUP))
+#define GANV_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GANV_TYPE_GROUP, GanvGroupClass))
+
+struct _GanvGroup;
+struct _GanvGroupClass;
+
+typedef struct _GanvGroup GanvGroup;
+typedef struct _GanvGroupPrivate GanvGroupPrivate;
+typedef struct _GanvGroupClass GanvGroupClass;
+
+struct _GanvGroup {
+ GanvItem item;
+ GanvGroupPrivate* impl;
+};
+
+struct _GanvGroupClass {
+ GanvItemClass parent_class;
+
+ /* Reserved for future expansion */
+ gpointer spare_vmethods[4];
+};
+
+GType ganv_group_get_type(void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* GANV_GROUP_H */
diff --git a/include/ganv/item.h b/include/ganv/item.h
new file mode 100644
index 0000000..2433574
--- /dev/null
+++ b/include/ganv/item.h
@@ -0,0 +1,188 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2016 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Based on GnomeCanvas, by Federico Mena <federico@nuclecu.unam.mx>
+ * and Raph Levien <raph@gimp.org>
+ * Copyright 1997-2000 Free Software Foundation
+ */
+
+#ifndef GANV_ITEM_H
+#define GANV_ITEM_H
+
+#include <cairo.h>
+#include <gdk/gdk.h>
+#include <glib-object.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#include <stdarg.h>
+
+G_BEGIN_DECLS
+
+struct _GanvItem;
+struct _GanvItemClass;
+
+typedef struct _GanvItem GanvItem;
+typedef struct _GanvItemPrivate GanvItemPrivate;
+typedef struct _GanvItemClass GanvItemClass;
+
+/* Object flags for items */
+enum {
+ GANV_ITEM_REALIZED = 1 << 1,
+ GANV_ITEM_MAPPED = 1 << 2,
+ GANV_ITEM_ALWAYS_REDRAW = 1 << 3,
+ GANV_ITEM_VISIBLE = 1 << 4,
+ GANV_ITEM_NEED_UPDATE = 1 << 5,
+ GANV_ITEM_NEED_VIS = 1 << 6
+};
+
+#define GANV_TYPE_ITEM (ganv_item_get_type())
+#define GANV_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GANV_TYPE_ITEM, GanvItem))
+#define GANV_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GANV_TYPE_ITEM, GanvItemClass))
+#define GANV_IS_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GANV_TYPE_ITEM))
+#define GANV_IS_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GANV_TYPE_ITEM))
+#define GANV_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GANV_TYPE_ITEM, GanvItemClass))
+
+struct _GanvItem {
+ GtkObject object;
+ GanvItemPrivate* impl;
+};
+
+struct _GanvItemClass {
+ GtkObjectClass parent_class;
+
+ /* Add a child to this item (optional). */
+ void (*add)(GanvItem* item, GanvItem* child);
+
+ /* Remove a child from this item (optional). */
+ void (*remove)(GanvItem* item, GanvItem* child);
+
+ /* Tell the item to update itself.
+ *
+ * The flags are from the update flags defined above. The item should
+ * update its internal state from its queued state, and recompute and
+ * request its repaint area. The update method also recomputes the
+ * bounding box of the item.
+ */
+ void (*update)(GanvItem* item, int flags);
+
+ /* Realize an item (create GCs, etc.). */
+ void (*realize)(GanvItem* item);
+
+ /* Unrealize an item. */
+ void (*unrealize)(GanvItem* item);
+
+ /* Map an item - normally only need by items with their own GdkWindows. */
+ void (*map)(GanvItem* item);
+
+ /* Unmap an item */
+ void (*unmap)(GanvItem* item);
+
+ /* Draw an item of this type.
+ *
+ * (cx, cy) and (width, height) describe the rectangle being drawn in
+ * world-relative coordinates.
+ */
+ void (*draw)(GanvItem* item,
+ cairo_t* cr,
+ double cx,
+ double cy,
+ double cw,
+ double ch);
+
+ /* Calculate the distance from an item to the specified point.
+ *
+ * It also returns a canvas item which is actual item the point is within,
+ * which may not be equal to @item if @item has children.
+ * (x, y) are item-relative coordinates.
+ */
+ double (*point)(GanvItem* item,
+ double x,
+ double y,
+ GanvItem** actual_item);
+
+ /* Fetch the item's bounding box (need not be exactly tight).
+ *
+ * This should be in item-relative coordinates.
+ */
+ void (*bounds)(GanvItem* item, double* x1, double* y1, double* x2, double* y2);
+
+ /* Signal: an event occurred for an item of this type.
+ *
+ * The (x, y) coordinates are in the canvas world coordinate system.
+ */
+ gboolean (*event)(GanvItem* item, GdkEvent* event);
+
+ /* Reserved for future expansion */
+ gpointer spare_vmethods[4];
+};
+
+GType ganv_item_get_type(void) G_GNUC_CONST;
+
+GanvItem* ganv_item_new(GanvItem* parent, GType type,
+ const gchar* first_arg_name, ...);
+
+void ganv_item_construct(GanvItem* item, GanvItem* parent,
+ const gchar* first_arg_name, va_list args);
+
+void ganv_item_set(GanvItem* item, const gchar* first_arg_name, ...);
+
+void ganv_item_set_valist(GanvItem* item,
+ const gchar* first_arg_name, va_list args);
+
+/**
+ * ganv_item_get_canvas:
+ * @item: The item.
+ *
+ * Return value: (transfer none): The canvas @item is on.
+ */
+struct _GanvCanvas* ganv_item_get_canvas(GanvItem* item);
+
+/**
+ * ganv_item_get_parent:
+ * @item: The item.
+ *
+ * Return value: (transfer none): The parent of @item.
+ */
+GanvItem* ganv_item_get_parent(GanvItem* item);
+
+void ganv_item_raise(GanvItem* item);
+
+void ganv_item_lower(GanvItem* item);
+
+void ganv_item_move(GanvItem* item, double dx, double dy);
+
+void ganv_item_show(GanvItem* item);
+
+void ganv_item_hide(GanvItem* item);
+
+void ganv_item_i2w(GanvItem* item, double* x, double* y);
+
+void ganv_item_w2i(GanvItem* item, double* x, double* y);
+
+void ganv_item_grab_focus(GanvItem* item);
+
+void ganv_item_get_bounds(GanvItem* item,
+ double* x1, double* y1, double* x2, double* y2);
+
+void ganv_item_request_update(GanvItem* item);
+
+void ganv_item_set_wrapper(GanvItem* item, void* wrapper);
+
+void* ganv_item_get_wrapper(GanvItem* item);
+
+G_END_DECLS
+
+#endif /* GANV_ITEM_H */
diff --git a/include/ganv/module.h b/include/ganv/module.h
new file mode 100644
index 0000000..969965b
--- /dev/null
+++ b/include/ganv/module.h
@@ -0,0 +1,103 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2014 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// IWYU pragma: no_include "ganv-private.h"
+
+#ifndef GANV_MODULE_H
+#define GANV_MODULE_H
+
+#include "ganv/types.h"
+
+#include <glib-object.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#include "ganv/box.h"
+#include "ganv/canvas.h"
+
+G_BEGIN_DECLS
+
+#define GANV_TYPE_MODULE (ganv_module_get_type())
+#define GANV_MODULE(obj) (GTK_CHECK_CAST((obj), GANV_TYPE_MODULE, GanvModule))
+#define GANV_MODULE_CLASS(klass) (GTK_CHECK_CLASS_CAST((klass), GANV_TYPE_MODULE, GanvModuleClass))
+#define GANV_IS_MODULE(obj) (GTK_CHECK_TYPE((obj), GANV_TYPE_MODULE))
+#define GANV_IS_MODULE_CLASS(klass) (GTK_CHECK_CLASS_TYPE((klass), GANV_TYPE_MODULE))
+#define GANV_MODULE_GET_CLASS(obj) (GTK_CHECK_GET_CLASS((obj), GANV_TYPE_MODULE, GanvModuleClass))
+
+struct _GanvModuleClass;
+
+typedef struct _GanvModuleClass GanvModuleClass;
+typedef struct _GanvModulePrivate GanvModulePrivate;
+
+typedef void (*GanvPortFunc)(GanvPort* port, void* data);
+
+struct _GanvModule {
+ GanvBox box;
+ GanvModulePrivate* impl;
+};
+
+struct _GanvModuleClass {
+ GanvBoxClass parent_class;
+
+ /* Reserved for future expansion */
+ gpointer spare_vmethods[4];
+};
+
+GType ganv_module_get_type(void) G_GNUC_CONST;
+
+GanvModule*
+ganv_module_new(GanvCanvas* canvas,
+ const char* first_prop_name, ...);
+
+guint
+ganv_module_num_ports(const GanvModule* module);
+
+/**
+ * ganv_module_get_port:
+ *
+ * Get a port by index.
+ *
+ * Return value: (transfer none): The port on @module at @index.
+ */
+GanvPort*
+ganv_module_get_port(GanvModule* module,
+ guint index);
+
+double
+ganv_module_get_empty_port_breadth(const GanvModule* module);
+
+double
+ganv_module_get_empty_port_depth(const GanvModule* module);
+
+void
+ganv_module_embed(GanvModule* module, GtkWidget* widget);
+
+void
+ganv_module_set_direction(GanvModule* module, GanvDirection direction);
+
+/**
+ * ganv_module_for_each_port:
+ * @module: The module.
+ * @f: (scope call): A function to call on every port on @module.
+ * @data: User data to pass to @f.
+ */
+void
+ganv_module_for_each_port(GanvModule* module,
+ GanvPortFunc f,
+ void* data);
+
+G_END_DECLS
+
+#endif /* GANV_MODULE_H */
diff --git a/include/ganv/node.h b/include/ganv/node.h
new file mode 100644
index 0000000..03c5982
--- /dev/null
+++ b/include/ganv/node.h
@@ -0,0 +1,186 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2014 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// IWYU pragma: no_include "ganv-private.h"
+
+#ifndef GANV_NODE_H
+#define GANV_NODE_H
+
+#include "ganv/item.h"
+#include "ganv/types.h"
+
+#include <glib-object.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GANV_TYPE_NODE (ganv_node_get_type())
+#define GANV_NODE(obj) (GTK_CHECK_CAST((obj), GANV_TYPE_NODE, GanvNode))
+#define GANV_NODE_CLASS(klass) (GTK_CHECK_CLASS_CAST((klass), GANV_TYPE_NODE, GanvNodeClass))
+#define GANV_IS_NODE(obj) (GTK_CHECK_TYPE((obj), GANV_TYPE_NODE))
+#define GANV_IS_NODE_CLASS(klass) (GTK_CHECK_CLASS_TYPE((klass), GANV_TYPE_NODE))
+#define GANV_NODE_GET_CLASS(obj) (GTK_CHECK_GET_CLASS((obj), GANV_TYPE_NODE, GanvNodeClass))
+
+struct _GanvNodeClass;
+
+typedef struct _GanvNodeClass GanvNodeClass;
+typedef struct _GanvNodePrivate GanvNodePrivate;
+
+struct _GanvNode {
+ GanvItem item;
+ GanvNodePrivate* impl;
+};
+
+struct _GanvNodeClass {
+ GanvItemClass parent_class;
+
+ void (*tick)(GanvNode* self,
+ double seconds);
+
+ void (*move)(GanvNode* node,
+ double dx,
+ double dy);
+
+ void (*move_to)(GanvNode* node,
+ double x,
+ double y);
+
+ void (*resize)(GanvNode* node);
+
+ void (*redraw_text)(GanvNode* node);
+
+ void (*disconnect)(GanvNode* node);
+
+ gboolean (*is_within)(const GanvNode* self,
+ double x1,
+ double y1,
+ double x2,
+ double y2);
+
+ void (*tail_vector)(const GanvNode* self,
+ const GanvNode* head,
+ double* x,
+ double* y,
+ double* dx,
+ double* dy);
+
+ void (*head_vector)(const GanvNode* self,
+ const GanvNode* tail,
+ double* x,
+ double* y,
+ double* dx,
+ double* dy);
+
+ /* Reserved for future expansion */
+ gpointer spare_vmethods[4];
+};
+
+GType ganv_node_get_type(void) G_GNUC_CONST;
+
+/**
+ * ganv_node_can_tail:
+ *
+ * Return value: True iff node can act as the tail of an edge.
+ */
+gboolean
+ganv_node_can_tail(const GanvNode* node);
+
+/**
+ * ganv_node_can_head:
+ *
+ * Return value: True iff node can act as the head of an edge.
+ */
+gboolean
+ganv_node_can_head(const GanvNode* node);
+
+/**
+ * ganv_node_set_is_source:
+ *
+ * Flag a node as a source. This information is used to influence layout.
+ */
+void
+ganv_node_set_is_source(const GanvNode* node, gboolean is_source);
+
+/**
+ * ganv_node_is_within:
+ *
+ * Return value: True iff node is entirely within the given rectangle.
+ */
+gboolean
+ganv_node_is_within(const GanvNode* node,
+ double x1,
+ double y1,
+ double x2,
+ double y2);
+
+const char* ganv_node_get_label(const GanvNode* node);
+
+double ganv_node_get_border_width(const GanvNode* node);
+
+void ganv_node_set_border_width(const GanvNode* node, double border_width);
+
+double ganv_node_get_dash_length(const GanvNode* node);
+
+void ganv_node_set_dash_length(const GanvNode* node, double dash_length);
+
+double ganv_node_get_dash_offset(const GanvNode* node);
+
+void ganv_node_set_dash_offset(const GanvNode* node, double dash_offset);
+
+guint ganv_node_get_fill_color(const GanvNode* node);
+
+void ganv_node_set_fill_color(const GanvNode* node, guint fill_color);
+
+guint ganv_node_get_border_color(const GanvNode* node);
+
+void ganv_node_set_border_color(const GanvNode* node, guint border_color);
+
+/**
+ * ganv_node_get_partner:
+ *
+ * Return value: (transfer none): The partner of @node.
+ */
+GanvNode*
+ganv_node_get_partner(const GanvNode* node);
+
+void ganv_node_set_label(GanvNode* node, const char* str);
+void ganv_node_set_show_label(GanvNode* node, gboolean show);
+
+void
+ganv_node_move(GanvNode* node,
+ double dx,
+ double dy);
+
+void
+ganv_node_move_to(GanvNode* node,
+ double x,
+ double y);
+
+void
+ganv_node_resize(GanvNode* node);
+
+void
+ganv_node_redraw_text(GanvNode* node);
+
+void
+ganv_node_disconnect(GanvNode* node);
+
+gboolean
+ganv_node_is_selected(GanvNode* node);
+
+G_END_DECLS
+
+#endif /* GANV_NODE_H */
diff --git a/include/ganv/port.h b/include/ganv/port.h
new file mode 100644
index 0000000..8bf4a80
--- /dev/null
+++ b/include/ganv/port.h
@@ -0,0 +1,110 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2014 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// IWYU pragma: no_include "ganv-private.h"
+
+#ifndef GANV_PORT_H
+#define GANV_PORT_H
+
+#include "ganv/box.h"
+#include "ganv/types.h"
+
+#include <glib-object.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GANV_TYPE_PORT (ganv_port_get_type())
+#define GANV_PORT(obj) (GTK_CHECK_CAST((obj), GANV_TYPE_PORT, GanvPort))
+#define GANV_PORT_CLASS(klass) (GTK_CHECK_CLASS_CAST((klass), GANV_TYPE_PORT, GanvPortClass))
+#define GANV_IS_PORT(obj) (GTK_CHECK_TYPE((obj), GANV_TYPE_PORT))
+#define GANV_IS_PORT_CLASS(klass) (GTK_CHECK_CLASS_TYPE((klass), GANV_TYPE_PORT))
+#define GANV_PORT_GET_CLASS(obj) (GTK_CHECK_GET_CLASS((obj), GANV_TYPE_PORT, GanvPortClass))
+
+struct _GanvPortClass;
+
+typedef struct _GanvPortClass GanvPortClass;
+typedef struct _GanvPortPrivate GanvPortPrivate;
+
+struct _GanvPort {
+ GanvBox box;
+ GanvPortPrivate* impl;
+};
+
+struct _GanvPortClass {
+ GanvBoxClass parent_class;
+
+ /* Reserved for future expansion */
+ gpointer spare_vmethods[4];
+};
+
+GType ganv_port_get_type(void) G_GNUC_CONST;
+
+GanvPort*
+ganv_port_new(GanvModule* module,
+ gboolean is_input,
+ const char* first_prop_name, ...);
+
+void
+ganv_port_set_value_label(GanvPort* port,
+ const char* str);
+
+void
+ganv_port_show_control(GanvPort* port);
+
+void
+ganv_port_hide_control(GanvPort* port);
+
+void
+ganv_port_set_control_is_toggle(GanvPort* port,
+ gboolean is_toggle);
+
+void
+ganv_port_set_control_is_integer(GanvPort* port,
+ gboolean is_integer);
+
+void
+ganv_port_set_control_value(GanvPort* port,
+ float value);
+
+void
+ganv_port_set_control_min(GanvPort* port,
+ float min);
+
+void
+ganv_port_set_control_max(GanvPort* port,
+ float max);
+
+double
+ganv_port_get_natural_width(const GanvPort* port);
+
+/**
+ * ganv_port_get_module:
+ * @port: The port.
+ *
+ * Return value: (transfer none): The module @port is on.
+ */
+GanvModule* ganv_port_get_module(const GanvPort* port);
+
+float ganv_port_get_control_value(const GanvPort* port);
+float ganv_port_get_control_min(const GanvPort* port);
+float ganv_port_get_control_max(const GanvPort* port);
+gboolean ganv_port_is_input(const GanvPort* port);
+gboolean ganv_port_is_output(const GanvPort* port);
+
+G_END_DECLS
+
+#endif /* GANV_PORT_H */
diff --git a/include/ganv/text.h b/include/ganv/text.h
new file mode 100644
index 0000000..2aee253
--- /dev/null
+++ b/include/ganv/text.h
@@ -0,0 +1,59 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2014 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GANV_TEXT_H
+#define GANV_TEXT_H
+
+#include "ganv/item.h"
+
+#include <glib-object.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GANV_TYPE_TEXT (ganv_text_get_type())
+#define GANV_TEXT(obj) (GTK_CHECK_CAST((obj), GANV_TYPE_TEXT, GanvText))
+#define GANV_TEXT_CLASS(klass) (GTK_CHECK_CLASS_CAST((klass), GANV_TYPE_TEXT, GanvTextClass))
+#define GANV_IS_TEXT(obj) (GTK_CHECK_TYPE((obj), GANV_TYPE_TEXT))
+#define GANV_IS_TEXT_CLASS(klass) (GTK_CHECK_CLASS_TYPE((klass), GANV_TYPE_TEXT))
+#define GANV_TEXT_GET_CLASS(obj) (GTK_CHECK_GET_CLASS((obj), GANV_TYPE_TEXT, GanvTextClass))
+
+struct _GanvText;
+struct _GanvTextClass;
+
+typedef struct _GanvText GanvText;
+typedef struct _GanvTextClass GanvTextClass;
+typedef struct _GanvTextPrivate GanvTextPrivate;
+
+struct _GanvText {
+ GanvItem item;
+ GanvTextPrivate* impl;
+};
+
+struct _GanvTextClass {
+ GanvItemClass parent_class;
+
+ /* Reserved for future expansion */
+ gpointer spare_vmethodsx[4];
+};
+
+GType ganv_text_get_type(void) G_GNUC_CONST;
+
+void ganv_text_layout(GanvText* text);
+
+G_END_DECLS
+
+#endif /* GANV_TEXT_H */
diff --git a/include/ganv/types.h b/include/ganv/types.h
new file mode 100644
index 0000000..70c21ec
--- /dev/null
+++ b/include/ganv/types.h
@@ -0,0 +1,26 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2016 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GANV_TYPES_H
+#define GANV_TYPES_H
+
+typedef struct _GanvCanvas GanvCanvas;
+typedef struct _GanvEdge GanvEdge;
+typedef struct _GanvModule GanvModule;
+typedef struct _GanvNode GanvNode;
+typedef struct _GanvPort GanvPort;
+typedef struct _GanvBox GanvBox;
+
+#endif /* GANV_TYPES_H */
diff --git a/include/ganv/types.hpp b/include/ganv/types.hpp
new file mode 100644
index 0000000..ba797ba
--- /dev/null
+++ b/include/ganv/types.hpp
@@ -0,0 +1,30 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2015 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GANV_TYPES_HPP
+#define GANV_TYPES_HPP
+
+namespace Ganv {
+
+class Canvas; // IWYU pragma: keep
+class Edge; // IWYU pragma: keep
+class Item; // IWYU pragma: keep
+class Module; // IWYU pragma: keep
+class Node; // IWYU pragma: keep
+class Port; // IWYU pragma: keep
+
+} // namespace Ganv
+
+#endif // GANV_TYPES_HPP
diff --git a/include/ganv/widget.h b/include/ganv/widget.h
new file mode 100644
index 0000000..af31576
--- /dev/null
+++ b/include/ganv/widget.h
@@ -0,0 +1,62 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2014 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// IWYU pragma: no_include "ganv-private.h"
+
+/* Based on GnomeCanvasWidget, by Federico Mena <federico@nuclecu.unam.mx>
+ * Copyright 1997-2000 Free Software Foundation
+ */
+
+#ifndef GANV_WIDGET_H
+#define GANV_WIDGET_H
+
+#include "ganv/item.h"
+
+#include <glib-object.h>
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#define GANV_TYPE_WIDGET (ganv_widget_get_type ())
+#define GANV_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GANV_TYPE_WIDGET, GanvWidget))
+#define GANV_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GANV_TYPE_WIDGET, GanvWidgetClass))
+#define GANV_IS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GANV_TYPE_WIDGET))
+#define GANV_IS_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GANV_TYPE_WIDGET))
+#define GANV_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GANV_TYPE_WIDGET, GanvWidgetClass))
+
+struct _GanvWidget;
+struct _GanvWidgetClass;
+
+typedef struct _GanvWidget GanvWidget;
+typedef struct _GanvWidgetPrivate GanvWidgetPrivate;
+typedef struct _GanvWidgetClass GanvWidgetClass;
+
+struct _GanvWidget {
+ GanvItem item;
+ GanvWidgetPrivate* impl;
+};
+
+struct _GanvWidgetClass {
+ GanvItemClass parent_class;
+
+ /* Reserved for future expansion */
+ gpointer spare_vmethods [4];
+};
+
+GType ganv_widget_get_type(void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* GANV_WIDGET_H */
diff --git a/include/ganv/wrap.hpp b/include/ganv/wrap.hpp
new file mode 100644
index 0000000..8e0a421
--- /dev/null
+++ b/include/ganv/wrap.hpp
@@ -0,0 +1,140 @@
+/* This file is part of Ganv.
+ * Copyright 2007-2015 David Robillard <http://drobilla.net>
+ *
+ * Ganv is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or any later version.
+ *
+ * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with Ganv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// IWYU pragma: no_include "gettext.h"
+
+#ifndef GANV_WRAP_HPP
+#define GANV_WRAP_HPP
+
+#include "ganv/item.h"
+
+#include <glib-object.h> // IWYU pragma: keep
+#include <glib.h> // IWYU pragma: keep
+#include <gobject/gclosure.h> // IWYU pragma: keep
+#include <sigc++/functors/mem_fun.h> // IWYU pragma: keep
+#include <sigc++/signal.h> // IWYU pragma: keep
+
+#define CONNECT_PROP_SIGNAL(gobj, name, notify, handler) \
+ g_signal_connect(gobj, "notify::" #name, \
+ G_CALLBACK(notify), &_signal_##name); \
+ _signal_##name.connect(sigc::mem_fun(this, handler));
+
+#define SIGNAL1(name, argtype) \
+public: \
+ virtual bool on_##name(argtype) { return true; } \
+ sigc::signal<bool, argtype>& signal_##name() { return _signal_##name; } \
+private: \
+ sigc::signal<bool, argtype> _signal_##name;
+
+#define RW_PROPERTY(type, name) \
+ virtual type get_##name() const { \
+ type value; \
+ g_object_get(G_OBJECT(_gobj), #name, &value, nullptr); \
+ return value; \
+ } \
+ virtual void set_##name(type value) { \
+ g_object_set(G_OBJECT(_gobj), #name, value, nullptr); \
+ } \
+ SIGNAL1(name, type) \
+ public:
+
+#define RW_OBJECT_PROPERTY(type, name) \
+ type get_##name() const { \
+ if (!_gobj) return nullptr; \
+ Ganv##type ptr; \
+ g_object_get(G_OBJECT(_gobj), #name, &ptr, nullptr); \
+ return Glib::wrap(ptr); \
+ } \
+ void set_##name(type value) { \
+ if (!_gobj) return; \
+ ganv_item_set(GANV_ITEM(_gobj), \
+ #name, value->gobj(), \
+ nullptr); \
+ }
+
+#define METHOD0(prefix, name) \
+ virtual void name() { \
+ prefix##_##name(gobj()); \
+ }
+
+#define METHOD1(prefix, name, t1, a1) \
+ virtual void name(t1 a1) { \
+ prefix##_##name(gobj(), a1); \
+ }
+
+#define METHODRET0(prefix, ret, name) \
+ virtual ret name() const { \
+ return prefix##_##name(gobj()); \
+ }
+
+#define METHODRET1(prefix, ret, name, t1, a1) \
+ virtual ret name(t1 a1) { \
+ return prefix##_##name(gobj(), a1); \
+ }
+
+#define METHODRET2(prefix, ret, name, t1, a1, t2, a2) \
+ virtual ret name(t1 a1, t2 a2) { \
+ return prefix##_##name(gobj(), a1, a2); \
+ }
+
+#define METHODRETWRAP0(prefix, ret, name) \
+ virtual ret name() const { \
+ if (gobj()) { \
+ return Glib::wrap(prefix##_##name(gobj())); \
+ } \
+ return nullptr; \
+ }
+
+#define METHOD2(prefix, name, t1, a1, t2, a2) \
+ virtual void name(t1 a1, t2 a2) { \
+ prefix##_##name(gobj(), a1, a2); \
+ }
+
+#define METHOD3(prefix, name, t1, a1, t2, a2, t3, a3) \
+ virtual void name(t1 a1, t2 a2, t3 a3) { \
+ prefix##_##name(gobj(), a1, a2, a3); \
+ }
+
+#define METHOD4(prefix, name, t1, a1, t2, a2, t3, a3, t4, a4) \
+ virtual void name(t1 a1, t2 a2, t3 a3, t4 a4) { \
+ prefix##_##name(gobj(), a1, a2, a3, a4); \
+ }
+
+#define GANV_GLIB_WRAP(Name) \
+ namespace Ganv { \
+ class Name; /* NOLINT(bugprone-macro-parentheses) */ \
+ } \
+ namespace Glib { \
+ /** Return a Ganv::CPPType wrapper for a CType. */ \
+ static inline Ganv::Name* \
+ wrap(Ganv##Name* gobj) \
+ { \
+ if (gobj) { \
+ return static_cast<Ganv::Name*>(ganv_item_get_wrapper(GANV_ITEM(gobj))); \
+ } \
+ return nullptr; \
+ } \
+ /** Return a Ganv::CPPType wrapper for a CType. */ \
+ static inline const Ganv::Name* \
+ wrap(const Ganv##Name* gobj) \
+ { \
+ if (gobj) { \
+ return static_cast<const Ganv::Name*>(ganv_item_get_wrapper(GANV_ITEM(gobj))); \
+ } \
+ return nullptr; \
+ } \
+ }
+
+#endif // GANV_WRAP_HPP