aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-12-05 07:31:01 +0000
committerDavid Robillard <d@drobilla.net>2007-12-05 07:31:01 +0000
commitf673a148c7104b3aaee4b1332a3631ac15f5f769 (patch)
tree1939bcee973cc8a1feabccda4730d9ee379e7d0d
parent8e6c991346fbe7d578b02722fbe7f292c9747187 (diff)
downloadmachina-f673a148c7104b3aaee4b1332a3631ac15f5f769.tar.gz
machina-f673a148c7104b3aaee4b1332a3631ac15f5f769.tar.bz2
machina-f673a148c7104b3aaee4b1332a3631ac15f5f769.zip
Add preliminary mutation to machina (only random edge probability mutation so far).
git-svn-id: http://svn.drobilla.net/lad/machina@951 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--src/engine/Machine.cpp42
-rw-r--r--src/engine/MachineBuilder.cpp14
-rw-r--r--src/engine/MachineMutation.cpp55
-rw-r--r--src/engine/Makefile.am1
-rw-r--r--src/engine/Node.cpp36
-rw-r--r--src/engine/machina/Machine.hpp5
-rw-r--r--src/engine/machina/MachineMutation.hpp37
-rw-r--r--src/engine/machina/Makefile.am1
-rw-r--r--src/engine/machina/Node.hpp24
-rw-r--r--src/engine/machina/Schrodinbit.hpp45
-rw-r--r--src/gui/EdgeView.hpp2
-rw-r--r--src/gui/MachinaCanvas.cpp16
-rw-r--r--src/gui/MachinaCanvas.hpp1
-rw-r--r--src/gui/MachinaGUI.cpp35
-rw-r--r--src/gui/MachinaGUI.hpp10
-rw-r--r--src/gui/machina.glade407
16 files changed, 512 insertions, 219 deletions
diff --git a/src/engine/Machine.cpp b/src/engine/Machine.cpp
index 2033b5e..7a99b58 100644
--- a/src/engine/Machine.cpp
+++ b/src/engine/Machine.cpp
@@ -53,6 +53,34 @@ Machine::set_sink(SharedPtr<Raul::MIDISink> sink)
{
_sink = sink;
}
+
+
+/** Always returns a node, unless there are none */
+SharedPtr<Node>
+Machine::random_node()
+{
+ size_t i = rand() % _nodes.size();
+
+ // FIXME: O(n) worst case :(
+ for (Nodes::const_iterator n = _nodes.begin(); n != _nodes.end(); ++n, --i)
+ if (i == 0)
+ return *n;
+
+ return SharedPtr<Node>();
+}
+
+
+/** May return NULL even if edges exist (with low probability) */
+SharedPtr<Edge>
+Machine::random_edge()
+{
+ SharedPtr<Node> tail = random_node();
+
+ for (size_t i = 0; i < _nodes.size() && tail->edges().empty(); ++i)
+ tail = random_node();
+
+ return tail->random_edge();
+}
void
@@ -69,7 +97,7 @@ Machine::remove_node(SharedPtr<Node> node)
_nodes.erase(_nodes.find(node));
for (Nodes::const_iterator n = _nodes.begin(); n != _nodes.end(); ++n)
- (*n)->remove_outgoing_edges_to(node);
+ (*n)->remove_edges_to(node);
}
@@ -170,8 +198,8 @@ Machine::exit_node(SharedPtr<Raul::MIDISink> sink, const SharedPtr<Node> node)
const double rand_normal = rand() / (double)RAND_MAX; // [0, 1]
double range_min = 0;
- for (Node::Edges::const_iterator s = node->outgoing_edges().begin();
- s != node->outgoing_edges().end(); ++s) {
+ for (Node::Edges::const_iterator s = node->edges().begin();
+ s != node->edges().end(); ++s) {
if (!(*s)->head()->is_active()
&& rand_normal > range_min
@@ -187,8 +215,8 @@ Machine::exit_node(SharedPtr<Raul::MIDISink> sink, const SharedPtr<Node> node)
} else {
- for (Node::Edges::const_iterator s = node->outgoing_edges().begin();
- s != node->outgoing_edges().end(); ++s) {
+ for (Node::Edges::const_iterator s = node->edges().begin();
+ s != node->edges().end(); ++s) {
const double rand_normal = rand() / (double)RAND_MAX; // [0, 1]
@@ -328,8 +356,8 @@ Machine::write_state(Redland::Model& model)
for (Nodes::const_iterator n = _nodes.begin(); n != _nodes.end(); ++n) {
- for (Node::Edges::const_iterator e = (*n)->outgoing_edges().begin();
- e != (*n)->outgoing_edges().end(); ++e) {
+ for (Node::Edges::const_iterator e = (*n)->edges().begin();
+ e != (*n)->edges().end(); ++e) {
(*e)->write_state(model);
diff --git a/src/engine/MachineBuilder.cpp b/src/engine/MachineBuilder.cpp
index 1830ee6..fd53487 100644
--- a/src/engine/MachineBuilder.cpp
+++ b/src/engine/MachineBuilder.cpp
@@ -91,7 +91,7 @@ MachineBuilder::connect_nodes(SharedPtr<Machine> m,
SharedPtr<Node> delay_node;
- if (is_delay_node(tail) && tail->outgoing_edges().size() == 0) {
+ if (is_delay_node(tail) && tail->edges().size() == 0) {
// Tail is a delay node, just accumulate the time difference into it
set_node_duration(tail, tail->duration() + head_start_time - tail_end_time);
tail->add_outgoing_edge(SharedPtr<Edge>(new Edge(tail, head)));
@@ -133,7 +133,7 @@ MachineBuilder::event(Raul::BeatTime time_offset,
// Results in patterns closes to what a human would choose
if ( ! _poly_nodes.empty()) {
for (PolyList::iterator j = _poly_nodes.begin(); j != _poly_nodes.end(); ++j) {
- if (j->second->outgoing_edges().empty()) {
+ if (j->second->edges().empty()) {
this_connect_node = j->second;
this_connect_node_end_time = j->first + j->second->duration();
break;
@@ -194,7 +194,7 @@ MachineBuilder::event(Raul::BeatTime time_offset,
for (PolyList::iterator j = _poly_nodes.begin(); j != _poly_nodes.end(); ++j) {
_machine->add_node(j->second);
- if (j->second->outgoing_edges().size() == 0)
+ if (j->second->edges().size() == 0)
connect_nodes(_machine, j->second, j->first + j->second->duration(),
_connect_node, t);
}
@@ -207,11 +207,11 @@ MachineBuilder::event(Raul::BeatTime time_offset,
// Trim useless delay node if possible (these appear after poly sections)
if (is_delay_node(_connect_node) && _connect_node->duration() == 0
- && _connect_node->outgoing_edges().size() == 1
- && (*_connect_node->outgoing_edges().begin())->head() == resolved) {
+ && _connect_node->edges().size() == 1
+ && (*_connect_node->edges().begin())->head() == resolved) {
- _connect_node->outgoing_edges().clear();
- assert(_connect_node->outgoing_edges().empty());
+ _connect_node->edges().clear();
+ assert(_connect_node->edges().empty());
_connect_node->set_enter_action(resolved->enter_action());
_connect_node->set_exit_action(resolved->exit_action());
resolved->set_enter_action(SharedPtr<Action>());
diff --git a/src/engine/MachineMutation.cpp b/src/engine/MachineMutation.cpp
new file mode 100644
index 0000000..6e98ee0
--- /dev/null
+++ b/src/engine/MachineMutation.cpp
@@ -0,0 +1,55 @@
+/* This file is part of Machina.
+ * Copyright (C) 2007 Dave Robillard <http://drobilla.net>
+ *
+ * Machina is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * Machina 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <iostream>
+#include <cstdlib>
+#include "machina/Edge.hpp"
+#include "machina/Machine.hpp"
+#include "machina/MachineMutation.hpp"
+
+using namespace std;
+
+namespace Machina {
+namespace Mutation {
+
+
+void
+AddEdge::mutate(Machine& machine)
+{
+ cout << "ADD" << endl;
+}
+
+
+void
+RemoveEdge::mutate(Machine& machine)
+{
+ cout << "REMOVE" << endl;
+}
+
+
+void
+AdjustEdge::mutate(Machine& machine)
+{
+ SharedPtr<Edge> edge = machine.random_edge();
+ if (edge)
+ edge->set_probability(rand() / (float)RAND_MAX);
+}
+
+
+} // namespace Mutation
+} // namespace Machina
+
diff --git a/src/engine/Makefile.am b/src/engine/Makefile.am
index 5e291c7..010affa 100644
--- a/src/engine/Makefile.am
+++ b/src/engine/Makefile.am
@@ -10,6 +10,7 @@ libmachina_la_SOURCES = \
Edge.cpp \
Action.cpp \
Machine.cpp \
+ MachineMutation.cpp \
Loader.cpp \
MidiAction.cpp \
ActionFactory.cpp \
diff --git a/src/engine/Node.cpp b/src/engine/Node.cpp
index 5a1ca85..fd784e5 100644
--- a/src/engine/Node.cpp
+++ b/src/engine/Node.cpp
@@ -35,6 +35,28 @@ Node::Node(BeatCount duration, bool initial)
}
+/** Always returns an edge, unless there are none */
+SharedPtr<Edge>
+Node::random_edge()
+{
+ SharedPtr<Edge> ret;
+ if (_edges.empty())
+ return ret;
+
+ size_t i = rand() % _edges.size();
+
+ // FIXME: O(n) worst case :(
+ for (Edges::const_iterator e = _edges.begin(); e != _edges.end(); ++e, --i) {
+ if (i == 0) {
+ ret = *e;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+
void
Node::set_selector(bool yn)
{
@@ -42,10 +64,10 @@ Node::set_selector(bool yn)
if (yn) {
double prob_sum = 0;
- for (Edges::iterator i = _outgoing_edges.begin(); i != _outgoing_edges.end(); ++i)
+ for (Edges::iterator i = _edges.begin(); i != _edges.end(); ++i)
prob_sum += (*i)->probability();
- for (Edges::iterator i = _outgoing_edges.begin(); i != _outgoing_edges.end(); ++i)
+ for (Edges::iterator i = _edges.begin(); i != _edges.end(); ++i)
(*i)->set_probability((*i)->probability() / prob_sum);
}
_changed = true;
@@ -101,26 +123,26 @@ Node::add_outgoing_edge(SharedPtr<Edge> edge)
{
assert(edge->tail().lock().get() == this);
- _outgoing_edges.push_back(edge);
+ _edges.push_back(edge);
}
void
Node::remove_outgoing_edge(SharedPtr<Edge> edge)
{
- _outgoing_edges.erase(_outgoing_edges.find(edge));
+ _edges.erase(_edges.find(edge));
}
void
-Node::remove_outgoing_edges_to(SharedPtr<Node> node)
+Node::remove_edges_to(SharedPtr<Node> node)
{
- for (Edges::iterator i = _outgoing_edges.begin(); i != _outgoing_edges.end() ; ) {
+ for (Edges::iterator i = _edges.begin(); i != _edges.end() ; ) {
Edges::iterator next = i;
++next;
if ((*i)->head() == node)
- _outgoing_edges.erase(i);
+ _edges.erase(i);
i = next;
}
diff --git a/src/engine/machina/Machine.hpp b/src/engine/machina/Machine.hpp
index 626ef10..889dc1a 100644
--- a/src/engine/machina/Machine.hpp
+++ b/src/engine/machina/Machine.hpp
@@ -61,9 +61,12 @@ public:
SharedPtr<LearnRequest> pending_learn() { return _pending_learn; }
void clear_pending_learn() { _pending_learn.reset(); }
- typedef Raul::List<SharedPtr<Node> > Nodes;
+ typedef Raul::List< SharedPtr<Node> > Nodes;
Nodes& nodes() { return _nodes; }
+ SharedPtr<Node> random_node();
+ SharedPtr<Edge> random_edge();
+
void set_sink(SharedPtr<Raul::MIDISink> sink);
private:
diff --git a/src/engine/machina/MachineMutation.hpp b/src/engine/machina/MachineMutation.hpp
new file mode 100644
index 0000000..34eda30
--- /dev/null
+++ b/src/engine/machina/MachineMutation.hpp
@@ -0,0 +1,37 @@
+/* This file is part of Machina.
+ * Copyright (C) 2007 Dave Robillard <http://drobilla.net>
+ *
+ * Machina is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * Machina 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef MACHINA_MACHINE_MUTATION_HPP
+#define MACHINA_MACHINE_MUTATION_HPP
+
+namespace Machina {
+
+class Machine;
+
+namespace Mutation {
+
+struct Mutation { virtual void mutate(Machine& machine) = 0; };
+
+struct AddEdge { static void mutate(Machine& machine); };
+struct RemoveEdge { static void mutate(Machine& machine); };
+struct AdjustEdge { static void mutate(Machine& machine); };
+
+} // namespace Mutation
+
+} // namespace Machina
+
+#endif // MACHINA_MACHINE_MUTATION_HPP
diff --git a/src/engine/machina/Makefile.am b/src/engine/machina/Makefile.am
index 65ea295..de99845 100644
--- a/src/engine/machina/Makefile.am
+++ b/src/engine/machina/Makefile.am
@@ -11,6 +11,7 @@ libmachinainclude_HEADERS = \
Loader.hpp \
Machine.hpp \
MachineBuilder.hpp \
+ MachineMutation.hpp \
MidiAction.hpp \
Node.hpp \
Recorder.hpp \
diff --git a/src/engine/machina/Node.hpp b/src/engine/machina/Node.hpp
index 041f443..a916eb6 100644
--- a/src/engine/machina/Node.hpp
+++ b/src/engine/machina/Node.hpp
@@ -24,6 +24,7 @@
#include <raul/Stateful.hpp>
#include <raul/MIDISink.hpp>
#include "Action.hpp"
+#include "Schrodinbit.hpp"
namespace Machina {
@@ -57,7 +58,7 @@ public:
void add_outgoing_edge(SharedPtr<Edge> edge);
void remove_outgoing_edge(SharedPtr<Edge> edge);
- void remove_outgoing_edges_to(SharedPtr<Node> node);
+ void remove_edges_to(SharedPtr<Node> node);
void write_state(Redland::Model& model);
@@ -71,23 +72,16 @@ public:
bool is_selector() const { return _is_selector; }
void set_selector(bool i);
- /// Schroedinger's flag
- inline bool changed() {
- if (_changed) {
- _changed = false;
- return true;
- } else {
- return false;
- }
- }
-
- void set_changed() { _changed = true; }
+ inline bool changed() { return _changed; }
+ inline void set_changed() { _changed = true; }
typedef Raul::List<SharedPtr<Edge> > Edges;
- Edges& outgoing_edges() { return _outgoing_edges; }
+ Edges& edges() { return _edges; }
+
+ SharedPtr<Edge> random_edge();
private:
- bool _changed;
+ Schrodinbit _changed;
bool _is_initial;
bool _is_selector;
bool _is_active;
@@ -95,7 +89,7 @@ private:
BeatCount _duration;
SharedPtr<Action> _enter_action;
SharedPtr<Action> _exit_action;
- Edges _outgoing_edges;
+ Edges _edges;
};
diff --git a/src/engine/machina/Schrodinbit.hpp b/src/engine/machina/Schrodinbit.hpp
new file mode 100644
index 0000000..6065cfc
--- /dev/null
+++ b/src/engine/machina/Schrodinbit.hpp
@@ -0,0 +1,45 @@
+/* This file is part of Machina.
+ * Copyright (C) 2007 Dave Robillard <http://drobilla.net>
+ *
+ * Machina is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * Machina 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef SCHRODINBIT_HPP
+#define SCHRODINBIT_HPP
+
+
+/** A flag which becomes false when it's value is observed
+ */
+class Schrodinbit {
+public:
+ Schrodinbit() : _flag(false) {}
+
+ inline operator bool() {
+ const bool ret = _flag;
+ _flag = false;
+ return ret;
+ }
+
+ inline bool operator=(bool flag) {
+ _flag = flag;
+ return flag;
+ }
+
+private:
+ bool _flag;
+};
+
+
+#endif // SCHRODINBIT_HPP
+
diff --git a/src/gui/EdgeView.hpp b/src/gui/EdgeView.hpp
index 2555e4a..2b04324 100644
--- a/src/gui/EdgeView.hpp
+++ b/src/gui/EdgeView.hpp
@@ -34,11 +34,11 @@ public:
SharedPtr<Machina::Edge> edge() { return _edge; }
void show_label(bool show);
+ void update();
virtual double length_hint() const;
private:
- void update();
bool on_event(GdkEvent* ev);
SharedPtr<Machina::Edge> _edge;
diff --git a/src/gui/MachinaCanvas.cpp b/src/gui/MachinaCanvas.cpp
index e899a64..8ed9e40 100644
--- a/src/gui/MachinaCanvas.cpp
+++ b/src/gui/MachinaCanvas.cpp
@@ -131,7 +131,7 @@ void
MachinaCanvas::disconnect_node(boost::shared_ptr<NodeView> src,
boost::shared_ptr<NodeView> head)
{
- src->node()->remove_outgoing_edges_to(head->node());
+ src->node()->remove_edges_to(head->node());
remove_connection(src, head);
}
@@ -177,8 +177,8 @@ MachinaCanvas::build(SharedPtr<Machina::Machine> machine)
if (!view)
continue;
- for (Machina::Node::Edges::const_iterator e = view->node()->outgoing_edges().begin();
- e != view->node()->outgoing_edges().end(); ++e) {
+ for (Machina::Node::Edges::const_iterator e = view->node()->edges().begin();
+ e != view->node()->edges().end(); ++e) {
SharedPtr<NodeView> head_view = views[(*e)->head()];
if (!head_view) {
@@ -201,3 +201,13 @@ MachinaCanvas::build(SharedPtr<Machina::Machine> machine)
}
+void
+MachinaCanvas::update_edges()
+{
+ for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
+ SharedPtr<EdgeView> edge = PtrCast<EdgeView>(*i);
+ if (edge)
+ edge->update();
+ }
+}
+
diff --git a/src/gui/MachinaCanvas.hpp b/src/gui/MachinaCanvas.hpp
index 63c88fd..631957e 100644
--- a/src/gui/MachinaCanvas.hpp
+++ b/src/gui/MachinaCanvas.hpp
@@ -41,6 +41,7 @@ public:
SharedPtr<NodeView> port2);
void build(SharedPtr<Machina::Machine> machine);
+ void update_edges();
ArtVpathDash* selector_dash() { return _selector_dash; }
diff --git a/src/gui/MachinaGUI.cpp b/src/gui/MachinaGUI.cpp
index 2e383ec..6c94211 100644
--- a/src/gui/MachinaGUI.cpp
+++ b/src/gui/MachinaGUI.cpp
@@ -24,6 +24,7 @@
#include <libglademm/xml.h>
#include <redlandmm/Model.hpp>
#include <machina/Machine.hpp>
+#include <machina/MachineMutation.hpp>
#include <machina/SMFDriver.hpp>
#include "GladeXml.hpp"
#include "MachinaGUI.hpp"
@@ -31,6 +32,8 @@
#include "NodeView.hpp"
#include "EdgeView.hpp"
+using namespace Machina;
+
MachinaGUI::MachinaGUI(SharedPtr<Machina::Engine> engine)
: _refresh(false),
@@ -69,6 +72,9 @@ MachinaGUI::MachinaGUI(SharedPtr<Machina::Engine> engine)
xml->get_widget("zoom_normal_but", _zoom_normal_button);
xml->get_widget("zoom_full_but", _zoom_full_button);
xml->get_widget("arrange_but", _arrange_button);
+ xml->get_widget("add_edge_but", _add_edge_button);
+ xml->get_widget("remove_edge_but", _remove_edge_button);
+ xml->get_widget("adjust_edge_but", _adjust_edge_button);
_canvas_scrolledwindow->add(*_canvas);
_canvas_scrolledwindow->signal_event().connect(sigc::mem_fun(this,
@@ -121,6 +127,13 @@ MachinaGUI::MachinaGUI(SharedPtr<Machina::Engine> engine)
sigc::mem_fun(this, &MachinaGUI::quantize_changed));
_quantize_spinbutton->signal_changed().connect(
sigc::mem_fun(this, &MachinaGUI::quantize_changed));
+
+ _add_edge_button->signal_clicked().connect(
+ sigc::mem_fun(this, &MachinaGUI::add_edge));
+ _remove_edge_button->signal_clicked().connect(
+ sigc::mem_fun(this, &MachinaGUI::remove_edge));
+ _adjust_edge_button->signal_clicked().connect(
+ sigc::mem_fun(this, &MachinaGUI::adjust_edge));
connect_widgets();
@@ -198,6 +211,28 @@ MachinaGUI::arrange()
_canvas->arrange(_menu_view_time_edges->get_active());
}
+
+void
+MachinaGUI::add_edge()
+{
+ Mutation::AddEdge::mutate(*_engine->machine().get());
+}
+
+
+void
+MachinaGUI::remove_edge()
+{
+ Mutation::RemoveEdge::mutate(*_engine->machine().get());
+}
+
+
+void
+MachinaGUI::adjust_edge()
+{
+ Mutation::AdjustEdge::mutate(*_engine->machine().get());
+ _canvas->update_edges();
+}
+
void
MachinaGUI::update_toolbar()
diff --git a/src/gui/MachinaGUI.hpp b/src/gui/MachinaGUI.hpp
index 4b82ff3..cc1eee3 100644
--- a/src/gui/MachinaGUI.hpp
+++ b/src/gui/MachinaGUI.hpp
@@ -62,10 +62,13 @@ protected:
void show_labels_toggled();
void menu_help_about();
void menu_help_help();
+ void arrange();
+ void add_edge();
+ void remove_edge();
+ void adjust_edge();
void zoom(double z);
- bool idle_callback();
void update_toolbar();
- void arrange();
+ bool idle_callback();
bool scrolled_window_event(GdkEvent* ev);
void record_toggled();
@@ -116,6 +119,9 @@ protected:
Gtk::ToolButton* _zoom_normal_button;
Gtk::ToolButton* _zoom_full_button;
Gtk::ToolButton* _arrange_button;
+ Gtk::ToolButton* _add_edge_button;
+ Gtk::ToolButton* _remove_edge_button;
+ Gtk::ToolButton* _adjust_edge_button;
};
#endif // MACHINA_GUI_H
diff --git a/src/gui/machina.glade b/src/gui/machina.glade
index f892894..11f3e7c 100644
--- a/src/gui/machina.glade
+++ b/src/gui/machina.glade
@@ -207,86 +207,72 @@
</packing>
</child>
<child>
- <widget class="GtkToolbar" id="toolbar">
+ <widget class="GtkHBox" id="hbox2">
<property name="visible">True</property>
- <property name="toolbar_style">GTK_TOOLBAR_BOTH_HORIZ</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
- <widget class="GtkToggleToolButton" id="record_but">
- <property name="visible">True</property>
- <property name="tooltip" translatable="yes">Record</property>
- <property name="stock_id">gtk-media-record</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkToolButton" id="stop_but">
- <property name="visible">True</property>
- <property name="tooltip" translatable="yes">Stop playback or recording</property>
- <property name="stock_id">gtk-media-stop</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkToggleToolButton" id="play_but">
- <property name="visible">True</property>
- <property name="tooltip" translatable="yes">Play</property>
- <property name="stock_id">gtk-media-play</property>
- <property name="active">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkSeparatorToolItem" id="separatortoolitem4">
- <property name="visible">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkToolItem" id="toolitem1">
+ <widget class="GtkToolbar" id="toolbar">
<property name="visible">True</property>
+ <property name="toolbar_style">GTK_TOOLBAR_BOTH_HORIZ</property>
+ <property name="show_arrow">False</property>
<child>
- <widget class="GtkHBox" id="hbox1">
+ <widget class="GtkToggleToolButton" id="record_but">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Record</property>
+ <property name="stock_id">gtk-media-record</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolButton" id="stop_but">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Stop playback or recording</property>
+ <property name="stock_id">gtk-media-stop</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToggleToolButton" id="play_but">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Play</property>
+ <property name="stock_id">gtk-media-play</property>
+ <property name="active">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSeparatorToolItem" id="separatortoolitem4">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolItem" id="toolitem1">
<property name="visible">True</property>
- <property name="border_width">4</property>
- <property name="spacing">6</property>
- <child>
- <widget class="GtkRadioButton" id="slave_radiobutton">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="tooltip" translatable="yes">Slave to JACK transport</property>
- <property name="label" translatable="yes">Slave</property>
- <property name="use_underline">True</property>
- <property name="response_id">0</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
<child>
- <widget class="GtkHBox" id="hbox3">
+ <widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
+ <property name="border_width">4</property>
+ <property name="spacing">6</property>
<child>
- <widget class="GtkRadioButton" id="bpm_radiobutton">
+ <widget class="GtkRadioButton" id="slave_radiobutton">
<property name="visible">True</property>
+ <property name="sensitive">False</property>
<property name="can_focus">True</property>
- <property name="tooltip" translatable="yes">Use internal tempo</property>
+ <property name="tooltip" translatable="yes">Slave to JACK transport</property>
+ <property name="label" translatable="yes">Slave</property>
<property name="use_underline">True</property>
<property name="response_id">0</property>
- <property name="active">True</property>
<property name="draw_indicator">True</property>
- <property name="group">slave_radiobutton</property>
</widget>
<packing>
<property name="expand">False</property>
@@ -294,135 +280,204 @@
</packing>
</child>
<child>
- <widget class="GtkSpinButton" id="bpm_spinbutton">
+ <widget class="GtkHBox" id="hbox3">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="tooltip" translatable="yes">Set internal tempo</property>
- <property name="adjustment">120 1 640 1 10 10</property>
- <property name="climb_rate">1</property>
+ <child>
+ <widget class="GtkRadioButton" id="bpm_radiobutton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip" translatable="yes">Use internal tempo</property>
+ <property name="use_underline">True</property>
+ <property name="response_id">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">slave_radiobutton</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSpinButton" id="bpm_spinbutton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip" translatable="yes">Set internal tempo</property>
+ <property name="adjustment">120 1 640 1 10 10</property>
+ <property name="climb_rate">1</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"> BPM</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSeparatorToolItem" id="separatortoolitem2">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolItem" id="toolitem3">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkHBox" id="hbox4">
+ <property name="visible">True</property>
+ <property name="border_width">4</property>
<child>
- <widget class="GtkLabel" id="label8">
+ <widget class="GtkCheckButton" id="quantize_checkbutton">
<property name="visible">True</property>
- <property name="label" translatable="yes"> BPM</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip" translatable="yes">Quantize recording</property>
+ <property name="label" translatable="yes">Quantize: 1/</property>
+ <property name="use_underline">True</property>
+ <property name="response_id">0</property>
+ <property name="draw_indicator">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
- <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSpinButton" id="quantize_spinbutton">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">1 1 99 1 4 4</property>
+ <property name="climb_rate">1</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
</packing>
</child>
</widget>
- <packing>
- <property name="position">1</property>
- </packing>
</child>
</widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">False</property>
+ </packing>
</child>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkSeparatorToolItem" id="separatortoolitem2">
- <property name="visible">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkToolItem" id="toolitem3">
- <property name="visible">True</property>
<child>
- <widget class="GtkHBox" id="hbox4">
+ <widget class="GtkSeparatorToolItem" id="separatortoolitem3">
<property name="visible">True</property>
- <property name="border_width">4</property>
- <child>
- <widget class="GtkCheckButton" id="quantize_checkbutton">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="tooltip" translatable="yes">Quantize recording</property>
- <property name="label" translatable="yes">Quantize: 1/</property>
- <property name="use_underline">True</property>
- <property name="response_id">0</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkSpinButton" id="quantize_spinbutton">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="adjustment">1 1 99 1 4 4</property>
- <property name="climb_rate">1</property>
- </widget>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
</widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolButton" id="zoom_normal_but">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Zoom to normal size</property>
+ <property name="stock_id">gtk-zoom-100</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolButton" id="zoom_full_but">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Zoom to fit entire machine</property>
+ <property name="stock_id">gtk-zoom-fit</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolButton" id="arrange_but">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Automatically arrange nodes</property>
+ <property name="stock_id">gtk-refresh</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
</child>
</widget>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkSeparatorToolItem" id="separatortoolitem3">
- <property name="visible">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkToolButton" id="zoom_normal_but">
- <property name="visible">True</property>
- <property name="tooltip" translatable="yes">Zoom to normal size</property>
- <property name="stock_id">gtk-zoom-100</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- </packing>
- </child>
- <child>
- <widget class="GtkToolButton" id="zoom_full_but">
- <property name="visible">True</property>
- <property name="tooltip" translatable="yes">Zoom to fit entire machine</property>
- <property name="stock_id">gtk-zoom-fit</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- </packing>
</child>
<child>
- <widget class="GtkToolButton" id="arrange_but">
+ <widget class="GtkToolbar" id="toolbar1">
<property name="visible">True</property>
- <property name="tooltip" translatable="yes">Automatically arrange nodes</property>
- <property name="stock_id">gtk-refresh</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="show_arrow">False</property>
+ <property name="icon_size">GTK_ICON_SIZE_SMALL_TOOLBAR</property>
+ <property name="icon_size_set">True</property>
+ <child>
+ <widget class="GtkToolButton" id="add_edge_but">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip" translatable="yes">Add random edge</property>
+ <property name="label" translatable="yes">Add Edge</property>
+ <property name="stock_id">gtk-add</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolButton" id="remove_edge_but">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip" translatable="yes">Remove random edge</property>
+ <property name="label" translatable="yes">Remove Edge</property>
+ <property name="stock_id">gtk-remove</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolButton" id="adjust_edge_but">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip" translatable="yes">Adjust random edge probability</property>
+ <property name="label" translatable="yes">Mutate Edge Probabililty</property>
+ <property name="stock_id">gtk-edit</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="expand">False</property>
+ <property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
- <property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
@@ -559,58 +614,58 @@ Selector nodes are shown in green.
<property name="column_spacing">4</property>
<property name="row_spacing">8</property>
<child>
- <widget class="GtkSpinButton" id="node_properties_note_spinbutton">
+ <widget class="GtkSpinButton" id="node_properties_duration_spinbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="adjustment">60 0 127 1 10 10</property>
+ <property name="has_focus">True</property>
+ <property name="adjustment">1 0 999999 1 10 10</property>
<property name="climb_rate">1</property>
+ <property name="digits">2</property>
<property name="numeric">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="label6">
+ <widget class="GtkLabel" id="label7">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">Note: </property>
+ <property name="label" translatable="yes">Duration: </property>
</widget>
<packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
- <widget class="GtkLabel" id="label7">
+ <widget class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">Duration: </property>
+ <property name="label" translatable="yes">Note: </property>
</widget>
<packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
- <widget class="GtkSpinButton" id="node_properties_duration_spinbutton">
+ <widget class="GtkSpinButton" id="node_properties_note_spinbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="has_focus">True</property>
- <property name="adjustment">1 0 999999 1 10 10</property>
+ <property name="adjustment">60 0 127 1 10 10</property>
<property name="climb_rate">1</property>
- <property name="digits">2</property>
<property name="numeric">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>