diff options
Diffstat (limited to 'src/gui/MachinaGUI.cpp')
-rw-r--r-- | src/gui/MachinaGUI.cpp | 370 |
1 files changed, 370 insertions, 0 deletions
diff --git a/src/gui/MachinaGUI.cpp b/src/gui/MachinaGUI.cpp new file mode 100644 index 0000000..a7602c1 --- /dev/null +++ b/src/gui/MachinaGUI.cpp @@ -0,0 +1,370 @@ +/* This file is part of Machina. + * Copyright (C) 2007 Dave Robillard <http://drobilla.net> + * + * Machina is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Machina is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <cmath> +#include <sstream> +#include <libgnomecanvasmm.h> +#include <libglademm/xml.h> +#include <fstream> +#include <pthread.h> +#include "MachinaGUI.hpp" +#include "MachinaCanvas.hpp" + +//#include "config.h" + +// FIXME: include to avoid undefined reference to boost SP debug hooks stuff +#include <raul/SharedPtr.h> + + + +/* Gtk helpers (resize combo boxes) */ + +#if 0 +static void +gtkmm_get_ink_pixel_size (Glib::RefPtr<Pango::Layout> layout, + int& width, + int& height) +{ + Pango::Rectangle ink_rect = layout->get_ink_extents (); + + width = (ink_rect.get_width() + PANGO_SCALE / 2) / PANGO_SCALE; + height = (ink_rect.get_height() + PANGO_SCALE / 2) / PANGO_SCALE; +} + + +static void +gtkmm_set_width_for_given_text (Gtk::Widget &w, const gchar *text, + gint hpadding/*, gint vpadding*/) + +{ + int old_width, old_height; + w.get_size_request(old_width, old_height); + + int width, height; + w.ensure_style (); + + gtkmm_get_ink_pixel_size (w.create_pango_layout (text), width, height); + w.set_size_request(width + hpadding, old_height);//height + vpadding); +} +#endif +/* end Gtk helpers */ + + + +MachinaGUI::MachinaGUI(/*int argc, char** argv*/) +: _pane_closed(false), + _update_pane_position(true), + _user_pane_position(0), + _refresh(false) +{ + /*_settings_filename = getenv("HOME"); + _settings_filename += "/.machinarc";*/ + + _canvas = boost::shared_ptr<MachinaCanvas>(new MachinaCanvas(this, 1600*2, 1200*2)); + + Glib::RefPtr<Gnome::Glade::Xml> xml; + + // Check for the .glade file in current directory + string glade_filename = "./machina.glade"; + ifstream fs(glade_filename.c_str()); + if (fs.fail()) { // didn't find it, check PKGDATADIR + fs.clear(); + glade_filename = PKGDATADIR; + glade_filename += "/machina.glade"; + + fs.open(glade_filename.c_str()); + if (fs.fail()) { + cerr << "Unable to find machina.glade in current directory or " << PKGDATADIR << "." << endl; + exit(EXIT_FAILURE); + } + fs.close(); + } + + try { + xml = Gnome::Glade::Xml::create(glade_filename); + } catch(const Gnome::Glade::XmlError& ex) { + std::cerr << ex.what() << std::endl; + throw; + } + + xml->get_widget("machina_win", _main_window); + xml->get_widget("about_win", _about_window); + xml->get_widget("file_quit_menuitem", _menu_file_quit); + xml->get_widget("view_refresh_menuitem", _menu_view_refresh); + xml->get_widget("view_messages_menuitem", _menu_view_messages); + xml->get_widget("help_about_menuitem", _menu_help_about); + xml->get_widget("canvas_scrolledwindow", _canvas_scrolledwindow); + xml->get_widget("status_text", _status_text); + xml->get_widget("main_paned", _main_paned); + xml->get_widget("messages_expander", _messages_expander); + xml->get_widget("zoom_full_but", _zoom_full_button); + xml->get_widget("zoom_normal_but", _zoom_normal_button); + + _canvas_scrolledwindow->add(*_canvas); + //m_canvas_scrolledwindow->signal_event().connect(sigc::mem_fun(_canvas, &FlowCanvas::scroll_event_handler)); + _canvas->scroll_to(static_cast<int>(_canvas->width()/2 - 320), + static_cast<int>(_canvas->height()/2 - 240)); // FIXME: hardcoded + + //_zoom_slider->signal_value_changed().connect(sigc::mem_fun(this, &MachinaGUI::zoom_changed)); + + _zoom_normal_button->signal_clicked().connect(sigc::bind( + sigc::mem_fun(this, &MachinaGUI::zoom), 1.0)); + + _zoom_full_button->signal_clicked().connect(sigc::mem_fun(_canvas.get(), &MachinaCanvas::zoom_full)); + + _menu_file_quit->signal_activate().connect( sigc::mem_fun(this, &MachinaGUI::menu_file_quit)); + _menu_view_refresh->signal_activate().connect( sigc::mem_fun(this, &MachinaGUI::menu_view_refresh)); + _menu_view_messages->signal_toggled().connect( sigc::mem_fun(this, &MachinaGUI::show_messages_toggled)); + _menu_help_about->signal_activate().connect( sigc::mem_fun(this, &MachinaGUI::menu_help_about)); + + connect_widgets(); + + //update_state(); + + _canvas->show(); + + _main_window->present(); + + _update_pane_position = false; + _main_paned->set_position(max_pane_position()); + + _main_paned->property_position().signal_changed().connect( + sigc::mem_fun(*this, &MachinaGUI::on_pane_position_changed)); + + _messages_expander->property_expanded().signal_changed().connect( + sigc::mem_fun(*this, &MachinaGUI::on_messages_expander_changed)); + + _main_paned->set_position(max_pane_position()); + _user_pane_position = max_pane_position() - _main_window->get_height()/8; + _update_pane_position = true; + _pane_closed = true; + + // Idle callback, check if we need to refresh + Glib::signal_timeout().connect(sigc::mem_fun(this, &MachinaGUI::idle_callback), 100); + + // Faster idle callback to update DSP load progress bar + //Glib::signal_timeout().connect(sigc::mem_fun(this, &MachinaGUI::update_load), 50); +} + + +MachinaGUI::~MachinaGUI() +{ +} + + +void +MachinaGUI::attach() +{ +#if 0 + _jack_driver->attach(true); + + menu_view_refresh(); + + update_toolbar(); + + //m_status_bar->push("Connected to JACK server"); +#endif +} + + +bool +MachinaGUI::idle_callback() +{ +#if 0 + if (_jack_driver) { + while (!_jack_driver->events().empty()) { + MachinaEvent& ev = _jack_driver->events().front(); + _jack_driver->events().pop(); + ev.execute(); + } + } + + + bool refresh = _refresh; + + refresh = refresh || (_jack_driver && _jack_driver->is_dirty()); + + if (refresh) { + + _canvas->flag_all_connections(); + + _jack_driver->refresh(); + } + + if (refresh) { + _canvas->destroy_all_flagged_connections(); + _refresh = false; + } + + update_load(); +#endif + return true; +} + + +void +MachinaGUI::zoom(double z) +{ + _canvas->set_zoom(z); +} + + +void +MachinaGUI::zoom_changed() +{ +/* + static bool enable_signal = true; + if (enable_signal) { + enable_signal = false; + zoom(_zoom_slider->get_value()); + enable_signal = true; + } + */ +} + + +#if 0 +void +MachinaGUI::update_state() +{ + for (ModuleMap::iterator i = _canvas->modules().begin(); i != _canvas->modules().end(); ++i) + (*i).second->load_location(); + + //cerr << "[Machina] Resizing window: (" << _state_manager->get_window_size().x + // << "," << _state_manager->get_window_size().y << ")" << endl; + + _main_window->resize( + static_cast<int>(_state_manager->get_window_size().x), + static_cast<int>(_state_manager->get_window_size().y)); + + //cerr << "[Machina] Moving window: (" << _state_manager->get_window_location().x + // << "," << _state_manager->get_window_location().y << ")" << endl; + + _main_window->move( + static_cast<int>(_state_manager->get_window_location().x), + static_cast<int>(_state_manager->get_window_location().y)); + +} + +#endif + + +void +MachinaGUI::status_message(const string& msg) +{ + if (_status_text->get_buffer()->size() > 0) + _status_text->get_buffer()->insert(_status_text->get_buffer()->end(), "\n"); + + _status_text->get_buffer()->insert(_status_text->get_buffer()->end(), msg); + _status_text->scroll_to_mark(_status_text->get_buffer()->get_insert(), 0); +} + + +/** Update the sensitivity status of menus to reflect the present. + * + * (eg. disable "Connect to Jack" when Machina is already connected to Jack) + */ +void +MachinaGUI::connect_widgets() +{ + +} + + +void +MachinaGUI::menu_file_quit() +{ + _main_window->hide(); +} + + +void +MachinaGUI::on_pane_position_changed() +{ + // avoid infinite recursion... + if (!_update_pane_position) + return; + + _update_pane_position = false; + + int new_position = _main_paned->get_position(); + + if (_pane_closed && new_position < max_pane_position()) { + // Auto open + _user_pane_position = new_position; + _messages_expander->set_expanded(true); + _pane_closed = false; + _menu_view_messages->set_active(true); + } else if (new_position >= max_pane_position()) { + // Auto close + _pane_closed = true; + + _messages_expander->set_expanded(false); + if (new_position > max_pane_position()) + _main_paned->set_position(max_pane_position()); // ... here + _menu_view_messages->set_active(false); + + _user_pane_position = max_pane_position() - _main_window->get_height()/8; + } + + _update_pane_position = true; +} + + +void +MachinaGUI::on_messages_expander_changed() +{ + if (!_pane_closed) { + // Store pane position for restoring + _user_pane_position = _main_paned->get_position(); + if (_update_pane_position) { + _update_pane_position = false; + _main_paned->set_position(max_pane_position()); + _update_pane_position = true; + } + _pane_closed = true; + } else { + _main_paned->set_position(_user_pane_position); + _pane_closed = false; + } +} + + +void +MachinaGUI::show_messages_toggled() +{ + if (_update_pane_position) + _messages_expander->set_expanded(_menu_view_messages->get_active()); +} + + +void +MachinaGUI::menu_view_refresh() +{ + assert(_canvas); + + //_canvas->destroy(); +} + + +void +MachinaGUI::menu_help_about() +{ + _about_window->show(); +} + + |