diff options
author | David Robillard <d@drobilla.net> | 2011-01-10 21:23:14 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2011-01-10 21:23:14 +0000 |
commit | f293da6bc4f0f631c086d35666e3e8bfef19b8f2 (patch) | |
tree | d0e693bdec5e4a53daca500434533d2fc5c43650 /src/gui | |
parent | db319f5a8cb7915b2d5b93adab148fa16d92e7e5 (diff) | |
download | machina-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.cpp | 64 | ||||
-rw-r--r-- | src/gui/EdgeView.hpp | 30 | ||||
-rw-r--r-- | src/gui/GladeXml.hpp | 3 | ||||
-rw-r--r-- | src/gui/MachinaCanvas.cpp | 192 | ||||
-rw-r--r-- | src/gui/MachinaCanvas.hpp | 30 | ||||
-rw-r--r-- | src/gui/MachinaGUI.cpp | 86 | ||||
-rw-r--r-- | src/gui/MachinaGUI.hpp | 36 | ||||
-rw-r--r-- | src/gui/NodePropertiesWindow.cpp | 20 | ||||
-rw-r--r-- | src/gui/NodePropertiesWindow.hpp | 18 | ||||
-rw-r--r-- | src/gui/NodeView.cpp | 130 | ||||
-rw-r--r-- | src/gui/NodeView.hpp | 42 | ||||
-rw-r--r-- | src/gui/main.cpp | 4 | ||||
-rw-r--r-- | src/gui/wscript | 4 |
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 |