From 682a43546becbc86a210003846778ebb0c38718a Mon Sep 17 00:00:00 2001 From: David Robillard Date: Mon, 2 Oct 2006 20:56:28 +0000 Subject: boost::shared_ptr-ification of FlowCanvas. Extreme performance enhancements in Patchage (eg don't redraw the whole canvas every time). Patchage work towards being a control centre. Broken commit (ingen doesn't even compile) for machine transfer, don't even bother trying this revision. git-svn-id: http://svn.drobilla.net/lad/patchage@147 a436a847-0d15-0410-975c-d299462d15a1 --- src/Patchage.cpp | 231 +++++++++++++++++++++++++++---------------------------- 1 file changed, 114 insertions(+), 117 deletions(-) (limited to 'src/Patchage.cpp') diff --git a/src/Patchage.cpp b/src/Patchage.cpp index d6e3a55..0a37e58 100644 --- a/src/Patchage.cpp +++ b/src/Patchage.cpp @@ -1,11 +1,11 @@ -/* This file is part of Patchage. Copyright (C) 2005 Dave Robillard. +/* This file is part of Patchage. Copyright (C) 2006 Dave Robillard. * - * Om is free software; you can redistribute it and/or modify it under the + * Patchage 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. * - * Om is distributed in the hope that it will be useful, but WITHOUT ANY + * Patchage 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. * @@ -58,7 +58,7 @@ Patchage::Patchage(int argc, char** argv) m_lash_driver = new LashDriver(this, argc, argv); #endif - Glib::RefPtr refXml; + Glib::RefPtr xml; // Check for the .glade file in current directory string glade_filename = "./patchage.glade"; @@ -77,57 +77,59 @@ Patchage::Patchage(int argc, char** argv) } try { - refXml = Gnome::Glade::Xml::create(glade_filename); + xml = Gnome::Glade::Xml::create(glade_filename); } catch(const Gnome::Glade::XmlError& ex) { std::cerr << ex.what() << std::endl; throw; } - refXml->get_widget("patchage_win", m_main_window); - refXml->get_widget("about_win", m_about_window); - refXml->get_widget("about_project_label", m_about_project_label); - refXml->get_widget("launch_jack_menuitem", m_menu_jack_launch); - refXml->get_widget("connect_to_jack_menuitem", m_menu_jack_connect); - refXml->get_widget("disconnect_from_jack_menuitem", m_menu_jack_disconnect); + xml->get_widget("patchage_win", m_main_window); + xml->get_widget("about_win", m_about_window); + xml->get_widget("launch_jack_menuitem", m_menu_jack_launch); + xml->get_widget("connect_to_jack_menuitem", m_menu_jack_connect); + xml->get_widget("disconnect_from_jack_menuitem", m_menu_jack_disconnect); #ifdef HAVE_LASH - refXml->get_widget("launch_lash_menuitem", m_menu_lash_launch); - refXml->get_widget("connect_to_lash_menuitem", m_menu_lash_connect); - refXml->get_widget("disconnect_from_lash_menuitem", m_menu_lash_disconnect); + xml->get_widget("launch_lash_menuitem", m_menu_lash_launch); + xml->get_widget("connect_to_lash_menuitem", m_menu_lash_connect); + xml->get_widget("disconnect_from_lash_menuitem", m_menu_lash_disconnect); #endif #ifdef HAVE_ALSA - refXml->get_widget("connect_to_alsa_menuitem", m_menu_alsa_connect); - refXml->get_widget("disconnect_from_alsa_menuitem", m_menu_alsa_disconnect); + xml->get_widget("connect_to_alsa_menuitem", m_menu_alsa_connect); + xml->get_widget("disconnect_from_alsa_menuitem", m_menu_alsa_disconnect); #endif - refXml->get_widget("file_save_menuitem", m_menu_file_save); - refXml->get_widget("file_quit_menuitem", m_menu_file_quit); - refXml->get_widget("view_refresh_menuitem", m_menu_view_refresh); - refXml->get_widget("help_about_menuitem", m_menu_help_about); - refXml->get_widget("canvas_scrolledwindow", m_canvas_scrolledwindow); - refXml->get_widget("zoom_scale", m_zoom_slider); - refXml->get_widget("about_close_button", m_about_close_button); - refXml->get_widget("status_lab", m_status_label); + xml->get_widget("store_positions_menuitem", m_menu_store_positions); + xml->get_widget("file_quit_menuitem", m_menu_file_quit); + xml->get_widget("view_refresh_menuitem", m_menu_view_refresh); + xml->get_widget("help_about_menuitem", m_menu_help_about); + xml->get_widget("canvas_scrolledwindow", m_canvas_scrolledwindow); + xml->get_widget("zoom_scale", m_zoom_slider); + xml->get_widget("status_text", m_status_text); + xml->get_widget("main_paned", m_main_paned); + xml->get_widget("zoom_full_but", m_zoom_full_button); + xml->get_widget("zoom_normal_but", m_zoom_normal_button); - m_main_window->resize( - static_cast(m_state_manager->get_window_size().x), - static_cast(m_state_manager->get_window_size().y)); - - m_main_window->move( - static_cast(m_state_manager->get_window_location().x), - static_cast(m_state_manager->get_window_location().y)); + update_state(); m_canvas_scrolledwindow->add(*m_canvas); //m_canvas_scrolledwindow->signal_event().connect(sigc::mem_fun(m_canvas, &FlowCanvas::scroll_event_handler)); m_canvas->scroll_to(static_cast(m_canvas->width()/2 - 320), static_cast(m_canvas->height()/2 - 240)); // FIXME: hardcoded - m_canvas->show(); - // Idle callback, check if we need to refresh (every 250msec) - Glib::signal_timeout().connect(sigc::mem_fun(this, &Patchage::idle_callback), 250); + // Idle callback, check if we need to refresh + Glib::signal_timeout().connect(sigc::mem_fun(this, &Patchage::idle_callback), 100); + + m_zoom_slider->signal_value_changed().connect(sigc::mem_fun(this, &Patchage::zoom_changed)); + m_zoom_normal_button->signal_clicked().connect(sigc::bind( + sigc::mem_fun(this, &Patchage::zoom), 1.0)); + + m_menu_jack_launch->signal_activate().connect(sigc::bind( + sigc::mem_fun(m_jack_driver, &JackDriver::attach), true)); + + m_menu_jack_connect->signal_activate().connect(sigc::bind( + sigc::mem_fun(m_jack_driver, &JackDriver::attach), false)); - m_zoom_slider->signal_value_changed().connect( sigc::mem_fun(this, &Patchage::zoom_changed)); - m_menu_jack_launch->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_jack_launch)); - m_menu_jack_connect->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_jack_connect)); - m_menu_jack_disconnect->signal_activate().connect(sigc::mem_fun(this, &Patchage::menu_jack_disconnect)); + m_menu_jack_disconnect->signal_activate().connect(sigc::mem_fun(m_jack_driver, &JackDriver::detach)); + #ifdef HAVE_LASH m_menu_lash_launch->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_lash_launch)); m_menu_lash_connect->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_lash_connect)); @@ -135,26 +137,29 @@ Patchage::Patchage(int argc, char** argv) #endif m_menu_alsa_connect->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_alsa_connect)); m_menu_alsa_disconnect->signal_activate().connect(sigc::mem_fun(this, &Patchage::menu_alsa_disconnect)); - m_menu_file_save->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_file_save)); + m_menu_store_positions->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_store_positions)); m_menu_file_quit->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_file_quit)); m_menu_view_refresh->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_view_refresh)); m_menu_help_about->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_help_about)); - m_about_close_button->signal_clicked().connect( sigc::mem_fun(this, &Patchage::close_about)); - //_about_project_label->use_markup(true); - m_about_project_label->set_markup("Patchage " PACKAGE_VERSION ""); + attach_menu_items(); + m_main_paned->set_position(m_main_paned->get_height() - 20); + + m_canvas->show(); } Patchage::~Patchage() { + delete m_jack_driver; +#ifdef HAVE_ALSA + delete m_alsa_driver; +#endif #ifdef HAVE_LASH delete m_lash_driver; #endif - delete m_jack_driver; - delete m_alsa_driver; - delete m_canvas; delete m_state_manager; + delete m_canvas; } @@ -170,7 +175,6 @@ Patchage::attach() m_alsa_driver->attach(); #endif - update_menu_items(); menu_view_refresh(); } @@ -178,19 +182,20 @@ Patchage::attach() bool Patchage::idle_callback() { - // FIXME: no need to destroy the whole canvas every time - if (m_refresh || (m_jack_driver && m_jack_driver->is_dirty()) + bool refresh = m_refresh; + + refresh = refresh || (m_jack_driver && m_jack_driver->is_dirty()); #ifdef HAVE_ALSA - || (m_alsa_driver && m_alsa_driver->is_dirty()) + refresh = refresh || (m_alsa_driver && m_alsa_driver->is_dirty()); #endif - ) { - m_canvas->destroy(); + + if (refresh) { + m_canvas->flag_all_connections(); + m_jack_driver->refresh(); #ifdef HAVE_ALSA m_alsa_driver->refresh(); #endif - update_menu_items(); - m_refresh = false; } #ifdef HAVE_LASH @@ -198,20 +203,30 @@ Patchage::idle_callback() m_lash_driver->process_events(); #endif + if (refresh) { + m_canvas->destroy_all_flagged_connections(); + m_refresh = false; + } + return true; } void -Patchage::zoom_changed() +Patchage::zoom(double z) { - const double z = m_zoom_slider->get_value(); - m_canvas->set_zoom(z); m_state_manager->set_zoom(z); } +void +Patchage::zoom_changed() +{ + zoom(m_zoom_slider->get_value()); +} + + void Patchage::update_state() { @@ -236,10 +251,12 @@ Patchage::update_state() void Patchage::status_message(const string& msg) { - m_status_label->set_text(msg); -} - + if (m_status_text->get_buffer()->size() > 0) + m_status_text->get_buffer()->insert(m_status_text->get_buffer()->end(), "\n"); + m_status_text->get_buffer()->insert(m_status_text->get_buffer()->end(), msg); + m_status_text->scroll_to_mark(m_status_text->get_buffer()->get_insert(), 0); +} /** Update the sensitivity status of menus to reflect the present. @@ -247,61 +264,53 @@ Patchage::status_message(const string& msg) * (eg. disable "Connect to Jack" when Patchage is already connected to Jack) */ void -Patchage::update_menu_items() +Patchage::attach_menu_items() { - // Update Jack menu items - const bool jack_attached = m_jack_driver->is_attached(); - m_menu_jack_launch->set_sensitive(!jack_attached); - m_menu_jack_connect->set_sensitive(!jack_attached); - m_menu_jack_disconnect->set_sensitive(jack_attached); + m_lash_driver->signal_attached.connect(sigc::bind( + sigc::mem_fun(m_menu_lash_launch, &Gtk::MenuItem::set_sensitive), false)); + m_lash_driver->signal_attached.connect(sigc::bind( + sigc::mem_fun(m_menu_lash_connect, &Gtk::MenuItem::set_sensitive), false)); + m_lash_driver->signal_attached.connect(sigc::bind( + sigc::mem_fun(m_menu_lash_disconnect, &Gtk::MenuItem::set_sensitive), true)); - // Update Lash menu items -#ifdef HAVE_LASH - const bool lash_attached = m_lash_driver->is_attached(); - m_menu_lash_launch->set_sensitive(!lash_attached); - m_menu_lash_connect->set_sensitive(!lash_attached); - m_menu_lash_disconnect->set_sensitive(lash_attached); -#endif - -#ifdef HAVE_ALSA - // Update Alsa menu items - const bool alsa_attached = m_alsa_driver->is_attached(); - m_menu_alsa_connect->set_sensitive(!alsa_attached); - m_menu_alsa_disconnect->set_sensitive(alsa_attached); -#endif -} - - -void -Patchage::menu_jack_launch() -{ - m_jack_driver->attach(true); - update_menu_items(); -} - - -void -Patchage::menu_jack_connect() -{ - m_jack_driver->attach(false); - update_menu_items(); + m_lash_driver->signal_detached.connect(sigc::bind( + sigc::mem_fun(m_menu_lash_launch, &Gtk::MenuItem::set_sensitive), true)); + m_lash_driver->signal_detached.connect(sigc::bind( + sigc::mem_fun(m_menu_lash_connect, &Gtk::MenuItem::set_sensitive), true)); + m_lash_driver->signal_detached.connect(sigc::bind( + sigc::mem_fun(m_menu_lash_disconnect, &Gtk::MenuItem::set_sensitive), false)); + + m_jack_driver->signal_attached.connect(sigc::bind( + sigc::mem_fun(m_menu_jack_launch, &Gtk::MenuItem::set_sensitive), false)); + m_jack_driver->signal_attached.connect(sigc::bind( + sigc::mem_fun(m_menu_jack_connect, &Gtk::MenuItem::set_sensitive), false)); + m_jack_driver->signal_attached.connect(sigc::bind( + sigc::mem_fun(m_menu_jack_disconnect, &Gtk::MenuItem::set_sensitive), true)); + + m_jack_driver->signal_detached.connect(sigc::bind( + sigc::mem_fun(m_menu_jack_launch, &Gtk::MenuItem::set_sensitive), true)); + m_jack_driver->signal_detached.connect(sigc::bind( + sigc::mem_fun(m_menu_jack_connect, &Gtk::MenuItem::set_sensitive), true)); + m_jack_driver->signal_detached.connect(sigc::bind( + sigc::mem_fun(m_menu_jack_disconnect, &Gtk::MenuItem::set_sensitive), false)); + + m_alsa_driver->signal_attached.connect(sigc::bind( + sigc::mem_fun(m_menu_alsa_connect, &Gtk::MenuItem::set_sensitive), false)); + m_alsa_driver->signal_attached.connect(sigc::bind( + sigc::mem_fun(m_menu_alsa_disconnect, &Gtk::MenuItem::set_sensitive), true)); + + m_alsa_driver->signal_detached.connect(sigc::bind( + sigc::mem_fun(m_menu_alsa_connect, &Gtk::MenuItem::set_sensitive), true)); + m_alsa_driver->signal_detached.connect(sigc::bind( + sigc::mem_fun(m_menu_alsa_disconnect, &Gtk::MenuItem::set_sensitive), false)); } -void -Patchage::menu_jack_disconnect() -{ - m_jack_driver->detach(); - menu_view_refresh(); - update_menu_items(); -} - #ifdef HAVE_LASH void Patchage::menu_lash_launch() { m_lash_driver->attach(true); - update_menu_items(); } @@ -309,7 +318,6 @@ void Patchage::menu_lash_connect() { m_lash_driver->attach(false); - update_menu_items(); } @@ -317,7 +325,6 @@ void Patchage::menu_lash_disconnect() { m_lash_driver->detach(); - update_menu_items(); } #endif @@ -326,7 +333,6 @@ void Patchage::menu_alsa_connect() { m_alsa_driver->attach(false); - update_menu_items(); } @@ -335,12 +341,11 @@ Patchage::menu_alsa_disconnect() { m_alsa_driver->detach(); menu_view_refresh(); - update_menu_items(); } #endif void -Patchage::menu_file_save() +Patchage::menu_store_positions() { store_window_location(); m_state_manager->save(m_settings_filename); @@ -363,7 +368,6 @@ Patchage::menu_view_refresh() { assert(m_canvas); - // FIXME: rebuilding the entire canvas each time is garbage m_canvas->destroy(); if (m_jack_driver) @@ -383,13 +387,6 @@ Patchage::menu_help_about() } -void -Patchage::close_about() -{ - m_about_window->hide(); -} - - /** Update the stored window location and size in the StateManager (in memory). */ void -- cgit v1.2.1