diff options
Diffstat (limited to 'src/gui')
66 files changed, 2938 insertions, 2071 deletions
diff --git a/src/gui/.clang-tidy b/src/gui/.clang-tidy new file mode 100644 index 00000000..99bd2aba --- /dev/null +++ b/src/gui/.clang-tidy @@ -0,0 +1,29 @@ +Checks: > + -*-narrowing-conversions, + -android-cloexec-*, + -bugprone-branch-clone, + -bugprone-exception-escape, + -bugprone-macro-parentheses, + -bugprone-parent-virtual-call, + -bugprone-reserved-identifier, + -bugprone-suspicious-string-compare, + -cert-dcl21-cpp, + -cert-dcl37-c, + -cert-dcl51-cpp, + -cert-err58-cpp, + -cert-str34-c, + -clang-analyzer-core.CallAndMessage, + -cppcoreguidelines-macro-usage, + -cppcoreguidelines-pro-bounds-constant-array-index, + -cppcoreguidelines-pro-type-static-cast-downcast, + -cppcoreguidelines-pro-type-vararg, + -cppcoreguidelines-slicing, + -google-default-arguments, + -google-readability-todo, + -google-runtime-int, + -google-runtime-references, + -hicpp-multiway-paths-covered, + -hicpp-vararg, + -llvm-header-guard, + -readability-convert-member-functions-to-static, +InheritParentConfig: true diff --git a/src/gui/App.cpp b/src/gui/App.cpp index dfa34998..260afdba 100644 --- a/src/gui/App.cpp +++ b/src/gui/App.cpp @@ -18,74 +18,78 @@ #include "ConnectWindow.hpp" #include "GraphTreeWindow.hpp" -#include "GraphWindow.hpp" -#include "LoadPluginWindow.hpp" #include "MessagesWindow.hpp" -#include "NodeModule.hpp" #include "Port.hpp" #include "RDFS.hpp" #include "Style.hpp" -#include "SubgraphModule.hpp" #include "ThreadedLoader.hpp" #include "WidgetFactory.hpp" #include "WindowFactory.hpp" #include "rgba.hpp" -#include "ganv/Edge.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/EngineBase.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Log.hpp" -#include "ingen/QueuedInterface.hpp" -#include "ingen/StreamWriter.hpp" -#include "ingen/World.hpp" -#include "ingen/client/ClientStore.hpp" -#include "ingen/client/GraphModel.hpp" -#include "ingen/client/ObjectModel.hpp" -#include "ingen/client/PortModel.hpp" -#include "ingen/client/SigClientInterface.hpp" -#include "ingen/runtime_paths.hpp" -#include "lilv/lilv.h" -#include "raul/Path.hpp" -#include "suil/suil.h" - -#include <boost/variant/get.hpp> -#include <gtk/gtkwindow.h> +#include <ingen/Atom.hpp> +#include <ingen/ColorContext.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/EngineBase.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Log.hpp> +#include <ingen/Message.hpp> +#include <ingen/Properties.hpp> +#include <ingen/QueuedInterface.hpp> +#include <ingen/Resource.hpp> +#include <ingen/Status.hpp> +#include <ingen/StreamWriter.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/ClientStore.hpp> +#include <ingen/client/PluginModel.hpp> +#include <ingen/client/PortModel.hpp> +#include <ingen/client/SigClientInterface.hpp> +#include <ingen/fmt.hpp> +#include <ingen/runtime_paths.hpp> +#include <lilv/lilv.h> +#include <lv2/urid/urid.h> +#include <suil/suil.h> + +#include <glib.h> +#include <glibmm/main.h> +#include <glibmm/miscutils.h> +#include <glibmm/propertyproxy.h> +#include <glibmm/ustring.h> +#include <gtk/gtk.h> +#include <gtkmm/aboutdialog.h> +#include <gtkmm/dialog.h> +#include <gtkmm/enums.h> +#include <gtkmm/main.h> +#include <gtkmm/messagedialog.h> +#include <gtkmm/rc.h> #include <gtkmm/stock.h> +#include <gtkmm/widget.h> +#include <sigc++/functors/mem_fun.h> +#include <sigc++/functors/slot.h> +#include <algorithm> #include <cassert> -#include <fstream> +#include <cstdarg> +#include <cstdio> +#include <exception> +#include <iostream> +#include <map> +#include <memory> #include <string> #include <utility> +#include <variant> -namespace Raul { class Deletable; } - -namespace ingen { - -namespace client { class PluginModel; } - -using namespace client; - -namespace gui { - -class Port; +namespace ingen::gui { Gtk::Main* App::_main = nullptr; App::App(ingen::World& world) - : _style(new Style(*this)) - , _about_dialog(nullptr) - , _window_factory(new WindowFactory(*this)) - , _world(world) - , _sample_rate(48000) - , _block_length(1024) - , _n_threads(1) - , _mean_run_load(0.0f) - , _min_run_load(0.0f) - , _max_run_load(0.0f) - , _enable_signal(true) - , _requested_plugins(false) - , _is_plugin(false) + : _style(new Style(*this)) + , _window_factory(new WindowFactory(*this)) + , _world(world) { _world.conf().load_default("ingen", "gui.ttl"); @@ -99,11 +103,13 @@ App::App(ingen::World& world) _about_dialog->property_program_name() = "Ingen"; _about_dialog->property_logo_icon_name() = "ingen"; - PluginModel::set_rdf_world(*world.rdf_world()); - PluginModel::set_lilv_world(world.lilv_world()); + client::PluginModel::set_rdf_world(*world.rdf_world()); + client::PluginModel::set_lilv_world(world.lilv_world()); - using namespace std::placeholders; - world.log().set_sink(std::bind(&MessagesWindow::log, _messages_window, _1, _2, _3)); + world.log().set_sink( + [this](const LV2_URID type, const char* fmt, va_list args) { + return _messages_window->log(type, fmt, args); + }); } App::~App() @@ -112,7 +118,7 @@ App::~App() delete _window_factory; } -SPtr<App> +std::shared_ptr<App> App::create(ingen::World& world) { suil_init(&world.argc(), &world.argv(), SUIL_ARG_NONE); @@ -128,7 +134,7 @@ App::create(ingen::World& world) _main = new Gtk::Main(&world.argc(), &world.argv()); } - auto app = SPtr<App>{new App(world)}; + auto app = std::shared_ptr<App>(new App(world)); // Load configuration settings app->style()->load_settings(); @@ -151,16 +157,16 @@ App::run() // with 'ingen -egl' we'd get a bunch of notifications about load // immediately before even knowing about the root graph or plugins) while (!_connect_window->attached()) { - if (_main->iteration()) { + if (Gtk::Main::iteration()) { break; } } - _main->run(); + Gtk::Main::run(); } void -App::attach(SPtr<ingen::Interface> client) +App::attach(const std::shared_ptr<ingen::Interface>& client) { assert(!_client); assert(!_store); @@ -171,21 +177,26 @@ App::attach(SPtr<ingen::Interface> client) } _client = client; - _store = SPtr<ClientStore>(new ClientStore(_world.uris(), _world.log(), sig_client())); - _loader = SPtr<ThreadedLoader>(new ThreadedLoader(*this, _world.interface())); + + _store = std::make_shared<client::ClientStore>(_world.uris(), + _world.log(), + sig_client()); + + _loader = std::make_shared<ThreadedLoader>(*this, _world.interface()); + if (!_world.store()) { _world.set_store(_store); } if (_world.conf().option("dump").get<int32_t>()) { - _dumper = SPtr<StreamWriter>(new StreamWriter(_world.uri_map(), - _world.uris(), - URI("ingen:/client"), - stderr, - ColorContext::Color::CYAN)); + _dumper = std::make_shared<StreamWriter>(_world.uri_map(), + _world.uris(), + URI("ingen:/client"), + stderr, + ColorContext::Color::CYAN); sig_client()->signal_message().connect( - sigc::mem_fun(*_dumper.get(), &StreamWriter::message)); + sigc::mem_fun(*_dumper, &StreamWriter::message)); } _graph_tree_window->init(*this, *_store); @@ -202,7 +213,7 @@ App::detach() _loader.reset(); _store.reset(); _client.reset(); - _world.set_interface(SPtr<Interface>()); + _world.set_interface(nullptr); } } @@ -215,17 +226,17 @@ App::request_plugins_if_necessary() } } -SPtr<SigClientInterface> +std::shared_ptr<client::SigClientInterface> App::sig_client() { - SPtr<QueuedInterface> qi = dynamic_ptr_cast<QueuedInterface>(_client); + auto qi = std::dynamic_pointer_cast<QueuedInterface>(_client); if (qi) { - return dynamic_ptr_cast<SigClientInterface>(qi->sink()); + return std::dynamic_pointer_cast<client::SigClientInterface>(qi->sink()); } - return dynamic_ptr_cast<SigClientInterface>(_client); + return std::dynamic_pointer_cast<client::SigClientInterface>(_client); } -SPtr<Serialiser> +std::shared_ptr<Serialiser> App::serialiser() { return _world.serialiser(); @@ -234,13 +245,13 @@ App::serialiser() void App::message(const Message& msg) { - if (const Response* const r = boost::get<Response>(&msg)) { + if (const Response* const r = std::get_if<Response>(&msg)) { response(r->id, r->status, r->subject); - } else if (const Error* const e = boost::get<Error>(&msg)) { + } else if (const Error* const e = std::get_if<Error>(&msg)) { error_message(e->message); - } else if (const Put* const p = boost::get<Put>(&msg)) { + } else if (const Put* const p = std::get_if<Put>(&msg)) { put(p->uri, p->properties, p->ctx); - } else if (const SetProperty* const s = boost::get<SetProperty>(&msg)) { + } else if (const SetProperty* const s = std::get_if<SetProperty>(&msg)) { property_change(s->subject, s->predicate, s->value, s->ctx); } } @@ -312,7 +323,9 @@ App::property_change(const URI& subject, { if (subject != URI("ingen:/engine")) { return; - } else if (key == uris().param_sampleRate && value.type() == forge().Int) { + } + + if (key == uris().param_sampleRate && value.type() == forge().Int) { _sample_rate = value.get<int32_t>(); } else if (key == uris().bufsz_maxBlockLength && value.type() == forge().Int) { _block_length = value.get<int32_t>(); @@ -354,7 +367,7 @@ App::status_text() const return fmt( "%2.1f kHz / %.1f ms, %s, %s DSP", (_sample_rate / 1e3f), - (_block_length * 1e3f / (float)_sample_rate), + (_block_length * 1e3f / static_cast<float>(_sample_rate)), ((_n_threads == 1) ? "1 thread" : fmt("%1% threads", _n_threads)), fraction_label(_max_run_load)); } @@ -362,7 +375,7 @@ App::status_text() const void App::port_activity(Port* port) { - std::pair<ActivityPorts::iterator, bool> inserted = _activity_ports.emplace(port, false); + const auto inserted = _activity_ports.emplace(port, false); if (inserted.second) { inserted.first->second = false; } @@ -428,7 +441,7 @@ App::gtk_main_iteration() return false; } } else { - dynamic_ptr_cast<QueuedInterface>(_client)->emit(); + std::dynamic_pointer_cast<QueuedInterface>(_client)->emit(); } _enable_signal = true; @@ -495,5 +508,4 @@ App::sample_rate() const return _sample_rate; } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/App.hpp b/src/gui/App.hpp index 13c46414..0138f25a 100644 --- a/src/gui/App.hpp +++ b/src/gui/App.hpp @@ -17,47 +17,51 @@ #ifndef INGEN_GUI_APP_HPP #define INGEN_GUI_APP_HPP -#include "ingen/Atom.hpp" -#include "ingen/Message.hpp" -#include "ingen/Resource.hpp" -#include "ingen/Status.hpp" -#include "ingen/World.hpp" -#include "ingen/ingen.h" -#include "ingen/types.hpp" -#include "lilv/lilv.h" -#include "raul/Deletable.hpp" - -#include <gtkmm/aboutdialog.h> -#include <gtkmm/main.h> -#include <gtkmm/window.h> - -#include <unordered_map> +#include <ingen/Message.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <ingen/World.hpp> +#include <ingen/ingen.h> +#include <lilv/lilv.h> + +#include <sigc++/signal.h> + +#include <cstdint> +#include <memory> #include <string> +#include <unordered_map> + +namespace Gtk { +class AboutDialog; +class Main; +class Widget; +class Window; +} // namespace Gtk namespace ingen { +enum class Status; + +class Atom; +class Forge; class Interface; class Log; -class Port; class Serialiser; class StreamWriter; -class World; +class URIs; namespace client { class ClientStore; -class GraphModel; -class PluginModel; class PortModel; class SigClientInterface; -} +} // namespace client namespace gui { class ConnectWindow; -class GraphCanvas; -class GraphTreeView; class GraphTreeWindow; class MessagesWindow; class Port; @@ -73,9 +77,14 @@ class INGEN_API App public: ~App(); + App(const App&) = delete; + App& operator=(const App&) = delete; + App(App&&) = delete; + App& operator=(App&&) = delete; + void error_message(const std::string& str); - void attach(SPtr<ingen::Interface> client); + void attach(const std::shared_ptr<ingen::Interface>& client); void detach(); @@ -94,7 +103,7 @@ public: bool signal() const { return _enable_signal; } void enable_signals(bool b) { _enable_signal = b; } bool disable_signals() { - bool old = _enable_signal; + const bool old = _enable_signal; _enable_signal = false; return old; } @@ -118,17 +127,17 @@ public: Style* style() const { return _style; } WindowFactory* window_factory() const { return _window_factory; } - ingen::Forge& forge() const { return _world.forge(); } - SPtr<ingen::Interface> interface() const { return _world.interface(); } - SPtr<ingen::Interface> client() const { return _client; } - SPtr<client::ClientStore> store() const { return _store; } - SPtr<ThreadedLoader> loader() const { return _loader; } + ingen::Forge& forge() const { return _world.forge(); } + std::shared_ptr<ingen::Interface> interface() const { return _world.interface(); } + std::shared_ptr<ingen::Interface> client() const { return _client; } + std::shared_ptr<client::ClientStore> store() const { return _store; } + std::shared_ptr<ThreadedLoader> loader() const { return _loader; } - SPtr<client::SigClientInterface> sig_client(); + std::shared_ptr<client::SigClientInterface> sig_client(); - SPtr<Serialiser> serialiser(); + std::shared_ptr<Serialiser> serialiser(); - static SPtr<App> create(ingen::World& world); + static std::shared_ptr<App> create(ingen::World& world); void run(); @@ -136,9 +145,9 @@ public: sigc::signal<void, const std::string&> signal_status_text_changed; - inline ingen::World& world() const { return _world; } - inline ingen::URIs& uris() const { return _world.uris(); } - inline ingen::Log& log() const { return _world.log(); } + ingen::World& world() const { return _world; } + ingen::URIs& uris() const { return _world.uris(); } + ingen::Log& log() const { return _world.log(); } protected: explicit App(ingen::World& world); @@ -159,35 +168,35 @@ protected: static Gtk::Main* _main; - SPtr<ingen::Interface> _client; - SPtr<client::ClientStore> _store; - SPtr<ThreadedLoader> _loader; - SPtr<StreamWriter> _dumper; + std::shared_ptr<ingen::Interface> _client; + std::shared_ptr<client::ClientStore> _store; + std::shared_ptr<ThreadedLoader> _loader; + std::shared_ptr<StreamWriter> _dumper; Style* _style; - ConnectWindow* _connect_window; - MessagesWindow* _messages_window; - GraphTreeWindow* _graph_tree_window; - Gtk::AboutDialog* _about_dialog; - WindowFactory* _window_factory; + ConnectWindow* _connect_window = nullptr; + MessagesWindow* _messages_window = nullptr; + GraphTreeWindow* _graph_tree_window = nullptr; + Gtk::AboutDialog* _about_dialog = nullptr; + WindowFactory* _window_factory = nullptr; ingen::World& _world; - int32_t _sample_rate; - int32_t _block_length; - int32_t _n_threads; - float _mean_run_load; - float _min_run_load; - float _max_run_load; + int32_t _sample_rate{48000}; + int32_t _block_length{1024}; + int32_t _n_threads{1}; + float _mean_run_load{0.0f}; + float _min_run_load{0.0f}; + float _max_run_load{0.0f}; std::string _status_text; using ActivityPorts = std::unordered_map<Port*, bool>; ActivityPorts _activity_ports; - bool _enable_signal; - bool _requested_plugins; - bool _is_plugin; + bool _enable_signal{true}; + bool _requested_plugins{false}; + bool _is_plugin{false}; }; } // namespace gui diff --git a/src/gui/Arc.cpp b/src/gui/Arc.cpp index d811bd22..c13cf4a7 100644 --- a/src/gui/Arc.cpp +++ b/src/gui/Arc.cpp @@ -16,24 +16,30 @@ #include "Arc.hpp" -#include "ingen/client/ArcModel.hpp" -#include "ingen/client/BlockModel.hpp" +#include <ganv/Edge.hpp> +#include <ingen/URI.hpp> +#include <ingen/client/ArcModel.hpp> +#include <ingen/client/BlockModel.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <ingen/client/PortModel.hpp> + +#include <glib-object.h> + +#include <memory> #define NS_INTERNALS "http://drobilla.net/ns/ingen-internals#" -namespace ingen { -namespace gui { +namespace ingen::gui { -Arc::Arc(Ganv::Canvas& canvas, - SPtr<const client::ArcModel> model, - Ganv::Node* src, - Ganv::Node* dst) - : Ganv::Edge(canvas, src, dst) - , _arc_model(model) +Arc::Arc(Ganv::Canvas& canvas, + const std::shared_ptr<const client::ArcModel>& model, + Ganv::Node* src, + Ganv::Node* dst) + : Ganv::Edge(canvas, src, dst), _arc_model(model) { - SPtr<const client::ObjectModel> tparent = model->tail()->parent(); - SPtr<const client::BlockModel> tparent_block; - if ((tparent_block = dynamic_ptr_cast<const client::BlockModel>(tparent))) { + const std::shared_ptr<const client::ObjectModel> tparent = model->tail()->parent(); + std::shared_ptr<const client::BlockModel> tparent_block; + if ((tparent_block = std::dynamic_pointer_cast<const client::BlockModel>(tparent))) { if (tparent_block->plugin_uri() == NS_INTERNALS "BlockDelay") { g_object_set(_gobj, "dash-length", 4.0, nullptr); set_constraining(false); @@ -41,5 +47,4 @@ Arc::Arc(Ganv::Canvas& canvas, } } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/Arc.hpp b/src/gui/Arc.hpp index 453985fc..ad1bc6f2 100644 --- a/src/gui/Arc.hpp +++ b/src/gui/Arc.hpp @@ -17,14 +17,20 @@ #ifndef INGEN_GUI_ARC_HPP #define INGEN_GUI_ARC_HPP -#include "ganv/Edge.hpp" -#include "ingen/types.hpp" +#include <ganv/Edge.hpp> -#include <cassert> +#include <memory> + +namespace Ganv { +class Canvas; +class Node; +} // namespace Ganv namespace ingen { -namespace client { class ArcModel; } +namespace client { +class ArcModel; +} // namespace client namespace gui { @@ -35,15 +41,15 @@ namespace gui { class Arc : public Ganv::Edge { public: - Arc(Ganv::Canvas& canvas, - SPtr<const client::ArcModel> model, - Ganv::Node* src, - Ganv::Node* dst); + Arc(Ganv::Canvas& canvas, + const std::shared_ptr<const client::ArcModel>& model, + Ganv::Node* src, + Ganv::Node* dst); - SPtr<const client::ArcModel> model() const { return _arc_model; } + std::shared_ptr<const client::ArcModel> model() const { return _arc_model; } private: - SPtr<const client::ArcModel> _arc_model; + std::shared_ptr<const client::ArcModel> _arc_model; }; } // namespace gui diff --git a/src/gui/BreadCrumbs.cpp b/src/gui/BreadCrumbs.cpp index 33b2c4b3..5bd4d30a 100644 --- a/src/gui/BreadCrumbs.cpp +++ b/src/gui/BreadCrumbs.cpp @@ -17,23 +17,29 @@ #include "BreadCrumbs.hpp" #include "App.hpp" +#include "GraphView.hpp" -#include "ingen/client/SigClientInterface.hpp" +#include <ingen/Message.hpp> +#include <ingen/URI.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/SigClientInterface.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> -#include <boost/variant/get.hpp> +#include <sigc++/adaptors/bind.h> +#include <sigc++/functors/mem_fun.h> +#include <algorithm> #include <string> +#include <variant> -namespace ingen { -namespace gui { +namespace ingen::gui { using std::string; BreadCrumbs::BreadCrumbs(App& app) - : Gtk::HBox() - , _active_path("/") + : _active_path("/") , _full_path("/") - , _enable_signal(true) { app.sig_client()->signal_message().connect( sigc::mem_fun(this, &BreadCrumbs::message)); @@ -41,16 +47,16 @@ BreadCrumbs::BreadCrumbs(App& app) set_can_focus(false); } -SPtr<GraphView> -BreadCrumbs::view(const Raul::Path& path) +std::shared_ptr<GraphView> +BreadCrumbs::view(const raul::Path& path) { - for (const auto& b : _breadcrumbs) { - if (b->path() == path) { - return b->view(); - } - } + const auto b = std::find_if(_breadcrumbs.begin(), + _breadcrumbs.end(), + [&path](const auto* crumb) { + return crumb->path() == path; + }); - return SPtr<GraphView>(); + return b == _breadcrumbs.end() ? nullptr : (*b)->view(); } /** Sets up the crumbs to display `path`. @@ -59,21 +65,22 @@ BreadCrumbs::view(const Raul::Path& path) * children preserved. */ void -BreadCrumbs::build(Raul::Path path, SPtr<GraphView> view) +BreadCrumbs::build(const raul::Path& path, + const std::shared_ptr<GraphView>& view) { - bool old_enable_signal = _enable_signal; + const bool old_enable_signal = _enable_signal; _enable_signal = false; if (!_breadcrumbs.empty() && (path.is_parent_of(_full_path) || path == _full_path)) { // Moving to a path we already contain, just switch the active button - for (const auto& b : _breadcrumbs) { + for (auto* b : _breadcrumbs) { if (b->path() == path) { b->set_active(true); if (!b->view()) { b->set_view(view); } - // views are expensive, having two around for the same graph is a bug + // Views are expensive, having two around is a bug assert(b->view() == view); } else { @@ -82,71 +89,70 @@ BreadCrumbs::build(Raul::Path path, SPtr<GraphView> view) } _active_path = path; - _enable_signal = old_enable_signal; } else if (!_breadcrumbs.empty() && path.is_child_of(_full_path)) { - // Moving to a child of the full path, just append crumbs (preserve view cache) + // Moving to a child of the full path, append crumbs (preserve cache) string suffix = path.substr(_full_path.length()); - while (suffix.length() > 0) { + while (!suffix.empty()) { if (suffix[0] == '/') { suffix = suffix.substr(1); } - const string name = suffix.substr(0, suffix.find("/")); - _full_path = _full_path.child(Raul::Symbol(name)); + const string name = suffix.substr(0, suffix.find('/')); + _full_path = _full_path.child(raul::Symbol(name)); BreadCrumb* but = create_crumb(_full_path, view); pack_start(*but, false, false, 1); _breadcrumbs.push_back(but); but->show(); - if (suffix.find("/") == string::npos) { + if (suffix.find('/') == string::npos) { break; - } else { - suffix = suffix.substr(suffix.find("/")+1); } + + suffix = suffix.substr(suffix.find('/') + 1); } - for (const auto& b : _breadcrumbs) { + for (auto* b : _breadcrumbs) { b->set_active(false); } _breadcrumbs.back()->set_active(true); } else { - // Rebuild from scratch - // Getting here is bad unless absolutely necessary, since the GraphView cache is lost + /* Rebuild from scratch. Getting here is bad unless absolutely + necessary, since the GraphView cache is lost. */ _full_path = path; _active_path = path; // Empty existing breadcrumbs - for (const auto& b : _breadcrumbs) { + for (auto* b : _breadcrumbs) { remove(*b); } _breadcrumbs.clear(); // Add root - BreadCrumb* root_but = create_crumb(Raul::Path("/"), view); + BreadCrumb* root_but = create_crumb(raul::Path("/"), view); pack_start(*root_but, false, false, 1); _breadcrumbs.push_front(root_but); root_but->set_active(root_but->path() == _active_path); - Raul::Path working_path("/"); + raul::Path working_path("/"); string suffix = path.substr(1); - while (suffix.length() > 0) { + while (!suffix.empty()) { if (suffix[0] == '/') { suffix = suffix.substr(1); } - const string name = suffix.substr(0, suffix.find("/")); - working_path = working_path.child(Raul::Symbol(name)); + const string name = suffix.substr(0, suffix.find('/')); + working_path = working_path.child(raul::Symbol(name)); BreadCrumb* but = create_crumb(working_path, view); pack_start(*but, false, false, 1); _breadcrumbs.push_back(but); but->set_active(working_path == _active_path); but->show(); - if (suffix.find("/") == string::npos) { + if (suffix.find('/') == string::npos) { break; - } else { - suffix = suffix.substr(suffix.find("/")+1); } + + suffix = suffix.substr(suffix.find('/')+1); } } @@ -157,13 +163,11 @@ BreadCrumbs::build(Raul::Path path, SPtr<GraphView> view) * match, otherwise ignoring `view`. */ BreadCrumbs::BreadCrumb* -BreadCrumbs::create_crumb(const Raul::Path& path, - SPtr<GraphView> view) +BreadCrumbs::create_crumb(const raul::Path& path, + const std::shared_ptr<GraphView>& view) { - BreadCrumb* but = manage( - new BreadCrumb(path, - ((view && path == view->graph()->path()) - ? view : SPtr<GraphView>()))); + BreadCrumb* but = manage(new BreadCrumb( + path, ((view && path == view->graph()->path()) ? view : nullptr))); but->signal_toggled().connect( sigc::bind(sigc::mem_fun(this, &BreadCrumbs::breadcrumb_clicked), @@ -194,7 +198,7 @@ BreadCrumbs::breadcrumb_clicked(BreadCrumb* crumb) void BreadCrumbs::message(const Message& msg) { - if (const Del* const del = boost::get<Del>(&msg)) { + if (const Del* const del = std::get_if<Del>(&msg)) { object_destroyed(del->uri); } } @@ -202,28 +206,31 @@ BreadCrumbs::message(const Message& msg) void BreadCrumbs::object_destroyed(const URI& uri) { - for (auto i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) { - if ((*i)->path() == uri.c_str()) { - // Remove all crumbs after the removed one (inclusive) - for (auto j = i; j != _breadcrumbs.end(); ) { - BreadCrumb* bc = *j; - j = _breadcrumbs.erase(j); - remove(*bc); - } - break; + const auto i = std::find_if(_breadcrumbs.begin(), + _breadcrumbs.end(), + [&uri](const auto& b) { + return b->path() == uri.c_str(); + }); + + if (i != _breadcrumbs.end()) { + // Remove all crumbs after the removed one (inclusive) + for (auto j = i; j != _breadcrumbs.end();) { + BreadCrumb* const bc = *j; + + j = _breadcrumbs.erase(j); + remove(*bc); } } } void -BreadCrumbs::object_moved(const Raul::Path& old_path, const Raul::Path& new_path) +BreadCrumbs::object_moved(const raul::Path& old_path, const raul::Path& new_path) { - for (const auto& b : _breadcrumbs) { + for (auto* b : _breadcrumbs) { if (b->path() == old_path) { b->set_path(new_path); } } } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/BreadCrumbs.hpp b/src/gui/BreadCrumbs.hpp index 63872a78..89a339f2 100644 --- a/src/gui/BreadCrumbs.hpp +++ b/src/gui/BreadCrumbs.hpp @@ -19,21 +19,26 @@ #include "GraphView.hpp" -#include "ingen/Message.hpp" -#include "ingen/client/GraphModel.hpp" -#include "ingen/types.hpp" -#include "raul/Path.hpp" +#include <ingen/Message.hpp> +#include <ingen/URI.hpp> +#include <ingen/client/GraphModel.hpp> +#include <raul/Path.hpp> +#include <glibmm/ustring.h> #include <gtkmm/box.h> #include <gtkmm/label.h> +#include <gtkmm/object.h> #include <gtkmm/togglebutton.h> +#include <sigc++/signal.h> #include <cassert> #include <list> +#include <memory> #include <string> -namespace ingen { -namespace gui { +namespace ingen::gui { + +class App; /** Collection of breadcrumb buttons forming a path. * This doubles as a cache for GraphViews. @@ -45,11 +50,12 @@ class BreadCrumbs : public Gtk::HBox public: explicit BreadCrumbs(App& app); - SPtr<GraphView> view(const Raul::Path& path); + std::shared_ptr<GraphView> view(const raul::Path& path); - void build(Raul::Path path, SPtr<GraphView> view); + void build(const raul::Path& path, const std::shared_ptr<GraphView>& view); - sigc::signal<void, const Raul::Path&, SPtr<GraphView> > signal_graph_selected; + sigc::signal<void, const raul::Path&, std::shared_ptr<GraphView>> + signal_graph_selected; private: /** Breadcrumb button. @@ -64,9 +70,9 @@ private: class BreadCrumb : public Gtk::ToggleButton { public: - BreadCrumb(const Raul::Path& path, SPtr<GraphView> view = SPtr<GraphView>()) - : _path(path) - , _view(view) + BreadCrumb(const raul::Path& path, + const std::shared_ptr<GraphView>& view) + : _path(path), _view(view) { assert(!view || view->graph()->path() == path); set_border_width(0); @@ -75,15 +81,19 @@ private: show_all(); } - void set_view(SPtr<GraphView> view) { + explicit BreadCrumb(const raul::Path& path) + : BreadCrumb{path, nullptr} + {} + + void set_view(const std::shared_ptr<GraphView>& view) { assert(!view || view->graph()->path() == _path); _view = view; } - const Raul::Path& path() const { return _path; } - SPtr<GraphView> view() const { return _view; } + const raul::Path& path() const { return _path; } + std::shared_ptr<GraphView> view() const { return _view; } - void set_path(const Raul::Path& path) { + void set_path(const raul::Path& path) { remove(); const char* text = (path.is_root()) ? "/" : path.symbol(); Gtk::Label* lab = manage(new Gtk::Label(text)); @@ -91,31 +101,31 @@ private: lab->show(); add(*lab); - if (_view && _view->graph()->path() != path) + if (_view && _view->graph()->path() != path) { _view.reset(); + } } private: - Raul::Path _path; - SPtr<GraphView> _view; + raul::Path _path; + std::shared_ptr<GraphView> _view; }; - BreadCrumb* create_crumb(const Raul::Path& path, - SPtr<GraphView> view = SPtr<GraphView>()); + BreadCrumb* create_crumb(const raul::Path& path, + const std::shared_ptr<GraphView>& view = nullptr); void breadcrumb_clicked(BreadCrumb* crumb); void message(const Message& msg); void object_destroyed(const URI& uri); - void object_moved(const Raul::Path& old_path, const Raul::Path& new_path); + void object_moved(const raul::Path& old_path, const raul::Path& new_path); - Raul::Path _active_path; - Raul::Path _full_path; - bool _enable_signal; + raul::Path _active_path; + raul::Path _full_path; + bool _enable_signal{true}; std::list<BreadCrumb*> _breadcrumbs; }; -} // namespace gui -} // namespace ingen +} // namespace ingen::gui #endif // INGEN_GUI_BREADCRUMBS_HPP diff --git a/src/gui/ConnectWindow.cpp b/src/gui/ConnectWindow.cpp index 209475e0..edafdfa4 100644 --- a/src/gui/ConnectWindow.cpp +++ b/src/gui/ConnectWindow.cpp @@ -17,69 +17,71 @@ #include "ConnectWindow.hpp" #include "App.hpp" +#include "Window.hpp" #include "WindowFactory.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/EngineBase.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Log.hpp" -#include "ingen/Module.hpp" -#include "ingen/QueuedInterface.hpp" -#include "ingen/World.hpp" -#include "ingen/client/ClientStore.hpp" -#include "ingen/client/GraphModel.hpp" -#include "ingen/client/SigClientInterface.hpp" -#include "ingen/client/SocketClient.hpp" -#include "ingen_config.h" -#include "raul/Process.hpp" - -#include <boost/variant/get.hpp> +#include <ingen/Atom.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/EngineBase.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Log.hpp> +#include <ingen/Message.hpp> +#include <ingen/QueuedInterface.hpp> +#include <ingen/Status.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/ClientStore.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/SigClientInterface.hpp> +#include <ingen/client/SocketClient.hpp> +#include <ingen/fmt.hpp> +#include <ingen/paths.hpp> +#include <raul/Path.hpp> +#include <raul/Process.hpp> + #include <glib.h> +#include <glibmm/main.h> +#include <glibmm/ustring.h> +#include <gtkmm/builder.h> +#include <gtkmm/button.h> +#include <gtkmm/dialog.h> +#include <gtkmm/entry.h> +#include <gtkmm/enums.h> +#include <gtkmm/image.h> +#include <gtkmm/label.h> +#include <gtkmm/main.h> +#include <gtkmm/progressbar.h> +#include <gtkmm/radiobutton.h> +#include <gtkmm/spinbutton.h> #include <gtkmm/stock.h> +#include <sigc++/adaptors/bind.h> +#include <sigc++/functors/mem_fun.h> +#include <sigc++/functors/slot.h> +#include <sigc++/signal.h> #include <limits> +#include <memory> #include <string> +#include <sys/time.h> #include <utility> +#include <variant> -using namespace ingen::client; - -namespace ingen { -namespace gui { +namespace ingen::gui { ConnectWindow::ConnectWindow(BaseObjectType* cobject, Glib::RefPtr<Gtk::Builder> xml) : Dialog(cobject) , _xml(std::move(xml)) - , _icon(nullptr) - , _progress_bar(nullptr) - , _progress_label(nullptr) - , _url_entry(nullptr) - , _server_radio(nullptr) - , _port_spinbutton(nullptr) - , _launch_radio(nullptr) - , _internal_radio(nullptr) - , _activate_button(nullptr) - , _deactivate_button(nullptr) - , _disconnect_button(nullptr) - , _connect_button(nullptr) - , _quit_button(nullptr) - , _mode(Mode::CONNECT_REMOTE) - , _connect_uri("unix:///tmp/ingen.sock") - , _ping_id(-1) - , _attached(false) - , _finished_connecting(false) - , _widgets_loaded(false) - , _connect_stage(0) - , _quit_flag(false) -{ -} +{} void ConnectWindow::message(const Message& msg) { - if (const Response* const r = boost::get<Response>(&msg)) { + if (const Response* const r = std::get_if<Response>(&msg)) { ingen_response(r->id, r->status, r->subject); - } else if (const Error* const e = boost::get<Error>(&msg)) { + } else if (const Error* const e = std::get_if<Error>(&msg)) { error(e->message); } } @@ -111,7 +113,7 @@ ConnectWindow::start(App& app, ingen::World& world) } set_connected_to(world.interface()); - connect(bool(world.interface())); + connect(!!world.interface()); } void @@ -129,7 +131,7 @@ ConnectWindow::ingen_response(int32_t id, } void -ConnectWindow::set_connected_to(SPtr<ingen::Interface> engine) +ConnectWindow::set_connected_to(const std::shared_ptr<ingen::Interface>& engine) { _app->world().set_interface(engine); @@ -195,10 +197,10 @@ ConnectWindow::connect_remote(const URI& uri) { ingen::World& world = _app->world(); - SPtr<SigClientInterface> sci(new SigClientInterface()); - SPtr<QueuedInterface> qi(new QueuedInterface(sci)); + auto sci = std::make_shared<client::SigClientInterface>(); + auto qi = std::make_shared<QueuedInterface>(sci); - SPtr<ingen::Interface> iface(world.new_interface(uri, qi)); + const std::shared_ptr<ingen::Interface> iface{world.new_interface(uri, qi)}; if (iface) { world.set_interface(iface); _app->attach(qi); @@ -216,10 +218,10 @@ ConnectWindow::connect(bool existing) if (_app->client()) { error("Already connected"); return; - } else if (_attached) { - _attached = false; } + _attached = false; + set_connecting_widget_states(); _connect_stage = 0; @@ -230,7 +232,7 @@ ConnectWindow::connect(bool existing) if (existing) { uri_str = world.interface()->uri(); _connect_stage = 1; - SPtr<client::SocketClient> client = dynamic_ptr_cast<client::SocketClient>( + auto client = std::dynamic_pointer_cast<client::SocketClient>( world.interface()); if (client) { _app->attach(client->respondee()); @@ -254,7 +256,7 @@ ConnectWindow::connect(bool existing) const std::string port = std::to_string(_port_spinbutton->get_value_as_int()); const char* cmd[] = { "ingen", "-e", "-E", port.c_str(), nullptr }; - if (!Raul::Process::launch(cmd)) { + if (!raul::Process::launch(cmd)) { error("Failed to launch engine process"); return; } @@ -266,10 +268,14 @@ ConnectWindow::connect(bool existing) if (!world.load_module("server")) { error("Failed to load server module"); return; - } else if (!world.load_module("jack")) { + } + + if (!world.load_module("jack")) { error("Failed to load jack module"); return; - } else if (!world.engine()->activate()) { + } + + if (!world.engine()->activate()) { error("Failed to activate engine"); return; } @@ -291,7 +297,7 @@ ConnectWindow::disconnect() _attached = false; _app->detach(); - set_connected_to(SPtr<ingen::Interface>()); + set_connected_to(nullptr); if (!_widgets_loaded) { return; @@ -437,18 +443,17 @@ ConnectWindow::internal_toggled() void ConnectWindow::next_stage() { - static const char* labels[] = { - "Connecting...", - "Pinging engine...", - "Attaching to engine...", - "Requesting root graph...", - "Waiting for root graph...", - "Connected" - }; - - ++_connect_stage; if (_widgets_loaded) { + static const char* labels[] = { + "Connecting...", + "Pinging engine...", + "Attaching to engine...", + "Requesting root graph...", + "Waiting for root graph...", + "Connected" + }; + _progress_label->set_text(labels[_connect_stage]); } } @@ -463,7 +468,7 @@ ConnectWindow::gtk_callback() } // Timing stuff for repeated attach attempts - timeval now; + timeval now = {}; gettimeofday(&now, nullptr); static const timeval start = now; static timeval last = now; @@ -471,8 +476,8 @@ ConnectWindow::gtk_callback() // Show if attempted connection goes on for a noticeable amount of time if (!is_visible()) { - const float ms_since_start = (now.tv_sec - start.tv_sec) * 1000.0f + - (now.tv_usec - start.tv_usec) * 0.001f; + const float ms_since_start = ((now.tv_sec - start.tv_sec) * 1000.0f) + + ((now.tv_usec - start.tv_usec) * 0.001f); if (ms_since_start > 500) { present(); set_connecting_widget_states(); @@ -480,12 +485,12 @@ ConnectWindow::gtk_callback() } if (_connect_stage == 0) { - const float ms_since_last = (now.tv_sec - last.tv_sec) * 1000.0f + - (now.tv_usec - last.tv_usec) * 0.001f; + const float ms_since_last = ((now.tv_sec - last.tv_sec) * 1000.0f) + + ((now.tv_usec - last.tv_usec) * 0.001f); if (ms_since_last >= 250) { last = now; if (_mode == Mode::INTERNAL) { - SPtr<SigClientInterface> client(new SigClientInterface()); + auto client = std::make_shared<client::SigClientInterface>(); _app->world().interface()->set_respondee(client); _app->attach(client); _app->register_callbacks(); @@ -510,8 +515,8 @@ ConnectWindow::gtk_callback() if (_attached) { next_stage(); } else { - const float ms_since_last = (now.tv_sec - last.tv_sec) * 1000.0f + - (now.tv_usec - last.tv_usec) * 0.001f; + const float ms_since_last = ((now.tv_sec - last.tv_sec) * 1000.0f) + + ((now.tv_usec - last.tv_usec) * 0.001f); if (attempts > 10) { error("Failed to ping engine"); _connect_stage = -1; @@ -527,8 +532,8 @@ ConnectWindow::gtk_callback() next_stage(); } else if (_connect_stage == 4) { if (!_app->store()->empty()) { - SPtr<const GraphModel> root = dynamic_ptr_cast<const GraphModel>( - _app->store()->object(Raul::Path("/"))); + auto root = std::dynamic_pointer_cast<const client::GraphModel>( + _app->store()->object(raul::Path("/"))); if (root) { set_connected_to(_app->interface()); _app->window_factory()->present_graph(root); @@ -557,9 +562,9 @@ ConnectWindow::gtk_callback() _progress_label->set_text(std::string("Disconnected")); } return false; - } else { - return true; } + + return true; } void @@ -569,5 +574,4 @@ ConnectWindow::quit() Gtk::Main::quit(); } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/ConnectWindow.hpp b/src/gui/ConnectWindow.hpp index 882e0142..cd9059e1 100644 --- a/src/gui/ConnectWindow.hpp +++ b/src/gui/ConnectWindow.hpp @@ -19,24 +19,30 @@ #include "Window.hpp" -#include "ingen/Message.hpp" -#include "ingen/types.hpp" -#include "lilv/lilv.h" +#include <ingen/Message.hpp> +#include <ingen/URI.hpp> +#include <glibmm/refptr.h> #include <gtkmm/builder.h> -#include <gtkmm/button.h> -#include <gtkmm/entry.h> -#include <gtkmm/image.h> -#include <gtkmm/label.h> -#include <gtkmm/progressbar.h> -#include <gtkmm/radiobutton.h> -#include <gtkmm/spinbutton.h> #include <cstdint> +#include <memory> #include <string> +namespace Gtk { +class Button; +class Entry; +class Image; +class Label; +class ProgressBar; +class RadioButton; +class SpinButton; +} // namespace Gtk + namespace ingen { +enum class Status; + class Interface; class World; @@ -57,7 +63,7 @@ public: ConnectWindow(BaseObjectType* cobject, Glib::RefPtr<Gtk::Builder> xml); - void set_connected_to(SPtr<ingen::Interface> engine); + void set_connected_to(const std::shared_ptr<ingen::Interface>& engine); void start(App& app, ingen::World& world); bool attached() const { return _finished_connecting; } @@ -94,28 +100,28 @@ private: const Glib::RefPtr<Gtk::Builder> _xml; - Gtk::Image* _icon; - Gtk::ProgressBar* _progress_bar; - Gtk::Label* _progress_label; - Gtk::Entry* _url_entry; - Gtk::RadioButton* _server_radio; - Gtk::SpinButton* _port_spinbutton; - Gtk::RadioButton* _launch_radio; - Gtk::RadioButton* _internal_radio; - Gtk::Button* _activate_button; - Gtk::Button* _deactivate_button; - Gtk::Button* _disconnect_button; - Gtk::Button* _connect_button; - Gtk::Button* _quit_button; - - Mode _mode; - URI _connect_uri; - int32_t _ping_id; - bool _attached; - bool _finished_connecting; - bool _widgets_loaded; - int _connect_stage; - bool _quit_flag; + Gtk::Image* _icon{nullptr}; + Gtk::ProgressBar* _progress_bar{nullptr}; + Gtk::Label* _progress_label{nullptr}; + Gtk::Entry* _url_entry{nullptr}; + Gtk::RadioButton* _server_radio{nullptr}; + Gtk::SpinButton* _port_spinbutton{nullptr}; + Gtk::RadioButton* _launch_radio{nullptr}; + Gtk::RadioButton* _internal_radio{nullptr}; + Gtk::Button* _activate_button{nullptr}; + Gtk::Button* _deactivate_button{nullptr}; + Gtk::Button* _disconnect_button{nullptr}; + Gtk::Button* _connect_button{nullptr}; + Gtk::Button* _quit_button{nullptr}; + + Mode _mode{Mode::CONNECT_REMOTE}; + URI _connect_uri{"unix:///tmp/ingen.sock"}; + int32_t _ping_id{-1}; + bool _attached{false}; + bool _finished_connecting{false}; + bool _widgets_loaded{false}; + int _connect_stage{0}; + bool _quit_flag{false}; }; } // namespace gui diff --git a/src/gui/GraphBox.cpp b/src/gui/GraphBox.cpp index 5ce54d99..47c567e3 100644 --- a/src/gui/GraphBox.cpp +++ b/src/gui/GraphBox.cpp @@ -1,6 +1,6 @@ /* This file is part of Ingen. - Copyright 2007-2017 David Robillard <http://drobilla.net/> + Copyright 2007-2024 David Robillard <http://drobilla.net/> Ingen is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free @@ -14,6 +14,8 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ +#include "GraphBox.hpp" + #include "App.hpp" #include "BreadCrumbs.hpp" #include "ConnectWindow.hpp" @@ -21,38 +23,93 @@ #include "GraphTreeWindow.hpp" #include "GraphView.hpp" #include "GraphWindow.hpp" -#include "LoadGraphWindow.hpp" -#include "LoadPluginWindow.hpp" #include "MessagesWindow.hpp" -#include "NewSubgraphWindow.hpp" -#include "Style.hpp" #include "ThreadedLoader.hpp" #include "WidgetFactory.hpp" #include "WindowFactory.hpp" #include "ingen_config.h" -#include "ingen/Configuration.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Log.hpp" -#include "ingen/client/ClientStore.hpp" -#include "ingen/client/GraphModel.hpp" -#include "ingen/fmt.hpp" - -#include <boost/format.hpp> +#include <ganv/canvas.h> +#include <ingen/Atom.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/BlockModel.hpp> +#include <ingen/client/ClientStore.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <ingen/client/PluginModel.hpp> +#include <ingen/client/PortModel.hpp> +#include <ingen/fmt.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> + +#include <gdk/gdk.h> +#include <glib.h> #include <glib/gstdio.h> +#include <glibmm/convert.h> #include <glibmm/fileutils.h> +#include <glibmm/miscutils.h> +#include <glibmm/propertyproxy.h> +#include <glibmm/refptr.h> +#include <glibmm/ustring.h> +#include <gtkmm/alignment.h> +#include <gtkmm/box.h> +#include <gtkmm/builder.h> +#include <gtkmm/button.h> +#include <gtkmm/checkbutton.h> +#include <gtkmm/checkmenuitem.h> +#include <gtkmm/clipboard.h> +#include <gtkmm/container.h> +#include <gtkmm/dialog.h> +#include <gtkmm/enums.h> +#include <gtkmm/filechooser.h> +#include <gtkmm/filechooserdialog.h> +#include <gtkmm/filefilter.h> +#include <gtkmm/label.h> +#include <gtkmm/menuitem.h> +#include <gtkmm/messagedialog.h> +#include <gtkmm/object.h> +#include <gtkmm/paned.h> +#include <gtkmm/scrolledwindow.h> +#include <gtkmm/statusbar.h> #include <gtkmm/stock.h> -#ifdef HAVE_WEBKIT -#include <webkit/webkit.h> +#include <gtkmm/textbuffer.h> +#include <gtkmm/textview.h> +#include <gtkmm/toolitem.h> +#include <gtkmm/widget.h> +#include <sigc++/adaptors/retype_return.h> +#include <sigc++/connection.h> +#include <sigc++/functors/mem_fun.h> +#include <sigc++/signal.h> + +#if USE_WEBKIT +# include <webkit/webkit.h> #endif +#include <algorithm> #include <cassert> +#include <cstdint> +#include <cstdio> +#include <limits> +#include <map> +#include <memory> #include <sstream> #include <string> +#include <utility> namespace ingen { -using namespace client; +using client::BlockModel; +using client::GraphModel; +using client::ObjectModel; +using client::PluginModel; +using client::PortModel; namespace gui { @@ -63,11 +120,6 @@ static const int STATUS_CONTEXT_HOVER = 2; GraphBox::GraphBox(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml) : Gtk::VBox(cobject) - , _app(nullptr) - , _window(nullptr) - , _breadcrumbs(nullptr) - , _has_shown_documentation(false) - , _enable_signal(true) { property_visible() = false; @@ -176,7 +228,7 @@ GraphBox::GraphBox(BaseObjectType* cobject, _menu_view_graph_properties->signal_activate().connect( sigc::mem_fun(this, &GraphBox::event_show_properties)); - Glib::RefPtr<Gtk::Clipboard> clipboard = Gtk::Clipboard::get(); + const Glib::RefPtr<Gtk::Clipboard> clipboard = Gtk::Clipboard::get(); clipboard->signal_owner_change().connect( sigc::mem_fun(this, &GraphBox::event_clipboard_changed)); @@ -194,21 +246,25 @@ GraphBox::~GraphBox() delete _breadcrumbs; } -SPtr<GraphBox> -GraphBox::create(App& app, SPtr<const GraphModel> graph) +std::shared_ptr<GraphBox> +GraphBox::create(App& app, const std::shared_ptr<const GraphModel>& graph) { GraphBox* result = nullptr; - Glib::RefPtr<Gtk::Builder> xml = WidgetFactory::create("graph_win"); + const Glib::RefPtr<Gtk::Builder> xml = WidgetFactory::create("graph_win"); xml->get_widget_derived("graph_win_vbox", result); + if (!result) { + return {}; + } + result->init_box(app); - result->set_graph(graph, SPtr<GraphView>()); + result->set_graph(graph, nullptr); if (app.is_plugin()) { result->_menu_close->set_sensitive(false); result->_menu_quit->set_sensitive(false); } - return SPtr<GraphBox>(result); + return std::shared_ptr<GraphBox>(result); } void @@ -248,13 +304,14 @@ GraphBox::set_status_text(const std::string& text) } void -GraphBox::set_graph_from_path(const Raul::Path& path, SPtr<GraphView> view) +GraphBox::set_graph_from_path(const raul::Path& path, + const std::shared_ptr<GraphView>& view) { if (view) { assert(view->graph()->path() == path); _app->window_factory()->present_graph(view->graph(), _window, view); } else { - SPtr<const GraphModel> model = dynamic_ptr_cast<const GraphModel>( + auto model = std::dynamic_pointer_cast<const GraphModel>( _app->store()->object(path)); if (model) { _app->window_factory()->present_graph(model, _window); @@ -267,8 +324,8 @@ GraphBox::set_graph_from_path(const Raul::Path& path, SPtr<GraphView> view) * If `view` is null, a new view will be created. */ void -GraphBox::set_graph(SPtr<const GraphModel> graph, - SPtr<GraphView> view) +GraphBox::set_graph(const std::shared_ptr<const GraphModel>& graph, + const std::shared_ptr<GraphView>& view) { if (!graph || graph == _graph) { return; @@ -307,11 +364,11 @@ GraphBox::set_graph(SPtr<const GraphModel> graph, // Add view to our alignment if (_view->get_parent()) { - _view->get_parent()->remove(*_view.get()); + _view->get_parent()->remove(*_view); } _alignment->remove(); - _alignment->add(*_view.get()); + _alignment->add(*_view); if (_breadcrumbs->get_parent()) { _breadcrumbs->get_parent()->remove(*_breadcrumbs); @@ -326,14 +383,14 @@ GraphBox::set_graph(SPtr<const GraphModel> graph, _menu_view_control_window->property_sensitive() = false; - for (const auto& p : graph->ports()) { - if (_app->can_control(p.get())) { - _menu_view_control_window->property_sensitive() = true; - break; - } - } + _menu_view_control_window->property_sensitive() = + std::any_of(graph->ports().begin(), + graph->ports().end(), + [this](const auto& p) { + return _app->can_control(p.get()); + }); - _menu_parent->property_sensitive() = bool(graph->parent()); + _menu_parent->property_sensitive() = !!graph->parent(); new_port_connection = graph->signal_new_port().connect( sigc::mem_fun(this, &GraphBox::graph_port_added)); @@ -355,7 +412,7 @@ GraphBox::set_graph(SPtr<const GraphModel> graph, } void -GraphBox::graph_port_added(SPtr<const PortModel> port) +GraphBox::graph_port_added(const std::shared_ptr<const PortModel>& port) { if (port->is_input() && _app->can_control(port.get())) { _menu_view_control_window->property_sensitive() = true; @@ -363,20 +420,18 @@ GraphBox::graph_port_added(SPtr<const PortModel> port) } void -GraphBox::graph_port_removed(SPtr<const PortModel> port) +GraphBox::graph_port_removed(const std::shared_ptr<const PortModel>& port) { if (!(port->is_input() && _app->can_control(port.get()))) { return; } - for (const auto& p : _graph->ports()) { - if (p->is_input() && _app->can_control(p.get())) { - _menu_view_control_window->property_sensitive() = true; - return; - } - } - - _menu_view_control_window->property_sensitive() = false; + _menu_view_control_window->property_sensitive() = + std::any_of(_graph->ports().begin(), + _graph->ports().end(), + [this](const auto& p) { + return p->is_input() && _app->can_control(p.get()); + }); } void @@ -397,7 +452,7 @@ GraphBox::set_documentation(const std::string& doc, bool html) _doc_scrolledwindow->hide(); return; } -#ifdef HAVE_WEBKIT +#if USE_WEBKIT WebKitWebView* view = WEBKIT_WEB_VIEW(webkit_web_view_new()); webkit_web_view_load_html_string(view, doc.c_str(), ""); Gtk::Widget* widget = Gtk::manage(Glib::wrap(GTK_WIDGET(view))); @@ -425,7 +480,7 @@ GraphBox::show_status(const ObjectModel* model) show_port_status(port, port->value()); } else if ((block = dynamic_cast<const BlockModel*>(model))) { - const PluginModel* plugin = dynamic_cast<const PluginModel*>(block->plugin()); + const auto* plugin = dynamic_cast<const PluginModel*>(block->plugin()); if (plugin) { msg << fmt(" (%1%)", plugin->human_name()); } @@ -441,7 +496,7 @@ GraphBox::show_port_status(const PortModel* port, const Atom& value) const BlockModel* parent = dynamic_cast<const BlockModel*>(port->parent().get()); if (parent) { - const PluginModel* plugin = dynamic_cast<const PluginModel*>(parent->plugin()); + const auto* plugin = dynamic_cast<const PluginModel*>(parent->plugin()); if (plugin) { const std::string& human_name = plugin->port_human_name(port->index()); if (!human_name.empty()) { @@ -482,7 +537,7 @@ GraphBox::event_show_engine() void GraphBox::event_clipboard_changed(GdkEventOwnerChange* ev) { - Glib::RefPtr<Gtk::Clipboard> clipboard = Gtk::Clipboard::get(); + const Glib::RefPtr<Gtk::Clipboard> clipboard = Gtk::Clipboard::get(); _menu_paste->set_sensitive(clipboard->wait_is_text_available()); } @@ -591,8 +646,8 @@ GraphBox::event_save_as() filename += ".ingen"; basename += ".ingen"; } else if (filename.substr(filename.length() - 4) == ".ttl") { - const Glib::ustring dir = Glib::path_get_dirname(filename); - if (dir.substr(dir.length() - 6) != ".ingen") { + const Glib::ustring dirname = Glib::path_get_dirname(filename); + if (dirname.substr(dirname.length() - 6) != ".ingen") { error("<b>File does not appear to be in an Ingen bundle."); } } else if (filename.substr(filename.length() - 6) != ".ingen") { @@ -602,7 +657,7 @@ GraphBox::event_save_as() const std::string symbol(basename.substr(0, basename.find('.'))); - if (!Raul::Symbol::is_valid(symbol)) { + if (!raul::Symbol::is_valid(symbol)) { error( "<b>Ingen bundle names must be valid symbols.</b>", "All characters must be _, a-z, A-Z, or 0-9, but the first may not be 0-9."); @@ -664,24 +719,23 @@ GraphBox::event_export_image() dialog.set_transient_for(*_window); } - using Types = std::map<std::string, std::string>; - Types types; + std::map<std::string, std::string> types; types["*.dot"] = "Graphviz DOT"; types["*.pdf"] = "Portable Document Format"; types["*.ps"] = "PostScript"; types["*.svg"] = "Scalable Vector Graphics"; - for (Types::const_iterator t = types.begin(); t != types.end(); ++t) { + for (const auto& t : types) { Gtk::FileFilter filt; - filt.add_pattern(t->first); - filt.set_name(t->second); + filt.add_pattern(t.first); + filt.set_name(t.second); dialog.add_filter(filt); - if (t->first == "*.pdf") { + if (t.first == "*.pdf") { dialog.set_filter(filt); } } - Gtk::CheckButton* bg_but = new Gtk::CheckButton("Draw _Background", true); - Gtk::Alignment* extra = new Gtk::Alignment(1.0, 0.5, 0.0, 0.0); + auto* bg_but = new Gtk::CheckButton("Draw _Background", true); + auto* extra = new Gtk::Alignment(1.0, 0.5, 0.0, 0.0); bg_but->set_active(true); extra->add(*Gtk::manage(bg_but)); extra->show_all(); @@ -813,7 +867,9 @@ GraphBox::event_arrange() void GraphBox::event_parent_activated() { - SPtr<client::GraphModel> parent = dynamic_ptr_cast<client::GraphModel>(_graph->parent()); + auto parent = + std::dynamic_pointer_cast<client::GraphModel>(_graph->parent()); + if (parent) { _app->window_factory()->present_graph(parent, _window); } @@ -828,10 +884,10 @@ GraphBox::event_refresh_activated() void GraphBox::event_fullscreen_toggled() { - // FIXME: ugh, use GTK signals to track state and know for sure - static bool is_fullscreen = false; - if (_window) { + // FIXME: ugh, use GTK signals to track state and know for sure + static bool is_fullscreen = false; + if (!is_fullscreen) { _window->fullscreen(); is_fullscreen = true; @@ -873,7 +929,7 @@ GraphBox::event_animate_signals_toggled() _app->interface()->set_property( URI("ingen:/clients/this"), _app->uris().ingen_broadcast, - _app->forge().make((bool)_menu_animate_signals->get_active())); + _app->forge().make(_menu_animate_signals->get_active())); } void diff --git a/src/gui/GraphBox.hpp b/src/gui/GraphBox.hpp index 93599e0b..07962a3d 100644 --- a/src/gui/GraphBox.hpp +++ b/src/gui/GraphBox.hpp @@ -17,47 +17,52 @@ #ifndef INGEN_GUI_GRAPH_BOX_HPP #define INGEN_GUI_GRAPH_BOX_HPP -#include <string> +#include <ingen/ingen.h> +#include <gdk/gdk.h> +#include <glibmm/ustring.h> #include <gtkmm/alignment.h> #include <gtkmm/box.h> -#include <gtkmm/builder.h> -#include <gtkmm/menushell.h> -#include <gtkmm/messagedialog.h> -#include <gtkmm/paned.h> #include <gtkmm/scrolledwindow.h> -#include <gtkmm/statusbar.h> +#include <sigc++/connection.h> -#include "ingen/ingen.h" -#include "ingen/types.hpp" +#include <memory> +#include <string> -#include "Window.hpp" +namespace Glib { +template <class T> class RefPtr; +} // namespace Glib -namespace Raul { -class Atom; +namespace Gtk { +class Builder; +class CheckMenuItem; +class HPaned; +class Label; +class MenuItem; +class Statusbar; +} // namespace Gtk + +namespace raul { class Path; -} +} // namespace raul namespace ingen { +class Atom; class URI; namespace client { class GraphModel; class PortModel; class ObjectModel; -} +} // namespace client namespace gui { +class App; class BreadCrumbs; -class LoadGraphBox; -class LoadPluginWindow; -class NewSubgraphWindow; -class GraphDescriptionWindow; class GraphView; class GraphWindow; -class SubgraphModule; /** A window for a graph. * @@ -68,37 +73,39 @@ class INGEN_API GraphBox : public Gtk::VBox public: GraphBox(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml); - ~GraphBox(); - static SPtr<GraphBox> create( - App& app, SPtr<const client::GraphModel> graph); + ~GraphBox() override; + + static std::shared_ptr<GraphBox> + create(App& app, const std::shared_ptr<const client::GraphModel>& graph); void init_box(App& app); void set_status_text(const std::string& text); - void set_graph(SPtr<const client::GraphModel> graph, - SPtr<GraphView> view); + void set_graph(const std::shared_ptr<const client::GraphModel>& graph, + const std::shared_ptr<GraphView>& view); void set_window(GraphWindow* win) { _window = win; } bool documentation_is_visible() { return _doc_scrolledwindow->is_visible(); } void set_documentation(const std::string& doc, bool html); - SPtr<const client::GraphModel> graph() const { return _graph; } - SPtr<GraphView> view() const { return _view; } + std::shared_ptr<const client::GraphModel> graph() const { return _graph; } + std::shared_ptr<GraphView> view() const { return _view; } void show_port_status(const client::PortModel* port, const Atom& value); - void set_graph_from_path(const Raul::Path& path, SPtr<GraphView> view); + void set_graph_from_path(const raul::Path& path, + const std::shared_ptr<GraphView>& view); void object_entered(const client::ObjectModel* model); void object_left(const client::ObjectModel* model); private: - void graph_port_added(SPtr<const client::PortModel> port); - void graph_port_removed(SPtr<const client::PortModel> port); + void graph_port_added(const std::shared_ptr<const client::PortModel>& port); + void graph_port_removed(const std::shared_ptr<const client::PortModel>& port); void property_changed(const URI& predicate, const Atom& value); void show_status(const client::ObjectModel* model); @@ -143,59 +150,59 @@ private: void event_show_engine(); void event_clipboard_changed(GdkEventOwnerChange* ev); - App* _app; - SPtr<const client::GraphModel> _graph; - SPtr<GraphView> _view; - GraphWindow* _window; + App* _app = nullptr; + std::shared_ptr<const client::GraphModel> _graph; + std::shared_ptr<GraphView> _view; + GraphWindow* _window = nullptr; sigc::connection new_port_connection; sigc::connection removed_port_connection; sigc::connection edit_mode_connection; - Gtk::MenuItem* _menu_import; - Gtk::MenuItem* _menu_save; - Gtk::MenuItem* _menu_save_as; - Gtk::MenuItem* _menu_export_image; - Gtk::MenuItem* _menu_redo; - Gtk::MenuItem* _menu_undo; - Gtk::MenuItem* _menu_cut; - Gtk::MenuItem* _menu_copy; - Gtk::MenuItem* _menu_paste; - Gtk::MenuItem* _menu_delete; - Gtk::MenuItem* _menu_select_all; - Gtk::MenuItem* _menu_close; - Gtk::MenuItem* _menu_quit; - Gtk::CheckMenuItem* _menu_animate_signals; - Gtk::CheckMenuItem* _menu_sprung_layout; - Gtk::CheckMenuItem* _menu_human_names; - Gtk::CheckMenuItem* _menu_show_port_names; - Gtk::CheckMenuItem* _menu_show_doc_pane; - Gtk::CheckMenuItem* _menu_show_status_bar; - Gtk::MenuItem* _menu_zoom_in; - Gtk::MenuItem* _menu_zoom_out; - Gtk::MenuItem* _menu_zoom_normal; - Gtk::MenuItem* _menu_zoom_full; - Gtk::MenuItem* _menu_increase_font_size; - Gtk::MenuItem* _menu_decrease_font_size; - Gtk::MenuItem* _menu_normal_font_size; - Gtk::MenuItem* _menu_parent; - Gtk::MenuItem* _menu_refresh; - Gtk::MenuItem* _menu_fullscreen; - Gtk::MenuItem* _menu_arrange; - Gtk::MenuItem* _menu_view_engine_window; - Gtk::MenuItem* _menu_view_control_window; - Gtk::MenuItem* _menu_view_graph_properties; - Gtk::MenuItem* _menu_view_messages_window; - Gtk::MenuItem* _menu_view_graph_tree_window; - Gtk::MenuItem* _menu_help_about; - - Gtk::Alignment* _alignment; - BreadCrumbs* _breadcrumbs; - Gtk::Statusbar* _status_bar; - Gtk::Label* _status_label; - - Gtk::HPaned* _doc_paned; - Gtk::ScrolledWindow* _doc_scrolledwindow; + Gtk::MenuItem* _menu_import = nullptr; + Gtk::MenuItem* _menu_save = nullptr; + Gtk::MenuItem* _menu_save_as = nullptr; + Gtk::MenuItem* _menu_export_image = nullptr; + Gtk::MenuItem* _menu_redo = nullptr; + Gtk::MenuItem* _menu_undo = nullptr; + Gtk::MenuItem* _menu_cut = nullptr; + Gtk::MenuItem* _menu_copy = nullptr; + Gtk::MenuItem* _menu_paste = nullptr; + Gtk::MenuItem* _menu_delete = nullptr; + Gtk::MenuItem* _menu_select_all = nullptr; + Gtk::MenuItem* _menu_close = nullptr; + Gtk::MenuItem* _menu_quit = nullptr; + Gtk::CheckMenuItem* _menu_animate_signals = nullptr; + Gtk::CheckMenuItem* _menu_sprung_layout = nullptr; + Gtk::CheckMenuItem* _menu_human_names = nullptr; + Gtk::CheckMenuItem* _menu_show_port_names = nullptr; + Gtk::CheckMenuItem* _menu_show_doc_pane = nullptr; + Gtk::CheckMenuItem* _menu_show_status_bar = nullptr; + Gtk::MenuItem* _menu_zoom_in = nullptr; + Gtk::MenuItem* _menu_zoom_out = nullptr; + Gtk::MenuItem* _menu_zoom_normal = nullptr; + Gtk::MenuItem* _menu_zoom_full = nullptr; + Gtk::MenuItem* _menu_increase_font_size = nullptr; + Gtk::MenuItem* _menu_decrease_font_size = nullptr; + Gtk::MenuItem* _menu_normal_font_size = nullptr; + Gtk::MenuItem* _menu_parent = nullptr; + Gtk::MenuItem* _menu_refresh = nullptr; + Gtk::MenuItem* _menu_fullscreen = nullptr; + Gtk::MenuItem* _menu_arrange = nullptr; + Gtk::MenuItem* _menu_view_engine_window = nullptr; + Gtk::MenuItem* _menu_view_control_window = nullptr; + Gtk::MenuItem* _menu_view_graph_properties = nullptr; + Gtk::MenuItem* _menu_view_messages_window = nullptr; + Gtk::MenuItem* _menu_view_graph_tree_window = nullptr; + Gtk::MenuItem* _menu_help_about = nullptr; + + Gtk::Alignment* _alignment = nullptr; + BreadCrumbs* _breadcrumbs = nullptr; + Gtk::Statusbar* _status_bar = nullptr; + Gtk::Label* _status_label = nullptr; + + Gtk::HPaned* _doc_paned = nullptr; + Gtk::ScrolledWindow* _doc_scrolledwindow = nullptr; sigc::connection _entered_connection; sigc::connection _left_connection; @@ -203,8 +210,8 @@ private: /** Invisible bin used to store breadcrumbs when not shown by a view */ Gtk::Alignment _breadcrumb_bin; - bool _has_shown_documentation; - bool _enable_signal; + bool _has_shown_documentation = false; + bool _enable_signal = true; }; } // namespace gui diff --git a/src/gui/GraphCanvas.cpp b/src/gui/GraphCanvas.cpp index 40a0c675..3090186a 100644 --- a/src/gui/GraphCanvas.cpp +++ b/src/gui/GraphCanvas.cpp @@ -14,13 +14,12 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ +#include "GraphCanvas.hpp" + #include "App.hpp" #include "Arc.hpp" -#include "GraphCanvas.hpp" #include "GraphPortModule.hpp" #include "GraphWindow.hpp" -#include "LoadPluginWindow.hpp" -#include "NewSubgraphWindow.hpp" #include "NodeModule.hpp" #include "PluginMenu.hpp" #include "Port.hpp" @@ -29,35 +28,89 @@ #include "WidgetFactory.hpp" #include "WindowFactory.hpp" -#include "ganv/Canvas.hpp" -#include "ganv/Circle.hpp" -#include "ingen/ClashAvoider.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Log.hpp" -#include "ingen/Serialiser.hpp" -#include "ingen/World.hpp" -#include "ingen/client/BlockModel.hpp" -#include "ingen/client/ClientStore.hpp" -#include "ingen/client/GraphModel.hpp" -#include "ingen/client/PluginModel.hpp" -#include "ingen/ingen.h" -#include "lv2/atom/atom.h" - -#include <boost/optional/optional.hpp> +#include <ganv/Canvas.hpp> +#include <ganv/Edge.hpp> +#include <ganv/Module.hpp> +#include <ganv/Node.hpp> +#include <ganv/Port.hpp> +#include <ganv/canvas.h> +#include <ganv/edge.h> +#include <ganv/module.h> +#include <ganv/types.h> +#include <ingen/Arc.hpp> +#include <ingen/Atom.hpp> +#include <ingen/ClashAvoider.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Log.hpp> +#include <ingen/Node.hpp> +#include <ingen/Parser.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/Serialiser.hpp> +#include <ingen/Store.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/ArcModel.hpp> +#include <ingen/client/BlockModel.hpp> +#include <ingen/client/ClientStore.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <ingen/client/PluginModel.hpp> +#include <ingen/client/PortModel.hpp> +#include <ingen/paths.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> +#include <sord/sordmm.hpp> + +#include <gdk/gdk.h> +#include <gdk/gdkkeysyms-compat.h> +#include <gdkmm/window.h> +#include <glib.h> +#include <glibmm/refptr.h> +#include <glibmm/ustring.h> +#include <gtkmm/builder.h> +#include <gtkmm/checkmenuitem.h> +#include <gtkmm/clipboard.h> +#include <gtkmm/enums.h> +#include <gtkmm/image.h> +#include <gtkmm/layout.h> +#include <gtkmm/menu.h> +#include <gtkmm/menu_elems.h> +#include <gtkmm/menuitem.h> +#include <gtkmm/object.h> #include <gtkmm/stock.h> +#include <gtkmm/stockid.h> +#include <sigc++/adaptors/bind.h> +#include <sigc++/functors/mem_fun.h> +#include <sigc++/signal.h> #include <algorithm> #include <cassert> +#include <cstdio> +#include <cstring> +#include <initializer_list> +#include <limits> #include <map> +#include <memory> +#include <mutex> +#include <optional> #include <set> +#include <sstream> #include <string> +#include <vector> using std::string; namespace ingen { -using namespace client; +using client::ArcModel; +using client::BlockModel; +using client::GraphModel; +using client::PluginModel; +using client::PortModel; namespace gui { @@ -67,30 +120,21 @@ port_order(const GanvPort* a, const GanvPort* b, void* data) const Port* pa = dynamic_cast<const Port*>(Glib::wrap(a)); const Port* pb = dynamic_cast<const Port*>(Glib::wrap(b)); if (pa && pb) { - return ((int)pa->model()->index() - (int)pb->model()->index()); + return (static_cast<int>(pa->model()->index()) - + static_cast<int>(pb->model()->index())); } return 0; } -GraphCanvas::GraphCanvas(App& app, - SPtr<const GraphModel> graph, - int width, - int height) - : Canvas(width, height) - , _app(app) - , _graph(std::move(graph)) - , _auto_position_count(0) - , _menu_x(0) - , _menu_y(0) - , _paste_count(0) - , _menu(nullptr) - , _internal_menu(nullptr) - , _plugin_menu(nullptr) - , _human_names(true) - , _show_port_names(true) - , _menu_dirty(false) -{ - Glib::RefPtr<Gtk::Builder> xml = WidgetFactory::create("canvas_menu"); +GraphCanvas::GraphCanvas(App& app, + std::shared_ptr<const GraphModel> graph, + int width, + int height) + : Canvas(width, height) + , _app(app) + , _graph(std::move(graph)) +{ + const Glib::RefPtr<Gtk::Builder> xml = WidgetFactory::create("canvas_menu"); xml->get_widget("canvas_menu", _menu); xml->get_widget("canvas_menu_add_audio_input", _menu_add_audio_input); @@ -209,7 +253,7 @@ GraphCanvas::build_menus() _menu->reorder_child(*internal_menu_item, 4); } - // Build skeleton LV2 plugin class heirarchy for 'Plugin' menu + // Build skeleton LV2 plugin class hierarchy for 'Plugin' menu if (_plugin_menu) { _plugin_menu->clear(); } else { @@ -225,9 +269,9 @@ GraphCanvas::build_menus() sigc::mem_fun(this, &GraphCanvas::load_plugin)); } - // Add known plugins to menu heirarchy - SPtr<const ClientStore::Plugins> plugins = _app.store()->plugins(); - for (const auto& p : *plugins.get()) { + // Add known plugins to menu hierarchy + auto plugins = _app.store()->plugins(); + for (const auto& p : *plugins) { add_plugin(p.second); } @@ -240,8 +284,8 @@ GraphCanvas::build() const Store::const_range kids = _app.store()->children_range(_graph); // Create modules for blocks - for (Store::const_iterator i = kids.first; i != kids.second; ++i) { - SPtr<BlockModel> block = dynamic_ptr_cast<BlockModel>(i->second); + for (auto i = kids.first; i != kids.second; ++i) { + auto block = std::dynamic_pointer_cast<BlockModel>(i->second); if (block && block->parent() == _graph) { add_block(block); } @@ -254,22 +298,22 @@ GraphCanvas::build() // Create arcs for (const auto& a : _graph->arcs()) { - connection(dynamic_ptr_cast<ArcModel>(a.second)); + connection(std::dynamic_pointer_cast<ArcModel>(a.second)); } } static void show_module_human_names(GanvNode* node, void* data) { - bool b = *(bool*)data; + const bool b = *static_cast<bool*>(data); if (GANV_IS_MODULE(node)) { Ganv::Module* module = Glib::wrap(GANV_MODULE(node)); - NodeModule* nmod = dynamic_cast<NodeModule*>(module); + auto* nmod = dynamic_cast<NodeModule*>(module); if (nmod) { nmod->show_human_names(b); } - GraphPortModule* pmod = dynamic_cast<GraphPortModule*>(module); + auto* pmod = dynamic_cast<GraphPortModule*>(module); if (pmod) { pmod->show_human_names(b); } @@ -291,7 +335,7 @@ ensure_port_labels(GanvNode* node, void* data) if (GANV_IS_MODULE(node)) { Ganv::Module* module = Glib::wrap(GANV_MODULE(node)); for (Ganv::Port* p : *module) { - ingen::gui::Port* port = dynamic_cast<ingen::gui::Port*>(p); + auto* port = dynamic_cast<ingen::gui::Port*>(p); if (port) { port->ensure_label(); } @@ -307,7 +351,7 @@ GraphCanvas::show_port_names(bool b) } void -GraphCanvas::add_plugin(const SPtr<PluginModel>& p) +GraphCanvas::add_plugin(const std::shared_ptr<PluginModel>& p) { if (_internal_menu && _app.uris().ingen_Internal == p->type()) { _internal_menu->items().push_back( @@ -327,10 +371,10 @@ GraphCanvas::remove_plugin(const URI& uri) } void -GraphCanvas::add_block(const SPtr<const BlockModel>& bm) +GraphCanvas::add_block(const std::shared_ptr<const BlockModel>& bm) { - SPtr<const GraphModel> pm = dynamic_ptr_cast<const GraphModel>(bm); - NodeModule* module; + auto pm = std::dynamic_pointer_cast<const GraphModel>(bm); + NodeModule* module = nullptr; if (pm) { module = SubgraphModule::create(*this, pm, _human_names); } else { @@ -345,7 +389,7 @@ GraphCanvas::add_block(const SPtr<const BlockModel>& bm) } void -GraphCanvas::remove_block(const SPtr<const BlockModel>& bm) +GraphCanvas::remove_block(const std::shared_ptr<const BlockModel>& bm) { auto i = _views.find(bm); @@ -360,7 +404,7 @@ GraphCanvas::remove_block(const SPtr<const BlockModel>& bm) } void -GraphCanvas::add_port(const SPtr<const PortModel>& pm) +GraphCanvas::add_port(const std::shared_ptr<const PortModel>& pm) { GraphPortModule* view = GraphPortModule::create(*this, pm); _views.emplace(pm, view); @@ -368,7 +412,7 @@ GraphCanvas::add_port(const SPtr<const PortModel>& pm) } void -GraphCanvas::remove_port(const SPtr<const PortModel>& pm) +GraphCanvas::remove_port(const std::shared_ptr<const PortModel>& pm) { auto i = _views.find(pm); @@ -386,24 +430,24 @@ GraphCanvas::remove_port(const SPtr<const PortModel>& pm) } Ganv::Port* -GraphCanvas::get_port_view(const SPtr<PortModel>& port) +GraphCanvas::get_port_view(const std::shared_ptr<PortModel>& port) { Ganv::Module* module = _views[port]; // Port on this graph if (module) { - GraphPortModule* ppm = dynamic_cast<GraphPortModule*>(module); + auto* ppm = dynamic_cast<GraphPortModule*>(module); return ppm ? *ppm->begin() : dynamic_cast<Ganv::Port*>(module); - } else { - module = dynamic_cast<NodeModule*>(_views[port->parent()]); - if (module) { - for (const auto& p : *module) { - gui::Port* pv = dynamic_cast<gui::Port*>(p); - if (pv && pv->model() == port) { - return pv; - } + } + + module = dynamic_cast<NodeModule*>(_views[port->parent()]); + if (module) { + for (auto* p : *module) { + auto* pv = dynamic_cast<gui::Port*>(p); + if (pv && pv->model() == port) { + return pv; } } } @@ -413,7 +457,7 @@ GraphCanvas::get_port_view(const SPtr<PortModel>& port) /** Called when a connection is added to the model. */ void -GraphCanvas::connection(const SPtr<const ArcModel>& arc) +GraphCanvas::connection(const std::shared_ptr<const ArcModel>& arc) { Ganv::Port* const tail = get_port_view(arc->tail()); Ganv::Port* const head = get_port_view(arc->head()); @@ -428,7 +472,7 @@ GraphCanvas::connection(const SPtr<const ArcModel>& arc) /** Called when a connection is removed from the model. */ void -GraphCanvas::disconnection(const SPtr<const ArcModel>& arc) +GraphCanvas::disconnection(const std::shared_ptr<const ArcModel>& arc) { Ganv::Port* const tail = get_port_view(arc->tail()); Ganv::Port* const head = get_port_view(arc->head()); @@ -436,9 +480,9 @@ GraphCanvas::disconnection(const SPtr<const ArcModel>& arc) if (tail && head) { remove_edge_between(tail, head); if (arc->head()->is_a(_app.uris().lv2_AudioPort)) { - gui::Port* const h = dynamic_cast<gui::Port*>(head); + auto* const h = dynamic_cast<gui::Port*>(head); if (h) { - h->activity(_app.forge().make(0.0f)); // Reset peaks + h->activity(_app.forge().make(0.0f)); // Reset peaks } } } else { @@ -490,8 +534,8 @@ GraphCanvas::auto_menu_position(int& x, int& y, bool& push_in) *_app.window_factory()->graph_window(_graph), 64, 64, _menu_x, _menu_y); - int origin_x; - int origin_y; + int origin_x = 0; + int origin_y = 0; widget().get_window()->get_origin(origin_x, origin_y); _menu_x += origin_x; _menu_y += origin_y; @@ -518,8 +562,8 @@ GraphCanvas::on_event(GdkEvent* event) case GDK_BUTTON_PRESS: if (event->button.button == 3) { _auto_position_count = 1; - _menu_x = (int)event->button.x_root; - _menu_y = (int)event->button.y_root; + _menu_x = static_cast<int>(event->button.x_root); + _menu_y = static_cast<int>(event->button.y_root); show_menu(false, event->button.button, event->button.time); ret = true; } @@ -537,6 +581,7 @@ GraphCanvas::on_event(GdkEvent* event) case GDK_space: case GDK_Menu: show_menu(true, 3, event->key.time); + break; default: break; } break; @@ -569,14 +614,14 @@ destroy_node(GanvNode* node, void* data) return; } - App* app = (App*)data; + const App* app = static_cast<App*>(data); Ganv::Module* module = Glib::wrap(GANV_MODULE(node)); - NodeModule* node_module = dynamic_cast<NodeModule*>(module); + const auto* node_module = dynamic_cast<NodeModule*>(module); if (node_module) { app->interface()->del(node_module->block()->uri()); } else { - GraphPortModule* port_module = dynamic_cast<GraphPortModule*>(module); + const auto* port_module = dynamic_cast<GraphPortModule*>(module); if (port_module && strcmp(port_module->port()->path().symbol(), "control") && strcmp(port_module->port()->path().symbol(), "notify")) { @@ -588,11 +633,11 @@ destroy_node(GanvNode* node, void* data) static void destroy_arc(GanvEdge* arc, void* data) { - App* app = (App*)data; + const App* app = static_cast<App*>(data); Ganv::Edge* arcmm = Glib::wrap(arc); - Port* tail = dynamic_cast<Port*>(arcmm->get_tail()); - Port* head = dynamic_cast<Port*>(arcmm->get_head()); + const Port* tail = dynamic_cast<Port*>(arcmm->get_tail()); + const Port* head = dynamic_cast<Port*>(arcmm->get_head()); app->interface()->disconnect(tail->model()->path(), head->model()->path()); } @@ -611,18 +656,18 @@ GraphCanvas::destroy_selection() static void serialise_node(GanvNode* node, void* data) { - Serialiser* serialiser = (Serialiser*)data; + auto* serialiser = static_cast<Serialiser*>(data); if (!GANV_IS_MODULE(node)) { return; } Ganv::Module* module = Glib::wrap(GANV_MODULE(node)); - NodeModule* node_module = dynamic_cast<NodeModule*>(module); + const auto* node_module = dynamic_cast<NodeModule*>(module); if (node_module) { serialiser->serialise(node_module->block()); } else { - GraphPortModule* port_module = dynamic_cast<GraphPortModule*>(module); + const auto* port_module = dynamic_cast<GraphPortModule*>(module); if (port_module) { serialiser->serialise(port_module->port()); } @@ -632,12 +677,12 @@ serialise_node(GanvNode* node, void* data) static void serialise_arc(GanvEdge* arc, void* data) { - Serialiser* serialiser = (Serialiser*)data; + auto* serialiser = static_cast<Serialiser*>(data); if (!GANV_IS_EDGE(arc)) { return; } - gui::Arc* garc = dynamic_cast<gui::Arc*>(Glib::wrap(GANV_EDGE(arc))); + const auto* garc = dynamic_cast<gui::Arc*>(Glib::wrap(GANV_EDGE(arc))); if (garc) { serialiser->serialise_arc(Sord::Node(), garc->model()); } @@ -646,7 +691,7 @@ serialise_arc(GanvEdge* arc, void* data) void GraphCanvas::copy_selection() { - std::lock_guard<std::mutex> lock(_app.world().rdf_mutex()); + const std::lock_guard<std::mutex> lock{_app.world().rdf_mutex()}; Serialiser serialiser(_app.world()); serialiser.start_to_string(_graph->path(), _graph->base_uri()); @@ -654,7 +699,7 @@ GraphCanvas::copy_selection() for_each_selected_node(serialise_node, &serialiser); for_each_selected_edge(serialise_arc, &serialiser); - Glib::RefPtr<Gtk::Clipboard> clipboard = Gtk::Clipboard::get(); + const Glib::RefPtr<Gtk::Clipboard> clipboard = Gtk::Clipboard::get(); clipboard->set_text(serialiser.finish()); _paste_count = 0; } @@ -662,14 +707,12 @@ GraphCanvas::copy_selection() void GraphCanvas::paste() { - using PropIter = Properties::const_iterator; - - std::lock_guard<std::mutex> lock(_app.world().rdf_mutex()); + const std::lock_guard<std::mutex> lock{_app.world().rdf_mutex()}; const Glib::ustring str = Gtk::Clipboard::get()->wait_for_text(); - SPtr<Parser> parser = _app.loader()->parser(); + auto parser = _app.loader()->parser(); const URIs& uris = _app.uris(); - const Raul::Path& parent = _graph->path(); + const raul::Path& parent = _graph->path(); if (!parser) { _app.log().error("Unable to load parser, paste unavailable\n"); return; @@ -681,21 +724,21 @@ GraphCanvas::paste() ++_paste_count; // Make a client store to serve as clipboard - ClientStore clipboard(_app.world().uris(), _app.log()); + client::ClientStore clipboard(_app.world().uris(), _app.log()); clipboard.set_plugins(_app.store()->plugins()); clipboard.put(main_uri(), {{uris.rdf_type, Property(uris.ingen_Graph)}}); // Parse clipboard text into clipboard store - boost::optional<URI> base_uri = parser->parse_string( + std::optional<URI> base_uri = parser->parse_string( _app.world(), clipboard, str, main_uri()); // Figure out the copy graph base path - Raul::Path copy_root("/"); + raul::Path copy_root("/"); if (base_uri) { std::string base = *base_uri; if (base[base.size() - 1] == '/') { - base = base.substr(0, base.size() - 1); + base.resize(base.size() - 1); } copy_root = uri_to_path(URI(base)); } @@ -704,7 +747,7 @@ GraphCanvas::paste() float min_x = std::numeric_limits<float>::max(); float min_y = std::numeric_limits<float>::max(); for (const auto& c : clipboard) { - if (c.first.parent() == Raul::Path("/")) { + if (c.first.parent() == raul::Path("/")) { const Atom& x = c.second->get_property(uris.ingen_canvasX); const Atom& y = c.second->get_property(uris.ingen_canvasY); if (x.type() == uris.atom_Float) { @@ -717,7 +760,10 @@ GraphCanvas::paste() } // Find canvas paste origin based on pointer position - int widget_point_x, widget_point_y, scroll_x, scroll_y; + int widget_point_x = 0; + int widget_point_y = 0; + int scroll_x = 0; + int scroll_y = 0; widget().get_pointer(widget_point_x, widget_point_y); get_scroll_offsets(scroll_x, scroll_y); const int paste_x = widget_point_x + scroll_x + (20.0f * _paste_count); @@ -726,16 +772,17 @@ GraphCanvas::paste() _app.interface()->bundle_begin(); // Put each top level object in the clipboard store - ClashAvoider avoider(*_app.store().get()); + ClashAvoider avoider(*_app.store()); for (const auto& c : clipboard) { - if (c.first.is_root() || c.first.parent() != Raul::Path("/")) { + if (c.first.is_root() || c.first.parent() != raul::Path("/")) { continue; } - const SPtr<Node> node = c.second; - const Raul::Path& old_path = copy_root.child(node->path()); + const auto node = c.second; + const raul::Path& old_path = copy_root.child(node->path()); const URI& old_uri = path_to_uri(old_path); - const Raul::Path& new_path = avoider.map_path(parent.child(node->path())); + const raul::Path& new_path = + avoider.map_path(parent.child(node->path())); // Copy properties, except those that should not be inherited in copies Properties props = node->properties(); @@ -758,8 +805,8 @@ GraphCanvas::paste() } // Set coordinates so paste origin is at the mouse pointer - PropIter xi = node->properties().find(uris.ingen_canvasX); - PropIter yi = node->properties().find(uris.ingen_canvasY); + const auto xi = node->properties().find(uris.ingen_canvasX); + const auto yi = node->properties().find(uris.ingen_canvasY); if (xi != node->properties().end()) { const float x = xi->second.get<float>() - min_x + paste_x; props.insert({xi->first, Property(_app.forge().make(x), @@ -776,7 +823,7 @@ GraphCanvas::paste() } // Connect objects - for (auto a : clipboard.object(Raul::Path("/"))->arcs()) { + for (const auto& a : clipboard.object(raul::Path("/"))->arcs()) { _app.interface()->connect( avoider.map_path(parent.child(a.second->tail_path())), avoider.map_path(parent.child(a.second->head_path()))); @@ -799,12 +846,12 @@ GraphCanvas::generate_port_name( snprintf(num_buf, sizeof(num_buf), "%u", i); symbol = sym_base + "_"; symbol += num_buf; - if (!_graph->get_port(Raul::Symbol::symbolify(symbol))) { + if (!_graph->get_port(raul::Symbol::symbolify(symbol))) { break; } } - assert(Raul::Path::is_valid(string("/") + symbol)); + assert(raul::Path::is_valid(string("/") + symbol)); name.append(" ").append(num_buf); } @@ -815,9 +862,10 @@ GraphCanvas::menu_add_port(const string& sym_base, const URI& type, bool is_output) { - string sym, name; + string sym; + string name; generate_port_name(sym_base, sym, name_base, name); - const Raul::Path& path = _graph->path().child(Raul::Symbol(sym)); + const raul::Path& path = _graph->path().child(raul::Symbol(sym)); const URIs& uris = _app.uris(); @@ -830,29 +878,29 @@ GraphCanvas::menu_add_port(const string& sym_base, uris.rdf_type, Property(is_output ? uris.lv2_OutputPort : uris.lv2_InputPort)); props.emplace(uris.lv2_index, - _app.forge().make(int32_t(_graph->num_ports()))); + _app.forge().make(static_cast<int32_t>(_graph->num_ports()))); props.emplace(uris.lv2_name, _app.forge().alloc(name.c_str())); _app.interface()->put(path_to_uri(path), props); } void -GraphCanvas::load_plugin(WPtr<PluginModel> weak_plugin) +GraphCanvas::load_plugin(const std::weak_ptr<PluginModel>& weak_plugin) { - SPtr<PluginModel> plugin = weak_plugin.lock(); + auto plugin = weak_plugin.lock(); if (!plugin) { return; } - Raul::Symbol symbol = plugin->default_block_symbol(); - unsigned offset = _app.store()->child_name_offset(_graph->path(), symbol); + raul::Symbol symbol = plugin->default_block_symbol(); + const unsigned offset = _app.store()->child_name_offset(_graph->path(), symbol); if (offset != 0) { std::stringstream ss; ss << symbol << "_" << offset; - symbol = Raul::Symbol(ss.str()); + symbol = raul::Symbol(ss.str()); } const URIs& uris = _app.uris(); - const Raul::Path path = _graph->path().child(symbol); + const raul::Path path = _graph->path().child(symbol); // FIXME: polyphony? Properties props = get_initial_data(); @@ -866,8 +914,8 @@ GraphCanvas::load_plugin(WPtr<PluginModel> weak_plugin) void GraphCanvas::get_new_module_location(double& x, double& y) { - int scroll_x; - int scroll_y; + int scroll_x = 0; + int scroll_y = 0; get_scroll_offsets(scroll_x, scroll_y); x = scroll_x + 20; y = scroll_y + 20; @@ -879,9 +927,11 @@ GraphCanvas::get_initial_data(Resource::Graph ctx) Properties result; const URIs& uris = _app.uris(); result.emplace(uris.ingen_canvasX, - Property(_app.forge().make((float)_menu_x), ctx)); + Property(_app.forge().make(static_cast<float>(_menu_x)), + ctx)); result.emplace(uris.ingen_canvasY, - Property(_app.forge().make((float)_menu_y), ctx)); + Property(_app.forge().make(static_cast<float>(_menu_y)), + ctx)); return result; } diff --git a/src/gui/GraphCanvas.hpp b/src/gui/GraphCanvas.hpp index 7aa4bb98..38f3ab08 100644 --- a/src/gui/GraphCanvas.hpp +++ b/src/gui/GraphCanvas.hpp @@ -17,27 +17,48 @@ #ifndef INGEN_GUI_GRAPHCANVAS_HPP #define INGEN_GUI_GRAPHCANVAS_HPP -#include "NodeModule.hpp" +#include <ganv/Canvas.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <lilv/lilv.h> +#include <raul/Path.hpp> -#include "ganv/Canvas.hpp" -#include "ganv/Module.hpp" -#include "ingen/Node.hpp" -#include "ingen/client/ArcModel.hpp" -#include "ingen/types.hpp" -#include "lilv/lilv.h" -#include "raul/Path.hpp" +#include <gdk/gdk.h> -#include <string> +#include <cstdint> #include <map> +#include <memory> #include <set> +#include <string> +#include <utility> + +namespace Ganv { +class Module; +class Node; +class Port; +} // namespace Ganv + +namespace Gtk { +class CheckMenuItem; +class Menu; +class MenuItem; +} // namespace Gtk namespace ingen { -namespace client { class GraphModel; } +namespace client { +class ArcModel; +class BlockModel; +class GraphModel; +class ObjectModel; +class PluginModel; +class PortModel; +} // namespace client namespace gui { -class NodeModule; +class App; class PluginMenu; /** Graph canvas widget. @@ -47,12 +68,12 @@ class PluginMenu; class GraphCanvas : public Ganv::Canvas { public: - GraphCanvas(App& app, - SPtr<const client::GraphModel> graph, - int width, - int height); + GraphCanvas(App& app, + std::shared_ptr<const client::GraphModel> graph, + int width, + int height); - virtual ~GraphCanvas() {} + ~GraphCanvas() override = default; App& app() { return _app; } @@ -61,14 +82,14 @@ public: void show_port_names(bool b); bool show_port_names() const { return _show_port_names; } - void add_plugin(const SPtr<client::PluginModel>& p); + void add_plugin(const std::shared_ptr<client::PluginModel>& p); void remove_plugin(const URI& uri); - void add_block(const SPtr<const client::BlockModel>& bm); - void remove_block(const SPtr<const client::BlockModel>& bm); - void add_port(const SPtr<const client::PortModel>& pm); - void remove_port(const SPtr<const client::PortModel>& pm); - void connection(const SPtr<const client::ArcModel>& arc); - void disconnection(const SPtr<const client::ArcModel>& arc); + void add_block(const std::shared_ptr<const client::BlockModel>& bm); + void remove_block(const std::shared_ptr<const client::BlockModel>& bm); + void add_port(const std::shared_ptr<const client::PortModel>& pm); + void remove_port(const std::shared_ptr<const client::PortModel>& pm); + void connection(const std::shared_ptr<const client::ArcModel>& arc); + void disconnection(const std::shared_ptr<const client::ArcModel>& arc); void get_new_module_location(double& x, double& y); @@ -96,7 +117,7 @@ private: void menu_new_graph(); void menu_load_graph(); void menu_properties(); - void load_plugin(WPtr<client::PluginModel> weak_plugin); + void load_plugin(const std::weak_ptr<client::PluginModel>& weak_plugin); void build_menus(); @@ -106,7 +127,7 @@ private: Properties get_initial_data(Resource::Graph ctx=Resource::Graph::DEFAULT); - Ganv::Port* get_port_view(const SPtr<client::PortModel>& port); + Ganv::Port* get_port_view(const std::shared_ptr<client::PortModel>& port); void connect(Ganv::Node* tail, Ganv::Node* head); @@ -114,42 +135,42 @@ private: void disconnect(Ganv::Node* tail, Ganv::Node* head); - App& _app; - SPtr<const client::GraphModel> _graph; + App& _app; + std::shared_ptr<const client::GraphModel> _graph; - using Views = std::map<SPtr<const client::ObjectModel>, Ganv::Module*>; + using Views = std::map<std::shared_ptr<const client::ObjectModel>, Ganv::Module*>; Views _views; - int _auto_position_count; + int _auto_position_count{0}; std::pair<int, int> _auto_position_scroll_offsets; - int _menu_x; - int _menu_y; - int _paste_count; + int _menu_x{0}; + int _menu_y{0}; + int _paste_count{0}; // Track pasted objects so they can be selected when they arrive - std::set<Raul::Path> _pastees; - - Gtk::Menu* _menu; - Gtk::Menu* _internal_menu; - PluginMenu* _plugin_menu; - Gtk::MenuItem* _menu_add_audio_input; - Gtk::MenuItem* _menu_add_audio_output; - Gtk::MenuItem* _menu_add_control_input; - Gtk::MenuItem* _menu_add_control_output; - Gtk::MenuItem* _menu_add_cv_input; - Gtk::MenuItem* _menu_add_cv_output; - Gtk::MenuItem* _menu_add_event_input; - Gtk::MenuItem* _menu_add_event_output; - Gtk::MenuItem* _menu_load_plugin; - Gtk::MenuItem* _menu_load_graph; - Gtk::MenuItem* _menu_new_graph; - Gtk::MenuItem* _menu_properties; - Gtk::CheckMenuItem* _menu_edit; - - bool _human_names; - bool _show_port_names; - bool _menu_dirty; + std::set<raul::Path> _pastees; + + Gtk::Menu* _menu = nullptr; + Gtk::Menu* _internal_menu = nullptr; + PluginMenu* _plugin_menu = nullptr; + Gtk::MenuItem* _menu_add_audio_input = nullptr; + Gtk::MenuItem* _menu_add_audio_output = nullptr; + Gtk::MenuItem* _menu_add_control_input = nullptr; + Gtk::MenuItem* _menu_add_control_output = nullptr; + Gtk::MenuItem* _menu_add_cv_input = nullptr; + Gtk::MenuItem* _menu_add_cv_output = nullptr; + Gtk::MenuItem* _menu_add_event_input = nullptr; + Gtk::MenuItem* _menu_add_event_output = nullptr; + Gtk::MenuItem* _menu_load_plugin = nullptr; + Gtk::MenuItem* _menu_load_graph = nullptr; + Gtk::MenuItem* _menu_new_graph = nullptr; + Gtk::MenuItem* _menu_properties = nullptr; + Gtk::CheckMenuItem* _menu_edit = nullptr; + + bool _human_names = true; + bool _show_port_names = true; + bool _menu_dirty = false; }; } // namespace gui diff --git a/src/gui/GraphPortModule.cpp b/src/gui/GraphPortModule.cpp index 1947f355..cd471d97 100644 --- a/src/gui/GraphPortModule.cpp +++ b/src/gui/GraphPortModule.cpp @@ -14,41 +14,47 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ +#include "GraphPortModule.hpp" + #include "App.hpp" -#include "Style.hpp" #include "GraphCanvas.hpp" -#include "GraphPortModule.hpp" -#include "GraphWindow.hpp" #include "Port.hpp" -#include "PortMenu.hpp" -#include "RenameWindow.hpp" -#include "WidgetFactory.hpp" -#include "WindowFactory.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/Interface.hpp" -#include "ingen/client/BlockModel.hpp" -#include "ingen/client/GraphModel.hpp" +#include <ganv/Module.hpp> +#include <ingen/Atom.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/PortModel.hpp> +#include <raul/Symbol.hpp> + +#include <sigc++/functors/mem_fun.h> +#include <sigc++/signal.h> #include <cassert> +#include <cstdint> +#include <map> +#include <memory> #include <string> #include <utility> -namespace ingen { - -using namespace client; - -namespace gui { +namespace ingen::gui { -GraphPortModule::GraphPortModule(GraphCanvas& canvas, - const SPtr<const client::PortModel>& model) - : Ganv::Module(canvas, "", 0, 0, false) // FIXME: coords? - , _model(model) - , _port(nullptr) +GraphPortModule::GraphPortModule( + GraphCanvas& canvas, + const std::shared_ptr<const client::PortModel>& model) + : Ganv::Module(canvas, "", 0, 0, false) // FIXME: coords? + , _model(model) { assert(model); - assert(dynamic_ptr_cast<const GraphModel>(model->parent())); + assert( + std::dynamic_pointer_cast<const client::GraphModel>(model->parent())); set_stacked(model->polyphonic()); if (model->is_input() && !model->is_numeric()) { @@ -63,10 +69,11 @@ GraphPortModule::GraphPortModule(GraphCanvas& canvas, } GraphPortModule* -GraphPortModule::create(GraphCanvas& canvas, const SPtr<const PortModel>& model) +GraphPortModule::create(GraphCanvas& canvas, + const std::shared_ptr<const client::PortModel>& model) { - GraphPortModule* ret = new GraphPortModule(canvas, model); - Port* port = Port::create(canvas.app(), *ret, model, true); + auto* ret = new GraphPortModule(canvas, model); + Port* port = Port::create(canvas.app(), *ret, model, true); ret->set_port(port); if (model->is_numeric()) { @@ -83,7 +90,7 @@ GraphPortModule::create(GraphCanvas& canvas, const SPtr<const PortModel>& model) App& GraphPortModule::app() const { - return ((GraphCanvas*)canvas())->app(); + return static_cast<GraphCanvas*>(canvas())->app(); } bool @@ -134,9 +141,9 @@ GraphPortModule::property_changed(const URI& key, const Atom& value) const URIs& uris = app().uris(); if (value.type() == uris.forge.Float) { if (key == uris.ingen_canvasX) { - move_to(value.get<float>(), get_y()); + move_to(static_cast<double>(value.get<float>()), get_y()); } else if (key == uris.ingen_canvasY) { - move_to(get_x(), value.get<float>()); + move_to(get_x(), static_cast<double>(value.get<float>())); } } else if (value.type() == uris.forge.String) { if (key == uris.lv2_name && @@ -161,5 +168,4 @@ GraphPortModule::set_selected(gboolean b) } } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/GraphPortModule.hpp b/src/gui/GraphPortModule.hpp index cad3bfc5..a8091f38 100644 --- a/src/gui/GraphPortModule.hpp +++ b/src/gui/GraphPortModule.hpp @@ -17,24 +17,28 @@ #ifndef INGEN_GUI_GRAPHPORTMODULE_HPP #define INGEN_GUI_GRAPHPORTMODULE_HPP -#include "Port.hpp" +#include <ganv/Module.hpp> +#include <ingen/URI.hpp> -#include "ganv/Module.hpp" +#include <gdk/gdk.h> +#include <glib.h> +#include <memory> #include <string> -namespace Raul { class Atom; } +namespace ingen { + +class Atom; -namespace ingen { namespace client { +namespace client { class PortModel; -} } +} // namespace client -namespace ingen { namespace gui { +class App; class GraphCanvas; class Port; -class PortMenu; /** A "module" to represent a graph's port on its own canvas. * @@ -46,7 +50,8 @@ class GraphPortModule : public Ganv::Module { public: static GraphPortModule* - create(GraphCanvas& canvas, const SPtr<const client::PortModel>& model); + create(GraphCanvas& canvas, + const std::shared_ptr<const client::PortModel>& model); App& app() const; @@ -55,11 +60,11 @@ public: void set_name(const std::string& n); - SPtr<const client::PortModel> port() const { return _model; } + std::shared_ptr<const client::PortModel> port() const { return _model; } protected: - GraphPortModule(GraphCanvas& canvas, - const SPtr<const client::PortModel>& model); + GraphPortModule(GraphCanvas& canvas, + const std::shared_ptr<const client::PortModel>& model); bool show_menu(GdkEventButton* ev); void set_selected(gboolean b) override; @@ -68,8 +73,8 @@ protected: void property_changed(const URI& key, const Atom& value); - SPtr<const client::PortModel> _model; - Port* _port; + std::shared_ptr<const client::PortModel> _model; + Port* _port{nullptr}; }; } // namespace gui diff --git a/src/gui/GraphTreeWindow.cpp b/src/gui/GraphTreeWindow.cpp index 68f6e392..1d141271 100644 --- a/src/gui/GraphTreeWindow.cpp +++ b/src/gui/GraphTreeWindow.cpp @@ -14,27 +14,51 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "App.hpp" #include "GraphTreeWindow.hpp" -#include "SubgraphModule.hpp" + +#include "App.hpp" +#include "Window.hpp" #include "WindowFactory.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Log.hpp" -#include "ingen/client/ClientStore.hpp" -#include "ingen/client/GraphModel.hpp" -#include "raul/Path.hpp" + +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Log.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/ClientStore.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> + +#include <glibmm/propertyproxy.h> +#include <gtkmm/builder.h> +#include <gtkmm/cellrenderer.h> +#include <gtkmm/cellrenderertoggle.h> +#include <gtkmm/object.h> +#include <gtkmm/treeiter.h> +#include <gtkmm/treepath.h> +#include <gtkmm/treeviewcolumn.h> +#include <sigc++/adaptors/bind.h> +#include <sigc++/functors/mem_fun.h> +#include <sigc++/signal.h> + +#include <cassert> +#include <cstdint> +#include <memory> +#include <string> namespace ingen { -using namespace client; +using client::GraphModel; +using client::ObjectModel; namespace gui { GraphTreeWindow::GraphTreeWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml) : Window(cobject) - , _app(nullptr) - , _enable_signal(true) { xml->get_widget_derived("graphs_treeview", _graphs_treeview); @@ -50,7 +74,7 @@ GraphTreeWindow::GraphTreeWindow(BaseObjectType* cobject, _graphs_treeview->append_column(*name_col); _graphs_treeview->append_column(*enabled_col); - Gtk::CellRendererToggle* enabled_renderer = dynamic_cast<Gtk::CellRendererToggle*>( + auto* enabled_renderer = dynamic_cast<Gtk::CellRendererToggle*>( _graphs_treeview->get_column_cell_renderer(1)); enabled_renderer->property_activatable() = true; @@ -65,28 +89,28 @@ GraphTreeWindow::GraphTreeWindow(BaseObjectType* cobject, } void -GraphTreeWindow::init(App& app, ClientStore& store) +GraphTreeWindow::init(App& app, client::ClientStore& store) { - _app = &app; + init_window(app); store.signal_new_object().connect( sigc::mem_fun(this, &GraphTreeWindow::new_object)); } void -GraphTreeWindow::new_object(const SPtr<ObjectModel>& object) +GraphTreeWindow::new_object(const std::shared_ptr<ObjectModel>& object) { - SPtr<GraphModel> graph = dynamic_ptr_cast<GraphModel>(object); + auto graph = std::dynamic_pointer_cast<GraphModel>(object); if (graph) { add_graph(graph); } } void -GraphTreeWindow::add_graph(const SPtr<GraphModel>& pm) +GraphTreeWindow::add_graph(const std::shared_ptr<GraphModel>& pm) { if (!pm->parent()) { - Gtk::TreeModel::iterator iter = _graph_treestore->append(); - Gtk::TreeModel::Row row = *iter; + const auto iter = _graph_treestore->append(); + auto row = *iter; if (pm->path().is_root()) { row[_graph_tree_columns.name_col] = _app->interface()->uri().string(); } else { @@ -96,12 +120,13 @@ GraphTreeWindow::add_graph(const SPtr<GraphModel>& pm) row[_graph_tree_columns.graph_model_col] = pm; _graphs_treeview->expand_row(_graph_treestore->get_path(iter), true); } else { - Gtk::TreeModel::Children children = _graph_treestore->children(); - Gtk::TreeModel::iterator c = find_graph(children, pm->parent()); + const auto& children = _graph_treestore->children(); + auto c = find_graph(children, pm->parent()); if (c != children.end()) { - Gtk::TreeModel::iterator iter = _graph_treestore->append(c->children()); - Gtk::TreeModel::Row row = *iter; + const auto iter = _graph_treestore->append(c->children()); + auto row = *iter; + row[_graph_tree_columns.name_col] = pm->symbol().c_str(); row[_graph_tree_columns.enabled_col] = pm->enabled(); row[_graph_tree_columns.graph_model_col] = pm; @@ -123,24 +148,26 @@ GraphTreeWindow::add_graph(const SPtr<GraphModel>& pm) } void -GraphTreeWindow::remove_graph(const SPtr<GraphModel>& pm) +GraphTreeWindow::remove_graph(const std::shared_ptr<GraphModel>& pm) { - Gtk::TreeModel::iterator i = find_graph(_graph_treestore->children(), pm); + const auto i = find_graph(_graph_treestore->children(), pm); if (i != _graph_treestore->children().end()) { _graph_treestore->erase(i); } } Gtk::TreeModel::iterator -GraphTreeWindow::find_graph(Gtk::TreeModel::Children root, - const SPtr<client::ObjectModel>& graph) +GraphTreeWindow::find_graph(Gtk::TreeModel::Children root, + const std::shared_ptr<client::ObjectModel>& graph) { - for (Gtk::TreeModel::iterator c = root.begin(); c != root.end(); ++c) { - SPtr<GraphModel> pm = (*c)[_graph_tree_columns.graph_model_col]; + for (auto c = root.begin(); c != root.end(); ++c) { + const std::shared_ptr<GraphModel> pm = (*c)[_graph_tree_columns.graph_model_col]; if (graph == pm) { return c; - } else if (!(*c)->children().empty()) { - Gtk::TreeModel::iterator ret = find_graph(c->children(), graph); + } + + if (!(*c)->children().empty()) { + auto ret = find_graph(c->children(), graph); if (ret != c->children().end()) { return ret; } @@ -154,10 +181,12 @@ GraphTreeWindow::find_graph(Gtk::TreeModel::Children root, void GraphTreeWindow::show_graph_menu(GdkEventButton* ev) { - Gtk::TreeModel::iterator active = _graph_tree_selection->get_selected(); + const auto active = _graph_tree_selection->get_selected(); if (active) { - Gtk::TreeModel::Row row = *active; - SPtr<GraphModel> pm = row[_graph_tree_columns.graph_model_col]; + auto row = *active; + auto col = _graph_tree_columns.graph_model_col; + + const std::shared_ptr<GraphModel>& pm = row[col]; if (pm) { _app->log().warn("TODO: graph menu from tree window"); } @@ -168,9 +197,10 @@ void GraphTreeWindow::event_graph_activated(const Gtk::TreeModel::Path& path, Gtk::TreeView::Column* col) { - Gtk::TreeModel::iterator active = _graph_treestore->get_iter(path); - Gtk::TreeModel::Row row = *active; - SPtr<GraphModel> pm = row[_graph_tree_columns.graph_model_col]; + const auto active = _graph_treestore->get_iter(path); + auto row = *active; + + const std::shared_ptr<GraphModel> pm = row[_graph_tree_columns.graph_model_col]; _app->window_factory()->present_graph(pm); } @@ -178,31 +208,32 @@ GraphTreeWindow::event_graph_activated(const Gtk::TreeModel::Path& path, void GraphTreeWindow::event_graph_enabled_toggled(const Glib::ustring& path_str) { - Gtk::TreeModel::Path path(path_str); - Gtk::TreeModel::iterator active = _graph_treestore->get_iter(path); - Gtk::TreeModel::Row row = *active; + const Gtk::TreeModel::Path path{path_str}; + auto active = _graph_treestore->get_iter(path); + auto row = *active; - SPtr<GraphModel> pm = row[_graph_tree_columns.graph_model_col]; + const std::shared_ptr<GraphModel> pm = row[_graph_tree_columns.graph_model_col]; assert(pm); if (_enable_signal) { _app->set_property(pm->uri(), _app->uris().ingen_enabled, - _app->forge().make((bool)!pm->enabled())); + _app->forge().make(!pm->enabled())); } } void -GraphTreeWindow::graph_property_changed(const URI& key, - const Atom& value, - const SPtr<GraphModel>& graph) +GraphTreeWindow::graph_property_changed( + const URI& key, + const Atom& value, + const std::shared_ptr<GraphModel>& graph) { const URIs& uris = _app->uris(); _enable_signal = false; if (key == uris.ingen_enabled && value.type() == uris.forge.Bool) { - Gtk::TreeModel::iterator i = find_graph(_graph_treestore->children(), graph); + const auto i = find_graph(_graph_treestore->children(), graph); if (i != _graph_treestore->children().end()) { - Gtk::TreeModel::Row row = *i; + auto row = *i; row[_graph_tree_columns.enabled_col] = value.get<int32_t>(); } else { _app->log().error("Unable to find graph %1%\n", graph->path()); @@ -212,15 +243,13 @@ GraphTreeWindow::graph_property_changed(const URI& key, } void -GraphTreeWindow::graph_moved(const SPtr<GraphModel>& graph) +GraphTreeWindow::graph_moved(const std::shared_ptr<GraphModel>& graph) { _enable_signal = false; - Gtk::TreeModel::iterator i - = find_graph(_graph_treestore->children(), graph); - + auto i = find_graph(_graph_treestore->children(), graph); if (i != _graph_treestore->children().end()) { - Gtk::TreeModel::Row row = *i; + auto row = *i; row[_graph_tree_columns.name_col] = graph->symbol().c_str(); } else { _app->log().error("Unable to find graph %1%\n", graph->path()); diff --git a/src/gui/GraphTreeWindow.hpp b/src/gui/GraphTreeWindow.hpp index c1ea53c2..6f33f258 100644 --- a/src/gui/GraphTreeWindow.hpp +++ b/src/gui/GraphTreeWindow.hpp @@ -19,20 +19,36 @@ #include "Window.hpp" -#include <gtkmm/builder.h> +#include <ingen/URI.hpp> + +#include <gdk/gdk.h> +#include <glibmm/refptr.h> +#include <glibmm/ustring.h> #include <gtkmm/treemodel.h> +#include <gtkmm/treemodelcolumn.h> +#include <gtkmm/treeselection.h> #include <gtkmm/treestore.h> #include <gtkmm/treeview.h> -namespace Raul { class Path; } +#include <memory> + +namespace Gtk { +class Builder; +} // namespace Gtk namespace ingen { -namespace client { class ClientStore; class ObjectModel; } +class Atom; + +namespace client { +class ClientStore; +class ObjectModel; +class GraphModel; +} // namespace client namespace gui { -class GraphWindow; +class App; class GraphTreeView; /** Window with a TreeView of all loaded graphs. @@ -47,16 +63,17 @@ public: void init(App& app, client::ClientStore& store); - void new_object(const SPtr<client::ObjectModel>& object); + void new_object(const std::shared_ptr<client::ObjectModel>& object); - void graph_property_changed(const URI& key, - const Atom& value, - const SPtr<client::GraphModel>& graph); + void + graph_property_changed(const URI& key, + const Atom& value, + const std::shared_ptr<client::GraphModel>& graph); - void graph_moved(const SPtr<client::GraphModel>& graph); + void graph_moved(const std::shared_ptr<client::GraphModel>& graph); - void add_graph(const SPtr<client::GraphModel>& pm); - void remove_graph(const SPtr<client::GraphModel>& pm); + void add_graph(const std::shared_ptr<client::GraphModel>& pm); + void remove_graph(const std::shared_ptr<client::GraphModel>& pm); void show_graph_menu(GdkEventButton* ev); protected: @@ -65,30 +82,28 @@ protected: void event_graph_enabled_toggled(const Glib::ustring& path_str); - Gtk::TreeModel::iterator find_graph( - Gtk::TreeModel::Children root, - const SPtr<client::ObjectModel>& graph); + Gtk::TreeModel::iterator + find_graph(Gtk::TreeModel::Children root, + const std::shared_ptr<client::ObjectModel>& graph); - GraphTreeView* _graphs_treeview; + GraphTreeView* _graphs_treeview{nullptr}; - struct GraphTreeModelColumns : public Gtk::TreeModel::ColumnRecord - { + struct GraphTreeModelColumns : public Gtk::TreeModel::ColumnRecord { GraphTreeModelColumns() { add(name_col); add(enabled_col); add(graph_model_col); } - Gtk::TreeModelColumn<Glib::ustring> name_col; - Gtk::TreeModelColumn<bool> enabled_col; - Gtk::TreeModelColumn<SPtr<client::GraphModel> > graph_model_col; + Gtk::TreeModelColumn<Glib::ustring> name_col; + Gtk::TreeModelColumn<bool> enabled_col; + Gtk::TreeModelColumn<std::shared_ptr<client::GraphModel>> graph_model_col; }; - App* _app; GraphTreeModelColumns _graph_tree_columns; Glib::RefPtr<Gtk::TreeStore> _graph_treestore; Glib::RefPtr<Gtk::TreeSelection> _graph_tree_selection; - bool _enable_signal; + bool _enable_signal{true}; }; /** Derived TreeView class to support context menus for graphs */ @@ -98,24 +113,23 @@ public: GraphTreeView(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml) : Gtk::TreeView(cobject) - , _window(nullptr) {} void set_window(GraphTreeWindow* win) { _window = win; } bool on_button_press_event(GdkEventButton* ev) override { - bool ret = Gtk::TreeView::on_button_press_event(ev); + const bool ret = Gtk::TreeView::on_button_press_event(ev); - if ((ev->type == GDK_BUTTON_PRESS) && (ev->button == 3)) + if ((ev->type == GDK_BUTTON_PRESS) && (ev->button == 3)) { _window->show_graph_menu(ev); + } return ret; } private: - GraphTreeWindow* _window; - -}; // struct GraphTreeView + GraphTreeWindow* _window{nullptr}; +}; } // namespace gui } // namespace ingen diff --git a/src/gui/GraphView.cpp b/src/gui/GraphView.cpp index 36c6caed..8d1e1777 100644 --- a/src/gui/GraphView.cpp +++ b/src/gui/GraphView.cpp @@ -14,32 +14,49 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ +#include "GraphView.hpp" + #include "App.hpp" -#include "LoadPluginWindow.hpp" -#include "NewSubgraphWindow.hpp" #include "GraphCanvas.hpp" -#include "GraphTreeWindow.hpp" -#include "GraphView.hpp" #include "WidgetFactory.hpp" -#include "ingen/Interface.hpp" -#include "ingen/client/GraphModel.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/GraphModel.hpp> + +#include <glibmm/propertyproxy.h> +#include <glibmm/refptr.h> +#include <gtkmm/adjustment.h> +#include <gtkmm/builder.h> +#include <gtkmm/enums.h> +#include <gtkmm/layout.h> +#include <gtkmm/scrolledwindow.h> +#include <gtkmm/spinbutton.h> +#include <gtkmm/toggletoolbutton.h> +#include <gtkmm/toolbar.h> +#include <gtkmm/toolitem.h> +#include <sigc++/functors/mem_fun.h> +#include <sigc++/signal.h> #include <cassert> -#include <fstream> +#include <cstdint> +#include <map> +#include <memory> +#include <string> +#include <utility> namespace ingen { -using namespace client; +using client::GraphModel; namespace gui { GraphView::GraphView(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml) : Gtk::Box(cobject) - , _app(nullptr) - , _breadcrumb_container(nullptr) - , _enable_signal(true) { property_visible() = false; @@ -66,14 +83,14 @@ GraphView::init(App& app) } void -GraphView::set_graph(const SPtr<const GraphModel>& graph) +GraphView::set_graph(const std::shared_ptr<const GraphModel>& graph) { assert(!_canvas); // FIXME: remove assert(_breadcrumb_container); // ensure created _graph = graph; - _canvas = SPtr<GraphCanvas>(new GraphCanvas(*_app, graph, 1600*2, 1200*2)); + _canvas = std::make_shared<GraphCanvas>(*_app, graph, 1600*2, 1200*2); _canvas->build(); _canvas_scrolledwindow->add(_canvas->widget()); @@ -100,15 +117,21 @@ GraphView::set_graph(const SPtr<const GraphModel>& graph) _canvas->widget().grab_focus(); } -SPtr<GraphView> -GraphView::create(App& app, const SPtr<const GraphModel>& graph) +std::shared_ptr<GraphView> +GraphView::create(App& app, const std::shared_ptr<const GraphModel>& graph) { - GraphView* result = nullptr; - Glib::RefPtr<Gtk::Builder> xml = WidgetFactory::create("warehouse_win"); + GraphView* result = nullptr; + const Glib::RefPtr<Gtk::Builder> xml = + WidgetFactory::create("warehouse_win"); + xml->get_widget_derived("graph_view_box", result); + if (!result) { + return nullptr; + } + result->init(app); result->set_graph(graph); - return SPtr<GraphView>(result); + return std::shared_ptr<GraphView>(result); } void @@ -120,14 +143,14 @@ GraphView::process_toggled() _app->set_property(_graph->uri(), _app->uris().ingen_enabled, - _app->forge().make((bool)_process_but->get_active())); + _app->forge().make(_process_but->get_active())); } void GraphView::poly_changed() { const int poly = _poly_spin->get_value_as_int(); - if (_enable_signal && poly != (int)_graph->internal_poly()) { + if (_enable_signal && poly != static_cast<int>(_graph->internal_poly())) { _app->set_property(_graph->uri(), _app->uris().ingen_polyphony, _app->forge().make(poly)); diff --git a/src/gui/GraphView.hpp b/src/gui/GraphView.hpp index 457a5f76..812f2cbc 100644 --- a/src/gui/GraphView.hpp +++ b/src/gui/GraphView.hpp @@ -17,18 +17,22 @@ #ifndef INGEN_GUI_GRAPHVIEW_HPP #define INGEN_GUI_GRAPHVIEW_HPP -#include "ingen/types.hpp" - #include <gtkmm/box.h> -#include <gtkmm/builder.h> -#include <gtkmm/scrolledwindow.h> -#include <gtkmm/spinbutton.h> -#include <gtkmm/toggletoolbutton.h> -#include <gtkmm/toolbar.h> -#include <gtkmm/toolitem.h> -#include <gtkmm/toolitem.h> -namespace Raul { class Atom; } +#include <memory> + +namespace Glib { +template <class T> class RefPtr; +} // namespace Glib + +namespace Gtk { +class Builder; +class ScrolledWindow; +class SpinButton; +class ToggleToolButton; +class ToolItem; +class Toolbar; +} // namespace Gtk namespace ingen { @@ -36,22 +40,15 @@ class Atom; class URI; namespace client { -class PortModel; -class MetadataModel; class GraphModel; -class ObjectModel; -} +} // namespace client namespace gui { class App; -class LoadPluginWindow; -class NewSubgraphWindow; class GraphCanvas; -class GraphDescriptionWindow; -class SubgraphModule; -/** The graph specific contents of a GraphWindow (ie the canvas and whatever else). +/** The graph specific contents of a GraphWindow (the canvas and whatever else). * * \ingroup GUI */ @@ -61,19 +58,23 @@ public: GraphView(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml); - ~GraphView(); + ~GraphView() override; void init(App& app); - SPtr<GraphCanvas> canvas() const { return _canvas; } - SPtr<const client::GraphModel> graph() const { return _graph; } - Gtk::ToolItem* breadcrumb_container() const { return _breadcrumb_container; } + std::shared_ptr<GraphCanvas> canvas() const { return _canvas; } + std::shared_ptr<const client::GraphModel> graph() const { return _graph; } + + Gtk::ToolItem* breadcrumb_container() const + { + return _breadcrumb_container; + } - static SPtr<GraphView> - create(App& app, const SPtr<const client::GraphModel>& graph); + static std::shared_ptr<GraphView> + create(App& app, const std::shared_ptr<const client::GraphModel>& graph); private: - void set_graph(const SPtr<const client::GraphModel>& graph); + void set_graph(const std::shared_ptr<const client::GraphModel>& graph); void process_toggled(); void poly_changed(); @@ -81,18 +82,18 @@ private: void property_changed(const URI& predicate, const Atom& value); - App* _app; + App* _app = nullptr; - SPtr<const client::GraphModel> _graph; - SPtr<GraphCanvas> _canvas; + std::shared_ptr<const client::GraphModel> _graph; + std::shared_ptr<GraphCanvas> _canvas; - Gtk::ScrolledWindow* _canvas_scrolledwindow; - Gtk::Toolbar* _toolbar; - Gtk::ToggleToolButton* _process_but; - Gtk::SpinButton* _poly_spin; - Gtk::ToolItem* _breadcrumb_container; + Gtk::ScrolledWindow* _canvas_scrolledwindow = nullptr; + Gtk::Toolbar* _toolbar = nullptr; + Gtk::ToggleToolButton* _process_but = nullptr; + Gtk::SpinButton* _poly_spin = nullptr; + Gtk::ToolItem* _breadcrumb_container = nullptr; - bool _enable_signal; + bool _enable_signal = true; }; } // namespace gui diff --git a/src/gui/GraphWindow.cpp b/src/gui/GraphWindow.cpp index 086886ef..a6978e46 100644 --- a/src/gui/GraphWindow.cpp +++ b/src/gui/GraphWindow.cpp @@ -14,25 +14,24 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/client/ClientStore.hpp" -#include "ingen/client/GraphModel.hpp" +#include "GraphWindow.hpp" -#include "App.hpp" +#include "GraphBox.hpp" #include "GraphCanvas.hpp" #include "GraphView.hpp" -#include "GraphWindow.hpp" -#include "WindowFactory.hpp" +#include "Window.hpp" + +#include <glibmm/propertyproxy.h> +#include <glibmm/refptr.h> +#include <gtkmm/builder.h> +#include <gtkmm/layout.h> +#include <gtkmm/window.h> -namespace ingen { -namespace gui { +namespace ingen::gui { GraphWindow::GraphWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml) : Window(cobject) - , _box(nullptr) - , _position_stored(false) - , _x(0) - , _y(0) { property_visible() = false; @@ -81,5 +80,4 @@ GraphWindow::on_key_press_event(GdkEventKey* event) return Gtk::Window::on_key_press_event(event); } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/GraphWindow.hpp b/src/gui/GraphWindow.hpp index e3d30d4c..9936b5df 100644 --- a/src/gui/GraphWindow.hpp +++ b/src/gui/GraphWindow.hpp @@ -20,17 +20,27 @@ #include "GraphBox.hpp" #include "Window.hpp" -#include "ingen/types.hpp" - -#include <gtkmm/builder.h> +#include <gdk/gdk.h> +#include <memory> #include <string> +namespace Glib { +template <class T> class RefPtr; +} // namespace Glib + +namespace Gtk { +class Builder; +} // namespace Gtk + namespace ingen { +class Atom; + namespace client { class GraphModel; -} +class PortModel; +} // namespace client namespace gui { @@ -44,12 +54,16 @@ public: GraphWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml); - ~GraphWindow(); + ~GraphWindow() override; void init_window(App& app) override; - SPtr<const client::GraphModel> graph() const { return _box->graph(); } - GraphBox* box() const { return _box; } + std::shared_ptr<const client::GraphModel> graph() const + { + return _box->graph(); + } + + GraphBox* box() const { return _box; } bool documentation_is_visible() { return _box->documentation_is_visible(); } @@ -68,10 +82,10 @@ protected: bool on_key_press_event(GdkEventKey* event) override; private: - GraphBox* _box; - bool _position_stored; - int _x; - int _y; + GraphBox* _box{nullptr}; + bool _position_stored{false}; + int _x{0}; + int _y{0}; }; } // namespace gui diff --git a/src/gui/LoadGraphWindow.cpp b/src/gui/LoadGraphWindow.cpp index 62c68b04..5124face 100644 --- a/src/gui/LoadGraphWindow.cpp +++ b/src/gui/LoadGraphWindow.cpp @@ -17,36 +17,55 @@ #include "LoadGraphWindow.hpp" #include "App.hpp" -#include "GraphView.hpp" -#include "Style.hpp" #include "ThreadedLoader.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/Interface.hpp" -#include "ingen/client/BlockModel.hpp" -#include "ingen/client/ClientStore.hpp" -#include "ingen/client/GraphModel.hpp" -#include "ingen/runtime_paths.hpp" - -#include <boost/optional/optional.hpp> +#include <ingen/Atom.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/FilePath.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/ClientStore.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/runtime_paths.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> + +#include <glibmm/fileutils.h> #include <glibmm/miscutils.h> +#include <glibmm/propertyproxy.h> +#include <glibmm/refptr.h> +#include <glibmm/slisthandle.h> +#include <gtkmm/builder.h> +#include <gtkmm/button.h> +#include <gtkmm/entry.h> +#include <gtkmm/filefilter.h> +#include <gtkmm/label.h> +#include <gtkmm/radiobutton.h> +#include <gtkmm/spinbutton.h> +#include <gtkmm/window.h> +#include <sigc++/adaptors/bind.h> +#include <sigc++/functors/mem_fun.h> #include <list> -#include <ostream> +#include <map> +#include <memory> +#include <optional> +#include <sstream> #include <string> #include <utility> namespace ingen { -using namespace client; +using client::GraphModel; namespace gui { LoadGraphWindow::LoadGraphWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml) : Gtk::FileChooserDialog(cobject) - , _app(nullptr) - , _merge_ports(false) { xml->get_widget("load_graph_symbol_label", _symbol_label); xml->get_widget("load_graph_symbol_entry", _symbol_entry); @@ -97,9 +116,9 @@ LoadGraphWindow::LoadGraphWindow(BaseObjectType* cobject, } void -LoadGraphWindow::present(const SPtr<const GraphModel>& graph, - bool import, - const Properties& data) +LoadGraphWindow::present(const std::shared_ptr<const GraphModel>& graph, + bool import, + const Properties& data) { _import = import; set_graph(graph); @@ -117,7 +136,7 @@ LoadGraphWindow::present(const SPtr<const GraphModel>& graph, * This function MUST be called before using the window in any way! */ void -LoadGraphWindow::set_graph(const SPtr<const GraphModel>& graph) +LoadGraphWindow::set_graph(const std::shared_ptr<const GraphModel>& graph) { _graph = graph; _symbol_entry->set_text(""); @@ -169,8 +188,8 @@ LoadGraphWindow::ok_clicked() if (_import) { // If unset load_graph will load value - boost::optional<Raul::Path> parent; - boost::optional<Raul::Symbol> symbol; + std::optional<raul::Path> parent; + std::optional<raul::Symbol> symbol; if (!_graph->path().is_root()) { parent = _graph->path().parent(); symbol = _graph->symbol(); @@ -180,17 +199,17 @@ LoadGraphWindow::ok_clicked() true, FilePath(get_filename()), parent, symbol, _initial_data); } else { - std::list<Glib::ustring> uri_list = get_filenames(); - for (auto u : uri_list) { + const std::list<Glib::ustring> uri_list = get_filenames(); + for (const auto& u : uri_list) { // Cascade Atom& x = _initial_data.find(uris.ingen_canvasX)->second; x = _app->forge().make(x.get<float>() + 20.0f); Atom& y = _initial_data.find(uris.ingen_canvasY)->second; y = _app->forge().make(y.get<float>() + 20.0f); - Raul::Symbol symbol(symbol_from_filename(u)); + raul::Symbol symbol(symbol_from_filename(u)); if (uri_list.size() == 1 && !_symbol_entry->get_text().empty()) { - symbol = Raul::Symbol::symbolify(_symbol_entry->get_text()); + symbol = raul::Symbol::symbolify(_symbol_entry->get_text()); } symbol = avoid_symbol_clash(symbol); @@ -215,27 +234,27 @@ LoadGraphWindow::cancel_clicked() hide(); } -Raul::Symbol +raul::Symbol LoadGraphWindow::symbol_from_filename(const Glib::ustring& filename) { std::string symbol_str = Glib::path_get_basename(get_filename()); - symbol_str = symbol_str.substr(0, symbol_str.find('.')); - return Raul::Symbol::symbolify(symbol_str); + symbol_str.resize(symbol_str.find('.')); + return raul::Symbol::symbolify(symbol_str); } -Raul::Symbol -LoadGraphWindow::avoid_symbol_clash(const Raul::Symbol& symbol) +raul::Symbol +LoadGraphWindow::avoid_symbol_clash(const raul::Symbol& symbol) { - unsigned offset = _app->store()->child_name_offset( + const unsigned offset = _app->store()->child_name_offset( _graph->path(), symbol); if (offset != 0) { std::stringstream ss; ss << symbol << "_" << offset; - return Raul::Symbol(ss.str()); - } else { - return symbol; + return raul::Symbol(ss.str()); } + + return symbol; } void diff --git a/src/gui/LoadGraphWindow.hpp b/src/gui/LoadGraphWindow.hpp index a2217d83..bfa2590e 100644 --- a/src/gui/LoadGraphWindow.hpp +++ b/src/gui/LoadGraphWindow.hpp @@ -17,20 +17,32 @@ #ifndef INGEN_GUI_LOADGRAPHWINDOW_HPP #define INGEN_GUI_LOADGRAPHWINDOW_HPP -#include "ingen/Node.hpp" -#include "ingen/types.hpp" +#include <ingen/Properties.hpp> +#include <raul/Symbol.hpp> -#include <gtkmm/builder.h> -#include <gtkmm/button.h> -#include <gtkmm/entry.h> +#include <glibmm/ustring.h> #include <gtkmm/filechooserdialog.h> -#include <gtkmm/label.h> -#include <gtkmm/radiobutton.h> -#include <gtkmm/spinbutton.h> + +#include <memory> + +namespace Glib { +template <class T> class RefPtr; +} // namespace Glib + +namespace Gtk { +class Builder; +class Button; +class Entry; +class Label; +class RadioButton; +class SpinButton; +} // namespace Gtk namespace ingen { -namespace client { class GraphModel; } +namespace client { +class GraphModel; +} // namespace client namespace gui { @@ -50,11 +62,11 @@ public: void init(App& app) { _app = &app; } - void set_graph(const SPtr<const client::GraphModel>& graph); + void set_graph(const std::shared_ptr<const client::GraphModel>& graph); - void present(const SPtr<const client::GraphModel>& graph, - bool import, - const Properties& data); + void present(const std::shared_ptr<const client::GraphModel>& graph, + bool import, + const Properties& data); protected: void on_show() override; @@ -67,28 +79,28 @@ private: void cancel_clicked(); void ok_clicked(); - Raul::Symbol symbol_from_filename(const Glib::ustring& filename); - Raul::Symbol avoid_symbol_clash(const Raul::Symbol& symbol); + raul::Symbol symbol_from_filename(const Glib::ustring& filename); + raul::Symbol avoid_symbol_clash(const raul::Symbol& symbol); - App* _app; + App* _app = nullptr; Properties _initial_data; - SPtr<const client::GraphModel> _graph; - - Gtk::Label* _symbol_label; - Gtk::Entry* _symbol_entry; - Gtk::Label* _ports_label; - Gtk::RadioButton* _merge_ports_radio; - Gtk::RadioButton* _insert_ports_radio; - Gtk::RadioButton* _poly_voices_radio; - Gtk::RadioButton* _poly_from_file_radio; - Gtk::SpinButton* _poly_spinbutton; - Gtk::Button* _ok_button; - Gtk::Button* _cancel_button; - - bool _import; - bool _merge_ports; + std::shared_ptr<const client::GraphModel> _graph; + + Gtk::Label* _symbol_label = nullptr; + Gtk::Entry* _symbol_entry = nullptr; + Gtk::Label* _ports_label = nullptr; + Gtk::RadioButton* _merge_ports_radio = nullptr; + Gtk::RadioButton* _insert_ports_radio = nullptr; + Gtk::RadioButton* _poly_voices_radio = nullptr; + Gtk::RadioButton* _poly_from_file_radio = nullptr; + Gtk::SpinButton* _poly_spinbutton = nullptr; + Gtk::Button* _ok_button = nullptr; + Gtk::Button* _cancel_button = nullptr; + + bool _import = false; + bool _merge_ports = false; }; } // namespace gui diff --git a/src/gui/LoadPluginWindow.cpp b/src/gui/LoadPluginWindow.cpp index bb84f96f..3d8b2cd5 100644 --- a/src/gui/LoadPluginWindow.cpp +++ b/src/gui/LoadPluginWindow.cpp @@ -14,36 +14,66 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "App.hpp" -#include "GraphCanvas.hpp" -#include "GraphView.hpp" -#include "GraphWindow.hpp" #include "LoadPluginWindow.hpp" -#include "ingen_config.h" -#include "ingen/Interface.hpp" -#include "ingen/client/ClientStore.hpp" -#include "ingen/client/GraphModel.hpp" +#include "App.hpp" +#include "Window.hpp" + +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/ClientStore.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/PluginModel.hpp> +#include <ingen/paths.hpp> +#include <lilv/lilv.h> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> + +#include <gdk/gdkkeysyms-compat.h> +#include <glibmm/listhandle.h> +#include <glibmm/propertyproxy.h> +#include <glibmm/ustring.h> +#include <gtkmm/builder.h> +#include <gtkmm/button.h> +#include <gtkmm/checkbutton.h> +#include <gtkmm/combobox.h> +#include <gtkmm/enums.h> +#include <gtkmm/messagedialog.h> +#include <gtkmm/object.h> +#include <gtkmm/treeiter.h> +#include <gtkmm/treepath.h> +#include <gtkmm/treeview.h> +#include <gtkmm/treeviewcolumn.h> +#include <gtkmm/window.h> +#include <sigc++/adaptors/bind.h> +#include <sigc++/functors/mem_fun.h> +#include <sigc++/signal.h> -#include <string> -#include <cstddef> -#include <cassert> #include <algorithm> +#include <cctype> +#include <cstddef> +#include <memory> +#include <sstream> +#include <string> +#include <utility> using std::string; namespace ingen { -using namespace client; +using client::ClientStore; +using client::GraphModel; +using client::PluginModel; namespace gui { LoadPluginWindow::LoadPluginWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml) : Window(cobject) - , _name_offset(0) - , _has_shown(false) - , _refresh_list(true) { xml->get_widget("load_plugin_plugins_treeview", _plugins_treeview); xml->get_widget("load_plugin_polyphonic_checkbutton", _polyphonic_checkbutton); @@ -77,8 +107,9 @@ LoadPluginWindow::LoadPluginWindow(BaseObjectType* cobject, _criteria_liststore = Gtk::ListStore::create(_criteria_columns); _filter_combo->set_model(_criteria_liststore); - Gtk::TreeModel::iterator iter = _criteria_liststore->append(); - Gtk::TreeModel::Row row = *iter; + auto iter = _criteria_liststore->append(); + auto row = *iter; + row[_criteria_columns._col_label] = "Name contains"; row[_criteria_columns._col_criteria] = CriteriaColumns::Criteria::NAME; _filter_combo->set_active(iter); @@ -125,8 +156,8 @@ LoadPluginWindow::LoadPluginWindow(BaseObjectType* cobject, } void -LoadPluginWindow::present(SPtr<const GraphModel> graph, - Properties data) +LoadPluginWindow::present(const std::shared_ptr<const GraphModel>& graph, + const Properties& data) { set_graph(graph); _initial_data = data; @@ -142,9 +173,9 @@ LoadPluginWindow::name_changed() // Toggle add button sensitivity according name legality if (_selection->get_selected_rows().size() == 1) { const string sym = _name_entry->get_text(); - if (!Raul::Symbol::is_valid(sym)) { + if (!raul::Symbol::is_valid(sym)) { _add_button->property_sensitive() = false; - } else if (_app->store()->find(_graph->path().child(Raul::Symbol(sym))) + } else if (_app->store()->find(_graph->path().child(raul::Symbol(sym))) != _app->store()->end()) { _add_button->property_sensitive() = false; } else { @@ -164,7 +195,7 @@ LoadPluginWindow::name_cleared(Gtk::EntryIconPosition pos, const GdkEventButton* * This function MUST be called before using the window in any way! */ void -LoadPluginWindow::set_graph(SPtr<const GraphModel> graph) +LoadPluginWindow::set_graph(const std::shared_ptr<const GraphModel>& graph) { if (_graph) { _graph = graph; @@ -199,12 +230,13 @@ LoadPluginWindow::on_show() } void -LoadPluginWindow::set_plugins(SPtr<const ClientStore::Plugins> plugins) +LoadPluginWindow::set_plugins( + const std::shared_ptr<const ClientStore::Plugins>& plugins) { _rows.clear(); _plugins_liststore->clear(); - for (const auto& p : *plugins.get()) { + for (const auto& p : *plugins) { add_plugin(p.second); } @@ -213,7 +245,7 @@ LoadPluginWindow::set_plugins(SPtr<const ClientStore::Plugins> plugins) } void -LoadPluginWindow::new_plugin(SPtr<const PluginModel> pm) +LoadPluginWindow::new_plugin(const std::shared_ptr<const PluginModel>& pm) { if (is_visible()) { add_plugin(pm); @@ -223,7 +255,7 @@ LoadPluginWindow::new_plugin(SPtr<const PluginModel> pm) } static std::string -get_project_name(SPtr<const PluginModel> plugin) +get_project_name(const std::shared_ptr<const PluginModel>& plugin) { std::string name; if (plugin->lilv_plugin()) { @@ -249,7 +281,7 @@ get_project_name(SPtr<const PluginModel> plugin) } static std::string -get_author_name(SPtr<const PluginModel> plugin) +get_author_name(const std::shared_ptr<const PluginModel>& plugin) { std::string name; if (plugin->lilv_plugin()) { @@ -263,8 +295,8 @@ get_author_name(SPtr<const PluginModel> plugin) } void -LoadPluginWindow::set_row(Gtk::TreeModel::Row& row, - SPtr<const PluginModel> plugin) +LoadPluginWindow::set_row(Gtk::TreeModel::Row& row, + const std::shared_ptr<const PluginModel>& plugin) { const URIs& uris = _app->uris(); const Atom& name = plugin->get_property(uris.doap_name); @@ -294,14 +326,14 @@ LoadPluginWindow::set_row(Gtk::TreeModel::Row& row, } void -LoadPluginWindow::add_plugin(SPtr<const PluginModel> plugin) +LoadPluginWindow::add_plugin(const std::shared_ptr<const PluginModel>& plugin) { if (plugin->lilv_plugin() && lilv_plugin_is_replaced(plugin->lilv_plugin())) { return; } - Gtk::TreeModel::iterator iter = _plugins_liststore->append(); - Gtk::TreeModel::Row row = *iter; + auto iter = _plugins_liststore->append(); + auto row = *iter; _rows.emplace(plugin->uri(), iter); set_row(row, plugin); @@ -323,20 +355,22 @@ LoadPluginWindow::plugin_activated(const Gtk::TreeModel::Path& path, void LoadPluginWindow::plugin_selection_changed() { - size_t n_selected = _selection->get_selected_rows().size(); + const size_t n_selected = _selection->get_selected_rows().size(); if (n_selected == 0) { _name_offset = 0; _name_entry->set_text(""); _name_entry->set_sensitive(false); } else if (n_selected == 1) { - Gtk::TreeModel::iterator iter = _plugins_liststore->get_iter( - *_selection->get_selected_rows().begin()); + auto iter = _plugins_liststore->get_iter( + *_selection->get_selected_rows().begin()); if (iter) { - Gtk::TreeModel::Row row = *iter; - SPtr<const PluginModel> p = row.get_value( - _plugins_columns._col_plugin); - _name_offset = _app->store()->child_name_offset( - _graph->path(), p->default_block_symbol()); + auto row = *iter; + auto p = row.get_value(_plugins_columns._col_plugin); + + _name_offset = + _app->store()->child_name_offset(_graph->path(), + p->default_block_symbol()); + _name_entry->set_text(generate_module_name(p, _name_offset)); _name_entry->set_sensitive(true); } else { @@ -357,8 +391,9 @@ LoadPluginWindow::plugin_selection_changed() * sends the notification back. */ string -LoadPluginWindow::generate_module_name(SPtr<const PluginModel> plugin, - int offset) +LoadPluginWindow::generate_module_name( + const std::shared_ptr<const PluginModel>& plugin, + int offset) { std::stringstream ss; ss << plugin->default_block_symbol(); @@ -371,17 +406,17 @@ LoadPluginWindow::generate_module_name(SPtr<const PluginModel> plugin, void LoadPluginWindow::load_plugin(const Gtk::TreeModel::iterator& iter) { - const URIs& uris = _app->uris(); - Gtk::TreeModel::Row row = *iter; - SPtr<const PluginModel> plugin = row.get_value(_plugins_columns._col_plugin); - bool polyphonic = _polyphonic_checkbutton->get_active(); - string name = _name_entry->get_text(); + const URIs& uris = _app->uris(); + auto row = *iter; + auto plugin = row.get_value(_plugins_columns._col_plugin); + const bool polyphonic = _polyphonic_checkbutton->get_active(); + string name = _name_entry->get_text(); if (name.empty()) { name = generate_module_name(plugin, _name_offset); } - if (name.empty() || !Raul::Symbol::is_valid(name)) { + if (name.empty() || !raul::Symbol::is_valid(name)) { Gtk::MessageDialog dialog( *this, "Unable to choose a default name, please provide one", @@ -389,8 +424,8 @@ LoadPluginWindow::load_plugin(const Gtk::TreeModel::iterator& iter) dialog.run(); } else { - Raul::Path path = _graph->path().child(Raul::Symbol::symbolify(name)); - Properties props = _initial_data; + const raul::Path path = _graph->path().child(raul::Symbol::symbolify(name)); + Properties props = _initial_data; props.emplace(uris.rdf_type, Property(uris.ingen_Block)); props.emplace(uris.lv2_prototype, _app->forge().make_urid(plugin->uri())); props.emplace(uris.ingen_polyphonic, _app->forge().make(polyphonic)); @@ -425,8 +460,8 @@ LoadPluginWindow::filter_changed() transform(search.begin(), search.end(), search.begin(), ::toupper); // Get selected criteria - const Gtk::TreeModel::Row row = *(_filter_combo->get_active()); - CriteriaColumns::Criteria criteria = row[_criteria_columns._col_criteria]; + const auto row = *(_filter_combo->get_active()); + const CriteriaColumns::Criteria criteria = row[_criteria_columns._col_criteria]; string field; @@ -435,9 +470,9 @@ LoadPluginWindow::filter_changed() size_t num_visible = 0; const URIs& uris = _app->uris(); - for (const auto& p : *_app->store()->plugins().get()) { - const SPtr<PluginModel> plugin = p.second; - const Atom& name = plugin->get_property(uris.doap_name); + for (const auto& p : *_app->store()->plugins()) { + const auto plugin = p.second; + const Atom& name = plugin->get_property(uris.doap_name); switch (criteria) { case CriteriaColumns::Criteria::NAME: @@ -485,9 +520,9 @@ LoadPluginWindow::on_key_press_event(GdkEventKey* event) if (event->keyval == GDK_w && event->state & GDK_CONTROL_MASK) { hide(); return true; - } else { - return Gtk::Window::on_key_press_event(event); } + + return Gtk::Window::on_key_press_event(event); } void @@ -497,7 +532,7 @@ LoadPluginWindow::plugin_property_changed(const URI& plugin, { const URIs& uris = _app->uris(); if (predicate == uris.doap_name) { - Rows::const_iterator i = _rows.find(plugin); + const auto i = _rows.find(plugin); if (i != _rows.end() && value.type() == uris.forge.String) { (*i->second)[_plugins_columns._col_name] = value.ptr<char>(); } diff --git a/src/gui/LoadPluginWindow.hpp b/src/gui/LoadPluginWindow.hpp index 31843dde..eab48913 100644 --- a/src/gui/LoadPluginWindow.hpp +++ b/src/gui/LoadPluginWindow.hpp @@ -19,26 +19,43 @@ #include "Window.hpp" -#include "ingen/Node.hpp" -#include "ingen/client/ClientStore.hpp" -#include "ingen/types.hpp" -#include "ingen_config.h" +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/client/ClientStore.hpp> -#include <gtkmm/builder.h> -#include <gtkmm/combobox.h> +#include <gdk/gdk.h> +#include <glibmm/refptr.h> +#include <gtkmm/entry.h> #include <gtkmm/liststore.h> #include <gtkmm/treemodel.h> -#include <gtkmm/treeview.h> +#include <gtkmm/treemodelcolumn.h> +#include <gtkmm/treeselection.h> #include <map> +#include <memory> #include <string> +namespace Glib { +class ustring; +} // namespace Glib + +namespace Gtk { +class Builder; +class Button; +class CheckButton; +class ComboBox; +class TreeView; +class TreeViewColumn; +} // namespace Gtk + namespace ingen { +class Atom; + namespace client { class GraphModel; class PluginModel; -} +} // namespace client namespace gui { @@ -54,13 +71,15 @@ public: LoadPluginWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml); - void set_graph(SPtr<const client::GraphModel> graph); - void set_plugins(SPtr<const client::ClientStore::Plugins> plugins); + void set_graph(const std::shared_ptr<const client::GraphModel>& graph); + + void set_plugins( + const std::shared_ptr<const client::ClientStore::Plugins>& plugins); - void add_plugin(SPtr<const client::PluginModel> plugin); + void add_plugin(const std::shared_ptr<const client::PluginModel>& plugin); - void present(SPtr<const client::GraphModel> graph, - Properties data); + void present(const std::shared_ptr<const client::GraphModel>& graph, + const Properties& data); protected: void on_show() override; @@ -68,7 +87,8 @@ protected: private: /** Columns for the plugin list */ - class ModelColumns : public Gtk::TreeModel::ColumnRecord { + class ModelColumns : public Gtk::TreeModel::ColumnRecord + { public: ModelColumns() { add(_col_name); @@ -86,11 +106,12 @@ private: Gtk::TreeModelColumn<Glib::ustring> _col_uri; // Not displayed: - Gtk::TreeModelColumn< SPtr<const client::PluginModel> > _col_plugin; + Gtk::TreeModelColumn<std::shared_ptr<const client::PluginModel>> _col_plugin; }; /** Column for the filter criteria combo box. */ - class CriteriaColumns : public Gtk::TreeModel::ColumnRecord { + class CriteriaColumns : public Gtk::TreeModel::ColumnRecord + { public: enum class Criteria { NAME, TYPE, PROJECT, AUTHOR, URI, }; @@ -109,10 +130,10 @@ private: void name_changed(); void name_cleared(Gtk::EntryIconPosition pos, const GdkEventButton* event); - void set_row(Gtk::TreeModel::Row& row, - SPtr<const client::PluginModel> plugin); + void set_row(Gtk::TreeModel::Row& row, + const std::shared_ptr<const client::PluginModel>& plugin); - void new_plugin(SPtr<const client::PluginModel> pm); + void new_plugin(const std::shared_ptr<const client::PluginModel>& pm); void plugin_property_changed(const URI& plugin, const URI& predicate, @@ -121,14 +142,15 @@ private: void plugin_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* col); void plugin_selection_changed(); - std::string generate_module_name(SPtr<const client::PluginModel> plugin, - int offset=0); + static std::string generate_module_name( + const std::shared_ptr<const client::PluginModel>& plugin, + int offset = 0); void load_plugin(const Gtk::TreeModel::iterator& iter); Properties _initial_data; - SPtr<const client::GraphModel> _graph; + std::shared_ptr<const client::GraphModel> _graph; using Rows = std::map<URI, Gtk::TreeModel::iterator>; Rows _rows; @@ -141,17 +163,17 @@ private: Glib::RefPtr<Gtk::TreeSelection> _selection; - int _name_offset; // see comments for generate_plugin_name - - bool _has_shown; - bool _refresh_list; - Gtk::TreeView* _plugins_treeview; - Gtk::CheckButton* _polyphonic_checkbutton; - Gtk::Entry* _name_entry; - Gtk::Button* _close_button; - Gtk::Button* _add_button; - Gtk::ComboBox* _filter_combo; - Gtk::Entry* _search_entry; + int _name_offset = 0; // see comments for generate_plugin_name + + bool _has_shown = false; + bool _refresh_list = true; + Gtk::TreeView* _plugins_treeview = nullptr; + Gtk::CheckButton* _polyphonic_checkbutton = nullptr; + Gtk::Entry* _name_entry = nullptr; + Gtk::Button* _close_button = nullptr; + Gtk::Button* _add_button = nullptr; + Gtk::ComboBox* _filter_combo = nullptr; + Gtk::Entry* _search_entry = nullptr; }; } // namespace gui diff --git a/src/gui/MessagesWindow.cpp b/src/gui/MessagesWindow.cpp index 84d29679..993fbb33 100644 --- a/src/gui/MessagesWindow.cpp +++ b/src/gui/MessagesWindow.cpp @@ -17,16 +17,30 @@ #include "MessagesWindow.hpp" #include "App.hpp" - -#include "ingen/URIs.hpp" +#include "Window.hpp" +#include "ingen_config.h" + +#include <ingen/URIs.hpp> +#include <lv2/urid/urid.h> + +#include <gdkmm/color.h> +#include <glibmm/propertyproxy.h> +#include <glibmm/ustring.h> +#include <gtkmm/builder.h> +#include <gtkmm/button.h> +#include <gtkmm/enums.h> +#include <gtkmm/textbuffer.h> +#include <gtkmm/texttagtable.h> +#include <gtkmm/textview.h> +#include <sigc++/functors/mem_fun.h> #include <cstdio> #include <cstdlib> #include <string> #include <utility> -namespace ingen { -namespace gui { +namespace ingen::gui { + using std::string; MessagesWindow::MessagesWindow(BaseObjectType* cobject, @@ -41,8 +55,8 @@ MessagesWindow::MessagesWindow(BaseObjectType* cobject, _close_button->signal_clicked().connect(sigc::mem_fun(this, &Window::hide)); for (int s = Gtk::STATE_NORMAL; s <= Gtk::STATE_INSENSITIVE; ++s) { - _textview->modify_base((Gtk::StateType)s, Gdk::Color("#000000")); - _textview->modify_text((Gtk::StateType)s, Gdk::Color("#EEEEEC")); + _textview->modify_base(static_cast<Gtk::StateType>(s), Gdk::Color("#000000")); + _textview->modify_text(static_cast<Gtk::StateType>(s), Gdk::Color("#EEEEEC")); } } @@ -70,7 +84,7 @@ MessagesWindow::init_window(App& app) void MessagesWindow::post_error(const string& msg) { - Glib::RefPtr<Gtk::TextBuffer> text_buf = _textview->get_buffer(); + const Glib::RefPtr<Gtk::TextBuffer> text_buf = _textview->get_buffer(); text_buf->insert_with_tag(text_buf->end(), msg, _error_tag); text_buf->insert(text_buf->end(), "\n"); @@ -87,9 +101,9 @@ MessagesWindow::post_error(const string& msg) int MessagesWindow::log(LV2_URID type, const char* fmt, va_list args) { - std::lock_guard<std::mutex> lock(_mutex); + const std::lock_guard<std::mutex> lock{_mutex}; -#ifdef HAVE_VASPRINTF +#if USE_VASPRINTF char* buf = nullptr; const int len = vasprintf(&buf, fmt, args); #else @@ -107,10 +121,11 @@ void MessagesWindow::flush() { while (true) { - LV2_URID type; + LV2_URID type = 0; std::string line; + { - std::lock_guard<std::mutex> lock(_mutex); + const std::lock_guard<std::mutex> lock{_mutex}; if (!_stream.rdbuf()->in_avail()) { return; } @@ -118,7 +133,7 @@ MessagesWindow::flush() std::getline(_stream, line, '\0'); } - Glib::RefPtr<Gtk::TextBuffer> text_buf = _textview->get_buffer(); + const Glib::RefPtr<Gtk::TextBuffer> text_buf = _textview->get_buffer(); auto t = _tags.find(type); if (t != _tags.end()) { @@ -136,10 +151,9 @@ MessagesWindow::flush() void MessagesWindow::clear_clicked() { - Glib::RefPtr<Gtk::TextBuffer> text_buf = _textview->get_buffer(); + const Glib::RefPtr<Gtk::TextBuffer> text_buf = _textview->get_buffer(); text_buf->erase(text_buf->begin(), text_buf->end()); _clear_button->set_sensitive(false); } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/MessagesWindow.hpp b/src/gui/MessagesWindow.hpp index add87455..0a70e76c 100644 --- a/src/gui/MessagesWindow.hpp +++ b/src/gui/MessagesWindow.hpp @@ -19,11 +19,10 @@ #include "Window.hpp" -#include "lv2/log/log.h" +#include <lv2/urid/urid.h> -#include <gtkmm/builder.h> -#include <gtkmm/button.h> -#include <gtkmm/textview.h> +#include <glibmm/refptr.h> +#include <gtkmm/texttag.h> #include <cstdarg> #include <map> @@ -31,8 +30,13 @@ #include <sstream> #include <string> -namespace ingen { -namespace gui { +namespace Gtk { +class Builder; +class Button; +class TextView; +} // namespace Gtk + +namespace ingen::gui { /** Messages Window. * @@ -59,15 +63,14 @@ private: std::mutex _mutex; std::stringstream _stream; - Gtk::TextView* _textview; - Gtk::Button* _clear_button; - Gtk::Button* _close_button; + Gtk::TextView* _textview{nullptr}; + Gtk::Button* _clear_button{nullptr}; + Gtk::Button* _close_button{nullptr}; Glib::RefPtr<Gtk::TextTag> _error_tag; std::map< LV2_URID, Glib::RefPtr<Gtk::TextTag> > _tags; }; -} // namespace gui -} // namespace ingen +} // namespace ingen::gui #endif // INGEN_GUI_MESSAGESWINDOW_HPP diff --git a/src/gui/NewSubgraphWindow.cpp b/src/gui/NewSubgraphWindow.cpp index 228bd91c..3d6bf019 100644 --- a/src/gui/NewSubgraphWindow.cpp +++ b/src/gui/NewSubgraphWindow.cpp @@ -17,17 +17,38 @@ #include "NewSubgraphWindow.hpp" #include "App.hpp" -#include "GraphView.hpp" - -#include "ingen/Interface.hpp" -#include "ingen/client/ClientStore.hpp" -#include "ingen/client/GraphModel.hpp" +#include "Window.hpp" + +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/ClientStore.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/paths.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> + +#include <glibmm/propertyproxy.h> +#include <glibmm/refptr.h> +#include <glibmm/ustring.h> +#include <gtkmm/adjustment.h> +#include <gtkmm/builder.h> +#include <gtkmm/button.h> +#include <gtkmm/entry.h> +#include <gtkmm/label.h> +#include <gtkmm/spinbutton.h> +#include <gtkmm/window.h> +#include <sigc++/functors/mem_fun.h> #include <cstdint> +#include <map> #include <string> +#include <utility> -namespace ingen { -namespace gui { +namespace ingen::gui { NewSubgraphWindow::NewSubgraphWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml) @@ -49,10 +70,10 @@ NewSubgraphWindow::NewSubgraphWindow(BaseObjectType* cobject, } void -NewSubgraphWindow::present(SPtr<const client::GraphModel> graph, - Properties data) +NewSubgraphWindow::present(std::shared_ptr<const client::GraphModel> graph, + const Properties& data) { - set_graph(graph); + set_graph(std::move(graph)); _initial_data = data; Gtk::Window::present(); } @@ -62,9 +83,9 @@ NewSubgraphWindow::present(SPtr<const client::GraphModel> graph, * This function MUST be called before using the window in any way! */ void -NewSubgraphWindow::set_graph(SPtr<const client::GraphModel> graph) +NewSubgraphWindow::set_graph(std::shared_ptr<const client::GraphModel> graph) { - _graph = graph; + _graph = std::move(graph); } /** Called every time the user types into the name input box. @@ -73,11 +94,11 @@ NewSubgraphWindow::set_graph(SPtr<const client::GraphModel> graph) void NewSubgraphWindow::name_changed() { - std::string name = _name_entry->get_text(); - if (!Raul::Symbol::is_valid(name)) { + const std::string name = _name_entry->get_text(); + if (!raul::Symbol::is_valid(name)) { _message_label->set_text("Name contains invalid characters."); _ok_button->property_sensitive() = false; - } else if (_app->store()->find(_graph->path().child(Raul::Symbol(name))) + } else if (_app->store()->find(_graph->path().child(raul::Symbol(name))) != _app->store()->end()) { _message_label->set_text("An object already exists with that name."); _ok_button->property_sensitive() = false; @@ -91,14 +112,14 @@ void NewSubgraphWindow::ok_clicked() { const uint32_t poly = _poly_spinbutton->get_value_as_int(); - const Raul::Path path = _graph->path().child( - Raul::Symbol::symbolify(_name_entry->get_text())); + const raul::Path path = _graph->path().child( + raul::Symbol::symbolify(_name_entry->get_text())); // Create graph Properties props; props.emplace(_app->uris().rdf_type, Property(_app->uris().ingen_Graph)); - props.emplace(_app->uris().ingen_polyphony, _app->forge().make(int32_t(poly))); - props.emplace(_app->uris().ingen_enabled, _app->forge().make(bool(true))); + props.emplace(_app->uris().ingen_polyphony, _app->forge().make(static_cast<int32_t>(poly))); + props.emplace(_app->uris().ingen_enabled, _app->forge().make(true)); _app->interface()->put( path_to_uri(path), props, Resource::Graph::INTERNAL); @@ -117,5 +138,4 @@ NewSubgraphWindow::cancel_clicked() hide(); } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/NewSubgraphWindow.hpp b/src/gui/NewSubgraphWindow.hpp index 2d249cf3..b0fb24d2 100644 --- a/src/gui/NewSubgraphWindow.hpp +++ b/src/gui/NewSubgraphWindow.hpp @@ -19,18 +19,27 @@ #include "Window.hpp" -#include "ingen/Node.hpp" -#include "ingen/types.hpp" +#include <ingen/Properties.hpp> -#include <gtkmm/builder.h> -#include <gtkmm/button.h> -#include <gtkmm/entry.h> -#include <gtkmm/label.h> -#include <gtkmm/spinbutton.h> +#include <memory> + +namespace Glib { +template <class T> class RefPtr; +} // namespace Glib + +namespace Gtk { +class Builder; +class Button; +class Entry; +class Label; +class SpinButton; +} // namespace Gtk namespace ingen { -namespace client { class GraphModel; } +namespace client { +class GraphModel; +} // namespace client namespace gui { @@ -46,24 +55,24 @@ public: NewSubgraphWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml); - void set_graph(SPtr<const client::GraphModel> graph); + void set_graph(std::shared_ptr<const client::GraphModel> graph); - void present(SPtr<const client::GraphModel> graph, - Properties data); + void present(std::shared_ptr<const client::GraphModel> graph, + const Properties& data); private: void name_changed(); void ok_clicked(); void cancel_clicked(); - Properties _initial_data; - SPtr<const client::GraphModel> _graph; + Properties _initial_data; + std::shared_ptr<const client::GraphModel> _graph; - Gtk::Entry* _name_entry; - Gtk::Label* _message_label; - Gtk::SpinButton* _poly_spinbutton; - Gtk::Button* _ok_button; - Gtk::Button* _cancel_button; + Gtk::Entry* _name_entry{nullptr}; + Gtk::Label* _message_label{nullptr}; + Gtk::SpinButton* _poly_spinbutton{nullptr}; + Gtk::Button* _ok_button{nullptr}; + Gtk::Button* _cancel_button{nullptr}; }; } // namespace gui diff --git a/src/gui/NodeMenu.cpp b/src/gui/NodeMenu.cpp index e2478592..2815194c 100644 --- a/src/gui/NodeMenu.cpp +++ b/src/gui/NodeMenu.cpp @@ -1,6 +1,6 @@ /* This file is part of Ingen. - Copyright 2007-2015 David Robillard <http://drobilla.net/> + Copyright 2007-2024 David Robillard <http://drobilla.net/> Ingen is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free @@ -17,37 +17,58 @@ #include "NodeMenu.hpp" #include "App.hpp" -#include "WidgetFactory.hpp" -#include "WindowFactory.hpp" - -#include "ingen/Interface.hpp" -#include "ingen/Log.hpp" -#include "ingen/URIMap.hpp" -#include "ingen/client/BlockModel.hpp" -#include "ingen/client/PluginModel.hpp" -#include "ingen/client/PortModel.hpp" -#include "lv2/presets/presets.h" +#include "ObjectMenu.hpp" + +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/BlockModel.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <ingen/client/PluginModel.hpp> +#include <ingen/client/PortModel.hpp> +#include <raul/Symbol.hpp> #include <glib.h> +#include <glibmm/convert.h> +#include <glibmm/miscutils.h> +#include <glibmm/refptr.h> +#include <glibmm/ustring.h> +#include <gtkmm/box.h> +#include <gtkmm/builder.h> +#include <gtkmm/checkmenuitem.h> +#include <gtkmm/dialog.h> #include <gtkmm/entry.h> +#include <gtkmm/enums.h> +#include <gtkmm/filechooser.h> #include <gtkmm/filechooserdialog.h> #include <gtkmm/image.h> +#include <gtkmm/label.h> +#include <gtkmm/menu.h> +#include <gtkmm/menu_elems.h> +#include <gtkmm/menuitem.h> +#include <gtkmm/object.h> +#include <gtkmm/separatormenuitem.h> #include <gtkmm/stock.h> +#include <gtkmm/stockid.h> +#include <sigc++/adaptors/bind.h> +#include <sigc++/functors/mem_fun.h> +#include <algorithm> #include <cstdint> +#include <map> +#include <memory> #include <string> #include <utility> +#include <vector> -namespace ingen { - -using namespace client; - -namespace gui { +namespace ingen::gui { NodeMenu::NodeMenu(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml) : ObjectMenu(cobject, xml) - , _presets_menu(nullptr) { xml->get_widget("node_popup_gui_menuitem", _popup_gui_menuitem); xml->get_widget("node_embed_gui_menuitem", _embed_gui_menuitem); @@ -56,7 +77,7 @@ NodeMenu::NodeMenu(BaseObjectType* cobject, } void -NodeMenu::init(App& app, SPtr<const client::BlockModel> block) +NodeMenu::init(App& app, const std::shared_ptr<const client::BlockModel>& block) { ObjectMenu::init(app, block); @@ -71,7 +92,7 @@ NodeMenu::init(App& app, SPtr<const client::BlockModel> block) _randomize_menuitem->signal_activate().connect( sigc::mem_fun(this, &NodeMenu::on_menu_randomize)); - SPtr<PluginModel> plugin = block->plugin_model(); + auto plugin = block->plugin_model(); if (plugin) { // Get the plugin to receive related presets _preset_connection = plugin->signal_preset().connect( @@ -141,6 +162,12 @@ NodeMenu::init(App& app, SPtr<const client::BlockModel> block) _enable_signal = true; } +std::shared_ptr<const client::BlockModel> +NodeMenu::block() const +{ + return std::dynamic_pointer_cast<const client::BlockModel>(_object); +} + void NodeMenu::add_preset(const URI& uri, const std::string& label) { @@ -164,7 +191,7 @@ NodeMenu::on_menu_enabled() { _app->set_property(_object->uri(), _app->uris().ingen_enabled, - _app->forge().make(bool(_enabled_menuitem->get_active()))); + _app->forge().make(_enabled_menuitem->get_active())); } void @@ -172,12 +199,15 @@ NodeMenu::on_menu_randomize() { _app->interface()->bundle_begin(); - const SPtr<const BlockModel> bm = block(); + const auto bm = block(); for (const auto& p : bm->ports()) { if (p->is_input() && _app->can_control(p.get())) { - float min = 0.0f, max = 1.0f; + float min = 0.0f; + float max = 1.0f; bm->port_value_range(p, min, max, _app->sample_rate()); - const float val = g_random_double_range(0.0, 1.0) * (max - min) + min; + + const auto r = static_cast<float>(g_random_double_range(0.0, 1.0)); + const float val = (r * (max - min)) + min; _app->set_property(p->uri(), _app->uris().ingen_value, _app->forge().make(val)); @@ -215,15 +245,15 @@ NodeMenu::on_save_preset_activated() const std::string user_path = Glib::filename_from_uri(user_uri); const std::string dirname = Glib::path_get_dirname(user_path); const std::string basename = Glib::path_get_basename(user_path); - const std::string sym = Raul::Symbol::symbolify(basename); + const std::string sym = raul::Symbol::symbolify(basename); const std::string plugname = block()->plugin_model()->human_name(); - const std::string prefix = Raul::Symbol::symbolify(plugname); + const std::string prefix = raul::Symbol::symbolify(plugname); const std::string bundle = prefix + "_" + sym + ".preset.lv2/"; const std::string file = sym + ".ttl"; const std::string real_path = Glib::build_filename(dirname, bundle, file); const std::string real_uri = Glib::filename_to_uri(real_path); - Properties props{ + const Properties props{ { _app->uris().rdf_type, _app->uris().pset_Preset }, { _app->uris().rdfs_label, @@ -245,14 +275,11 @@ NodeMenu::on_preset_activated(const std::string& uri) bool NodeMenu::has_control_inputs() { - for (const auto& p : block()->ports()) { - if (p->is_input() && p->is_numeric()) { - return true; - } - } - - return false; + return std::any_of(block()->ports().begin(), + block()->ports().end(), + [](const auto& p) { + return p->is_input() && p->is_numeric(); + }); } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/NodeMenu.hpp b/src/gui/NodeMenu.hpp index 2a3268b4..0427672c 100644 --- a/src/gui/NodeMenu.hpp +++ b/src/gui/NodeMenu.hpp @@ -19,18 +19,35 @@ #include "ObjectMenu.hpp" -#include "ingen/client/BlockModel.hpp" -#include "ingen/types.hpp" +#include <ingen/URI.hpp> -#include <gtkmm/builder.h> -#include <gtkmm/menu.h> -#include <gtkmm/menushell.h> +#include <sigc++/connection.h> +#include <sigc++/signal.h> +#include <memory> #include <string> +namespace Glib { +template <class T> class RefPtr; +} // namespace Glib + +namespace Gtk { +class Builder; +class CheckMenuItem; +class Menu; +class MenuItem; +} // namespace Gtk + namespace ingen { + +namespace client { +class BlockModel; +} // namespace client + namespace gui { +class App; + /** Menu for a Node. * * \ingroup GUI @@ -41,7 +58,7 @@ public: NodeMenu(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml); - void init(App& app, SPtr<const client::BlockModel> block); + void init(App& app, const std::shared_ptr<const client::BlockModel>& block); bool has_control_inputs(); @@ -49,9 +66,7 @@ public: sigc::signal<void, bool> signal_embed_gui; protected: - SPtr<const client::BlockModel> block() const { - return dynamic_ptr_cast<const client::BlockModel>(_object); - } + std::shared_ptr<const client::BlockModel> block() const; void add_preset(const URI& uri, const std::string& label); @@ -62,11 +77,11 @@ protected: void on_save_preset_activated(); void on_preset_activated(const std::string& uri); - Gtk::MenuItem* _popup_gui_menuitem; - Gtk::CheckMenuItem* _embed_gui_menuitem; - Gtk::CheckMenuItem* _enabled_menuitem; - Gtk::MenuItem* _randomize_menuitem; - Gtk::Menu* _presets_menu; + Gtk::MenuItem* _popup_gui_menuitem{nullptr}; + Gtk::CheckMenuItem* _embed_gui_menuitem{nullptr}; + Gtk::CheckMenuItem* _enabled_menuitem{nullptr}; + Gtk::MenuItem* _randomize_menuitem{nullptr}; + Gtk::Menu* _presets_menu{nullptr}; sigc::connection _preset_connection; }; diff --git a/src/gui/NodeModule.cpp b/src/gui/NodeModule.cpp index 5984dbe1..deb8fe52 100644 --- a/src/gui/NodeModule.cpp +++ b/src/gui/NodeModule.cpp @@ -17,45 +17,69 @@ #include "NodeModule.hpp" #include "App.hpp" +#include "GraphBox.hpp" #include "GraphCanvas.hpp" #include "GraphWindow.hpp" #include "NodeMenu.hpp" #include "Port.hpp" -#include "RenameWindow.hpp" -#include "Style.hpp" #include "SubgraphModule.hpp" #include "WidgetFactory.hpp" #include "WindowFactory.hpp" #include "ingen_config.h" -#include "ingen/Atom.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Log.hpp" -#include "ingen/client/BlockModel.hpp" -#include "ingen/client/GraphModel.hpp" -#include "ingen/client/PluginModel.hpp" -#include "ingen/client/PluginUI.hpp" -#include "lv2/atom/util.h" - +#include <ganv/Module.hpp> +#include <ganv/Port.hpp> +#include <ingen/Atom.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Log.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/BlockModel.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/PluginModel.hpp> +#include <ingen/client/PluginUI.hpp> +#include <ingen/client/PortModel.hpp> +#include <lv2/atom/util.h> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> + +#include <glibmm/main.h> +#include <glibmm/ustring.h> +#include <gtkmm/container.h> #include <gtkmm/eventbox.h> +#include <gtkmm/widget.h> +#include <gtkmm/window.h> +#include <sigc++/adaptors/bind.h> +#include <sigc++/adaptors/retype_return.h> +#include <sigc++/functors/mem_fun.h> +#include <sigc++/functors/slot.h> +#include <sigc++/signal.h> #include <cassert> +#include <map> +#include <memory> #include <string> +#include <utility> +#include <vector> namespace ingen { -using namespace client; +using client::BlockModel; +using client::GraphModel; +using client::PluginModel; +using client::PortModel; namespace gui { -NodeModule::NodeModule(GraphCanvas& canvas, - SPtr<const BlockModel> block) - : Ganv::Module(canvas, block->path().symbol(), 0, 0, true) - , _block(block) - , _gui_widget(nullptr) - , _gui_window(nullptr) - , _initialised(false) +NodeModule::NodeModule(GraphCanvas& canvas, + const std::shared_ptr<const BlockModel>& block) + : Ganv::Module(canvas, block->path().symbol(), 0, 0, true) + , _block(block) { block->signal_new_port().connect( sigc::mem_fun(this, &NodeModule::new_port_view)); @@ -75,7 +99,7 @@ NodeModule::NodeModule(GraphCanvas& canvas, signal_selected().connect( sigc::mem_fun(this, &NodeModule::on_selected)); - const PluginModel* plugin = dynamic_cast<const PluginModel*>(block->plugin()); + const auto* plugin = dynamic_cast<const PluginModel*>(block->plugin()); if (plugin) { plugin->signal_changed().connect( sigc::mem_fun(this, &NodeModule::plugin_changed)); @@ -104,8 +128,8 @@ NodeModule::~NodeModule() bool NodeModule::idle_init() { - if (_block->ports().size() == 0) { - return true; // Need to embed GUI, but ports haven't shown up yet + if (_block->ports().empty()) { + return true; // Need to embed GUI, but ports haven't shown up yet } // Ports have arrived, embed GUI and deregister this callback @@ -133,11 +157,11 @@ NodeModule::show_menu(GdkEventButton* ev) } NodeModule* -NodeModule::create(GraphCanvas& canvas, - SPtr<const BlockModel> block, - bool human) +NodeModule::create(GraphCanvas& canvas, + const std::shared_ptr<const BlockModel>& block, + bool human) { - SPtr<const GraphModel> graph = dynamic_ptr_cast<const GraphModel>(block); + auto graph = std::dynamic_pointer_cast<const GraphModel>(block); NodeModule* ret = (graph) ? new SubgraphModule(canvas, graph) @@ -163,7 +187,7 @@ NodeModule::create(GraphCanvas& canvas, App& NodeModule::app() const { - return ((GraphCanvas*)canvas())->app(); + return static_cast<GraphCanvas*>(canvas())->app(); } void @@ -177,22 +201,22 @@ NodeModule::show_human_names(bool b) set_label(block()->symbol().c_str()); } - for (iterator i = begin(); i != end(); ++i) { - ingen::gui::Port* const port = dynamic_cast<ingen::gui::Port*>(*i); + for (auto* p : *this) { + auto* const port = dynamic_cast<ingen::gui::Port*>(p); Glib::ustring label(port->model()->symbol().c_str()); if (b) { const Atom& name_property = port->model()->get_property(uris.lv2_name); if (name_property.type() == uris.forge.String) { label = name_property.ptr<char>(); } else { - Glib::ustring hn = block()->plugin_model()->port_human_name( + const Glib::ustring hn = block()->plugin_model()->port_human_name( port->model()->index()); if (!hn.empty()) { label = hn; } } } - (*i)->set_label(label.c_str()); + port->set_label(label.c_str()); } } @@ -234,8 +258,8 @@ NodeModule::port_value_changed(uint32_t index, const Atom& value) void NodeModule::plugin_changed() { - for (iterator p = begin(); p != end(); ++p) { - dynamic_cast<ingen::gui::Port*>(*p)->update_metadata(); + for (auto* p : *this) { + dynamic_cast<ingen::gui::Port*>(p)->update_metadata(); } } @@ -268,7 +292,9 @@ NodeModule::embed_gui(bool embed) if (!_plugin_ui->instantiate()) { app().log().error("Failed to instantiate LV2 UI\n"); } else { - GtkWidget* c_widget = (GtkWidget*)_plugin_ui->get_widget(); + auto* c_widget = + static_cast<GtkWidget*>(_plugin_ui->get_widget()); + _gui_widget = Glib::wrap(c_widget); Gtk::Container* container = new Gtk::EventBox(); @@ -302,7 +328,7 @@ NodeModule::rename() } void -NodeModule::new_port_view(SPtr<const PortModel> port) +NodeModule::new_port_view(const std::shared_ptr<const PortModel>& port) { Port::create(app(), *this, port); @@ -316,10 +342,10 @@ NodeModule::new_port_view(SPtr<const PortModel> port) } Port* -NodeModule::port(SPtr<const PortModel> model) +NodeModule::port(const std::shared_ptr<const PortModel>& model) { - for (iterator p = begin(); p != end(); ++p) { - Port* const port = dynamic_cast<Port*>(*p); + for (auto* p : *this) { + auto* const port = dynamic_cast<Port*>(p); if (port->model() == model) { return port; } @@ -328,15 +354,16 @@ NodeModule::port(SPtr<const PortModel> model) } void -NodeModule::delete_port_view(SPtr<const PortModel> model) +NodeModule::delete_port_view(const std::shared_ptr<const PortModel>& model) { - Port* p = port(model); - if (p) { - delete p; - } else { + Port* const p = port(model); + + if (!p) { app().log().warn("Failed to find port %1% on module %2%\n", model->path(), _block->path()); } + + delete p; } bool @@ -348,7 +375,9 @@ NodeModule::popup_gui() return true; } - const PluginModel* const plugin = dynamic_cast<const PluginModel*>(_block->plugin()); + const auto* const plugin = + dynamic_cast<const PluginModel*>(_block->plugin()); + assert(plugin); _plugin_ui = plugin->ui(app().world(), _block); @@ -362,7 +391,8 @@ NodeModule::popup_gui() return false; } - GtkWidget* c_widget = (GtkWidget*)_plugin_ui->get_widget(); + auto* c_widget = static_cast<GtkWidget*>(_plugin_ui->get_widget()); + _gui_widget = Glib::wrap(c_widget); _gui_window = new Gtk::Window(); @@ -380,9 +410,9 @@ NodeModule::popup_gui() _gui_window->present(); return true; - } else { - app().log().warn("No LV2 GUI for %1%\n", _block->path()); } + + app().log().warn("No LV2 GUI for %1%\n", _block->path()); } return false; @@ -421,17 +451,21 @@ NodeModule::on_event(GdkEvent* ev) { if (ev->type == GDK_BUTTON_PRESS && ev->button.button == 3) { return show_menu(&ev->button); - } else if (ev->type == GDK_2BUTTON_PRESS) { + } + + if (ev->type == GDK_2BUTTON_PRESS) { return on_double_click(&ev->button); - } else if (ev->type == GDK_ENTER_NOTIFY) { + } + + if (ev->type == GDK_ENTER_NOTIFY) { GraphBox* const box = app().window_factory()->graph_box( - dynamic_ptr_cast<const GraphModel>(_block->parent())); + std::dynamic_pointer_cast<const GraphModel>(_block->parent())); if (box) { box->object_entered(_block.get()); } } else if (ev->type == GDK_LEAVE_NOTIFY) { GraphBox* const box = app().window_factory()->graph_box( - dynamic_ptr_cast<const GraphModel>(_block->parent())); + std::dynamic_pointer_cast<const GraphModel>(_block->parent())); if (box) { box->object_left(_block.get()); } @@ -462,9 +496,9 @@ NodeModule::property_changed(const URI& key, const Atom& value) const URIs& uris = app().uris(); if (value.type() == uris.forge.Float) { if (key == uris.ingen_canvasX) { - move_to(value.get<float>(), get_y()); + move_to(static_cast<double>(value.get<float>()), get_y()); } else if (key == uris.ingen_canvasY) { - move_to(get_x(), value.get<float>()); + move_to(get_x(), static_cast<double>(value.get<float>())); } } else if (value.type() == uris.forge.Bool) { if (key == uris.ingen_polyphonic) { @@ -499,11 +533,11 @@ NodeModule::on_selected(gboolean selected) } if (selected && win->documentation_is_visible()) { - GraphWindow* win = app().window_factory()->parent_graph_window(block()); std::string doc; - bool html = false; -#ifdef HAVE_WEBKIT - html = true; +#if USE_WEBKIT + const bool html = true; +#else + const bool html = false; #endif if (block()->plugin_model()) { doc = block()->plugin_model()->documentation(html); diff --git a/src/gui/NodeModule.hpp b/src/gui/NodeModule.hpp index ed5914de..64ad8f66 100644 --- a/src/gui/NodeModule.hpp +++ b/src/gui/NodeModule.hpp @@ -17,25 +17,37 @@ #ifndef INGEN_GUI_NODEMODULE_HPP #define INGEN_GUI_NODEMODULE_HPP -#include "ganv/Module.hpp" -#include "ingen/types.hpp" +#include <ganv/Module.hpp> +#include <ingen/URI.hpp> -#include "Port.hpp" +#include <gdk/gdk.h> +#include <glib.h> -namespace Raul { class Atom; } +#include <cstdint> +#include <memory> -namespace ingen { namespace client { +namespace Gtk { +class Widget; +class Window; +} // namespace Gtk + +namespace ingen { + +class Atom; + +namespace client { class BlockModel; class PluginUI; class PortModel; -} } +} // namespace client +} // namespace ingen -namespace ingen { -namespace gui { +namespace ingen::gui { +class App; class GraphCanvas; -class Port; class NodeMenu; +class Port; /** A module in a graphn. * @@ -46,26 +58,28 @@ class NodeMenu; class NodeModule : public Ganv::Module { public: - static NodeModule* create( - GraphCanvas& canvas, - SPtr<const client::BlockModel> block, - bool human); + static NodeModule* + create(GraphCanvas& canvas, + const std::shared_ptr<const client::BlockModel>& block, + bool human); - virtual ~NodeModule(); + ~NodeModule() override; App& app() const; - Port* port(SPtr<const client::PortModel> model); + Port* port(const std::shared_ptr<const client::PortModel>& model); - void delete_port_view(SPtr<const client::PortModel> model); + void + delete_port_view(const std::shared_ptr<const client::PortModel>& model); virtual void store_location(double ax, double ay); void show_human_names(bool b); - SPtr<const client::BlockModel> block() const { return _block; } + std::shared_ptr<const client::BlockModel> block() const { return _block; } protected: - NodeModule(GraphCanvas& canvas, SPtr<const client::BlockModel> block); + NodeModule(GraphCanvas& canvas, + const std::shared_ptr<const client::BlockModel>& block); virtual bool on_double_click(GdkEventButton* ev); @@ -81,7 +95,7 @@ protected: void rename(); void property_changed(const URI& key, const Atom& value); - void new_port_view(SPtr<const client::PortModel> port); + void new_port_view(const std::shared_ptr<const client::PortModel>& port); void port_activity(uint32_t index, const Atom& value); void port_value_changed(uint32_t index, const Atom& value); @@ -90,15 +104,14 @@ protected: bool show_menu(GdkEventButton* ev); - SPtr<const client::BlockModel> _block; - NodeMenu* _menu; - SPtr<client::PluginUI> _plugin_ui; - Gtk::Widget* _gui_widget; - Gtk::Window* _gui_window; ///< iff popped up - bool _initialised; + std::shared_ptr<const client::BlockModel> _block; + NodeMenu* _menu{nullptr}; + std::shared_ptr<client::PluginUI> _plugin_ui; + Gtk::Widget* _gui_widget{nullptr}; + Gtk::Window* _gui_window{nullptr}; ///< iff popped up + bool _initialised{false}; }; -} // namespace gui -} // namespace ingen +} // namespace ingen::gui #endif // INGEN_GUI_NODEMODULE_HPP diff --git a/src/gui/ObjectMenu.cpp b/src/gui/ObjectMenu.cpp index 7a523f4e..8c41ff10 100644 --- a/src/gui/ObjectMenu.cpp +++ b/src/gui/ObjectMenu.cpp @@ -17,31 +17,33 @@ #include "ObjectMenu.hpp" #include "App.hpp" -#include "WidgetFactory.hpp" #include "WindowFactory.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/client/ObjectModel.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/ObjectModel.hpp> + +#include <glibmm/refptr.h> +#include <gtkmm/builder.h> +#include <gtkmm/checkmenuitem.h> +#include <gtkmm/menuitem.h> +#include <gtkmm/separatormenuitem.h> +#include <sigc++/adaptors/bind.h> +#include <sigc++/functors/mem_fun.h> +#include <sigc++/signal.h> #include <cstdint> +#include <memory> -namespace ingen { - -using namespace client; - -namespace gui { +namespace ingen::gui { ObjectMenu::ObjectMenu(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml) : Gtk::Menu(cobject) - , _app(nullptr) - , _polyphonic_menuitem(nullptr) - , _disconnect_menuitem(nullptr) - , _rename_menuitem(nullptr) - , _destroy_menuitem(nullptr) - , _properties_menuitem(nullptr) - , _enable_signal(false) { xml->get_widget("object_learn_menuitem", _learn_menuitem); xml->get_widget("object_unlearn_menuitem", _unlearn_menuitem); @@ -54,7 +56,8 @@ ObjectMenu::ObjectMenu(BaseObjectType* cobject, } void -ObjectMenu::init(App& app, SPtr<const ObjectModel> object) +ObjectMenu::init(App& app, + const std::shared_ptr<const client::ObjectModel>& object) { _app = &app; _object = object; @@ -96,7 +99,7 @@ ObjectMenu::on_menu_learn() { _app->interface()->set_property(_object->uri(), _app->uris().midi_binding, - _app->uris().patch_wildcard.urid); + _app->uris().patch_wildcard.urid_atom()); } void @@ -115,7 +118,7 @@ ObjectMenu::on_menu_polyphonic() _app->set_property( _object->uri(), _app->uris().ingen_polyphonic, - _app->forge().make(bool(_polyphonic_menuitem->get_active()))); + _app->forge().make(_polyphonic_menuitem->get_active())); } } @@ -142,5 +145,4 @@ ObjectMenu::on_menu_properties() _app->window_factory()->present_properties(_object); } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/ObjectMenu.hpp b/src/gui/ObjectMenu.hpp index 22eef74b..5a4c83f4 100644 --- a/src/gui/ObjectMenu.hpp +++ b/src/gui/ObjectMenu.hpp @@ -17,21 +17,34 @@ #ifndef INGEN_GUI_OBJECTMENU_HPP #define INGEN_GUI_OBJECTMENU_HPP -#include "ingen/client/ObjectModel.hpp" -#include "ingen/types.hpp" +#include <ingen/URI.hpp> -#include <gtkmm/builder.h> -#include <gtkmm/checkmenuitem.h> #include <gtkmm/menu.h> -#include <gtkmm/menuitem.h> + +#include <memory> + +namespace Glib { +template <class T> class RefPtr; +} // namespace Glib + +namespace Gtk { +class Builder; +class CheckMenuItem; +class MenuItem; +class SeparatorMenuItem; +} // namespace Gtk namespace ingen { + +class Atom; + +namespace client { +class ObjectModel; +} // namespace client + namespace gui { class App; -class ObjectControlWindow; -class ObjectPropertiesWindow; -class GraphCanvas; /** Menu for a Object. * @@ -43,10 +56,15 @@ public: ObjectMenu(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml); - void init(App& app, SPtr<const client::ObjectModel> object); + void + init(App& app, const std::shared_ptr<const client::ObjectModel>& object); + + std::shared_ptr<const client::ObjectModel> object() const + { + return _object; + } - SPtr<const client::ObjectModel> object() const { return _object; } - App* app() const { return _app; } + App* app() const { return _app; } protected: void on_menu_learn(); @@ -58,18 +76,18 @@ protected: void property_changed(const URI& predicate, const Atom& value); - App* _app; - SPtr<const client::ObjectModel> _object; - Gtk::MenuItem* _learn_menuitem; - Gtk::MenuItem* _unlearn_menuitem; - Gtk::CheckMenuItem* _polyphonic_menuitem; - Gtk::MenuItem* _disconnect_menuitem; - Gtk::MenuItem* _rename_menuitem; - Gtk::MenuItem* _destroy_menuitem; - Gtk::MenuItem* _properties_menuitem; - Gtk::SeparatorMenuItem* _separator_menuitem; - - bool _enable_signal; + App* _app{nullptr}; + std::shared_ptr<const client::ObjectModel> _object; + Gtk::MenuItem* _learn_menuitem{nullptr}; + Gtk::MenuItem* _unlearn_menuitem{nullptr}; + Gtk::CheckMenuItem* _polyphonic_menuitem{nullptr}; + Gtk::MenuItem* _disconnect_menuitem{nullptr}; + Gtk::MenuItem* _rename_menuitem{nullptr}; + Gtk::MenuItem* _destroy_menuitem{nullptr}; + Gtk::MenuItem* _properties_menuitem{nullptr}; + Gtk::SeparatorMenuItem* _separator_menuitem{nullptr}; + + bool _enable_signal{false}; }; } // namespace gui diff --git a/src/gui/PluginMenu.cpp b/src/gui/PluginMenu.cpp index f30c2b4b..26bbed08 100644 --- a/src/gui/PluginMenu.cpp +++ b/src/gui/PluginMenu.cpp @@ -15,13 +15,24 @@ */ #include "PluginMenu.hpp" -#include "ingen/Log.hpp" -#include "ingen/client/PluginModel.hpp" +#include <ingen/Log.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/PluginModel.hpp> +#include <lilv/lilv.h> + +#include <glibmm/ustring.h> +#include <gtkmm/menu_elems.h> +#include <gtkmm/menuitem.h> +#include <gtkmm/object.h> +#include <sigc++/adaptors/bind.h> +#include <sigc++/functors/mem_fun.h> + +#include <memory> #include <utility> -namespace ingen { -namespace gui { +namespace ingen::gui { PluginMenu::PluginMenu(ingen::World& world) : _world(world) @@ -44,7 +55,7 @@ PluginMenu::clear() // Build skeleton LV2Children children; - LILV_FOREACH(plugin_classes, i, classes) { + LILV_FOREACH (plugin_classes, i, classes) { const LilvPluginClass* c = lilv_plugin_classes_get(classes, i); const LilvNode* p = lilv_plugin_class_get_parent_uri(c); if (!p) { @@ -64,10 +75,8 @@ PluginMenu::clear() } void -PluginMenu::add_plugin(SPtr<client::PluginModel> p) +PluginMenu::add_plugin(const std::shared_ptr<client::PluginModel>& p) { - using iterator = ClassMenus::iterator; - if (!p->lilv_plugin() || lilv_plugin_is_replaced(p->lilv_plugin())) { return; } @@ -76,7 +85,7 @@ PluginMenu::add_plugin(SPtr<client::PluginModel> p) const LilvNode* class_uri = lilv_plugin_class_get_uri(pc); const char* class_uri_str = lilv_node_as_string(class_uri); - std::pair<iterator, iterator> range = _class_menus.equal_range(class_uri_str); + const auto range = _class_menus.equal_range(class_uri_str); if (range.first == _class_menus.end() || range.first == range.second || range.first->second.menu == this) { // Add to uncategorized plugin menu @@ -100,16 +109,14 @@ PluginMenu::build_plugin_class_menu(Gtk::Menu* menu, const LilvNode* class_uri = lilv_plugin_class_get_uri(plugin_class); const char* class_uri_str = lilv_node_as_string(class_uri); - const std::pair<LV2Children::const_iterator, LV2Children::const_iterator> kids - = children.equal_range(class_uri_str); - + const auto kids = children.equal_range(class_uri_str); if (kids.first == children.end()) { return 0; } // Add submenus ancestors.insert(class_uri_str); - for (LV2Children::const_iterator i = kids.first; i != kids.second; ++i) { + for (auto i = kids.first; i != kids.second; ++i) { const LilvPluginClass* c = i->second; const char* sub_label_str = lilv_node_as_string(lilv_plugin_class_get_label(c)); const char* sub_uri_str = lilv_node_as_string(lilv_plugin_class_get_uri(c)); @@ -119,7 +126,7 @@ PluginMenu::build_plugin_class_menu(Gtk::Menu* menu, return 0; } - Gtk::Menu_Helpers::MenuElem menu_elem = Gtk::Menu_Helpers::MenuElem( + const Gtk::Menu_Helpers::MenuElem menu_elem = Gtk::Menu_Helpers::MenuElem( std::string("_") + sub_label_str); menu->items().push_back(menu_elem); Gtk::MenuItem* menu_item = &(menu->items().back()); @@ -127,7 +134,7 @@ PluginMenu::build_plugin_class_menu(Gtk::Menu* menu, Gtk::Menu* submenu = Gtk::manage(new Gtk::Menu()); menu_item->set_submenu(*submenu); - size_t num_child_items = build_plugin_class_menu( + const size_t num_child_items = build_plugin_class_menu( submenu, c, classes, children, ancestors); _class_menus.emplace(sub_uri_str, MenuRecord(menu_item, submenu)); @@ -143,17 +150,18 @@ PluginMenu::build_plugin_class_menu(Gtk::Menu* menu, } void -PluginMenu::add_plugin_to_menu(MenuRecord& menu, SPtr<client::PluginModel> p) +PluginMenu::add_plugin_to_menu(MenuRecord& menu, + const std::shared_ptr<client::PluginModel>& p) { const URIs& uris = _world.uris(); LilvWorld* lworld = _world.lilv_world(); LilvNode* ingen_Graph = lilv_new_uri(lworld, uris.ingen_Graph.c_str()); LilvNode* rdf_type = lilv_new_uri(lworld, uris.rdf_type.c_str()); - bool is_graph = lilv_world_ask(lworld, - lilv_plugin_get_uri(p->lilv_plugin()), - rdf_type, - ingen_Graph); + const bool is_graph = lilv_world_ask(lworld, + lilv_plugin_get_uri(p->lilv_plugin()), + rdf_type, + ingen_Graph); menu.menu->items().push_back( Gtk::Menu_Helpers::MenuElem( @@ -169,10 +177,9 @@ PluginMenu::add_plugin_to_menu(MenuRecord& menu, SPtr<client::PluginModel> p) } void -PluginMenu::load_plugin(WPtr<client::PluginModel> weak_plugin) +PluginMenu::load_plugin(const std::weak_ptr<client::PluginModel>& weak_plugin) { signal_load_plugin.emit(weak_plugin); } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/PluginMenu.hpp b/src/gui/PluginMenu.hpp index 6c7aa6b0..eb0a565a 100644 --- a/src/gui/PluginMenu.hpp +++ b/src/gui/PluginMenu.hpp @@ -17,20 +17,28 @@ #ifndef INGEN_GUI_PLUGINMENU_HPP #define INGEN_GUI_PLUGINMENU_HPP -#include "ingen/World.hpp" -#include "ingen/types.hpp" -#include "lilv/lilv.h" +#include <lilv/lilv.h> #include <gtkmm/menu.h> +#include <sigc++/signal.h> #include <cstddef> #include <map> +#include <memory> #include <set> #include <string> +namespace Gtk { +class MenuItem; +} // namespace Gtk + namespace ingen { -namespace client { class PluginModel; } +class World; + +namespace client { +class PluginModel; +} // namespace client namespace gui { @@ -42,16 +50,18 @@ namespace gui { class PluginMenu : public Gtk::Menu { public: - PluginMenu(ingen::World& world); + explicit PluginMenu(ingen::World& world); void clear(); - void add_plugin(SPtr<client::PluginModel> p); + void add_plugin(const std::shared_ptr<client::PluginModel>& p); - sigc::signal< void, WPtr<client::PluginModel> > signal_load_plugin; + sigc::signal<void, std::weak_ptr<client::PluginModel>> signal_load_plugin; private: struct MenuRecord { - MenuRecord(Gtk::MenuItem* i, Gtk::Menu* m) : item(i), menu(m) {} + MenuRecord(Gtk::MenuItem* i, Gtk::Menu* m) noexcept : item(i), menu(m) + {} + Gtk::MenuItem* item; Gtk::Menu* menu; }; @@ -66,9 +76,10 @@ private: const LV2Children& children, std::set<const char*>& ancestors); - void add_plugin_to_menu(MenuRecord& menu, SPtr<client::PluginModel> p); + void add_plugin_to_menu(MenuRecord& menu, + const std::shared_ptr<client::PluginModel>& p); - void load_plugin(WPtr<client::PluginModel> weak_plugin); + void load_plugin(const std::weak_ptr<client::PluginModel>& weak_plugin); ingen::World& _world; MenuRecord _classless_menu; diff --git a/src/gui/Port.cpp b/src/gui/Port.cpp index 14f87fc1..4d11e309 100644 --- a/src/gui/Port.cpp +++ b/src/gui/Port.cpp @@ -17,6 +17,7 @@ #include "Port.hpp" #include "App.hpp" +#include "GraphBox.hpp" #include "GraphWindow.hpp" #include "PortMenu.hpp" #include "RDFS.hpp" @@ -26,45 +27,76 @@ #include "ingen_config.h" #include "rgba.hpp" -#include "ganv/Module.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Log.hpp" -#include "ingen/URIMap.hpp" -#include "ingen/client/GraphModel.hpp" -#include "ingen/client/PortModel.hpp" +#include <ganv/Port.hpp> +#include <ingen/Atom.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Log.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIMap.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/BlockModel.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <ingen/client/PluginModel.hpp> +#include <ingen/client/PortModel.hpp> +#include <lilv/lilv.h> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> +#include <sord/sordmm.hpp> + +#include <glibmm/ustring.h> +#include <gtkmm/menu.h> +#include <gtkmm/menu_elems.h> +#include <gtkmm/menuitem.h> +#include <gtkmm/object.h> +#include <sigc++/adaptors/bind.h> +#include <sigc++/functors/mem_fun.h> +#include <sigc++/signal.h> #include <cassert> +#include <cmath> +#include <cstdint> +#include <map> +#include <memory> #include <string> - -using namespace ingen::client; +#include <utility> namespace ingen { + +using client::BlockModel; +using client::GraphModel; +using client::PluginModel; +using client::PortModel; + namespace gui { Port* -Port::create(App& app, - Ganv::Module& module, - SPtr<const PortModel> pm, - bool flip) +Port::create(App& app, + Ganv::Module& module, + const std::shared_ptr<const PortModel>& pm, + bool flip) { return new Port(app, module, pm, port_label(app, pm), flip); } /** @param flip Make an input port appear as an output port, and vice versa. */ -Port::Port(App& app, - Ganv::Module& module, - SPtr<const PortModel> pm, - const std::string& name, - bool flip) - : Ganv::Port(module, name, - flip ? (!pm->is_input()) : pm->is_input(), - app.style()->get_port_color(pm.get())) - , _app(app) - , _port_model(pm) - , _entered(false) - , _flipped(flip) +Port::Port(App& app, + Ganv::Module& module, + const std::shared_ptr<const PortModel>& pm, + const std::string& name, + bool flip) + : Ganv::Port(module, + name, + flip ? (!pm->is_input()) : pm->is_input(), + app.style()->get_port_color(pm.get())) + , _app(app) + , _port_model(pm) + , _entered(false) + , _flipped(flip) { assert(pm); @@ -111,7 +143,7 @@ Port::~Port() } std::string -Port::port_label(App& app, SPtr<const PortModel> pm) +Port::port_label(App& app, const std::shared_ptr<const PortModel>& pm) { if (!pm) { return ""; @@ -124,8 +156,8 @@ Port::port_label(App& app, SPtr<const PortModel> pm) if (name.type() == app.forge().String) { label = name.ptr<char>(); } else { - const SPtr<const BlockModel> parent( - dynamic_ptr_cast<const BlockModel>(pm->parent())); + const auto parent = + std::dynamic_pointer_cast<const BlockModel>(pm->parent()); if (parent && parent->plugin_model()) { label = parent->plugin_model()->port_human_name(pm->index()); } @@ -148,9 +180,9 @@ Port::ensure_label() void Port::update_metadata() { - SPtr<const PortModel> pm = _port_model.lock(); + auto pm = _port_model.lock(); if (pm && _app.can_control(pm.get()) && pm->is_numeric()) { - SPtr<const BlockModel> parent = dynamic_ptr_cast<const BlockModel>(pm->parent()); + auto parent = std::dynamic_pointer_cast<const BlockModel>(pm->parent()); if (parent) { float min = 0.0f; float max = 1.0f; @@ -191,14 +223,14 @@ Port::on_value_changed(double value) const URIs& uris = _app.uris(); const Atom& current_value = model()->value(); if (current_value.type() != uris.forge.Float) { - return; // Non-float, unsupported + return; // Non-float, unsupported } - if (current_value.get<float>() == (float)value) { - return; // No change + if (current_value.get<float>() == static_cast<float>(value)) { + return; // No change } - const Atom atom = _app.forge().make(float(value)); + const Atom atom = _app.forge().make(static_cast<float>(value)); _app.set_property(model()->uri(), _app.world().uris().ingen_value, atom); @@ -230,17 +262,17 @@ Port::on_scale_point_activated(float f) Gtk::Menu* Port::build_enum_menu() { - SPtr<const BlockModel> block = dynamic_ptr_cast<BlockModel>(model()->parent()); - Gtk::Menu* menu = Gtk::manage(new Gtk::Menu()); + auto block = std::dynamic_pointer_cast<BlockModel>(model()->parent()); + Gtk::Menu* menu = Gtk::manage(new Gtk::Menu()); - PluginModel::ScalePoints points = block->plugin_model()->port_scale_points( + const PluginModel::ScalePoints points = block->plugin_model()->port_scale_points( model()->index()); - for (auto i = points.begin(); i != points.end(); ++i) { - menu->items().push_back(Gtk::Menu_Helpers::MenuElem(i->second)); + for (const auto& p : points) { + menu->items().push_back(Gtk::Menu_Helpers::MenuElem(p.second)); Gtk::MenuItem* menu_item = &(menu->items().back()); menu_item->signal_activate().connect( sigc::bind(sigc::mem_fun(this, &Port::on_scale_point_activated), - i->first)); + p.first)); } return menu; @@ -258,9 +290,9 @@ Port::on_uri_activated(const URI& uri) Gtk::Menu* Port::build_uri_menu() { - World& world = _app.world(); - SPtr<const BlockModel> block = dynamic_ptr_cast<BlockModel>(model()->parent()); - Gtk::Menu* menu = Gtk::manage(new Gtk::Menu()); + World& world = _app.world(); + auto block = std::dynamic_pointer_cast<BlockModel>(model()->parent()); + Gtk::Menu* menu = Gtk::manage(new Gtk::Menu()); // Get the port designation, which should be a rdf:Property const Atom& designation_atom = model()->get_property( @@ -278,13 +310,13 @@ Port::build_uri_menu() rdfs::URISet ranges; LilvNodes* range = lilv_world_find_nodes( world.lilv_world(), designation, rdfs_range, nullptr); - LILV_FOREACH(nodes, r, range) { + LILV_FOREACH (nodes, r, range) { ranges.insert(URI(lilv_node_as_string(lilv_nodes_get(range, r)))); } rdfs::classes(world, ranges, false); // Get all objects in range - rdfs::Objects values = rdfs::instances(world, ranges); + const rdfs::Objects values = rdfs::instances(world, ranges); // Add a menu item for each such class for (const auto& v : values) { @@ -325,7 +357,9 @@ Port::on_event(GdkEvent* ev) Gtk::Menu* menu = build_enum_menu(); menu->popup(ev->button.button, ev->button.time); return true; - } else if (model()->is_uri()) { + } + + if (model()->is_uri()) { Gtk::Menu* menu = build_uri_menu(); if (menu) { menu->popup(ev->button.button, ev->button.time); @@ -343,7 +377,7 @@ Port::on_event(GdkEvent* ev) return false; } -inline static uint32_t +static inline uint32_t peak_color(float peak) { static const uint32_t min = 0x4A8A0EC0; @@ -351,11 +385,11 @@ peak_color(float peak) static const uint32_t peak_min = 0xFF561FC0; static const uint32_t peak_max = 0xFF0A38C0; - if (peak < 1.0) { + if (peak < 1.0f) { return rgba_interpolate(min, max, peak); - } else { - return rgba_interpolate(peak_min, peak_max, fminf(peak, 2.0f) - 1.0f); } + + return rgba_interpolate(peak_min, peak_max, fminf(peak, 2.0f) - 1.0f); } void @@ -373,10 +407,10 @@ Port::activity(const Atom& value) GraphBox* Port::get_graph_box() const { - SPtr<const GraphModel> graph = dynamic_ptr_cast<const GraphModel>(model()->parent()); - GraphBox* box = _app.window_factory()->graph_box(graph); + auto graph = std::dynamic_pointer_cast<const GraphModel>(model()->parent()); + GraphBox* box = _app.window_factory()->graph_box(graph); if (!box) { - graph = dynamic_ptr_cast<const GraphModel>(model()->parent()->parent()); + graph = std::dynamic_pointer_cast<const GraphModel>(model()->parent()->parent()); box = _app.window_factory()->graph_box(graph); } return box; @@ -512,14 +546,17 @@ bool Port::on_selected(gboolean b) { if (b) { - SPtr<const PortModel> pm = _port_model.lock(); + auto pm = _port_model.lock(); if (pm) { - SPtr<const BlockModel> block = dynamic_ptr_cast<const BlockModel>(pm->parent()); + auto block = + std::dynamic_pointer_cast<const BlockModel>(pm->parent()); + GraphWindow* win = _app.window_factory()->parent_graph_window(block); if (win && win->documentation_is_visible() && block->plugin_model()) { - bool html = false; -#ifdef HAVE_WEBKIT - html = true; +#if USE_WEBKIT + const bool html = true; +#else + const bool html = false; #endif const std::string& doc = block->plugin_model()->port_documentation( pm->index(), html); diff --git a/src/gui/Port.hpp b/src/gui/Port.hpp index c95c93ef..bfd8e15d 100644 --- a/src/gui/Port.hpp +++ b/src/gui/Port.hpp @@ -17,24 +17,30 @@ #ifndef INGEN_GUI_PORT_HPP #define INGEN_GUI_PORT_HPP -#include "ganv/Port.hpp" -#include "ingen/types.hpp" +#include <ganv/Port.hpp> -#include <gtkmm/menu.h> +#include <gdk/gdk.h> +#include <glib.h> -#include <cassert> +#include <memory> #include <string> -namespace Raul { -class Atom; -} +namespace Ganv { +class Module; +} // namespace Ganv + +namespace Gtk { +class Menu; +} // namespace Gtk namespace ingen { class URI; class Atom; -namespace client { class PortModel; } +namespace client { +class PortModel; +} // namespace client namespace gui { @@ -48,15 +54,17 @@ class GraphBox; class Port : public Ganv::Port { public: - static Port* create( - App& app, - Ganv::Module& module, - SPtr<const client::PortModel> pm, - bool flip = false); + static Port* create(App& app, + Ganv::Module& module, + const std::shared_ptr<const client::PortModel>& pm, + bool flip = false); - ~Port(); + ~Port() override; - SPtr<const client::PortModel> model() const { return _port_model.lock(); } + std::shared_ptr<const client::PortModel> model() const + { + return _port_model.lock(); + } bool show_menu(GdkEventButton* ev); void update_metadata(); @@ -68,13 +76,14 @@ public: bool on_selected(gboolean b) override; private: - Port(App& app, - Ganv::Module& module, - SPtr<const client::PortModel> pm, - const std::string& name, - bool flip = false); + Port(App& app, + Ganv::Module& module, + const std::shared_ptr<const client::PortModel>& pm, + const std::string& name, + bool flip = false); - static std::string port_label(App& app, SPtr<const client::PortModel> pm); + static std::string + port_label(App& app, const std::shared_ptr<const client::PortModel>& pm); Gtk::Menu* build_enum_menu(); Gtk::Menu* build_uri_menu(); @@ -91,10 +100,10 @@ private: void port_properties_changed(); void set_type_tag(); - App& _app; - WPtr<const client::PortModel> _port_model; - bool _entered : 1; - bool _flipped : 1; + App& _app; + std::weak_ptr<const client::PortModel> _port_model; + bool _entered : 1; + bool _flipped : 1; }; } // namespace gui diff --git a/src/gui/PortMenu.cpp b/src/gui/PortMenu.cpp index ff3d2571..373425cf 100644 --- a/src/gui/PortMenu.cpp +++ b/src/gui/PortMenu.cpp @@ -17,25 +17,45 @@ #include "PortMenu.hpp" #include "App.hpp" -#include "WindowFactory.hpp" - -#include "ingen/Interface.hpp" -#include "ingen/client/GraphModel.hpp" -#include "ingen/client/PortModel.hpp" -#include "ingen/types.hpp" - +#include "ObjectMenu.hpp" + +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/BlockModel.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <ingen/client/PortModel.hpp> +#include <ingen/paths.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> + +#include <glibmm/refptr.h> +#include <gtkmm/builder.h> +#include <gtkmm/checkmenuitem.h> +#include <gtkmm/menu.h> +#include <gtkmm/menuitem.h> +#include <gtkmm/separatormenuitem.h> +#include <sigc++/functors/mem_fun.h> + +#include <memory> #include <string> namespace ingen { -using namespace client; +using client::BlockModel; +using client::GraphModel; +using client::PortModel; namespace gui { PortMenu::PortMenu(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml) : ObjectMenu(cobject, xml) - , _internal_graph_port(false) { xml->get_widget("object_menu", _port_menu); xml->get_widget("port_set_min_menuitem", _set_min_menuitem); @@ -45,7 +65,9 @@ PortMenu::PortMenu(BaseObjectType* cobject, } void -PortMenu::init(App& app, SPtr<const PortModel> port, bool internal_graph_port) +PortMenu::init(App& app, + const std::shared_ptr<const PortModel>& port, + bool internal_graph_port) { const URIs& uris = app.uris(); @@ -65,7 +87,7 @@ PortMenu::init(App& app, SPtr<const PortModel> port, bool internal_graph_port) sigc::mem_fun(this, &PortMenu::on_menu_expose)); const bool is_control(app.can_control(port.get()) && port->is_numeric()); - const bool is_on_graph(dynamic_ptr_cast<GraphModel>(port->parent())); + const bool is_on_graph(std::dynamic_pointer_cast<GraphModel>(port->parent())); const bool is_input(port->is_input()); if (!is_on_graph) { @@ -107,9 +129,9 @@ PortMenu::on_menu_disconnect() void PortMenu::on_menu_set_min() { - const URIs& uris = _app->uris(); - SPtr<const PortModel> model = dynamic_ptr_cast<const PortModel>(_object); - const Atom& value = model->get_property(uris.ingen_value); + const URIs& uris = _app->uris(); + auto model = std::dynamic_pointer_cast<const PortModel>(_object); + const Atom& value = model->get_property(uris.ingen_value); if (value.is_valid()) { _app->set_property(_object->uri(), uris.lv2_minimum, value); } @@ -118,9 +140,9 @@ PortMenu::on_menu_set_min() void PortMenu::on_menu_set_max() { - const URIs& uris = _app->uris(); - SPtr<const PortModel> model = dynamic_ptr_cast<const PortModel>(_object); - const Atom& value = model->get_property(uris.ingen_value); + const URIs& uris = _app->uris(); + auto model = std::dynamic_pointer_cast<const PortModel>(_object); + const Atom& value = model->get_property(uris.ingen_value); if (value.is_valid()) { _app->set_property(_object->uri(), uris.lv2_maximum, value); } @@ -129,8 +151,8 @@ PortMenu::on_menu_set_max() void PortMenu::on_menu_reset_range() { - const URIs& uris = _app->uris(); - SPtr<const PortModel> model = dynamic_ptr_cast<const PortModel>(_object); + const URIs& uris = _app->uris(); + auto model = std::dynamic_pointer_cast<const PortModel>(_object); // Remove lv2:minimum and lv2:maximum properties Properties remove; @@ -142,14 +164,14 @@ PortMenu::on_menu_reset_range() void PortMenu::on_menu_expose() { - const URIs& uris = _app->uris(); - SPtr<const PortModel> port = dynamic_ptr_cast<const PortModel>(_object); - SPtr<const BlockModel> block = dynamic_ptr_cast<const BlockModel>(port->parent()); + const URIs& uris = _app->uris(); + auto port = std::dynamic_pointer_cast<const PortModel>(_object); + auto block = std::dynamic_pointer_cast<const BlockModel>(port->parent()); const std::string label = block->label() + " " + block->port_label(port); - const Raul::Path path = Raul::Path(block->path() + Raul::Symbol("_" + port->symbol())); + const auto path = raul::Path{block->path() + raul::Symbol("_" + port->symbol())}; - ingen::Resource r(*_object.get()); + ingen::Resource r(*_object); r.remove_property(uris.lv2_index, uris.patch_wildcard); r.set_property(uris.lv2_symbol, _app->forge().alloc(path.symbol())); r.set_property(uris.lv2_name, _app->forge().alloc(label.c_str())); diff --git a/src/gui/PortMenu.hpp b/src/gui/PortMenu.hpp index 26298e76..cf7f9c62 100644 --- a/src/gui/PortMenu.hpp +++ b/src/gui/PortMenu.hpp @@ -19,16 +19,28 @@ #include "ObjectMenu.hpp" -#include "ingen/client/PortModel.hpp" -#include "ingen/types.hpp" +#include <memory> -#include <gtkmm/builder.h> -#include <gtkmm/menu.h> -#include <gtkmm/menushell.h> +namespace Glib { +template <class T> class RefPtr; +} // namespace Glib + +namespace Gtk { +class Builder; +class Menu; +class MenuItem; +} // namespace Gtk namespace ingen { + +namespace client { +class PortModel; +} // namespace client + namespace gui { +class App; + /** Menu for a Port. * * \ingroup GUI @@ -39,9 +51,9 @@ public: PortMenu(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml); - void init(App& app, - SPtr<const client::PortModel> port, - bool internal_graph_port = false); + void init(App& app, + const std::shared_ptr<const client::PortModel>& port, + bool internal_graph_port = false); private: void on_menu_disconnect() override; @@ -50,14 +62,14 @@ private: void on_menu_reset_range(); void on_menu_expose(); - Gtk::Menu* _port_menu; - Gtk::MenuItem* _set_min_menuitem; - Gtk::MenuItem* _set_max_menuitem; - Gtk::MenuItem* _reset_range_menuitem; - Gtk::MenuItem* _expose_menuitem; + Gtk::Menu* _port_menu{nullptr}; + Gtk::MenuItem* _set_min_menuitem{nullptr}; + Gtk::MenuItem* _set_max_menuitem{nullptr}; + Gtk::MenuItem* _reset_range_menuitem{nullptr}; + Gtk::MenuItem* _expose_menuitem{nullptr}; /// True iff this is a (flipped) port on a GraphPortModule in its graph - bool _internal_graph_port; + bool _internal_graph_port{false}; }; } // namespace gui diff --git a/src/gui/PropertiesWindow.cpp b/src/gui/PropertiesWindow.cpp index 9912f73a..0dde0ab2 100644 --- a/src/gui/PropertiesWindow.cpp +++ b/src/gui/PropertiesWindow.cpp @@ -14,31 +14,64 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "App.hpp" #include "PropertiesWindow.hpp" + +#include "App.hpp" #include "RDFS.hpp" #include "URIEntry.hpp" - -#include "ingen/Interface.hpp" -#include "ingen/Log.hpp" -#include "ingen/URIMap.hpp" -#include "ingen/World.hpp" -#include "ingen/client/BlockModel.hpp" -#include "ingen/client/PluginModel.hpp" - +#include "Window.hpp" + +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Log.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIMap.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <lilv/lilv.h> +#include <lv2/urid/urid.h> +#include <raul/Path.hpp> +#include <sord/sordmm.hpp> + +#include <glibmm/containers.h> +#include <glibmm/propertyproxy.h> +#include <glibmm/ustring.h> +#include <gtk/gtk.h> +#include <gtkmm/alignment.h> +#include <gtkmm/bin.h> +#include <gtkmm/box.h> +#include <gtkmm/builder.h> +#include <gtkmm/button.h> +#include <gtkmm/checkbutton.h> +#include <gtkmm/combobox.h> +#include <gtkmm/entry.h> +#include <gtkmm/enums.h> #include <gtkmm/label.h> +#include <gtkmm/object.h> +#include <gtkmm/scrolledwindow.h> #include <gtkmm/spinbutton.h> +#include <gtkmm/table.h> +#include <gtkmm/treeiter.h> +#include <gtkmm/widget.h> +#include <gtkmm/window.h> +#include <sigc++/adaptors/bind.h> +#include <sigc++/functors/mem_fun.h> +#include <sigc++/signal.h> #include <algorithm> #include <cfloat> #include <climits> #include <cstdint> +#include <memory> #include <set> #include <utility> namespace ingen { -using namespace client; +using client::ObjectModel; namespace gui { @@ -47,7 +80,6 @@ using URISet = std::set<URI>; PropertiesWindow::PropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml) : Window(cobject) - , _value_type(0) { xml->get_widget("properties_vbox", _vbox); xml->get_widget("properties_scrolledwindow", _scrolledwindow); @@ -96,7 +128,7 @@ PropertiesWindow::reset() } void -PropertiesWindow::present(SPtr<const ObjectModel> model) +PropertiesWindow::present(const std::shared_ptr<const ObjectModel>& model) { set_object(model); Gtk::Window::present(); @@ -116,10 +148,12 @@ PropertiesWindow::add_property(const URI& key, const Atom& value) if (name.empty()) { name = world.rdf_world()->prefixes().qualify(key); } - Gtk::Label* label = new Gtk::Label( - std::string("<a href=\"") + key.string() + "\">" + name + "</a>", - 1.0, - 0.5); + + auto* label = new Gtk::Label(std::string("<a href=\"") + key.string() + + "\">" + name + "</a>", + 1.0, + 0.5); + label->set_use_markup(true); _app->set_tooltip(label, prop); _table->attach(*Gtk::manage(label), 0, 1, n_rows, n_rows + 1, @@ -154,16 +188,24 @@ PropertiesWindow::datatype_supported(const rdfs::URISet& types, if (types.find(_app->uris().atom_Int) != types.end()) { *widget_type = _app->uris().atom_Int; return true; - } else if (types.find(_app->uris().atom_Float) != types.end()) { + } + + if (types.find(_app->uris().atom_Float) != types.end()) { *widget_type = _app->uris().atom_Float; return true; - } else if (types.find(_app->uris().atom_Bool) != types.end()) { + } + + if (types.find(_app->uris().atom_Bool) != types.end()) { *widget_type = _app->uris().atom_Bool; return true; - } else if (types.find(_app->uris().atom_String) != types.end()) { + } + + if (types.find(_app->uris().atom_String) != types.end()) { *widget_type = _app->uris().atom_String; return true; - } else if (types.find(_app->uris().atom_URID) != types.end()) { + } + + if (types.find(_app->uris().atom_URID) != types.end()) { *widget_type = _app->uris().atom_URID; return true; } @@ -200,7 +242,7 @@ PropertiesWindow::class_supported(const rdfs::URISet& types) * This function MUST be called before using this object in any way. */ void -PropertiesWindow::set_object(SPtr<const ObjectModel> model) +PropertiesWindow::set_object(const std::shared_ptr<const ObjectModel>& model) { reset(); _model = model; @@ -245,8 +287,9 @@ PropertiesWindow::set_object(SPtr<const ObjectModel> model) } for (const auto& e : entries) { - Gtk::ListStore::iterator ki = _key_store->append(); - Gtk::ListStore::Row row = *ki; + auto ki = _key_store->append(); + auto row = *ki; + row[_combo_columns.uri_col] = e.second.string(); row[_combo_columns.label_col] = e.first; } @@ -301,19 +344,23 @@ PropertiesWindow::create_value_widget(const URI& key, widget->signal_value_changed().connect( sigc::bind(sigc::mem_fun(this, &PropertiesWindow::on_change), key)); return widget; - } else if (type == _app->uris().atom_Float) { + } + + if (type == _app->uris().atom_Float) { Gtk::SpinButton* widget = manage(new Gtk::SpinButton(0.0, 4)); widget->property_numeric() = true; widget->set_snap_to_ticks(false); - widget->set_range(-FLT_MAX, FLT_MAX); + widget->set_range(-DBL_MAX, DBL_MAX); widget->set_increments(0.1, 1.0); if (value.is_valid()) { - widget->set_value(value.get<float>()); + widget->set_value(static_cast<double>(value.get<float>())); } widget->signal_value_changed().connect( sigc::bind(sigc::mem_fun(this, &PropertiesWindow::on_change), key)); return widget; - } else if (type == _app->uris().atom_Bool) { + } + + if (type == _app->uris().atom_Bool) { Gtk::CheckButton* widget = manage(new Gtk::CheckButton()); if (value.is_valid()) { widget->set_active(value.get<int32_t>()); @@ -321,7 +368,9 @@ PropertiesWindow::create_value_widget(const URI& key, widget->signal_toggled().connect( sigc::bind(sigc::mem_fun(this, &PropertiesWindow::on_change), key)); return widget; - } else if (type == _app->uris().atom_String) { + } + + if (type == _app->uris().atom_String) { Gtk::Entry* widget = manage(new Gtk::Entry()); if (value.is_valid()) { widget->set_text(value.ptr<char>()); @@ -329,14 +378,16 @@ PropertiesWindow::create_value_widget(const URI& key, widget->signal_changed().connect( sigc::bind(sigc::mem_fun(this, &PropertiesWindow::on_change), key)); return widget; - } else if (type == _app->uris().atom_URID) { + } + + if (type == _app->uris().atom_URID) { const char* str = (value.is_valid() ? world.uri_map().unmap_uri(value.get<int32_t>()) : ""); - LilvNode* pred = lilv_new_uri(lworld, key.c_str()); - URISet ranges = rdfs::range(world, pred, true); - URIEntry* widget = manage(new URIEntry(_app, ranges, str ? str : "")); + LilvNode* pred = lilv_new_uri(lworld, key.c_str()); + const URISet ranges = rdfs::range(world, pred, true); + URIEntry* widget = manage(new URIEntry(_app, ranges, str ? str : "")); widget->signal_changed().connect( sigc::bind(sigc::mem_fun(this, &PropertiesWindow::on_change), key)); lilv_node_free(pred); @@ -352,10 +403,10 @@ PropertiesWindow::create_value_widget(const URI& key, if (type == _app->uris().atom_URI || type == _app->uris().rdfs_Class || is_class) { - LilvNode* pred = lilv_new_uri(lworld, key.c_str()); - URISet ranges = rdfs::range(world, pred, true); - const char* str = value.is_valid() ? value.ptr<const char>() : ""; - URIEntry* widget = manage(new URIEntry(_app, ranges, str)); + LilvNode* pred = lilv_new_uri(lworld, key.c_str()); + const URISet ranges = rdfs::range(world, pred, true); + const char* str = value.is_valid() ? value.ptr<const char>() : ""; + URIEntry* widget = manage(new URIEntry(_app, ranges, str)); widget->signal_changed().connect( sigc::bind(sigc::mem_fun(this, &PropertiesWindow::on_change), key)); lilv_node_free(pred); @@ -434,38 +485,40 @@ PropertiesWindow::remove_property(const URI& key, const Atom& value) Atom PropertiesWindow::get_value(LV2_URID type, Gtk::Widget* value_widget) { - Forge& forge = _app->forge(); + const Forge& forge = _app->forge(); if (type == forge.Int) { - Gtk::SpinButton* spin = dynamic_cast<Gtk::SpinButton*>(value_widget); + auto* spin = dynamic_cast<Gtk::SpinButton*>(value_widget); if (spin) { return _app->forge().make(spin->get_value_as_int()); } } else if (type == forge.Float) { - Gtk::SpinButton* spin = dynamic_cast<Gtk::SpinButton*>(value_widget); + auto* spin = dynamic_cast<Gtk::SpinButton*>(value_widget); if (spin) { return _app->forge().make(static_cast<float>(spin->get_value())); } } else if (type == forge.Bool) { - Gtk::CheckButton* check = dynamic_cast<Gtk::CheckButton*>(value_widget); + auto* check = dynamic_cast<Gtk::CheckButton*>(value_widget); if (check) { return _app->forge().make(check->get_active()); } } else if (type == forge.URI || type == forge.URID) { - URIEntry* uri_entry = dynamic_cast<URIEntry*>(value_widget); - if (uri_entry && URI::is_valid(uri_entry->get_text())) { - return _app->forge().make_urid(URI(uri_entry->get_text())); - } else { + auto* uri_entry = dynamic_cast<URIEntry*>(value_widget); + if (uri_entry) { + if (URI::is_valid(uri_entry->get_text())) { + return _app->forge().make_urid(URI(uri_entry->get_text())); + } + _app->log().error("Invalid URI <%1%>\n", uri_entry->get_text()); } } else if (type == forge.String) { - Gtk::Entry* entry = dynamic_cast<Gtk::Entry*>(value_widget); + auto* entry = dynamic_cast<Gtk::Entry*>(value_widget); if (entry) { return _app->forge().alloc(entry->get_text()); } } - return Atom(); + return {}; } void @@ -490,12 +543,12 @@ PropertiesWindow::on_change(const URI& key) std::string PropertiesWindow::active_key() const { - const Gtk::ListStore::iterator iter = _key_combo->get_active(); + const auto iter = _key_combo->get_active(); if (!iter) { return ""; } - Glib::ustring prop_uri = (*iter)[_combo_columns.uri_col]; + const Glib::ustring prop_uri = (*iter)[_combo_columns.uri_col]; return prop_uri; } diff --git a/src/gui/PropertiesWindow.hpp b/src/gui/PropertiesWindow.hpp index 81e29ae1..e788d140 100644 --- a/src/gui/PropertiesWindow.hpp +++ b/src/gui/PropertiesWindow.hpp @@ -19,26 +19,43 @@ #include "Window.hpp" -#include "ingen/client/BlockModel.hpp" -#include "ingen/types.hpp" - -#include <gtkmm/alignment.h> -#include <gtkmm/box.h> -#include <gtkmm/builder.h> -#include <gtkmm/button.h> -#include <gtkmm/checkbutton.h> -#include <gtkmm/combobox.h> +#include <ingen/Atom.hpp> +#include <ingen/URI.hpp> +#include <lv2/urid/urid.h> + +#include <glibmm/refptr.h> #include <gtkmm/liststore.h> -#include <gtkmm/scrolledwindow.h> -#include <gtkmm/table.h> +#include <gtkmm/treemodel.h> +#include <gtkmm/treemodelcolumn.h> +#include <sigc++/connection.h> #include <map> +#include <memory> #include <set> #include <string> +namespace Glib { +class ustring; +} // namespace Glib + +namespace Gtk { +class Alignment; +class Bin; +class Builder; +class Button; +class CheckButton; +class ComboBox; +class ScrolledWindow; +class Table; +class VBox; +class Widget; +} // namespace Gtk + namespace ingen { -namespace client { class ObjectModel; } +namespace client { +class ObjectModel; +} // namespace client namespace gui { @@ -54,8 +71,8 @@ public: PropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml); - void present(SPtr<const client::ObjectModel> model); - void set_object(SPtr<const client::ObjectModel> model); + void present(const std::shared_ptr<const client::ObjectModel>& model); + void set_object(const std::shared_ptr<const client::ObjectModel>& model); private: /** Record of a property (row in the table) */ @@ -108,21 +125,21 @@ private: using Records = std::map<URI, Record>; Records _records; - SPtr<const client::ObjectModel> _model; - ComboColumns _combo_columns; - Glib::RefPtr<Gtk::ListStore> _key_store; - sigc::connection _property_connection; - sigc::connection _property_removed_connection; - Gtk::VBox* _vbox; - Gtk::ScrolledWindow* _scrolledwindow; - Gtk::Table* _table; - Gtk::ComboBox* _key_combo; - LV2_URID _value_type; - Gtk::Bin* _value_bin; - Gtk::Button* _add_button; - Gtk::Button* _cancel_button; - Gtk::Button* _apply_button; - Gtk::Button* _ok_button; + std::shared_ptr<const client::ObjectModel> _model; + ComboColumns _combo_columns; + Glib::RefPtr<Gtk::ListStore> _key_store; + sigc::connection _property_connection; + sigc::connection _property_removed_connection; + Gtk::VBox* _vbox{nullptr}; + Gtk::ScrolledWindow* _scrolledwindow{nullptr}; + Gtk::Table* _table{nullptr}; + Gtk::ComboBox* _key_combo{nullptr}; + LV2_URID _value_type{0}; + Gtk::Bin* _value_bin{nullptr}; + Gtk::Button* _add_button{nullptr}; + Gtk::Button* _cancel_button{nullptr}; + Gtk::Button* _apply_button{nullptr}; + Gtk::Button* _ok_button{nullptr}; }; } // namespace gui diff --git a/src/gui/RDFS.cpp b/src/gui/RDFS.cpp index 1091c443..09af81af 100644 --- a/src/gui/RDFS.cpp +++ b/src/gui/RDFS.cpp @@ -14,20 +14,20 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/Forge.hpp" -#include "ingen/Log.hpp" -#include "ingen/Resource.hpp" -#include "ingen/World.hpp" -#include "ingen/client/ObjectModel.hpp" -#include "lilv/lilv.h" - #include "RDFS.hpp" +#include <ingen/Forge.hpp> +#include <ingen/Log.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <lilv/lilv.h> + #include <utility> -namespace ingen { -namespace gui { -namespace rdfs { +namespace ingen::gui::rdfs { std::string label(World& world, const LilvNode* node) @@ -75,10 +75,10 @@ closure(World& world, const LilvNode* pred, URISet& types, bool super) world.lilv_world(), type, pred, nullptr) : lilv_world_find_nodes( world.lilv_world(), nullptr, pred, type); - LILV_FOREACH(nodes, m, matches) { + LILV_FOREACH (nodes, m, matches) { const LilvNode* klass_node = lilv_nodes_get(matches, m); if (lilv_node_is_uri(klass_node)) { - URI klass(lilv_node_as_uri(klass_node)); + const URI klass{lilv_node_as_uri(klass_node)}; if (!types.count(klass)) { ++added; klasses.insert(klass); @@ -115,22 +115,19 @@ datatypes(World& world, URISet& types, bool super) } URISet -types(World& world, SPtr<const client::ObjectModel> model) +types(World& world, const std::shared_ptr<const client::ObjectModel>& model) { - using PropIter = Properties::const_iterator; - using PropRange = std::pair<PropIter, PropIter>; - // Start with every rdf:type URISet types; types.insert(URI(LILV_NS_RDFS "Resource")); - PropRange range = model->properties().equal_range(world.uris().rdf_type); + const auto range = model->properties().equal_range(world.uris().rdf_type); for (auto t = range.first; t != range.second; ++t) { if (t->second.type() == world.forge().URI || t->second.type() == world.forge().URID) { const URI type(world.forge().str(t->second, false)); types.insert(type); if (world.uris().ingen_Graph == type) { - // Add lv2:Plugin as a type for graphs so plugin properties show up + // Add lv2:Plugin as a type so plugin properties show up types.insert(world.uris().lv2_Plugin); } } else { @@ -145,10 +142,11 @@ types(World& world, SPtr<const client::ObjectModel> model) } URISet -properties(World& world, SPtr<const client::ObjectModel> model) +properties(World& world, + const std::shared_ptr<const client::ObjectModel>& model) { - URISet properties; - URISet types = rdfs::types(world, model); + URISet properties; + const URISet types = rdfs::types(world, model); LilvNode* rdf_type = lilv_new_uri(world.lilv_world(), LILV_NS_RDF "type"); @@ -159,13 +157,13 @@ properties(World& world, SPtr<const client::ObjectModel> model) LilvNodes* props = lilv_world_find_nodes( world.lilv_world(), nullptr, rdf_type, rdf_Property); - LILV_FOREACH(nodes, p, props) { + LILV_FOREACH (nodes, p, props) { const LilvNode* prop = lilv_nodes_get(props, p); if (lilv_node_is_uri(prop)) { LilvNodes* domains = lilv_world_find_nodes( world.lilv_world(), prop, rdfs_domain, nullptr); unsigned n_matching_domains = 0; - LILV_FOREACH(nodes, d, domains) { + LILV_FOREACH (nodes, d, domains) { const LilvNode* domain_node = lilv_nodes_get(domains, d); if (!lilv_node_is_uri(domain_node)) { // TODO: Blank node domains (e.g. unions) @@ -206,7 +204,7 @@ instances(World& world, const URISet& types) LilvNode* type = lilv_new_uri(world.lilv_world(), t.c_str()); LilvNodes* objects = lilv_world_find_nodes( world.lilv_world(), nullptr, rdf_type, type); - LILV_FOREACH(nodes, o, objects) { + LILV_FOREACH (nodes, o, objects) { const LilvNode* object = lilv_nodes_get(objects, o); if (!lilv_node_is_uri(object)) { continue; @@ -231,8 +229,10 @@ range(World& world, const LilvNode* prop, bool recursive) world.lilv_world(), prop, rdfs_range, nullptr); URISet ranges; - LILV_FOREACH(nodes, n, nodes) { - ranges.insert(URI(lilv_node_as_string(lilv_nodes_get(nodes, n)))); + LILV_FOREACH (nodes, n, nodes) { + if (lilv_node_is_uri(lilv_nodes_get(nodes, n))) { + ranges.insert(URI(lilv_node_as_string(lilv_nodes_get(nodes, n)))); + } } if (recursive) { @@ -256,6 +256,4 @@ is_a(World& world, const LilvNode* inst, const LilvNode* klass) return is_instance; } -} // namespace rdfs -} // namespace gui -} // namespace ingen +} // namespace ingen::gui::rdfs diff --git a/src/gui/RDFS.hpp b/src/gui/RDFS.hpp index a8d161cb..e4c2b673 100644 --- a/src/gui/RDFS.hpp +++ b/src/gui/RDFS.hpp @@ -17,11 +17,11 @@ #ifndef INGEN_GUI_RDF_HPP #define INGEN_GUI_RDF_HPP -#include "ingen/URI.hpp" -#include "ingen/types.hpp" -#include "lilv/lilv.h" +#include <ingen/URI.hpp> +#include <lilv/lilv.h> #include <map> +#include <memory> #include <set> #include <string> @@ -29,11 +29,11 @@ namespace ingen { class World; -namespace client { class ObjectModel; } +namespace client { +class ObjectModel; +} // namespace client -namespace gui { - -namespace rdfs { +namespace gui::rdfs { /** Set of URIs. */ using URISet = std::set<URI>; @@ -61,10 +61,13 @@ void datatypes(World& world, URISet& types, bool super); Objects instances(World& world, const URISet& types); /** Get all the types which `model` is an instance of. */ -URISet types(World& world, SPtr<const client::ObjectModel> model); +URISet +types(World& world, const std::shared_ptr<const client::ObjectModel>& model); /** Get all the properties with domains appropriate for `model`. */ -URISet properties(World& world, SPtr<const client::ObjectModel> model); +URISet +properties(World& world, + const std::shared_ptr<const client::ObjectModel>& model); /** Return the range (value types) of `prop`. * @param recursive If true, include all subclasses. @@ -74,8 +77,7 @@ URISet range(World& world, const LilvNode* prop, bool recursive); /** Return true iff `inst` is-a `klass`. */ bool is_a(World& world, const LilvNode* inst, const LilvNode* klass); -} // namespace rdfs -} // namespace gui +} // namespace gui::rdfs } // namespace ingen #endif // INGEN_GUI_RDF_HPP diff --git a/src/gui/RenameWindow.cpp b/src/gui/RenameWindow.cpp index 8c5e9edb..569baea8 100644 --- a/src/gui/RenameWindow.cpp +++ b/src/gui/RenameWindow.cpp @@ -17,18 +17,34 @@ #include "RenameWindow.hpp" #include "App.hpp" - -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/client/ClientStore.hpp" -#include "ingen/client/ObjectModel.hpp" -#include "lv2/core/lv2.h" - +#include "Window.hpp" + +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/ClientStore.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <ingen/paths.hpp> +#include <raul/Path.hpp> +#include <raul/Symbol.hpp> + +#include <glibmm/propertyproxy.h> +#include <glibmm/refptr.h> +#include <glibmm/ustring.h> +#include <gtkmm/builder.h> +#include <gtkmm/button.h> +#include <gtkmm/entry.h> +#include <gtkmm/label.h> +#include <gtkmm/window.h> +#include <sigc++/functors/mem_fun.h> + +#include <memory> #include <string> namespace ingen { -using namespace client; +using client::ObjectModel; namespace gui { @@ -58,7 +74,7 @@ RenameWindow::RenameWindow(BaseObjectType* cobject, * This function MUST be called before using this object in any way. */ void -RenameWindow::set_object(SPtr<const ObjectModel> object) +RenameWindow::set_object(const std::shared_ptr<const ObjectModel>& object) { _object = object; _symbol_entry->set_text(object->path().symbol()); @@ -68,7 +84,7 @@ RenameWindow::set_object(SPtr<const ObjectModel> object) } void -RenameWindow::present(SPtr<const ObjectModel> object) +RenameWindow::present(const std::shared_ptr<const ObjectModel>& object) { set_object(object); _symbol_entry->grab_focus(); @@ -79,12 +95,12 @@ void RenameWindow::values_changed() { const std::string& symbol = _symbol_entry->get_text(); - if (!Raul::Symbol::is_valid(symbol)) { + if (!raul::Symbol::is_valid(symbol)) { _message_label->set_text("Invalid symbol"); _ok_button->property_sensitive() = false; } else if (_object->symbol() != symbol && _app->store()->object( - _object->parent()->path().child(Raul::Symbol(symbol)))) { + _object->parent()->path().child(raul::Symbol(symbol)))) { _message_label->set_text("An object already exists with that path"); _ok_button->property_sensitive() = false; } else { @@ -112,7 +128,7 @@ RenameWindow::ok_clicked() const URIs& uris = _app->uris(); const std::string& symbol_str = _symbol_entry->get_text(); const std::string& label = _label_entry->get_text(); - Raul::Path path = _object->path(); + raul::Path path = _object->path(); const Atom& name_atom = _object->get_property(uris.lv2_name); if (!label.empty() && (name_atom.type() != uris.forge.String || @@ -122,8 +138,8 @@ RenameWindow::ok_clicked() _app->forge().alloc(label)); } - if (Raul::Symbol::is_valid(symbol_str)) { - const Raul::Symbol symbol(symbol_str); + if (raul::Symbol::is_valid(symbol_str)) { + const raul::Symbol symbol(symbol_str); if (symbol != _object->symbol()) { path = _object->path().parent().child(symbol); _app->interface()->move(_object->path(), path); diff --git a/src/gui/RenameWindow.hpp b/src/gui/RenameWindow.hpp index 3b50f04e..9c97d234 100644 --- a/src/gui/RenameWindow.hpp +++ b/src/gui/RenameWindow.hpp @@ -19,15 +19,25 @@ #include "Window.hpp" -#include "ingen/client/ObjectModel.hpp" -#include "ingen/types.hpp" +#include <memory> -#include <gtkmm/builder.h> -#include <gtkmm/button.h> -#include <gtkmm/entry.h> -#include <gtkmm/label.h> +namespace Glib { +template <class T> class RefPtr; +} // namespace Glib + +namespace Gtk { +class Builder; +class Button; +class Entry; +class Label; +} // namespace Gtk namespace ingen { + +namespace client { +class ObjectModel; +} // namespace client + namespace gui { /** Rename window. Handles renaming of any (Ingen) object. @@ -40,22 +50,22 @@ public: RenameWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& xml); - void present(SPtr<const client::ObjectModel> object); + void present(const std::shared_ptr<const client::ObjectModel>& object); private: - void set_object(SPtr<const client::ObjectModel> object); + void set_object(const std::shared_ptr<const client::ObjectModel>& object); void values_changed(); void cancel_clicked(); void ok_clicked(); - SPtr<const client::ObjectModel> _object; + std::shared_ptr<const client::ObjectModel> _object; - Gtk::Entry* _symbol_entry; - Gtk::Entry* _label_entry; - Gtk::Label* _message_label; - Gtk::Button* _cancel_button; - Gtk::Button* _ok_button; + Gtk::Entry* _symbol_entry{nullptr}; + Gtk::Entry* _label_entry{nullptr}; + Gtk::Label* _message_label{nullptr}; + Gtk::Button* _cancel_button{nullptr}; + Gtk::Button* _ok_button{nullptr}; }; } // namespace gui diff --git a/src/gui/Style.cpp b/src/gui/Style.cpp index 81c9da2f..f1f1b12b 100644 --- a/src/gui/Style.cpp +++ b/src/gui/Style.cpp @@ -17,49 +17,31 @@ #include "Style.hpp" #include "App.hpp" -#include "Port.hpp" - -#include "ganv/Port.hpp" -#include "ingen/Log.hpp" -#include "ingen/Parser.hpp" -#include "ingen/client/PluginModel.hpp" -#include "ingen/client/PortModel.hpp" - -#include <cassert> -#include <cstdlib> -#include <fstream> -#include <map> -#include <string> -namespace ingen { -namespace gui { +#include <ingen/URIs.hpp> +#include <ingen/client/PortModel.hpp> + +#include <string> -using namespace ingen::client; +namespace ingen::gui { Style::Style(App& app) - // Colours from the Tango palette with modified V - : _app(app) + : _app(app) +{ #ifdef INGEN_USE_LIGHT_THEME - , _audio_port_color(0xC8E6ABFF) // Green - , _control_port_color(0xAAC0E6FF) // Blue - , _cv_port_color(0xACE6E0FF) // Teal (between audio and control) - , _event_port_color(0xE6ABABFF) // Red - , _string_port_color(0xD8ABE6FF) // Plum -#else - , _audio_port_color(0x4A8A0EFF) // Green - , _control_port_color(0x244678FF) // Blue - , _cv_port_color(0x248780FF) // Teal (between audio and control) - , _event_port_color(0x960909FF) // Red - , _string_port_color(0x5C3566FF) // Plum + _audio_port_color = 0xC8E6ABFF; + _control_port_color = 0xAAC0E6FF; + _cv_port_color = 0xACE6E0FF; + _event_port_color = 0xE6ABABFF; + _string_port_color = 0xD8ABE6FF; #endif -{ } /** Loads settings from the rc file. Passing no parameter will load from * the default location. */ void -Style::load_settings(std::string filename) +Style::load_settings(const std::string& filename) { /* ... */ } @@ -68,7 +50,7 @@ Style::load_settings(std::string filename) * default location. */ void -Style::save_settings(std::string filename) +Style::save_settings(const std::string& filename) { /* ... */ } @@ -86,22 +68,32 @@ uint32_t Style::get_port_color(const client::PortModel* p) { const URIs& uris = _app.uris(); + if (p->is_a(uris.lv2_AudioPort)) { return _audio_port_color; - } else if (p->is_a(uris.lv2_ControlPort)) { + } + + if (p->is_a(uris.lv2_ControlPort)) { return _control_port_color; - } else if (p->is_a(uris.lv2_CVPort)) { + } + + if (p->is_a(uris.lv2_CVPort)) { return _cv_port_color; - } else if (p->supports(uris.atom_String)) { + } + + if (p->supports(uris.atom_String)) { return _string_port_color; - } else if (_app.can_control(p)) { + } + + if (_app.can_control(p)) { return _control_port_color; - } else if (p->is_a(uris.atom_AtomPort)) { + } + + if (p->is_a(uris.atom_AtomPort)) { return _event_port_color; } return 0x555555FF; } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/Style.hpp b/src/gui/Style.hpp index bb403ffd..20d560a8 100644 --- a/src/gui/Style.hpp +++ b/src/gui/Style.hpp @@ -20,21 +20,23 @@ #include <cstdint> #include <string> -namespace ingen { namespace client { class PortModel; } } - namespace ingen { + +namespace client { +class PortModel; +} // namespace client + namespace gui { class App; -class Port; class Style { public: explicit Style(App& app); - void load_settings(std::string filename = ""); - void save_settings(std::string filename = ""); + void load_settings(const std::string& filename = ""); + void save_settings(const std::string& filename = ""); void apply_settings(); @@ -43,11 +45,12 @@ public: private: App& _app; - uint32_t _audio_port_color; - uint32_t _control_port_color; - uint32_t _cv_port_color; - uint32_t _event_port_color; - uint32_t _string_port_color; + // Colours from the Tango palette with modified V + uint32_t _audio_port_color{0x4A8A0EFF}; // Green + uint32_t _control_port_color{0x244678FF}; // Blue + uint32_t _cv_port_color{0x248780FF}; // Teal {between audio/control} + uint32_t _event_port_color{0x960909FF}; // Red + uint32_t _string_port_color{0x5C3566FF}; // Plum }; } // namespace gui diff --git a/src/gui/SubgraphModule.cpp b/src/gui/SubgraphModule.cpp index 52c37787..a1b14bb6 100644 --- a/src/gui/SubgraphModule.cpp +++ b/src/gui/SubgraphModule.cpp @@ -18,27 +18,31 @@ #include "App.hpp" #include "NodeModule.hpp" -#include "GraphCanvas.hpp" -#include "GraphWindow.hpp" -#include "Port.hpp" #include "WindowFactory.hpp" -#include "ingen/Interface.hpp" -#include "ingen/client/GraphModel.hpp" +#include <ingen/Atom.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Resource.hpp> +#include <ingen/URIs.hpp> +#include <ingen/client/BlockModel.hpp> +#include <ingen/client/GraphModel.hpp> #include <cassert> +#include <memory> #include <utility> namespace ingen { -using namespace client; +using client::GraphModel; namespace gui { -SubgraphModule::SubgraphModule(GraphCanvas& canvas, - SPtr<const GraphModel> graph) - : NodeModule(canvas, graph) - , _graph(graph) +class GraphWindow; + +SubgraphModule::SubgraphModule(GraphCanvas& canvas, + const std::shared_ptr<const GraphModel>& graph) + : NodeModule(canvas, graph), _graph(graph) { assert(graph); } @@ -48,7 +52,7 @@ SubgraphModule::on_double_click(GdkEventButton* event) { assert(_graph); - SPtr<GraphModel> parent = dynamic_ptr_cast<GraphModel>(_graph->parent()); + auto parent = std::dynamic_pointer_cast<GraphModel>(_graph->parent()); GraphWindow* const preferred = ( (parent && (event->state & GDK_SHIFT_MASK)) ? nullptr @@ -84,7 +88,7 @@ SubgraphModule::browse_to_graph() { assert(_graph->parent()); - SPtr<GraphModel> parent = dynamic_ptr_cast<GraphModel>(_graph->parent()); + auto parent = std::dynamic_pointer_cast<GraphModel>(_graph->parent()); GraphWindow* const preferred = (parent) ? app().window_factory()->graph_window(parent) diff --git a/src/gui/SubgraphModule.hpp b/src/gui/SubgraphModule.hpp index 6f4e1c4c..11a24e52 100644 --- a/src/gui/SubgraphModule.hpp +++ b/src/gui/SubgraphModule.hpp @@ -17,18 +17,18 @@ #ifndef INGEN_GUI_SUBGRAPHMODULE_HPP #define INGEN_GUI_SUBGRAPHMODULE_HPP -#include "ingen/types.hpp" - #include "NodeModule.hpp" -#include "GraphPortModule.hpp" -namespace ingen { namespace client { -class GraphModel; -class GraphWindow; -class PortModel; -} } +#include <gdk/gdk.h> + +#include <memory> namespace ingen { + +namespace client { +class GraphModel; +} // namespace client + namespace gui { class GraphCanvas; @@ -40,10 +40,10 @@ class GraphCanvas; class SubgraphModule : public NodeModule { public: - SubgraphModule(GraphCanvas& canvas, - SPtr<const client::GraphModel> graph); + SubgraphModule(GraphCanvas& canvas, + const std::shared_ptr<const client::GraphModel>& graph); - virtual ~SubgraphModule() {} + ~SubgraphModule() override = default; bool on_double_click(GdkEventButton* event) override; @@ -52,10 +52,10 @@ public: void browse_to_graph(); void menu_remove(); - SPtr<const client::GraphModel> graph() const { return _graph; } + std::shared_ptr<const client::GraphModel> graph() const { return _graph; } protected: - SPtr<const client::GraphModel> _graph; + std::shared_ptr<const client::GraphModel> _graph; }; } // namespace gui diff --git a/src/gui/ThreadedLoader.cpp b/src/gui/ThreadedLoader.cpp index 45ac4f7f..abbedbaf 100644 --- a/src/gui/ThreadedLoader.cpp +++ b/src/gui/ThreadedLoader.cpp @@ -18,24 +18,40 @@ #include "App.hpp" -#include "ingen/Log.hpp" -#include "ingen/Module.hpp" -#include "ingen/World.hpp" -#include "ingen/client/GraphModel.hpp" +#include <ingen/FilePath.hpp> +#include <ingen/Log.hpp> +#include <ingen/Parser.hpp> +#include <ingen/Properties.hpp> +#include <ingen/Serialiser.hpp> +#include <ingen/URI.hpp> +#include <ingen/World.hpp> +#include <ingen/client/GraphModel.hpp> +#include <raul/Path.hpp> +#include <raul/Semaphore.hpp> +#include <raul/Symbol.hpp> + +#include <glibmm/ustring.h> +#include <sigc++/adaptors/bind.h> +#include <sigc++/adaptors/retype_return.h> +#include <sigc++/functors/mem_fun.h> #include <cassert> +#include <filesystem> +#include <memory> +#include <optional> #include <string> - -using boost::optional; +#include <string_view> +#include <utility> namespace ingen { + +class Interface; + namespace gui { -ThreadedLoader::ThreadedLoader(App& app, SPtr<Interface> engine) +ThreadedLoader::ThreadedLoader(App& app, std::shared_ptr<Interface> engine) : _app(app) - , _sem(0) , _engine(std::move(engine)) - , _exit_flag(false) , _thread(&ThreadedLoader::run, this) { if (!parser()) { @@ -52,7 +68,7 @@ ThreadedLoader::~ThreadedLoader() } } -SPtr<Parser> +std::shared_ptr<Parser> ThreadedLoader::parser() { return _app.world().parser(); @@ -62,7 +78,7 @@ void ThreadedLoader::run() { while (_sem.wait() && !_exit_flag) { - std::lock_guard<std::mutex> lock(_mutex); + const std::lock_guard<std::mutex> lock{_mutex}; while (!_events.empty()) { _events.front()(); _events.pop_front(); @@ -71,24 +87,24 @@ ThreadedLoader::run() } void -ThreadedLoader::load_graph(bool merge, - const FilePath& file_path, - optional<Raul::Path> engine_parent, - optional<Raul::Symbol> engine_symbol, - optional<Properties> engine_data) +ThreadedLoader::load_graph(bool merge, + const FilePath& file_path, + const std::optional<raul::Path>& engine_parent, + const std::optional<raul::Symbol>& engine_symbol, + const std::optional<Properties>& engine_data) { - std::lock_guard<std::mutex> lock(_mutex); + const std::lock_guard<std::mutex> lock{_mutex}; Glib::ustring engine_base = ""; if (engine_parent) { if (merge) { - engine_base = engine_parent.get(); + engine_base = *engine_parent; } else { - engine_base = engine_parent.get().base(); + engine_base = engine_parent->base(); } } - _events.push_back(sigc::hide_return( + _events.emplace_back(sigc::hide_return( sigc::bind(sigc::mem_fun(this, &ThreadedLoader::load_graph_event), file_path, engine_parent, @@ -99,12 +115,13 @@ ThreadedLoader::load_graph(bool merge, } void -ThreadedLoader::load_graph_event(const FilePath& file_path, - optional<Raul::Path> engine_parent, - optional<Raul::Symbol> engine_symbol, - optional<Properties> engine_data) +ThreadedLoader::load_graph_event( + const FilePath& file_path, + const std::optional<raul::Path>& engine_parent, + const std::optional<raul::Symbol>& engine_symbol, + const std::optional<Properties>& engine_data) { - std::lock_guard<std::mutex> lock(_app.world().rdf_mutex()); + const std::lock_guard<std::mutex> lock{_app.world().rdf_mutex()}; _app.world().parser()->parse_file(_app.world(), *_app.world().interface(), @@ -115,11 +132,13 @@ ThreadedLoader::load_graph_event(const FilePath& file_path, } void -ThreadedLoader::save_graph(SPtr<const client::GraphModel> model, const URI& uri) +ThreadedLoader::save_graph( + const std::shared_ptr<const client::GraphModel>& model, + const URI& uri) { - std::lock_guard<std::mutex> lock(_mutex); + const std::lock_guard<std::mutex> lock{_mutex}; - _events.push_back(sigc::hide_return( + _events.emplace_back(sigc::hide_return( sigc::bind(sigc::mem_fun(this, &ThreadedLoader::save_graph_event), model, uri))); @@ -128,12 +147,13 @@ ThreadedLoader::save_graph(SPtr<const client::GraphModel> model, const URI& uri) } void -ThreadedLoader::save_graph_event(SPtr<const client::GraphModel> model, - const URI& uri) +ThreadedLoader::save_graph_event( + const std::shared_ptr<const client::GraphModel>& model, + const URI& uri) { assert(uri.scheme() == "file"); if (_app.serialiser()) { - std::lock_guard<std::mutex> lock(_app.world().rdf_mutex()); + const std::lock_guard<std::mutex> lock{_app.world().rdf_mutex()}; if (uri.string().find(".ingen") != std::string::npos) { _app.serialiser()->write_bundle(model, uri); diff --git a/src/gui/ThreadedLoader.hpp b/src/gui/ThreadedLoader.hpp index 3ab8f4a2..27ba7c8c 100644 --- a/src/gui/ThreadedLoader.hpp +++ b/src/gui/ThreadedLoader.hpp @@ -17,25 +17,32 @@ #ifndef INGEN_GUI_THREADEDLOADER_HPP #define INGEN_GUI_THREADEDLOADER_HPP -#include "ingen/FilePath.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Parser.hpp" -#include "ingen/Serialiser.hpp" -#include "raul/Semaphore.hpp" +#include <ingen/FilePath.hpp> +#include <raul/Semaphore.hpp> -#include <boost/optional/optional.hpp> -#include <sigc++/sigc++.h> +#include <sigc++/functors/slot.h> #include <list> +#include <memory> #include <mutex> +#include <optional> #include <thread> -#include <utility> + +namespace raul { +class Path; +class Symbol; +} // namespace raul namespace ingen { +class Interface; +class Parser; +class Properties; class URI; -namespace client { class GraphModel; } +namespace client { +class GraphModel; +} // namespace client namespace gui { @@ -43,7 +50,7 @@ class App; /** Thread for loading graph files. * - * This is a seperate thread so it can send all the loading message without + * This is a separate thread so it can send all the loading message without * blocking everything else, so the app can respond to the incoming events * caused as a result of the graph loading, while the graph loads. * @@ -56,41 +63,43 @@ class ThreadedLoader { public: ThreadedLoader(App& app, - SPtr<Interface> engine); + std::shared_ptr<Interface> engine); ~ThreadedLoader(); - void load_graph(bool merge, - const FilePath& file_path, - boost::optional<Raul::Path> engine_parent, - boost::optional<Raul::Symbol> engine_symbol, - boost::optional<Properties> engine_data); + void load_graph(bool merge, + const FilePath& file_path, + const std::optional<raul::Path>& engine_parent, + const std::optional<raul::Symbol>& engine_symbol, + const std::optional<Properties>& engine_data); - void save_graph(SPtr<const client::GraphModel> model, const URI& uri); + void save_graph(const std::shared_ptr<const client::GraphModel>& model, + const URI& uri); - SPtr<Parser> parser(); + std::shared_ptr<Parser> parser(); private: - void load_graph_event(const FilePath& file_path, - boost::optional<Raul::Path> engine_parent, - boost::optional<Raul::Symbol> engine_symbol, - boost::optional<Properties> engine_data); + void load_graph_event(const FilePath& file_path, + const std::optional<raul::Path>& engine_parent, + const std::optional<raul::Symbol>& engine_symbol, + const std::optional<Properties>& engine_data); - void save_graph_event(SPtr<const client::GraphModel> model, - const URI& filename); + void + save_graph_event(const std::shared_ptr<const client::GraphModel>& model, + const URI& uri); - /** Returns nothing and takes no parameters (because they have all been bound) */ + /// Returns nothing and takes no parameters (because they're all bound) using Closure = sigc::slot<void>; void run(); - App& _app; - Raul::Semaphore _sem; - SPtr<Interface> _engine; - std::mutex _mutex; - std::list<Closure> _events; - bool _exit_flag; - std::thread _thread; + App& _app; + raul::Semaphore _sem{0}; + std::shared_ptr<Interface> _engine; + std::mutex _mutex; + std::list<Closure> _events; + bool _exit_flag{false}; + std::thread _thread; }; } // namespace gui diff --git a/src/gui/URIEntry.cpp b/src/gui/URIEntry.cpp index 9d5249e8..92320009 100644 --- a/src/gui/URIEntry.cpp +++ b/src/gui/URIEntry.cpp @@ -19,11 +19,23 @@ #include "App.hpp" #include "RDFS.hpp" +#include <ingen/URI.hpp> +#include <ingen/World.hpp> +#include <lilv/lilv.h> + +#include <gdk/gdk.h> +#include <gtkmm/button.h> +#include <gtkmm/menu.h> +#include <gtkmm/menu_elems.h> +#include <gtkmm/menuitem.h> +#include <gtkmm/object.h> +#include <sigc++/adaptors/bind.h> +#include <sigc++/functors/mem_fun.h> + #include <map> #include <utility> -namespace ingen { -namespace gui { +namespace ingen::gui { URIEntry::URIEntry(App* app, std::set<URI> types, const std::string& value) : Gtk::HBox(false, 4) @@ -46,7 +58,7 @@ URIEntry::build_value_menu() { World& world = _app->world(); LilvWorld* lworld = world.lilv_world(); - Gtk::Menu* menu = new Gtk::Menu(); + auto* menu = new Gtk::Menu(); LilvNode* owl_onDatatype = lilv_new_uri(lworld, LILV_NS_OWL "onDatatype"); LilvNode* rdf_type = lilv_new_uri(lworld, LILV_NS_RDF "type"); @@ -54,7 +66,7 @@ URIEntry::build_value_menu() LilvNode* rdfs_Datatype = lilv_new_uri(lworld, LILV_NS_RDFS "Datatype"); LilvNode* rdfs_subClassOf = lilv_new_uri(lworld, LILV_NS_RDFS "subClassOf"); - rdfs::Objects values = rdfs::instances(world, _types); + const rdfs::Objects values = rdfs::instances(world, _types); for (const auto& v : values) { const LilvNode* inst = lilv_new_uri(lworld, v.second.c_str()); @@ -110,7 +122,7 @@ URIEntry::build_subclass_menu(const LilvNode* klass) return nullptr; } - Gtk::Menu* menu = new Gtk::Menu(); + auto* menu = new Gtk::Menu(); // Add "header" item for choosing this class itself add_leaf_menu_item(menu, klass, rdfs::label(world, klass)); @@ -118,11 +130,11 @@ URIEntry::build_subclass_menu(const LilvNode* klass) // Put subclasses/types in a map keyed by label (to sort menu) std::map<std::string, const LilvNode*> entries; - LILV_FOREACH(nodes, s, subclasses) { + LILV_FOREACH (nodes, s, subclasses) { const LilvNode* node = lilv_nodes_get(subclasses, s); entries.emplace(rdfs::label(world, node), node); } - LILV_FOREACH(nodes, s, subtypes) { + LILV_FOREACH (nodes, s, subtypes) { const LilvNode* node = lilv_nodes_get(subtypes, s); entries.emplace(rdfs::label(world, node), node); } @@ -190,5 +202,4 @@ URIEntry::menu_button_event(GdkEvent* ev) return true; } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/URIEntry.hpp b/src/gui/URIEntry.hpp index 535f0805..45fa6894 100644 --- a/src/gui/URIEntry.hpp +++ b/src/gui/URIEntry.hpp @@ -17,23 +17,29 @@ #ifndef INGEN_GUI_URI_ENTRY_HPP #define INGEN_GUI_URI_ENTRY_HPP -#include "ingen/URI.hpp" -#include "lilv/lilv.h" +#include <ingen/URI.hpp> +#include <lilv/lilv.h> +#include <gdk/gdk.h> +#include <glibmm/signalproxy.h> +#include <glibmm/ustring.h> #include <gtkmm/box.h> -#include <gtkmm/button.h> #include <gtkmm/entry.h> -#include <gtkmm/menu.h> #include <set> #include <string> -namespace ingen { -namespace gui { +namespace Gtk { +class Button; +class Menu; +} // namespace Gtk + +namespace ingen::gui { class App; -class URIEntry : public Gtk::HBox { +class URIEntry : public Gtk::HBox +{ public: /** Create a widget for entering URIs. * @@ -66,7 +72,6 @@ private: Gtk::Entry* _entry; }; -} // namespace gui -} // namespace ingen +} // namespace ingen::gui #endif // INGEN_GUI_URI_ENTRY_HPP diff --git a/src/gui/WidgetFactory.cpp b/src/gui/WidgetFactory.cpp index 154bcd3f..33660d77 100644 --- a/src/gui/WidgetFactory.cpp +++ b/src/gui/WidgetFactory.cpp @@ -16,20 +16,18 @@ #include "WidgetFactory.hpp" -#include "ingen/Log.hpp" -#include "ingen/runtime_paths.hpp" +#include <ingen/runtime_paths.hpp> #include <cstdlib> #include <fstream> #include <stdexcept> #include <string> -namespace ingen { -namespace gui { +namespace ingen::gui { Glib::ustring WidgetFactory::ui_filename = ""; -inline static bool +static inline bool is_readable(const std::string& filename) { std::ifstream fs(filename.c_str()); @@ -72,10 +70,9 @@ WidgetFactory::create(const std::string& toplevel_widget) if (toplevel_widget.empty()) { return Gtk::Builder::create_from_file(ui_filename); - } else { - return Gtk::Builder::create_from_file(ui_filename, toplevel_widget.c_str()); } + + return Gtk::Builder::create_from_file(ui_filename, toplevel_widget.c_str()); } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui diff --git a/src/gui/WidgetFactory.hpp b/src/gui/WidgetFactory.hpp index 0a9ea4c3..d10a5e1a 100644 --- a/src/gui/WidgetFactory.hpp +++ b/src/gui/WidgetFactory.hpp @@ -14,8 +14,8 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef INGEN_GUI_GLADEFACTORY_HPP -#define INGEN_GUI_GLADEFACTORY_HPP +#ifndef INGEN_GUI_WIDGETFACTORY_HPP +#define INGEN_GUI_WIDGETFACTORY_HPP #include <glibmm/refptr.h> #include <glibmm/ustring.h> @@ -23,30 +23,28 @@ #include <string> -namespace Gtk { class Builder; } - -namespace ingen { -namespace gui { +namespace ingen::gui { /** Loads widgets from an XML description. * Purely static. * * \ingroup GUI */ -class WidgetFactory { +class WidgetFactory +{ public: static Glib::RefPtr<Gtk::Builder> create(const std::string& toplevel_widget=""); template<typename T> static void get_widget(const Glib::ustring& name, T*& widget) { - Glib::RefPtr<Gtk::Builder> xml = create(name); + const Glib::RefPtr<Gtk::Builder> xml = create(name); xml->get_widget(name, widget); } template<typename T> static void get_widget_derived(const Glib::ustring& name, T*& widget) { - Glib::RefPtr<Gtk::Builder> xml = create(name); + const Glib::RefPtr<Gtk::Builder> xml = create(name); xml->get_widget_derived(name, widget); } @@ -55,7 +53,6 @@ private: static Glib::ustring ui_filename; }; -} // namespace gui -} // namespace ingen +} // namespace ingen::gui -#endif // INGEN_GUI_GLADEFACTORY_HPP +#endif // INGEN_GUI_WIDGETFACTORY_HPP diff --git a/src/gui/Window.hpp b/src/gui/Window.hpp index 5f49bc10..756ba8f0 100644 --- a/src/gui/Window.hpp +++ b/src/gui/Window.hpp @@ -17,13 +17,12 @@ #ifndef INGEN_GUI_WINDOW_HPP #define INGEN_GUI_WINDOW_HPP +#include <gdk/gdk.h> #include <gdk/gdkkeysyms.h> #include <gtkmm/dialog.h> #include <gtkmm/window.h> -namespace ingen { - -namespace gui { +namespace ingen::gui { class App; @@ -33,13 +32,16 @@ class App; class Window : public Gtk::Window { public: - Window() : Gtk::Window(), _app(nullptr) {} - explicit Window(BaseObjectType* cobject) : Gtk::Window(cobject), _app(nullptr) {} + Window() = default; + + explicit Window(BaseObjectType* cobject) + : Gtk::Window(cobject) + {} virtual void init_window(App& app) { _app = &app; } bool on_key_press_event(GdkEventKey* event) override { - if (event->keyval == GDK_w && event->state & GDK_CONTROL_MASK) { + if (event->keyval == GDK_KEY_w && event->state & GDK_CONTROL_MASK) { hide(); return true; } @@ -48,7 +50,7 @@ public: static bool key_press_handler(Gtk::Window* win, GdkEventKey* event); - App* _app; + App* _app = nullptr; }; /** Ingen GUI Dialog @@ -57,23 +59,25 @@ public: class Dialog : public Gtk::Dialog { public: - Dialog() : Gtk::Dialog(), _app(nullptr) {} - explicit Dialog(BaseObjectType* cobject) : Gtk::Dialog(cobject), _app(nullptr) {} + Dialog() = default; + + explicit Dialog(BaseObjectType* cobject) + : Gtk::Dialog(cobject) + {} virtual void init_dialog(App& app) { _app = &app; } bool on_key_press_event(GdkEventKey* event) override { - if (event->keyval == GDK_w && event->state & GDK_CONTROL_MASK) { + if (event->keyval == GDK_KEY_w && event->state & GDK_CONTROL_MASK) { hide(); return true; } return Gtk::Window::on_key_press_event(event); } - App* _app; + App* _app = nullptr; }; -} // namespace gui -} // namespace ingen +} // namespace ingen::gui #endif // INGEN_GUI_WINDOW_HPP diff --git a/src/gui/WindowFactory.cpp b/src/gui/WindowFactory.cpp index d85987f0..78acf4fb 100644 --- a/src/gui/WindowFactory.cpp +++ b/src/gui/WindowFactory.cpp @@ -1,6 +1,6 @@ /* This file is part of Ingen. - Copyright 2007-2015 David Robillard <http://drobilla.net/> + Copyright 2007-2024 David Robillard <http://drobilla.net/> Ingen is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free @@ -14,38 +14,47 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ +#include "WindowFactory.hpp" + #include "App.hpp" +#include "GraphBox.hpp" +#include "GraphWindow.hpp" #include "LoadGraphWindow.hpp" #include "LoadPluginWindow.hpp" #include "NewSubgraphWindow.hpp" -#include "GraphView.hpp" -#include "GraphWindow.hpp" #include "PropertiesWindow.hpp" #include "RenameWindow.hpp" #include "WidgetFactory.hpp" -#include "WindowFactory.hpp" -#include "ingen/Log.hpp" -#include "ingen/client/GraphModel.hpp" +#include <ingen/Log.hpp> +#include <ingen/client/BlockModel.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/ObjectModel.hpp> +#include <raul/Path.hpp> + +#include <gdkmm/window.h> +#include <sigc++/adaptors/bind.h> +#include <sigc++/functors/mem_fun.h> +#include <algorithm> #include <cassert> +#include <memory> #include <stdexcept> #include <string> #include <utility> namespace ingen { -using namespace client; +class Properties; + +using client::BlockModel; +using client::GraphModel; +using client::ObjectModel; namespace gui { WindowFactory::WindowFactory(App& app) : _app(app) - , _main_box(nullptr) - , _load_plugin_win(nullptr) - , _load_graph_win(nullptr) - , _new_subgraph_win(nullptr) - , _properties_win(nullptr) { WidgetFactory::get_widget_derived("load_plugin_win", _load_plugin_win); WidgetFactory::get_widget_derived("load_graph_win", _load_graph_win); @@ -87,29 +96,24 @@ WindowFactory::clear() size_t WindowFactory::num_open_graph_windows() { - size_t ret = 0; - for (const auto& w : _graph_windows) { - if (w.second->is_visible()) { - ++ret; - } - } - - return ret; + return std::count_if(_graph_windows.begin(), + _graph_windows.end(), + [](const auto& w) { return w.second->is_visible(); }); } GraphBox* -WindowFactory::graph_box(SPtr<const GraphModel> graph) +WindowFactory::graph_box(const std::shared_ptr<const GraphModel>& graph) { GraphWindow* window = graph_window(graph); if (window) { return window->box(); - } else { - return _main_box; } + + return _main_box; } GraphWindow* -WindowFactory::graph_window(SPtr<const GraphModel> graph) +WindowFactory::graph_window(const std::shared_ptr<const GraphModel>& graph) { if (!graph) { return nullptr; @@ -121,13 +125,14 @@ WindowFactory::graph_window(SPtr<const GraphModel> graph) } GraphWindow* -WindowFactory::parent_graph_window(SPtr<const BlockModel> block) +WindowFactory::parent_graph_window( + const std::shared_ptr<const BlockModel>& block) { if (!block) { return nullptr; } - return graph_window(dynamic_ptr_cast<GraphModel>(block->parent())); + return graph_window(std::dynamic_pointer_cast<GraphModel>(block->parent())); } /** Present a GraphWindow for a Graph. @@ -137,12 +142,10 @@ WindowFactory::parent_graph_window(SPtr<const BlockModel> block) * presented and `preferred` left unmodified. */ void -WindowFactory::present_graph(SPtr<const GraphModel> graph, - GraphWindow* preferred, - SPtr<GraphView> view) +WindowFactory::present_graph(const std::shared_ptr<const GraphModel>& graph, + GraphWindow* preferred, + const std::shared_ptr<GraphView>& view) { - assert(!view || view->graph() == graph); - auto w = _graph_windows.find(graph->path()); if (w != _graph_windows.end()) { @@ -163,11 +166,9 @@ WindowFactory::present_graph(SPtr<const GraphModel> graph, } GraphWindow* -WindowFactory::new_graph_window(SPtr<const GraphModel> graph, - SPtr<GraphView> view) +WindowFactory::new_graph_window(const std::shared_ptr<const GraphModel>& graph, + const std::shared_ptr<GraphView>& view) { - assert(!view || view->graph() == graph); - GraphWindow* win = nullptr; WidgetFactory::get_widget_derived("graph_win", win); if (!win) { @@ -205,8 +206,9 @@ WindowFactory::remove_graph_window(GraphWindow* win, GdkEventAny* ignored) } void -WindowFactory::present_load_plugin(SPtr<const GraphModel> graph, - Properties data) +WindowFactory::present_load_plugin( + const std::shared_ptr<const GraphModel>& graph, + const Properties& data) { _app.request_plugins_if_necessary(); @@ -219,9 +221,10 @@ WindowFactory::present_load_plugin(SPtr<const GraphModel> graph, _load_plugin_win->set_modal(false); _load_plugin_win->set_type_hint(Gdk::WINDOW_TYPE_HINT_DIALOG); if (w->second) { - int width, height; + int width = 0; + int height = 0; w->second->get_size(width, height); - _load_plugin_win->set_default_size(width - width / 8, height / 2); + _load_plugin_win->set_default_size(width - (width / 8), height / 2); } _load_plugin_win->set_title( std::string("Load Plugin - ") + graph->path() + " - Ingen"); @@ -229,8 +232,9 @@ WindowFactory::present_load_plugin(SPtr<const GraphModel> graph, } void -WindowFactory::present_load_graph(SPtr<const GraphModel> graph, - Properties data) +WindowFactory::present_load_graph( + const std::shared_ptr<const GraphModel>& graph, + const Properties& data) { auto w = _graph_windows.find(graph->path()); @@ -242,8 +246,9 @@ WindowFactory::present_load_graph(SPtr<const GraphModel> graph, } void -WindowFactory::present_load_subgraph(SPtr<const GraphModel> graph, - Properties data) +WindowFactory::present_load_subgraph( + const std::shared_ptr<const GraphModel>& graph, + const Properties& data) { auto w = _graph_windows.find(graph->path()); @@ -255,8 +260,9 @@ WindowFactory::present_load_subgraph(SPtr<const GraphModel> graph, } void -WindowFactory::present_new_subgraph(SPtr<const GraphModel> graph, - Properties data) +WindowFactory::present_new_subgraph( + const std::shared_ptr<const GraphModel>& graph, + const Properties& data) { auto w = _graph_windows.find(graph->path()); @@ -268,7 +274,7 @@ WindowFactory::present_new_subgraph(SPtr<const GraphModel> graph, } void -WindowFactory::present_rename(SPtr<const ObjectModel> object) +WindowFactory::present_rename(const std::shared_ptr<const ObjectModel>& object) { auto w = _graph_windows.find(object->path()); if (w == _graph_windows.end()) { @@ -283,7 +289,8 @@ WindowFactory::present_rename(SPtr<const ObjectModel> object) } void -WindowFactory::present_properties(SPtr<const ObjectModel> object) +WindowFactory::present_properties( + const std::shared_ptr<const ObjectModel>& object) { auto w = _graph_windows.find(object->path()); if (w == _graph_windows.end()) { diff --git a/src/gui/WindowFactory.hpp b/src/gui/WindowFactory.hpp index fad5b308..e643505a 100644 --- a/src/gui/WindowFactory.hpp +++ b/src/gui/WindowFactory.hpp @@ -17,11 +17,14 @@ #ifndef INGEN_GUI_WINDOWFACTORY_HPP #define INGEN_GUI_WINDOWFACTORY_HPP -#include "ingen/Node.hpp" -#include "ingen/types.hpp" +#include <ingen/Properties.hpp> +#include <raul/Path.hpp> + +#include <gdk/gdk.h> #include <cstddef> #include <map> +#include <memory> namespace ingen { @@ -29,7 +32,7 @@ namespace client { class BlockModel; class ObjectModel; class GraphModel; -} +} // namespace client namespace gui { @@ -49,28 +52,46 @@ class RenameWindow; * as well as an enumeration of all windows (the goal being to reduce that * number as much as possible). */ -class WindowFactory { +class WindowFactory +{ public: explicit WindowFactory(App& app); ~WindowFactory(); size_t num_open_graph_windows(); - GraphBox* graph_box(SPtr<const client::GraphModel> graph); - GraphWindow* graph_window(SPtr<const client::GraphModel> graph); - GraphWindow* parent_graph_window(SPtr<const client::BlockModel> block); + GraphBox* graph_box(const std::shared_ptr<const client::GraphModel>& graph); + + GraphWindow* + graph_window(const std::shared_ptr<const client::GraphModel>& graph); + + GraphWindow* + parent_graph_window(const std::shared_ptr<const client::BlockModel>& block); + + void present_graph(const std::shared_ptr<const client::GraphModel>& graph, + GraphWindow* preferred = nullptr, + const std::shared_ptr<GraphView>& view = nullptr); + + void + present_load_plugin(const std::shared_ptr<const client::GraphModel>& graph, + const Properties& data = Properties()); + + void + present_load_graph(const std::shared_ptr<const client::GraphModel>& graph, + const Properties& data = Properties()); + + void present_load_subgraph( + const std::shared_ptr<const client::GraphModel>& graph, + const Properties& data = Properties()); + + void + present_new_subgraph(const std::shared_ptr<const client::GraphModel>& graph, + const Properties& data = Properties()); - void present_graph( - SPtr<const client::GraphModel> graph, - GraphWindow* preferred = nullptr, - SPtr<GraphView> view = SPtr<GraphView>()); + void + present_rename(const std::shared_ptr<const client::ObjectModel>& object); - void present_load_plugin(SPtr<const client::GraphModel> graph, Properties data=Properties()); - void present_load_graph(SPtr<const client::GraphModel> graph, Properties data=Properties()); - void present_load_subgraph(SPtr<const client::GraphModel> graph, Properties data=Properties()); - void present_new_subgraph(SPtr<const client::GraphModel> graph, Properties data=Properties()); - void present_rename(SPtr<const client::ObjectModel> object); - void present_properties(SPtr<const client::ObjectModel> object); + void present_properties(const std::shared_ptr<const client::ObjectModel>& object); bool remove_graph_window(GraphWindow* win, GdkEventAny* ignored = nullptr); @@ -79,19 +100,20 @@ public: void clear(); private: - using GraphWindowMap = std::map<Raul::Path, GraphWindow*>; + using GraphWindowMap = std::map<raul::Path, GraphWindow*>; - GraphWindow* new_graph_window(SPtr<const client::GraphModel> graph, - SPtr<GraphView> view); + GraphWindow* + new_graph_window(const std::shared_ptr<const client::GraphModel>& graph, + const std::shared_ptr<GraphView>& view); App& _app; - GraphBox* _main_box; + GraphBox* _main_box{nullptr}; GraphWindowMap _graph_windows; - LoadPluginWindow* _load_plugin_win; - LoadGraphWindow* _load_graph_win; - NewSubgraphWindow* _new_subgraph_win; - PropertiesWindow* _properties_win; - RenameWindow* _rename_win; + LoadPluginWindow* _load_plugin_win{nullptr}; + LoadGraphWindow* _load_graph_win{nullptr}; + NewSubgraphWindow* _new_subgraph_win{nullptr}; + PropertiesWindow* _properties_win{nullptr}; + RenameWindow* _rename_win{nullptr}; }; } // namespace gui diff --git a/src/gui/ingen_gui.cpp b/src/gui/ingen_gui.cpp index 4504d3fe..7fba2d50 100644 --- a/src/gui/ingen_gui.cpp +++ b/src/gui/ingen_gui.cpp @@ -14,25 +14,33 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ -#include "ingen/Configuration.hpp" -#include "ingen/Module.hpp" -#include "ingen/QueuedInterface.hpp" -#include "ingen/client/SigClientInterface.hpp" - #include "App.hpp" -namespace ingen { -namespace gui { +#include <ingen/Atom.hpp> +#include <ingen/Configuration.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Module.hpp> +#include <ingen/QueuedInterface.hpp> +#include <ingen/URI.hpp> +#include <ingen/World.hpp> +#include <ingen/client/SigClientInterface.hpp> + +#include <glibmm/thread.h> + +#include <memory> +#include <string> + +namespace ingen::gui { struct GUIModule : public Module { using SigClientInterface = client::SigClientInterface; void load(World& world) override { - URI uri(world.conf().option("connect").ptr<char>()); + const URI uri{world.conf().option("connect").ptr<char>()}; if (!world.interface()) { world.set_interface( world.new_interface(URI(uri), make_client(world))); - } else if (!dynamic_ptr_cast<SigClientInterface>( + } else if (!std::dynamic_pointer_cast<SigClientInterface>( world.interface()->respondee())) { world.interface()->set_respondee(make_client(world)); } @@ -44,20 +52,22 @@ struct GUIModule : public Module { app->run(); } - SPtr<Interface> make_client(World& world) { - SPtr<SigClientInterface> sci(new SigClientInterface()); - return world.engine() ? sci : SPtr<Interface>(new QueuedInterface(sci)); + std::shared_ptr<Interface> make_client(World& world) + { + auto sci = std::make_shared<SigClientInterface>(); + return world.engine() + ? sci + : std::shared_ptr<Interface>(new QueuedInterface(sci)); } - SPtr<gui::App> app; + std::shared_ptr<gui::App> app; }; -} // namespace gui -} // namespace ingen +} // namespace ingen::gui extern "C" { -ingen::Module* +INGEN_MODULE_EXPORT ingen::Module* ingen_module_load() { Glib::thread_init(); diff --git a/src/gui/ingen_gui.ui b/src/gui/ingen_gui.ui.in index 9e751064..9e751064 100644 --- a/src/gui/ingen_gui.ui +++ b/src/gui/ingen_gui.ui.in diff --git a/src/gui/ingen_gui_lv2.cpp b/src/gui/ingen_gui_lv2.cpp index 4817e9ae..67290c76 100644 --- a/src/gui/ingen_gui_lv2.cpp +++ b/src/gui/ingen_gui_lv2.cpp @@ -17,41 +17,40 @@ #include "App.hpp" #include "GraphBox.hpp" -#include "ingen/AtomReader.hpp" -#include "ingen/AtomSink.hpp" -#include "ingen/AtomWriter.hpp" -#include "ingen/Forge.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Properties.hpp" -#include "ingen/URI.hpp" -#include "ingen/URIs.hpp" -#include "ingen/World.hpp" -#include "ingen/client/ClientStore.hpp" -#include "ingen/client/GraphModel.hpp" -#include "ingen/client/SigClientInterface.hpp" -#include "ingen/ingen.h" -#include "ingen/paths.hpp" -#include "ingen/runtime_paths.hpp" -#include "ingen/types.hpp" -#include "lv2/atom/atom.h" -#include "lv2/atom/util.h" -#include "lv2/core/lv2.h" -#include "lv2/core/lv2.h" -#include "lv2/log/log.h" -#include "lv2/ui/ui.h" -#include "lv2/urid/urid.h" -#include "lv2/urid/urid.h" -#include "raul/Path.hpp" +#include <ingen/AtomReader.hpp> +#include <ingen/AtomSink.hpp> +#include <ingen/AtomWriter.hpp> +#include <ingen/Forge.hpp> +#include <ingen/Interface.hpp> +#include <ingen/Properties.hpp> +#include <ingen/URI.hpp> +#include <ingen/URIs.hpp> +#include <ingen/World.hpp> +#include <ingen/client/ClientStore.hpp> +#include <ingen/client/GraphModel.hpp> +#include <ingen/client/SigClientInterface.hpp> +#include <ingen/ingen.h> +#include <ingen/paths.hpp> +#include <ingen/runtime_paths.hpp> +#include <lv2/atom/atom.h> +#include <lv2/atom/util.h> +#include <lv2/core/lv2.h> +#include <lv2/log/log.h> +#include <lv2/ui/ui.h> +#include <lv2/urid/urid.h> +#include <raul/Path.hpp> #include <cstdint> #include <cstring> +#include <memory> #define INGEN_LV2_UI_URI INGEN_NS "GraphUIGtk2" namespace ingen { /** A sink that writes atoms to a port via the UI extension. */ -struct IngenLV2AtomSink : public AtomSink { +class IngenLV2AtomSink : public AtomSink { +public: IngenLV2AtomSink(URIs& uris, LV2UI_Write_Function ui_write, LV2UI_Controller ui_controller) @@ -69,30 +68,23 @@ struct IngenLV2AtomSink : public AtomSink { return true; } +private: URIs& _uris; LV2UI_Write_Function _ui_write; LV2UI_Controller _ui_controller; }; struct IngenLV2UI { - IngenLV2UI() - : argc(0) - , argv(nullptr) - , forge(nullptr) - , world(nullptr) - , sink(nullptr) - {} - - int argc; - char** argv; - Forge* forge; - World* world; - IngenLV2AtomSink* sink; - SPtr<gui::App> app; - SPtr<gui::GraphBox> view; - SPtr<Interface> engine; - SPtr<AtomReader> reader; - SPtr<client::SigClientInterface> client; + int argc{0}; + char** argv{nullptr}; + Forge* forge{nullptr}; + World* world{nullptr}; + IngenLV2AtomSink* sink{nullptr}; + std::shared_ptr<gui::App> app; + std::shared_ptr<gui::GraphBox> view; + std::shared_ptr<Interface> engine; + std::shared_ptr<AtomReader> reader; + std::shared_ptr<client::SigClientInterface> client; }; } // namespace ingen @@ -106,24 +98,20 @@ instantiate(const LV2UI_Descriptor* descriptor, LV2UI_Widget* widget, const LV2_Feature* const* features) { -#if __cplusplus >= 201103L - using ingen::SPtr; -#endif - ingen::set_bundle_path(bundle_path); - ingen::IngenLV2UI* ui = new ingen::IngenLV2UI(); + auto* ui = new ingen::IngenLV2UI(); LV2_URID_Map* map = nullptr; LV2_URID_Unmap* unmap = nullptr; LV2_Log_Log* log = nullptr; for (int i = 0; features[i]; ++i) { if (!strcmp(features[i]->URI, LV2_URID__map)) { - map = (LV2_URID_Map*)features[i]->data; + map = static_cast<LV2_URID_Map*>(features[i]->data); } else if (!strcmp(features[i]->URI, LV2_URID__unmap)) { - unmap = (LV2_URID_Unmap*)features[i]->data; + unmap = static_cast<LV2_URID_Unmap*>(features[i]->data); } else if (!strcmp(features[i]->URI, LV2_LOG__log)) { - log = (LV2_Log_Log*)features[i]->data; + log = static_cast<LV2_Log_Log*>(features[i]->data); } } @@ -141,24 +129,22 @@ instantiate(const LV2UI_Descriptor* descriptor, ui->world->uris(), write_function, controller); // Set up an engine interface that writes LV2 atoms - ui->engine = SPtr<ingen::Interface>( + ui->engine = std::shared_ptr<ingen::Interface>( new ingen::AtomWriter( ui->world->uri_map(), ui->world->uris(), *ui->sink)); ui->world->set_interface(ui->engine); // Create App and client - ui->app = ingen::gui::App::create(*ui->world); - ui->client = SPtr<ingen::client::SigClientInterface>( - new ingen::client::SigClientInterface()); + ui->app = ingen::gui::App::create(*ui->world); + ui->client = std::make_shared<ingen::client::SigClientInterface>(); ui->app->set_is_plugin(true); ui->app->attach(ui->client); - ui->reader = SPtr<ingen::AtomReader>( - new ingen::AtomReader(ui->world->uri_map(), - ui->world->uris(), - ui->world->log(), - *ui->client.get())); + ui->reader = std::make_shared<ingen::AtomReader>(ui->world->uri_map(), + ui->world->uris(), + ui->world->log(), + *ui->client); // Create empty root graph model ingen::Properties props; @@ -167,9 +153,9 @@ instantiate(const LV2UI_Descriptor* descriptor, ui->app->store()->put(ingen::main_uri(), props); // Create a GraphBox for the root and set as the UI widget - SPtr<const ingen::client::GraphModel> root = - ingen::dynamic_ptr_cast<const ingen::client::GraphModel>( - ui->app->store()->object(Raul::Path("/"))); + auto root = std::dynamic_pointer_cast<const ingen::client::GraphModel>( + ui->app->store()->object(raul::Path("/"))); + ui->view = ingen::gui::GraphBox::create(*ui->app, root); ui->view->unparent(); *widget = ui->view->gobj(); @@ -183,7 +169,7 @@ instantiate(const LV2UI_Descriptor* descriptor, static void cleanup(LV2UI_Handle handle) { - ingen::IngenLV2UI* ui = (ingen::IngenLV2UI*)handle; + auto* ui = static_cast<ingen::IngenLV2UI*>(handle); delete ui; } @@ -194,8 +180,8 @@ port_event(LV2UI_Handle handle, uint32_t format, const void* buffer) { - ingen::IngenLV2UI* ui = (ingen::IngenLV2UI*)handle; - const LV2_Atom* atom = (const LV2_Atom*)buffer; + auto* ui = static_cast<ingen::IngenLV2UI*>(handle); + const auto* atom = static_cast<const LV2_Atom*>(buffer); ui->reader->write(atom); } diff --git a/src/gui/meson.build b/src/gui/meson.build new file mode 100644 index 00000000..810c7829 --- /dev/null +++ b/src/gui/meson.build @@ -0,0 +1,179 @@ +# Copyright 2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: 0BSD OR GPL-3.0-or-later + +################ +# Dependencies # +################ + +gui_defines = platform_defines + +glibmm_dep = dependency( + 'glibmm-2.4', + include_type: 'system', + required: get_option('gui'), + version: '>= 2.14.0', +) + +gthread_dep = dependency( + 'gthread-2.0', + include_type: 'system', + required: get_option('gui'), + version: '>= 2.14.0', +) + +gtkmm_dep = dependency( + 'gtkmm-2.4', + include_type: 'system', + required: get_option('gui'), + version: '>= 2.14.0', +) + +ganv_dep = dependency( + 'ganv-1', + include_type: 'system', + required: get_option('gui'), + version: '>= 1.5.2', +) + +webkit_dep = dependency( + 'webkit-1.0', + include_type: 'system', + required: false, + version: '>= 1.4.0', +) + +build_gui = ( + glibmm_dep.found() + and gthread_dep.found() + and gtkmm_dep.found() + and ganv_dep.found() +) + +if webkit_dep.found() + gui_defines += ['-DHAVE_WEBKIT=1'] +else + gui_defines += ['-DHAVE_WEBKIT=0'] +endif + +########## +# Module # +########## + +if build_gui + gui_sources = files( + 'App.cpp', + 'Arc.cpp', + 'BreadCrumbs.cpp', + 'ConnectWindow.cpp', + 'GraphBox.cpp', + 'GraphCanvas.cpp', + 'GraphPortModule.cpp', + 'GraphTreeWindow.cpp', + 'GraphView.cpp', + 'GraphWindow.cpp', + 'LoadGraphWindow.cpp', + 'LoadPluginWindow.cpp', + 'MessagesWindow.cpp', + 'NewSubgraphWindow.cpp', + 'NodeMenu.cpp', + 'NodeModule.cpp', + 'ObjectMenu.cpp', + 'PluginMenu.cpp', + 'Port.cpp', + 'PortMenu.cpp', + 'PropertiesWindow.cpp', + 'RDFS.cpp', + 'RenameWindow.cpp', + 'Style.cpp', + 'SubgraphModule.cpp', + 'ThreadedLoader.cpp', + 'URIEntry.cpp', + 'WidgetFactory.cpp', + 'WindowFactory.cpp', + 'ingen_gui.cpp', + ) + + gui_dependencies = [ + boost_dep, + ganv_dep, + glibmm_dep, + gthread_dep, + gtkmm_dep, + ingen_client_dep, + ingen_dep, + lilv_dep, + raul_dep, + sigcpp_dep, + suil_dep, + thread_dep, + webkit_dep, + ] + + gui_suppressions = [] + if cpp.get_id() == 'clang' + gui_suppressions += [ + '-Wno-reserved-identifier', # Ganv + ] + endif + + gui_suppressions = cpp.get_supported_arguments(gui_suppressions) + gui_suppressions += cpp_suppressions + + gui_args = gui_suppressions + gui_defines + ['-DINGEN_GUI_INTERNAL'] + + libingen_gui = shared_library( + 'ingen_gui', + gui_sources, + cpp_args: gui_args, + dependencies: gui_dependencies, + gnu_symbol_visibility: 'hidden', + implicit_include_directories: false, + include_directories: ingen_include_dirs, + install: true, + install_dir: ingen_module_dir, + ) + + ingen_gui_dep = declare_dependency( + dependencies: gui_dependencies, + link_with: libingen_gui, + ) + + ########## + # LV2 UI # + ########## + + ingen_gui_lv2 = shared_library( + 'ingen_gui_lv2', + files('ingen_gui_lv2.cpp'), + cpp_args: gui_args, + dependencies: [ingen_gui_dep], + gnu_symbol_visibility: 'hidden', + implicit_include_directories: false, + include_directories: ingen_include_dirs, + install: true, + install_dir: lv2dir / 'ingen.lv2', + ) + + ############### + # Shared Data # + ############### + + config = configuration_data() + config.set('INGEN_VERSION', meson.project_version()) + + configure_file( + configuration: config, + input: files('ingen_gui.ui.in'), + install: true, + install_dir: ingen_data_dir, + output: 'ingen_gui.ui', + ) + + configure_file( + copy: true, + input: files('ingen_style.rc'), + install: true, + install_dir: ingen_data_dir, + output: '@PLAINNAME@', + ) +endif diff --git a/src/gui/rgba.hpp b/src/gui/rgba.hpp index f31e958c..e01a069d 100644 --- a/src/gui/rgba.hpp +++ b/src/gui/rgba.hpp @@ -18,31 +18,31 @@ #define INGEN_GUI_RGBA_HPP #include <cmath> +#include <cstdint> -namespace ingen { -namespace gui { +namespace ingen::gui { -static inline uint32_t +inline uint32_t rgba_to_uint(uint8_t r, uint8_t g, uint8_t b, uint8_t a) { - return ((((uint32_t)(r)) << 24) | - (((uint32_t)(g)) << 16) | - (((uint32_t)(b)) << 8) | - (((uint32_t)(a)))); + return ((static_cast<uint32_t>(r) << 24) | + (static_cast<uint32_t>(g) << 16) | + (static_cast<uint32_t>(b) << 8) | + (static_cast<uint32_t>(a))); } -static inline uint8_t +inline uint8_t mono_interpolate(uint8_t v1, uint8_t v2, float f) { - return ((int)rint((v2) * (f) + (v1) * (1 - (f)))); + return static_cast<uint8_t>(rintf((v2 * f) + (v1 * (1.0f - f)))); } -#define RGBA_R(x) (((uint32_t)(x)) >> 24) -#define RGBA_G(x) ((((uint32_t)(x)) >> 16) & 0xFF) -#define RGBA_B(x) ((((uint32_t)(x)) >> 8) & 0xFF) -#define RGBA_A(x) (((uint32_t)(x)) & 0xFF) +#define RGBA_R(x) (static_cast<uint32_t>(x) >> 24) +#define RGBA_G(x) ((static_cast<uint32_t>(x) >> 16) & 0xFF) +#define RGBA_B(x) ((static_cast<uint32_t>(x) >> 8) & 0xFF) +#define RGBA_A(x) (static_cast<uint32_t>(x) & 0xFF) -static inline uint32_t +inline uint32_t rgba_interpolate(uint32_t c1, uint32_t c2, float f) { return rgba_to_uint( @@ -52,7 +52,6 @@ rgba_interpolate(uint32_t c1, uint32_t c2, float f) mono_interpolate(RGBA_A(c1), RGBA_A(c2), f)); } -} // namespace gui -} // namespace ingen +} // namespace ingen::gui #endif // INGEN_GUI_RGBA_HPP diff --git a/src/gui/wscript b/src/gui/wscript deleted file mode 100644 index b33bd31e..00000000 --- a/src/gui/wscript +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/env python - -import waflib.Utils as Utils -import waflib.Options as Options - - -def options(ctx): - opt = ctx.configuration_options() - opt.add_option('--light-theme', action='store_true', dest='light_theme', - help='use light coloured theme') - - -def configure(conf): - conf.check_pkg('glibmm-2.4 >= 2.14.0', - uselib_store='GLIBMM', - system=True, - mandatory=False) - conf.check_pkg('gthread-2.0 >= 2.14.0', - uselib_store='GTHREAD', - system=True, - mandatory=False) - conf.check_pkg('gtkmm-2.4 >= 2.14.0', - uselib_store='GTKMM', - system=True, - mandatory=False) - conf.check_pkg('ganv-1 >= 1.5.4', - uselib_store='GANV', - mandatory=False) - if not Options.options.no_webkit: - conf.check_pkg('webkit-1.0 >= 1.4.0', - uselib_store='WEBKIT', - system=True, - mandatory=False) - - if conf.env.HAVE_GANV and conf.env.HAVE_GTKMM: - conf.env.INGEN_BUILD_GUI = 1 - - if Options.options.light_theme: - conf.define('INGEN_USE_LIGHT_THEME', 1) - - -def build(bld): - obj = bld(features = 'cxx cxxshlib', - cflags = ['-fvisibility=hidden'], - export_includes = ['../..'], - includes = ['../..'], - name = 'libingen_gui', - target = 'ingen_gui', - install_path = '${LIBDIR}', - use = 'libingen libingen_client', - uselib = ''' - GANV - GLADEMM - GLIBMM - GNOMECANVAS - GTKMM - LILV - LV2 - RAUL - SIGCPP - SERD - SORD - SRATOM - SOUP - SUIL - WEBKIT - ''') - - obj.source = ''' - App.cpp - Arc.cpp - BreadCrumbs.cpp - ConnectWindow.cpp - GraphBox.cpp - GraphCanvas.cpp - GraphPortModule.cpp - GraphTreeWindow.cpp - GraphView.cpp - GraphWindow.cpp - LoadGraphWindow.cpp - LoadPluginWindow.cpp - MessagesWindow.cpp - NewSubgraphWindow.cpp - NodeMenu.cpp - NodeModule.cpp - ObjectMenu.cpp - PluginMenu.cpp - Port.cpp - PortMenu.cpp - PropertiesWindow.cpp - RDFS.cpp - RenameWindow.cpp - Style.cpp - SubgraphModule.cpp - ThreadedLoader.cpp - URIEntry.cpp - WidgetFactory.cpp - WindowFactory.cpp - ingen_gui.cpp - ''' - - # XML UI definition - bld(features = 'subst', - source = 'ingen_gui.ui', - target = '../../ingen_gui.ui', - install_path = '${DATADIR}/ingen', - chmod = Utils.O755, - INGEN_VERSION = bld.env.INGEN_VERSION) - - # Gtk style - bld(features = 'subst', - is_copy = True, - source = 'ingen_style.rc', - target = '../../ingen_style.rc', - install_path = '${DATADIR}/ingen', - chmod = Utils.O755) - - # LV2 UI - obj = bld(features = 'cxx cxxshlib', - cflags = ['-fvisibility=hidden'], - source = 'ingen_gui_lv2.cpp', - includes = ['.', '../..'], - name = 'ingen_gui_lv2', - target = 'ingen_gui_lv2', - install_path = '${LV2DIR}/ingen.lv2/', - use = 'libingen libingen_gui', - uselib = 'LV2 SERD SORD SRATOM LILV RAUL GLIBMM GTKMM') |