Logo Search packages:      
Sourcecode: patchage version File versions  Download package

Patchage.cpp

/* This file is part of Patchage.  Copyright (C) 2005 Dave Robillard.
 * 
 * Om 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
 * 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.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "Patchage.h"
#include "config.h"
#include <libgnomecanvasmm.h>
#include <libglademm/xml.h>
#include <fstream>
#include <pthread.h>

Patchage::Patchage(int argc, char** argv)
: m_refresh(false)
{
#ifdef HAVE_LASH
      m_lash_controller = new LashController(this, argc, argv);
#endif
      m_settings_filename = getenv("HOME");
      m_settings_filename += "/.patchagerc";

      pthread_mutex_init(&m_refresh_mutex, NULL);
      
      pthread_mutex_lock(&m_refresh_mutex);

      m_state_manager = new StateManager();
      m_patch_bay = new PatchagePatchBayArea(this, 1600*2, 1200*2);
      m_jack_driver = new JackDriver(this, &m_refresh_mutex);
      m_alsa_driver = new AlsaDriver(this, &m_refresh_mutex);
      

      m_state_manager->load(m_settings_filename);

      Glib::RefPtr<Gnome::Glade::Xml> refXml;

      // Check for the .glade file in current directory
      string glade_filename = "./patchage.glade";
      ifstream fs(glade_filename.c_str());
      if (fs.fail()) { // didn't find it, check PKGDATADIR
            fs.clear();
            glade_filename = PKGDATADIR;
            glade_filename += "/patchage.glade";
      
            fs.open(glade_filename.c_str());
            if (fs.fail()) {
                  cerr << "Unable to find patchage.glade in current directory or " << PKGDATADIR << "." << endl;
                  exit(EXIT_FAILURE);
            }
            fs.close();
      }
      
      try {
            refXml = 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("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);
      
      m_main_window->resize(
            static_cast<int>(m_state_manager->get_window_size().x),
            static_cast<int>(m_state_manager->get_window_size().y));
      
      m_main_window->move(
            static_cast<int>(m_state_manager->get_window_location().x),
            static_cast<int>(m_state_manager->get_window_location().y));

      m_canvas_scrolledwindow->add(*m_patch_bay);
      //m_canvas_scrolledwindow->signal_event().connect(sigc::mem_fun(m_patch_bay, &PatchBayArea::scroll_event_handler));
      m_patch_bay->scroll_to(static_cast<int>(m_patch_bay->width()/2 - 320),
                             static_cast<int>(m_patch_bay->height()/2 - 240)); // FIXME: hardcoded
      m_patch_bay->show();

      // Idle callback, check if we need to refresh (every 250msec)
      Glib::signal_timeout().connect(sigc::mem_fun(this, &Patchage::idle_callback), 250);
      
      m_zoom_slider->signal_value_changed().connect(  sigc::mem_fun(this, &Patchage::zoom_changed));
      m_menu_file_save->signal_activate().connect(    sigc::mem_fun(this, &Patchage::menu_file_save));
      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("<span size=\"xx-large\" weight=\"bold\">Patchage " PACKAGE_VERSION "</span>");
      pthread_mutex_unlock(&m_refresh_mutex);
}


Patchage::~Patchage() 
{
#ifdef HAVE_LASH
      //m_lash_controller->stop_thread();
      delete m_lash_controller;
#endif
      delete m_jack_driver;
      delete m_alsa_driver;
      delete m_patch_bay;
      delete m_state_manager;
      
      pthread_mutex_destroy(&m_refresh_mutex);
}

      
bool
Patchage::idle_callback() 
{
      if (!pthread_mutex_trylock(&m_refresh_mutex)) {
            if (m_refresh) {
                  m_refresh = false;
                  m_jack_driver->refresh();
                  m_alsa_driver->refresh();
            }
            pthread_mutex_unlock(&m_refresh_mutex);
      }

#ifdef HAVE_LASH
      if (m_lash_controller->enabled())
            m_lash_controller->process_events();
#endif

      return true;
}


void
Patchage::zoom_changed() 
{
      pthread_mutex_lock(&m_refresh_mutex);
      float z = m_zoom_slider->get_value();
      
      m_patch_bay->zoom(z);
      m_state_manager->set_zoom(z);

      pthread_mutex_unlock(&m_refresh_mutex);
}


void
Patchage::update_state()
{
      for (ModuleMap::iterator i = m_patch_bay->modules().begin(); i != m_patch_bay->modules().end(); ++i)
            (*i).second->load_location();

      cerr << "******* Resizing window: (" << m_state_manager->get_window_size().x
            << "," << m_state_manager->get_window_size().y << ")" << endl;

      m_main_window->resize(
            static_cast<int>(m_state_manager->get_window_size().x),
            static_cast<int>(m_state_manager->get_window_size().y));
      
      cerr << "******* Moving window: (" << m_state_manager->get_window_location().x
            << "," << m_state_manager->get_window_location().y << ")" << endl;
      m_main_window->move(
            static_cast<int>(m_state_manager->get_window_location().x),
            static_cast<int>(m_state_manager->get_window_location().y));
}


void
Patchage::status_message(const string& msg) 
{
      m_status_label->set_text(msg);
}


void
Patchage::menu_file_save() 
{
      store_window_location();
      m_state_manager->save(m_settings_filename);
}


void
Patchage::menu_file_quit() 
{
      m_alsa_driver->detach();
      m_jack_driver->detach();
      m_main_window->hide();
}


void
Patchage::menu_view_refresh() 
{
      pthread_mutex_lock(&m_refresh_mutex);
      m_jack_driver->refresh();
      m_alsa_driver->refresh();
      pthread_mutex_unlock(&m_refresh_mutex);
}


void
Patchage::menu_help_about() 
{
      m_about_window->show();
}


void
Patchage::close_about() 
{
      m_about_window->hide();
}


/** Update the stored window location and size in the StateManager (in memory).
 */
void
Patchage::store_window_location()
{
      int loc_x, loc_y, size_x, size_y;
      m_main_window->get_position(loc_x, loc_y);
      m_main_window->get_size(size_x, size_y);
      Coord window_location;
      window_location.x = loc_x;
      window_location.y = loc_y;
      Coord window_size;
      window_size.x = size_x;
      window_size.y = size_y;
      m_state_manager->set_window_location(window_location);
      m_state_manager->set_window_size(window_size);
}



Generated by  Doxygen 1.6.0   Back to index