aboutsummaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2011-01-10 21:23:14 +0000
committerDavid Robillard <d@drobilla.net>2011-01-10 21:23:14 +0000
commitf293da6bc4f0f631c086d35666e3e8bfef19b8f2 (patch)
treed0e693bdec5e4a53daca500434533d2fc5c43650 /src/gui
parentdb319f5a8cb7915b2d5b93adab148fa16d92e7e5 (diff)
downloadmachina-f293da6bc4f0f631c086d35666e3e8bfef19b8f2.tar.gz
machina-f293da6bc4f0f631c086d35666e3e8bfef19b8f2.tar.bz2
machina-f293da6bc4f0f631c086d35666e3e8bfef19b8f2.zip
Rewrite with UI/engine split.
Note some things aren't quite working right again yet... git-svn-id: http://svn.drobilla.net/lad/trunk/machina@2821 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/EdgeView.cpp64
-rw-r--r--src/gui/EdgeView.hpp30
-rw-r--r--src/gui/GladeXml.hpp3
-rw-r--r--src/gui/MachinaCanvas.cpp192
-rw-r--r--src/gui/MachinaCanvas.hpp30
-rw-r--r--src/gui/MachinaGUI.cpp86
-rw-r--r--src/gui/MachinaGUI.hpp36
-rw-r--r--src/gui/NodePropertiesWindow.cpp20
-rw-r--r--src/gui/NodePropertiesWindow.hpp18
-rw-r--r--src/gui/NodeView.cpp130
-rw-r--r--src/gui/NodeView.hpp42
-rw-r--r--src/gui/main.cpp4
-rw-r--r--src/gui/wscript4
13 files changed, 371 insertions, 288 deletions
diff --git a/src/gui/EdgeView.cpp b/src/gui/EdgeView.cpp
index 51b94be..725d685 100644
--- a/src/gui/EdgeView.cpp
+++ b/src/gui/EdgeView.cpp
@@ -15,13 +15,17 @@
* along with Machina. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <iomanip>
-#include <sstream>
#include "flowcanvas/Canvas.hpp"
-#include "machina/Edge.hpp"
+
+#include "machina/Controller.hpp"
+#include "machina/types.hpp"
+
#include "EdgeView.hpp"
+#include "MachinaCanvas.hpp"
+#include "MachinaGUI.hpp"
#include "NodeView.hpp"
+using Machina::URIs;
/* probability colour stuff */
@@ -59,61 +63,73 @@ inline static uint32_t edge_color(float prob)
using namespace FlowCanvas;
-EdgeView::EdgeView(SharedPtr<Canvas> canvas,
- SharedPtr<NodeView> src,
- SharedPtr<NodeView> dst,
- SharedPtr<Machina::Edge> edge)
+EdgeView::EdgeView(SharedPtr<Canvas> canvas,
+ SharedPtr<NodeView> src,
+ SharedPtr<NodeView> dst,
+ SharedPtr<Machina::Client::ClientObject> edge)
: FlowCanvas::Connection(canvas, src, dst, 0x9FA0A0F4, true)
, _edge(edge)
{
- set_color(edge_color(_edge->probability()));
+ set_color(edge_color(probability()));
set_handle_style(HANDLE_CIRCLE);
show_handle(true);
+
+ edge->signal_property.connect(
+ sigc::mem_fun(this, &EdgeView::on_property));
}
-double
-EdgeView::length_hint() const
+float
+EdgeView::probability() const
{
- return _edge->tail().lock()->duration().ticks() * 10;
+ return _edge->get(URIs::instance().machina_probability).get_float();
}
-void
-EdgeView::show_label(bool show)
+double
+EdgeView::length_hint() const
{
- show_handle(show);
- set_color(edge_color(_edge->probability()));
+ SharedPtr<NodeView> tail = PtrCast<NodeView>(source().lock());
+ return tail->node()->get(URIs::instance().machina_duration).get_float() * 10.0;
}
void
-EdgeView::update()
+EdgeView::show_label(bool show)
{
- if (_handle)
- show_handle(true);
- set_color(edge_color(_edge->probability()));
+ show_handle(show);
+ set_color(edge_color(probability()));
}
bool
EdgeView::on_event(GdkEvent* ev)
{
+ SharedPtr<MachinaCanvas> canvas = PtrCast<MachinaCanvas>(_canvas.lock());
if (ev->type == GDK_BUTTON_PRESS) {
if (ev->button.state & GDK_CONTROL_MASK) {
if (ev->button.button == 1) {
- _edge->set_probability(_edge->probability() - 0.1);
- update();
+ canvas->app()->controller()->set_property(
+ _edge->id(),
+ URIs::instance().machina_probability,
+ Raul::Atom(probability() - 0.1f));
return true;
} else if (ev->button.button == 3) {
- _edge->set_probability(_edge->probability() + 0.1);
- update();
+ canvas->app()->controller()->set_property(
+ _edge->id(),
+ URIs::instance().machina_probability,
+ Raul::Atom(probability() + 0.1f));
return true;
}
}
}
-
return false;
}
+void
+EdgeView::on_property(Machina::URIInt key, const Raul::Atom& value)
+{
+ if (key == URIs::instance().machina_probability)
+ set_color(edge_color(value.get_float()));
+}
diff --git a/src/gui/EdgeView.hpp b/src/gui/EdgeView.hpp
index ea49b27..d9ffe71 100644
--- a/src/gui/EdgeView.hpp
+++ b/src/gui/EdgeView.hpp
@@ -15,32 +15,38 @@
* along with Machina. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef MACHINA_EDGEVIEW_H
-#define MACHINA_EDGEVIEW_H
+#ifndef MACHINA_EDGEVIEW_HPP
+#define MACHINA_EDGEVIEW_HPP
#include "flowcanvas/Connection.hpp"
-namespace Machina { class Edge; }
-class NodeView;
+#include "client/ClientObject.hpp"
+
+#include "machina/types.hpp"
+class NodeView;
-class EdgeView : public FlowCanvas::Connection {
+class EdgeView
+ : public FlowCanvas::Connection
+ , public Machina::Client::ClientObject::View {
public:
- EdgeView(SharedPtr<FlowCanvas::Canvas> canvas,
- SharedPtr<NodeView> src,
- SharedPtr<NodeView> dst,
- SharedPtr<Machina::Edge> edge);
+ EdgeView(SharedPtr<FlowCanvas::Canvas> canvas,
+ SharedPtr<NodeView> src,
+ SharedPtr<NodeView> dst,
+ SharedPtr<Machina::Client::ClientObject> edge);
void show_label(bool show);
- void update();
virtual double length_hint() const;
private:
bool on_event(GdkEvent* ev);
+ void on_property(Machina::URIInt key, const Raul::Atom& value);
+
+ float probability() const;
- SharedPtr<Machina::Edge> _edge;
+ SharedPtr<Machina::Client::ClientObject> _edge;
};
-#endif // MACHINA_EDGEVIEW_H
+#endif // MACHINA_EDGEVIEW_HPP
diff --git a/src/gui/GladeXml.hpp b/src/gui/GladeXml.hpp
index 36223db..cb54806 100644
--- a/src/gui/GladeXml.hpp
+++ b/src/gui/GladeXml.hpp
@@ -16,9 +16,12 @@
*/
#include <fstream>
+#include <iostream>
#include <string>
+
#include <gtkmm.h>
#include <libglademm/xml.h>
+
#include "machina-config.h"
class GladeXml
diff --git a/src/gui/MachinaCanvas.cpp b/src/gui/MachinaCanvas.cpp
index 3cf3e28..d3e42bf 100644
--- a/src/gui/MachinaCanvas.cpp
+++ b/src/gui/MachinaCanvas.cpp
@@ -17,14 +17,14 @@
#include <map>
+#include "raul/log.hpp"
#include "raul/SharedPtr.hpp"
#include "raul/TimeStamp.hpp"
-#include "machina/Action.hpp"
-#include "machina/Edge.hpp"
#include "machina/Engine.hpp"
-#include "machina/Machine.hpp"
-#include "machina/Node.hpp"
+#include "machina/Controller.hpp"
+#include "client/ClientObject.hpp"
+#include "client/ClientModel.hpp"
#include "EdgeView.hpp"
#include "MachinaCanvas.hpp"
@@ -33,7 +33,7 @@
using namespace Raul;
using namespace FlowCanvas;
-
+using namespace Machina;
MachinaCanvas::MachinaCanvas(MachinaGUI* app, int width, int height)
: Canvas(width, height)
@@ -43,7 +43,6 @@ MachinaCanvas::MachinaCanvas(MachinaGUI* app, int width, int height)
grab_focus();
}
-
void
MachinaCanvas::node_clicked(WeakPtr<NodeView> item, GdkEventButton* event)
{
@@ -54,19 +53,19 @@ MachinaCanvas::node_clicked(WeakPtr<NodeView> item, GdkEventButton* event)
if (event->state & GDK_CONTROL_MASK)
return;
- // Middle click, learn
- if (event->button == 2) {
- _app->engine()->machine()->learn(_app->maid(), node->node());
+ if (event->button == 2) { // Middle click: learn
+ _app->controller()->learn(_app->maid(), node->node()->id());
return;
- } else if (event->button == 3) {
+
+ } else if (event->button == 3) { // Right click: connect/disconnect
SharedPtr<NodeView> last = _last_clicked.lock();
if (last) {
if (node != last) {
if (get_connection(last, node))
- disconnect_node(last, node);
+ action_disconnect(last, node);
else
- connect_node(last, node);
+ action_connect(last, node);
}
last->set_default_base_color();
@@ -79,38 +78,14 @@ MachinaCanvas::node_clicked(WeakPtr<NodeView> item, GdkEventButton* event)
}
}
-
bool
MachinaCanvas::canvas_event(GdkEvent* event)
{
- static int last = 0;
-
- SharedPtr<Machina::Machine> machine = _app->engine()->machine();
- if (!machine)
- return false;
-
if (event->type == GDK_BUTTON_RELEASE
&& event->button.button == 3
&& !(event->button.state & (GDK_CONTROL_MASK))) {
- const double x = event->button.x;
- const double y = event->button.y;
-
- string name = string("Note")+(char)(last++ +'0');
-
- TimeDuration dur(machine->time().unit(), 1.0);
- SharedPtr<Machina::Node> node(new Machina::Node(dur, false));
- SharedPtr<NodeView> view(new NodeView(_app->window(), shared_from_this(), node,
- name, x, y));
-
- view->signal_clicked.connect(sigc::bind<0>(sigc::mem_fun(this,
- &MachinaCanvas::node_clicked), WeakPtr<NodeView>(view)));
- add_item(view);
- view->resize();
- view->raise_to_top();
-
- machine->add_node(node);
-
+ action_create_node(event->button.x, event->button.y);
return true;
} else {
@@ -118,101 +93,90 @@ MachinaCanvas::canvas_event(GdkEvent* event)
}
}
-
-void
-MachinaCanvas::connect_node(boost::shared_ptr<NodeView> src,
- boost::shared_ptr<NodeView> head)
-{
- SharedPtr<Machina::Edge> edge(new Machina::Edge(src->node(), head->node()));
- src->node()->add_edge(edge);
-
- boost::shared_ptr<Connection> c(new EdgeView(shared_from_this(),
- src, head, edge));
- src->add_connection(c);
- head->add_connection(c);
- add_connection(c);
-}
-
-
void
-MachinaCanvas::disconnect_node(boost::shared_ptr<NodeView> src,
- boost::shared_ptr<NodeView> head)
+MachinaCanvas::on_new_object(SharedPtr<Client::ClientObject> object)
{
- src->node()->remove_edges_to(head->node());
- remove_connection(src, head);
-}
+ const Machina::URIs& uris = URIs::instance();
+ const Raul::Atom& type = object->get(uris.rdf_type);
+ if (type == "machina:Node") {
+ SharedPtr<NodeView> view(
+ new NodeView(_app->window(), shared_from_this(), object,
+ object->get(uris.machina_canvas_x).get_float(),
+ object->get(uris.machina_canvas_y).get_float()));
+
+ //if ( ! node->enter_action() && ! node->exit_action() )
+ // view->set_base_color(0x101010FF);
+
+ view->signal_clicked.connect(
+ sigc::bind<0>(sigc::mem_fun(this, &MachinaCanvas::node_clicked),
+ WeakPtr<NodeView>(view)));
+
+ object->set_view(view);
+ add_item(view);
+ } else if (type == "machina:Edge") {
+ SharedPtr<Machina::Client::ClientObject> tail = _app->client_model()->find(
+ object->get(uris.machina_tail_id).get_int32());
+ SharedPtr<Machina::Client::ClientObject> head = _app->client_model()->find(
+ object->get(uris.machina_head_id).get_int32());
-SharedPtr<NodeView>
-MachinaCanvas::create_node_view(SharedPtr<Machina::Node> node)
-{
- SharedPtr<NodeView> view(new NodeView(_app->window(), shared_from_this(), node,
- "", 10, 10));
+ SharedPtr<NodeView> tail_view = PtrCast<NodeView>(tail->view());
+ SharedPtr<NodeView> head_view = PtrCast<NodeView>(head->view());
- if ( ! node->enter_action() && ! node->exit_action() )
- view->set_base_color(0x101010FF);
+ SharedPtr<EdgeView> view(
+ new EdgeView(shared_from_this(), tail_view, head_view, object));
- view->signal_clicked.connect(sigc::bind<0>(sigc::mem_fun(this,
- &MachinaCanvas::node_clicked), WeakPtr<NodeView>(view)));
+ tail_view->add_connection(view);
+ head_view->add_connection(view);
- add_item(view);
+ object->set_view(view);
+ add_connection(view);
- return view;
+ } else {
+ Raul::error << "Unknown object type " << type << std::endl;
+ }
}
-
void
-MachinaCanvas::build(SharedPtr<const Machina::Machine> machine, bool show_labels)
+MachinaCanvas::on_erase_object(SharedPtr<Client::ClientObject> object)
{
- destroy();
- _last_clicked.reset();
- assert(_items.empty());
-
- if (!machine)
- return;
-
- std::map<SharedPtr<Machina::Node>, SharedPtr<NodeView> > views;
-
- for (Machina::Machine::Nodes::const_iterator i = machine->nodes().begin();
- i != machine->nodes().end(); ++i) {
-
- const SharedPtr<NodeView> view = create_node_view(*i);
- views.insert(std::make_pair((*i), view));
- }
-
- for (ItemList::iterator i = _items.begin(); i != _items.end(); ++i) {
- const SharedPtr<NodeView> view = PtrCast<NodeView>(*i);
- if (!view)
- continue;
-
- 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) {
- cerr << "WARNING: Edge to node with no view" << endl;
- continue;
- }
-
- boost::shared_ptr<Connection> c(new EdgeView(shared_from_this(),
- view, head_view, (*e)));
- view->add_connection(c);
- head_view->add_connection(c);
- add_connection(c);
+ const Raul::Atom& type = object->get(URIs::instance().rdf_type);
+ if (type == "machina:Node") {
+ SharedPtr<NodeView> view = PtrCast<NodeView>(object->view());
+ if (view) {
+ remove_item(view);
+ }
+ } else if (type == "machina:Edge") {
+ SharedPtr<EdgeView> view = PtrCast<EdgeView>(object->view());
+ if (view) {
+ remove_connection(view->source().lock(), view->dest().lock());
}
+ } else {
+ Raul::error << "Unknown object type " << type << std::endl;
}
-
- arrange();
}
+void
+MachinaCanvas::action_create_node(double x, double y)
+{
+ Machina::Client::ClientObject obj(0);
+ obj.set(URIs::instance().rdf_type, "machina:Node");
+ obj.set(URIs::instance().machina_canvas_x, Raul::Atom((float)x));
+ obj.set(URIs::instance().machina_canvas_y, Raul::Atom((float)y));
+ obj.set(URIs::instance().machina_duration, Raul::Atom((float)1.0));
+ _app->controller()->create(obj);
+}
void
-MachinaCanvas::update_edges()
+MachinaCanvas::action_connect(boost::shared_ptr<NodeView> src,
+ boost::shared_ptr<NodeView> head)
{
- for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
- SharedPtr<EdgeView> edge = PtrCast<EdgeView>(*i);
- if (edge)
- edge->update();
- }
+ _app->controller()->connect(src->node()->id(), head->node()->id());
}
+void
+MachinaCanvas::action_disconnect(boost::shared_ptr<NodeView> src,
+ boost::shared_ptr<NodeView> head)
+{
+ _app->controller()->disconnect(src->node()->id(), head->node()->id());
+}
diff --git a/src/gui/MachinaCanvas.hpp b/src/gui/MachinaCanvas.hpp
index b358638..dc23505 100644
--- a/src/gui/MachinaCanvas.hpp
+++ b/src/gui/MachinaCanvas.hpp
@@ -15,8 +15,8 @@
* along with Machina. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef MACHINA_CANVAS_HPP_H
-#define MACHINA_CANVAS_HPP_H
+#ifndef MACHINA_CANVAS_HPP_HPP
+#define MACHINA_CANVAS_HPP_HPP
#include <string>
#include "raul/SharedPtr.hpp"
@@ -28,30 +28,38 @@ using namespace FlowCanvas;
class MachinaGUI;
class NodeView;
+namespace Machina { namespace Client { class ClientObject; } }
class MachinaCanvas : public Canvas
{
public:
MachinaCanvas(MachinaGUI* app, int width, int height);
- void connect_node(SharedPtr<NodeView> port1,
- SharedPtr<NodeView> port2);
+ //void build(SharedPtr<const Machina::Machine> machine, bool show_labels);
+ //void update_edges();
- void disconnect_node(SharedPtr<NodeView> port1,
- SharedPtr<NodeView> port2);
-
- void build(SharedPtr<const Machina::Machine> machine, bool show_labels);
- void update_edges();
+ void on_new_object(SharedPtr<Machina::Client::ClientObject> object);
+ void on_erase_object(SharedPtr<Machina::Client::ClientObject> object);
ArtVpathDash* selector_dash() { return _selector_dash; }
+ MachinaGUI* app() { return _app; }
+
protected:
bool canvas_event(GdkEvent* event);
void node_clicked(WeakPtr<NodeView> item, GdkEventButton* ev);
private:
- SharedPtr<NodeView> create_node_view(SharedPtr<Machina::Node> node);
+ //SharedPtr<NodeView> create_node_view(SharedPtr<Machina::Node> node);
+
+ void action_create_node(double x, double y);
+
+ void action_connect(SharedPtr<NodeView> port1,
+ SharedPtr<NodeView> port2);
+
+ void action_disconnect(SharedPtr<NodeView> port1,
+ SharedPtr<NodeView> port2);
MachinaGUI* _app;
ArtVpathDash* _selector_dash;
@@ -59,4 +67,4 @@ private:
};
-#endif // MACHINA_CANVAS_HPP_H
+#endif // MACHINA_CANVAS_HPP_HPP
diff --git a/src/gui/MachinaGUI.cpp b/src/gui/MachinaGUI.cpp
index 5aa5116..83ae23b 100644
--- a/src/gui/MachinaGUI.cpp
+++ b/src/gui/MachinaGUI.cpp
@@ -25,10 +25,12 @@
#include <libgnomecanvasmm.h>
#include <libglademm/xml.h>
#include "redlandmm/Model.hpp"
+#include "machina/Controller.hpp"
#include "machina/Engine.hpp"
#include "machina/Machine.hpp"
#include "machina/Mutation.hpp"
-#include "machina/SMFDriver.hpp"
+#include "machina/Updates.hpp"
+#include "client/ClientModel.hpp"
#include "GladeXml.hpp"
#include "MachinaGUI.hpp"
#include "MachinaCanvas.hpp"
@@ -47,6 +49,8 @@ MachinaGUI::MachinaGUI(SharedPtr<Machina::Engine> engine)
, _evolve(false)
, _unit(TimeUnit::BEATS, 19200)
, _engine(engine)
+ , _client_model(new Machina::Client::ClientModel())
+ , _controller(new Machina::Controller(_engine, *_client_model.get()))
, _maid(new Raul::Maid(32))
{
_canvas = boost::shared_ptr<MachinaCanvas>(new MachinaCanvas(this, 1600*2, 1200*2));
@@ -190,7 +194,11 @@ MachinaGUI::MachinaGUI(SharedPtr<Machina::Engine> engine)
_evolve_toolbar->set_sensitive(false);
#endif
- _canvas->build(engine->machine(), _menu_view_labels->get_active());
+ _controller->announce(engine->machine());
+ _canvas->arrange();
+
+ _client_model->signal_new_object.connect(sigc::mem_fun(this, &MachinaGUI::on_new_object));
+ _client_model->signal_erase_object.connect(sigc::mem_fun(this, &MachinaGUI::on_erase_object));
}
@@ -218,14 +226,7 @@ MachinaGUI::evolve_callback()
bool
MachinaGUI::idle_callback()
{
- const bool show_labels = _menu_view_labels->get_active();
-
- for (ItemList::iterator i = _canvas->items().begin(); i != _canvas->items().end(); ++i) {
- const SharedPtr<NodeView> nv = PtrCast<NodeView>(*i);
- if (nv && nv->node()->changed())
- nv->update_state(show_labels);
- }
-
+ _controller->process_updates();
return true;
}
@@ -239,12 +240,12 @@ MachinaGUI::scrolled_window_event(GdkEvent* event)
ItemList selection = _canvas->selected_items();
_canvas->clear_selection();
- for (ItemList::iterator i = selection.begin();
- i != selection.end(); ++i) {
+ for (ItemList::iterator i = selection.begin(); i != selection.end(); ++i) {
SharedPtr<NodeView> view = PtrCast<NodeView>(*i);
if (view) {
- _engine->machine()->remove_node(view->node());
- _canvas->remove_item(view);
+ _controller->erase(view->node()->id());
+ //_engine->machine()->remove_node(view->node());
+ //_canvas->remove_item(view);
}
}
@@ -320,6 +321,7 @@ MachinaGUI::random_mutation(SharedPtr<Machine> machine)
void
MachinaGUI::mutate(SharedPtr<Machine> machine, unsigned mutation)
{
+ #if 0
if (!machine)
machine = _engine->machine();
@@ -356,6 +358,7 @@ MachinaGUI::mutate(SharedPtr<Machine> machine, unsigned mutation)
break;
default: throw;
}
+ #endif
}
@@ -428,10 +431,11 @@ MachinaGUI::menu_file_open()
const int result = dialog.run();
if (result == Gtk::RESPONSE_OK) {
- SharedPtr<Machina::Machine> new_machine = _engine->import_machine(dialog.get_uri());
+ SharedPtr<Machina::Machine> new_machine = _engine->load_machine(dialog.get_uri());
if (new_machine) {
_canvas->destroy();
- _canvas->build(new_machine, _menu_view_labels->get_active());
+ _controller->announce(new_machine);
+ _canvas->arrange();
_save_uri = dialog.get_uri();
}
}
@@ -537,19 +541,19 @@ MachinaGUI::menu_import_midi()
const int result = dialog.run();
if (result == Gtk::RESPONSE_OK) {
- SharedPtr<Machina::SMFDriver> file_driver(new Machina::SMFDriver());
-
- double length_dbl = length_sb->get_value_as_int();
- Raul::TimeStamp length(_unit, length_dbl);
+ const double length_dbl = length_sb->get_value_as_int();
+ const Raul::TimeStamp length(_unit, length_dbl);
- SharedPtr<Machina::Machine> machine = file_driver->learn(dialog.get_filename(), 0.0, length);
+ SharedPtr<Machina::Machine> machine = _engine->load_machine_midi(
+ dialog.get_filename(), 0.0, length);
if (machine) {
dialog.hide();
machine->activate();
machine->reset(machine->time());
- _canvas->build(machine, _menu_view_labels->get_active());
+ //_canvas->build(machine, _menu_view_labels->get_active());
_engine->driver()->set_machine(machine);
+ _controller->announce(machine);
} else {
Gtk::MessageDialog msg_dialog(dialog, "Error loading MIDI file",
false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
@@ -572,19 +576,23 @@ MachinaGUI::menu_export_midi()
filt.set_name("MIDI Files");
dialog.set_filter(filt);
+ Gtk::HBox* extra_widget = Gtk::manage(new Gtk::HBox());
+ Gtk::SpinButton* dur_sb = Gtk::manage(new Gtk::SpinButton());
+ dur_sb->set_increments(1, 10);
+ dur_sb->set_range(0, INT_MAX);
+ dur_sb->set_value(0);
+ extra_widget->pack_start(*Gtk::manage(new Gtk::Label("")), true, true);
+ extra_widget->pack_start(*Gtk::manage(new Gtk::Label("Duration (beats): ")), false, false);
+ extra_widget->pack_start(*dur_sb, false, false);
+ dialog.set_extra_widget(*extra_widget);
+ extra_widget->show_all();
+
const int result = dialog.run();
if (result == Gtk::RESPONSE_OK) {
- SharedPtr<Machina::SMFDriver> file_driver(new Machina::SMFDriver());
- _engine->driver()->deactivate();
- const SharedPtr<Machina::Machine> m = _engine->machine();
- m->set_sink(file_driver->writer());
- file_driver->writer()->start(dialog.get_filename(), TimeStamp(_unit, 0.0));
- file_driver->run(m, TimeStamp(_unit, 32.0)); // TODO: solve halting problem
- m->set_sink(_engine->driver());
- m->reset(m->time());
- file_driver->writer()->finish();
- _engine->driver()->activate();
+ const double dur_dbl = dur_sb->get_value_as_int();
+ const Raul::TimeStamp dur(_unit, dur_dbl);
+ _engine->export_midi(dialog.get_filename(), dur);
}
}
@@ -658,7 +666,7 @@ MachinaGUI::record_toggled()
_engine->driver()->start_record(_step_record_checkbutton->get_active());
} else if (_engine->driver()->recording()) {
_engine->driver()->finish_record();
- _canvas->build(_engine->machine(), _menu_view_labels->get_active());
+ //_canvas->build(_engine->machine(), _menu_view_labels->get_active());
update_toolbar();
}
}
@@ -672,7 +680,7 @@ MachinaGUI::stop_clicked()
if (_engine->driver()->recording()) {
_engine->driver()->stop();
_engine->machine()->deactivate();
- _canvas->build(_engine->machine(), _menu_view_labels->get_active());
+ //_canvas->build(_engine->machine(), _menu_view_labels->get_active());
} else {
_engine->driver()->stop();
_engine->machine()->deactivate();
@@ -691,4 +699,14 @@ MachinaGUI::play_toggled()
_engine->machine()->deactivate();
}
+void
+MachinaGUI::on_new_object(SharedPtr<Client::ClientObject> object)
+{
+ _canvas->on_new_object(object);
+}
+void
+MachinaGUI::on_erase_object(SharedPtr<Client::ClientObject> object)
+{
+ _canvas->on_erase_object(object);
+}
diff --git a/src/gui/MachinaGUI.hpp b/src/gui/MachinaGUI.hpp
index 75fdafd..58dc48f 100644
--- a/src/gui/MachinaGUI.hpp
+++ b/src/gui/MachinaGUI.hpp
@@ -15,18 +15,27 @@
* along with Machina. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef MACHINA_GUI_H
-#define MACHINA_GUI_H
+#ifndef MACHINA_GUI_HPP
+#define MACHINA_GUI_HPP
#include <string>
#include <libgnomecanvasmm.h>
-#include "machina-config.h"
-#include "raul/SharedPtr.hpp"
+
#include "raul/Maid.hpp"
+#include "raul/SharedPtr.hpp"
+#include "raul/TimeStamp.hpp"
+
+#include "machina-config.h"
using namespace std;
-namespace Machina { class Machine; class Engine; class Evolver; }
+namespace Machina {
+class Machine;
+class Engine;
+class Evolver;
+class Controller;
+namespace Client { class ClientModel; class ClientObject; }
+}
class MachinaCanvas;
@@ -46,8 +55,15 @@ public:
void attach();
void quit() { _main_window->hide(); }
+ SharedPtr<Machina::Controller> controller() { return _controller; }
+
inline void queue_refresh() { _refresh = true; }
+ void on_new_object(SharedPtr<Machina::Client::ClientObject> object);
+ void on_erase_object(SharedPtr<Machina::Client::ClientObject> object);
+
+ SharedPtr<Machina::Client::ClientModel> client_model() { return _client_model; }
+
protected:
void connect_widgets();
@@ -93,9 +109,11 @@ protected:
Raul::TimeUnit _unit;
- boost::shared_ptr<MachinaCanvas> _canvas;
- boost::shared_ptr<Machina::Engine> _engine;
-
+ SharedPtr<MachinaCanvas> _canvas;
+ SharedPtr<Machina::Engine> _engine;
+ SharedPtr<Machina::Client::ClientModel> _client_model;
+ SharedPtr<Machina::Controller> _controller;
+
SharedPtr<Raul::Maid> _maid;
SharedPtr<Machina::Evolver> _evolver;
@@ -144,4 +162,4 @@ protected:
Gtk::ToolButton* _adjust_edge_button;
};
-#endif // MACHINA_GUI_H
+#endif // MACHINA_GUI_HPP
diff --git a/src/gui/NodePropertiesWindow.cpp b/src/gui/NodePropertiesWindow.cpp
index fe1ec81..b896902 100644
--- a/src/gui/NodePropertiesWindow.cpp
+++ b/src/gui/NodePropertiesWindow.cpp
@@ -16,8 +16,6 @@
*/
#include <string>
-#include "machina/MidiAction.hpp"
-#include "machina/ActionFactory.hpp"
#include "NodePropertiesWindow.hpp"
#include "GladeXml.hpp"
@@ -38,9 +36,13 @@ NodePropertiesWindow::NodePropertiesWindow(BaseObjectType* cobject, const Glib::
xml->get_widget("node_properties_apply_button", _apply_button);
xml->get_widget("node_properties_cancel_button", _cancel_button);
xml->get_widget("node_properties_ok_button", _ok_button);
-
- _apply_button->signal_clicked().connect(sigc::mem_fun(this, &NodePropertiesWindow::apply_clicked));
- _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &NodePropertiesWindow::cancel_clicked)); _ok_button->signal_clicked().connect(sigc::mem_fun(this, &NodePropertiesWindow::ok_clicked));
+
+ _apply_button->signal_clicked().connect(
+ sigc::mem_fun(this, &NodePropertiesWindow::apply_clicked));
+ _cancel_button->signal_clicked().connect(
+ sigc::mem_fun(this, &NodePropertiesWindow::cancel_clicked));
+ _ok_button->signal_clicked().connect(
+ sigc::mem_fun(this, &NodePropertiesWindow::ok_clicked));
}
@@ -52,6 +54,7 @@ NodePropertiesWindow::~NodePropertiesWindow()
void
NodePropertiesWindow::apply_clicked()
{
+ #if 0
const uint8_t note = _note_spinbutton->get_value();
if (!_node->enter_action()) {
_node->set_enter_action(ActionFactory::note_on(note));
@@ -67,6 +70,7 @@ NodePropertiesWindow::apply_clicked()
TimeStamp duration(TimeUnit(TimeUnit::BEATS, 19200), duration_dbl);
_node->set_duration(duration);
_node->set_changed();
+ #endif
}
@@ -88,9 +92,10 @@ NodePropertiesWindow::ok_clicked()
void
-NodePropertiesWindow::set_node(SharedPtr<Machina::Node> node)
+NodePropertiesWindow::set_node(SharedPtr<Machina::Client::ClientObject> node)
{
_node = node;
+ #if 0
SharedPtr<MidiAction> enter_action = PtrCast<MidiAction>(node->enter_action());
if (enter_action && enter_action->event_size() > 1
&& (enter_action->event()[0] & 0xF0) == 0x90) {
@@ -103,11 +108,12 @@ NodePropertiesWindow::set_node(SharedPtr<Machina::Node> node)
_note_spinbutton->hide();
}
_duration_spinbutton->set_value(node->duration().to_double());
+ #endif
}
void
-NodePropertiesWindow::present(Gtk::Window* parent, SharedPtr<Machina::Node> node)
+NodePropertiesWindow::present(Gtk::Window* parent, SharedPtr<Machina::Client::ClientObject> node)
{
if (!_instance) {
Glib::RefPtr<Gnome::Glade::Xml> xml = GladeXml::create();
diff --git a/src/gui/NodePropertiesWindow.hpp b/src/gui/NodePropertiesWindow.hpp
index f88978c..b56941e 100644
--- a/src/gui/NodePropertiesWindow.hpp
+++ b/src/gui/NodePropertiesWindow.hpp
@@ -15,24 +15,28 @@
* along with Machina. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NODEPROPERTIESWINDOW_H
-#define NODEPROPERTIESWINDOW_H
+#ifndef NODEPROPERTIESWINDOW_HPP
+#define NODEPROPERTIESWINDOW_HPP
#include <gtkmm.h>
+
#include <libglademm/xml.h>
-#include "machina/Node.hpp"
+
+#include <raul/SharedPtr.hpp>
+
+namespace Machina { namespace Client { class ClientObject; } }
class NodePropertiesWindow : public Gtk::Dialog
{
public:
- static void present(Gtk::Window* parent, SharedPtr<Machina::Node> node);
+ static void present(Gtk::Window* parent, SharedPtr<Machina::Client::ClientObject> node);
private:
friend class Gnome::Glade::Xml;
NodePropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& glade_xml);
~NodePropertiesWindow();
- void set_node(SharedPtr<Machina::Node> node);
+ void set_node(SharedPtr<Machina::Client::ClientObject> node);
void apply_clicked();
void cancel_clicked();
@@ -40,7 +44,7 @@ private:
static NodePropertiesWindow* _instance;
- SharedPtr<Machina::Node> _node;
+ SharedPtr<Machina::Client::ClientObject> _node;
Gtk::SpinButton* _note_spinbutton;
Gtk::SpinButton* _duration_spinbutton;
@@ -50,4 +54,4 @@ private:
};
-#endif // NODEPROPERTIESWINDOW_H
+#endif // NODEPROPERTIESWINDOW_HPP
diff --git a/src/gui/NodeView.cpp b/src/gui/NodeView.cpp
index 943c6f7..2810f99 100644
--- a/src/gui/NodeView.cpp
+++ b/src/gui/NodeView.cpp
@@ -1,5 +1,5 @@
/* This file is part of Machina.
- * Copyright (C) 2007-2009 David Robillard <http://drobilla.net>
+ * Copyright (C) 2007-2010 David 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
@@ -15,29 +15,37 @@
* along with Machina. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <iostream>
-#include "machina/MidiAction.hpp"
-#include "NodeView.hpp"
+#include "machina/Controller.hpp"
+#include "machina/URIs.hpp"
+#include "machina/types.hpp"
+
+#include "client/ClientModel.hpp"
+
+#include "MachinaCanvas.hpp"
+#include "MachinaGUI.hpp"
#include "NodePropertiesWindow.hpp"
+#include "NodeView.hpp"
using namespace std;
-
-NodeView::NodeView(Gtk::Window* window,
- SharedPtr<FlowCanvas::Canvas> canvas,
- SharedPtr<Machina::Node> node,
- const std::string& name,
- double x,
- double y)
- : FlowCanvas::Ellipse(canvas, name, x, y, 20, 20, false)
+using Machina::URIs;
+
+NodeView::NodeView(Gtk::Window* window,
+ SharedPtr<FlowCanvas::Canvas> canvas,
+ SharedPtr<Machina::Client::ClientObject> node,
+ double x,
+ double y)
+ : FlowCanvas::Ellipse(canvas, "", x, y, 20, 20, false)
, _window(window)
, _node(node)
, _default_border_color(_border_color)
, _old_color(_color)
{
- signal_clicked.connect(sigc::mem_fun(this, &NodeView::handle_click));
- update_state(false);
-}
+ signal_clicked.connect(
+ sigc::mem_fun(this, &NodeView::handle_click));
+ node->signal_property.connect(
+ sigc::mem_fun(this, &NodeView::on_property));
+}
void
NodeView::on_double_click(GdkEventButton*)
@@ -45,24 +53,32 @@ NodeView::on_double_click(GdkEventButton*)
NodePropertiesWindow::present(_window, _node);
}
+bool
+NodeView::node_is(Machina::URIInt key)
+{
+ const Raul::Atom& value = _node->get(key);
+ return value.type() == Raul::Atom::BOOL && value.get_bool();
+}
void
NodeView::handle_click(GdkEventButton* event)
{
if (event->state & GDK_CONTROL_MASK) {
+ SharedPtr<MachinaCanvas> canvas = PtrCast<MachinaCanvas>(_canvas.lock());
if (event->button == 1) {
- bool is_initial = _node->is_initial();
- _node->set_initial( ! is_initial );
- update_state(_label != NULL);
+ canvas->app()->controller()->set_property(
+ _node->id(),
+ URIs::instance().machina_initial,
+ !node_is(URIs::instance().machina_initial));
} else if (event->button == 3) {
- bool is_selector = _node->is_selector();
- _node->set_selector( ! is_selector );
- update_state(_label != NULL);
+ canvas->app()->controller()->set_property(
+ _node->id(),
+ URIs::instance().machina_selector,
+ !node_is(URIs::instance().machina_selector));
}
}
}
-
static std::string
midi_note_name(uint8_t num)
{
@@ -79,23 +95,22 @@ midi_note_name(uint8_t num)
void
NodeView::show_label(bool show)
{
- SharedPtr<Machina::MidiAction> action
- = PtrCast<Machina::MidiAction>(_node->enter_action());
-
if (show) {
- if (action && action->event_size() > 1
- && (action->event()[0] & 0xF0) == 0x90) {
- const uint8_t note_num = action->event()[1];
- set_name(midi_note_name(note_num));
+ if (_enter_action) {
+ Raul::Atom note_number = _enter_action->get(URIs::instance().machina_note_number);
+ if (note_number.is_valid()) {
+ set_name(midi_note_name(note_number.get_int32()));
+ return;
+ }
}
- } else {
- set_name("");
}
+
+ set_name("");
}
-
/// Dash style for selector node outlines
-static ArtVpathDash* selector_dash()
+static ArtVpathDash*
+selector_dash()
{
static ArtVpathDash* selector_dash = NULL;
@@ -115,32 +130,45 @@ NodeView::set_selected(bool selected)
{
Ellipse::set_selected(selected);
if (!selected)
- _ellipse.property_dash() = _node->is_selector() ? selector_dash() : 0;
+ _ellipse.property_dash() = node_is(URIs::instance().machina_selector) ? selector_dash() : 0;
}
-
void
-NodeView::update_state(bool show_labels)
+NodeView::on_property(Machina::URIInt key, const Raul::Atom& value)
{
- static const uint32_t active_color = 0x408040FF;
+ static const uint32_t active_color = 0x408040FF;
static const uint32_t active_border_color = 0x00FF00FF;
- if (_node->is_active()) {
- if (_color != active_color) {
- _old_color = _color;
- set_base_color(active_color);
- set_border_color(active_border_color);
+ if (key == URIs::instance().machina_selector) {
+ _ellipse.property_dash() = value.get_bool() ? selector_dash() : 0;
+ } else if (key == URIs::instance().machina_initial) {
+ set_border_width(value.get_bool() ? 4.0 : 1.0);
+ } else if (key == URIs::instance().machina_active) {
+ if (value.get_bool()) {
+ if (_color != active_color) {
+ _old_color = _color;
+ set_base_color(active_color);
+ set_border_color(active_border_color);
+ }
+ } else if (_color == active_color) {
+ set_base_color(_old_color);
+ set_border_color(_default_border_color);
}
- } else if (_color == active_color) {
- set_base_color(_old_color);
- set_border_color(_default_border_color);
+ } else if (key == URIs::instance().machina_enter_action) {
+ const uint64_t action_id = value.get_int32();
+ SharedPtr<MachinaCanvas> canvas = PtrCast<MachinaCanvas>(_canvas.lock());
+ _enter_action_connection.disconnect();
+ _enter_action = canvas->app()->client_model()->find(action_id);
+ _enter_action_connection = _enter_action->signal_property.connect(
+ sigc::mem_fun(this, &NodeView::on_action_property));
+ } else {
+ cout << "Unknown property " << key << endl;
}
+}
- _ellipse.property_dash() = _node->is_selector() ? selector_dash() : 0;
-
- set_border_width(_node->is_initial() ? 4.0 : 1.0);
-
- if (show_labels)
+void
+NodeView::on_action_property(Machina::URIInt key, const Raul::Atom& value)
+{
+ if (key == URIs::instance().machina_note_number)
show_label(true);
}
-
diff --git a/src/gui/NodeView.hpp b/src/gui/NodeView.hpp
index 0de7d6f..a70e821 100644
--- a/src/gui/NodeView.hpp
+++ b/src/gui/NodeView.hpp
@@ -15,23 +15,26 @@
* along with Machina. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef MACHINA_NODEVIEW_H
-#define MACHINA_NODEVIEW_H
+#ifndef MACHINA_NODEVIEW_HPP
+#define MACHINA_NODEVIEW_HPP
#include "flowcanvas/Ellipse.hpp"
-#include "machina/Node.hpp"
+#include "client/ClientObject.hpp"
-class NodeView : public FlowCanvas::Ellipse {
+#include "machina/types.hpp"
+
+class NodeView
+ : public FlowCanvas::Ellipse
+ , public Machina::Client::ClientObject::View {
public:
- NodeView(Gtk::Window* window,
- SharedPtr<FlowCanvas::Canvas> canvas,
- SharedPtr<Machina::Node> node,
- const std::string& name,
- double x,
- double y);
+ NodeView(Gtk::Window* window,
+ SharedPtr<FlowCanvas::Canvas> canvas,
+ SharedPtr<Machina::Client::ClientObject> node,
+ double x,
+ double y);
- SharedPtr<Machina::Node> node() { return _node; }
+ SharedPtr<Machina::Client::ClientObject> node() { return _node; }
void show_label(bool show);
@@ -40,13 +43,20 @@ public:
private:
void handle_click(GdkEventButton* ev);
void on_double_click(GdkEventButton* ev);
+ void on_property(Machina::URIInt key, const Raul::Atom& value);
+ void on_action_property(Machina::URIInt key, const Raul::Atom& value);
void set_selected(bool selected);
- Gtk::Window* _window;
- SharedPtr<Machina::Node> _node;
- uint32_t _default_border_color;
- uint32_t _old_color;
+ bool node_is(Machina::URIInt key);
+
+ Gtk::Window* _window;
+ SharedPtr<Machina::Client::ClientObject> _node;
+ uint32_t _default_border_color;
+ uint32_t _old_color;
+
+ SharedPtr<Machina::Client::ClientObject> _enter_action;
+ sigc::connection _enter_action_connection;
};
-#endif // MACHINA_NODEVIEW_H
+#endif // MACHINA_NODEVIEW_HPP
diff --git a/src/gui/main.cpp b/src/gui/main.cpp
index 6f79c7d..a2fd12a 100644
--- a/src/gui/main.cpp
+++ b/src/gui/main.cpp
@@ -24,7 +24,7 @@
#include "machina/Engine.hpp"
#include "machina/Loader.hpp"
#include "machina/Machine.hpp"
-#include "machina/SMFDriver.hpp"
+#include "machina/URIs.hpp"
#include "MachinaGUI.hpp"
using namespace std;
@@ -39,6 +39,8 @@ main(int argc, char** argv)
Redland::World rdf_world;
+ Machina::URIs::init();
+
SharedPtr<Machina::Machine> machine;
// Load machine, if given
diff --git a/src/gui/wscript b/src/gui/wscript
index 634971e..2e0aa23 100644
--- a/src/gui/wscript
+++ b/src/gui/wscript
@@ -11,11 +11,11 @@ def build(bld):
NodeView.cpp
'''
- obj.includes = ['.', '../..', '../engine']
+ obj.includes = ['.', '..', '../..', '../engine']
obj.export_includes = ['.']
obj.name = 'libmachina_gui'
obj.target = 'machina_gui'
- obj.use = 'libmachina_engine'
+ obj.use = 'libmachina_engine libmachina_client'
autowaf.use_lib(bld, obj, '''
FLOWCANVAS
GLADEMM