summaryrefslogtreecommitdiffstats
path: root/src/gui/WindowFactory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/WindowFactory.cpp')
-rw-r--r--src/gui/WindowFactory.cpp302
1 files changed, 302 insertions, 0 deletions
diff --git a/src/gui/WindowFactory.cpp b/src/gui/WindowFactory.cpp
new file mode 100644
index 00000000..06c8266a
--- /dev/null
+++ b/src/gui/WindowFactory.cpp
@@ -0,0 +1,302 @@
+/*
+ This file is part of Ingen.
+ Copyright 2007-2015 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
+ Software Foundation, either version 3 of the License, or any later version.
+
+ Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Ingen. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdexcept>
+#include <string>
+
+#include "ingen/Log.hpp"
+#include "ingen/client/GraphModel.hpp"
+
+#include "App.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"
+
+namespace ingen {
+
+using namespace client;
+
+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);
+ WidgetFactory::get_widget_derived("new_subgraph_win", _new_subgraph_win);
+ WidgetFactory::get_widget_derived("properties_win", _properties_win);
+ WidgetFactory::get_widget_derived("rename_win", _rename_win);
+
+ if (!(_load_plugin_win && _load_graph_win && _new_subgraph_win
+ && _properties_win && _rename_win)) {
+ throw std::runtime_error("failed to load window widgets\n");
+ }
+
+ _load_plugin_win->init_window(app);
+ _load_graph_win->init(app);
+ _new_subgraph_win->init_window(app);
+ _properties_win->init_window(app);
+ _rename_win->init_window(app);
+}
+
+WindowFactory::~WindowFactory()
+{
+ for (const auto& w : _graph_windows) {
+ delete w.second;
+ }
+}
+
+void
+WindowFactory::clear()
+{
+ for (const auto& w : _graph_windows) {
+ delete w.second;
+ }
+
+ _graph_windows.clear();
+}
+
+/** Returns the number of Graph windows currently visible.
+ */
+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;
+}
+
+GraphBox*
+WindowFactory::graph_box(SPtr<const GraphModel> graph)
+{
+ GraphWindow* window = graph_window(graph);
+ if (window) {
+ return window->box();
+ } else {
+ return _main_box;
+ }
+}
+
+GraphWindow*
+WindowFactory::graph_window(SPtr<const GraphModel> graph)
+{
+ if (!graph) {
+ return nullptr;
+ }
+
+ auto w = _graph_windows.find(graph->path());
+
+ return (w == _graph_windows.end()) ? nullptr : w->second;
+}
+
+GraphWindow*
+WindowFactory::parent_graph_window(SPtr<const BlockModel> block)
+{
+ if (!block) {
+ return nullptr;
+ }
+
+ return graph_window(dynamic_ptr_cast<GraphModel>(block->parent()));
+}
+
+/** Present a GraphWindow for a Graph.
+ *
+ * If `preferred` is not null, it will be set to display `graph` if the graph
+ * does not already have a visible window, otherwise that window will be
+ * presented and `preferred` left unmodified.
+ */
+void
+WindowFactory::present_graph(SPtr<const GraphModel> graph,
+ GraphWindow* preferred,
+ SPtr<GraphView> view)
+{
+ assert(!view || view->graph() == graph);
+
+ auto w = _graph_windows.find(graph->path());
+
+ if (w != _graph_windows.end()) {
+ (*w).second->present();
+ } else if (preferred) {
+ w = _graph_windows.find(preferred->graph()->path());
+ assert((*w).second == preferred);
+
+ preferred->box()->set_graph(graph, view);
+ _graph_windows.erase(w);
+ _graph_windows[graph->path()] = preferred;
+ preferred->present();
+
+ } else {
+ GraphWindow* win = new_graph_window(graph, view);
+ win->present();
+ }
+}
+
+GraphWindow*
+WindowFactory::new_graph_window(SPtr<const GraphModel> graph,
+ SPtr<GraphView> view)
+{
+ assert(!view || view->graph() == graph);
+
+ GraphWindow* win = nullptr;
+ WidgetFactory::get_widget_derived("graph_win", win);
+ if (!win) {
+ _app.log().error("Failed to load graph window widget\n");
+ return nullptr;
+ }
+
+ win->init_window(_app);
+
+ win->box()->set_graph(graph, view);
+ _graph_windows[graph->path()] = win;
+
+ win->signal_delete_event().connect(
+ sigc::bind<0>(sigc::mem_fun(this, &WindowFactory::remove_graph_window),
+ win));
+
+ return win;
+}
+
+bool
+WindowFactory::remove_graph_window(GraphWindow* win, GdkEventAny* ignored)
+{
+ if (_graph_windows.size() <= 1) {
+ return !_app.quit(win);
+ }
+
+ auto w = _graph_windows.find(win->graph()->path());
+
+ assert((*w).second == win);
+ _graph_windows.erase(w);
+
+ delete win;
+
+ return false;
+}
+
+void
+WindowFactory::present_load_plugin(SPtr<const GraphModel> graph,
+ Properties data)
+{
+ _app.request_plugins_if_necessary();
+
+ auto w = _graph_windows.find(graph->path());
+
+ if (w != _graph_windows.end()) {
+ _load_plugin_win->set_transient_for(*w->second);
+ }
+
+ _load_plugin_win->set_modal(false);
+ _load_plugin_win->set_type_hint(Gdk::WINDOW_TYPE_HINT_DIALOG);
+ if (w->second) {
+ int width, height;
+ w->second->get_size(width, height);
+ _load_plugin_win->set_default_size(width - width / 8, height / 2);
+ }
+ _load_plugin_win->set_title(
+ std::string("Load Plugin - ") + graph->path() + " - Ingen");
+ _load_plugin_win->present(graph, data);
+}
+
+void
+WindowFactory::present_load_graph(SPtr<const GraphModel> graph,
+ Properties data)
+{
+ auto w = _graph_windows.find(graph->path());
+
+ if (w != _graph_windows.end()) {
+ _load_graph_win->set_transient_for(*w->second);
+ }
+
+ _load_graph_win->present(graph, true, data);
+}
+
+void
+WindowFactory::present_load_subgraph(SPtr<const GraphModel> graph,
+ Properties data)
+{
+ auto w = _graph_windows.find(graph->path());
+
+ if (w != _graph_windows.end()) {
+ _load_graph_win->set_transient_for(*w->second);
+ }
+
+ _load_graph_win->present(graph, false, data);
+}
+
+void
+WindowFactory::present_new_subgraph(SPtr<const GraphModel> graph,
+ Properties data)
+{
+ auto w = _graph_windows.find(graph->path());
+
+ if (w != _graph_windows.end()) {
+ _new_subgraph_win->set_transient_for(*w->second);
+ }
+
+ _new_subgraph_win->present(graph, data);
+}
+
+void
+WindowFactory::present_rename(SPtr<const ObjectModel> object)
+{
+ auto w = _graph_windows.find(object->path());
+ if (w == _graph_windows.end()) {
+ w = _graph_windows.find(object->path().parent());
+ }
+
+ if (w != _graph_windows.end()) {
+ _rename_win->set_transient_for(*w->second);
+ }
+
+ _rename_win->present(object);
+}
+
+void
+WindowFactory::present_properties(SPtr<const ObjectModel> object)
+{
+ auto w = _graph_windows.find(object->path());
+ if (w == _graph_windows.end()) {
+ w = _graph_windows.find(object->path().parent());
+ }
+ if (w == _graph_windows.end()) {
+ w = _graph_windows.find(object->path().parent().parent());
+ }
+
+ if (w != _graph_windows.end()) {
+ _properties_win->set_transient_for(*w->second);
+ }
+
+ _properties_win->present(object);
+}
+
+} // namespace gui
+} // namespace ingen