diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2008-09-17 12:56:00 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2008-09-17 12:56:00 +0000 |
commit | b5a57cc78c92b1d887b7e8de040d8663a9ba187e (patch) | |
tree | 7facf0cfbdab8ab95dcce93034e5e59750583057 /gtk2_ardour/export_multiplicator.cc | |
parent | 8876b57b0fda1000c63f8e1f7bb8f6d5ce53c480 (diff) |
new files from sakari, missed last time
git-svn-id: svn://localhost/ardour2/branches/3.0@3738 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour/export_multiplicator.cc')
-rw-r--r-- | gtk2_ardour/export_multiplicator.cc | 330 |
1 files changed, 330 insertions, 0 deletions
diff --git a/gtk2_ardour/export_multiplicator.cc b/gtk2_ardour/export_multiplicator.cc new file mode 100644 index 0000000000..969548e273 --- /dev/null +++ b/gtk2_ardour/export_multiplicator.cc @@ -0,0 +1,330 @@ +/* This file is not used at the moment. It includes code related to export a + * multiplication graph system that can be used together with the code in + * libs/ardour/export_multiplication.cc and libs/ardour/ardour/export_multiplication.h + * - Sakari Bergen 6.8.2008 - + */ + +/* + Copyright (C) 2008 Paul Davis + Author: Sakari Bergen + + This program 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. + + This program 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 more 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "export_multiplicator.h" + +#include <cassert> + +#include <pbd/compose.h> + +#include "i18n.h" + +using namespace ARDOUR; +using namespace PBD; + +#define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember)) + +ExportMultiplicator::ExportMultiplicator () : + graph (0) +{ + add (table); +} + +ExportMultiplicator::~ExportMultiplicator () +{} + +void +ExportMultiplicator::set_manager (boost::shared_ptr<ARDOUR::ExportProfileManager> _manager) +{ + manager = _manager; + manager->GraphChanged.connect (sigc::mem_fun (*this, &ExportMultiplicator::redraw)); + + redraw(); +} + +void +ExportMultiplicator::redraw () +{ + if (!manager) { return; } + + graph = &manager->get_graph(); + + /* Empty table */ + + table.foreach (sigc::mem_fun (table, &Gtk::Table::remove)); + widget_map.clear(); + + /* Calculate table dimensions */ + + uint32_t max_width = 0; + GraphLevel max_level = NoLevel; + + if (graph->timespans.size() > max_width) { + max_width = graph->timespans.size(); + max_level = Timespans; + } + + if (graph->channel_configs.size() > max_width) { + max_width = graph->channel_configs.size(); + max_level = ChannelConfigs; + } + + if (graph->formats.size() > max_width) { + max_width = graph->formats.size(); + max_level = Formats; + } + + if (graph->filenames.size() > max_width) { + max_width = graph->filenames.size(); + max_level = Filenames; + } + + table.resize (4, max_width); + + std::cout << "Table width: " << max_width << std::endl; + + /* Fill table */ + + for (list<ExportProfileManager::TimespanNodePtr>::const_iterator it = graph->timespans.begin(); it != graph->timespans.end(); ++it) { + draw_timespan (*it, get_bounds (it->get(), Timespans, max_level)); + } + + for (list<ExportProfileManager::ChannelConfigNodePtr>::const_iterator it = graph->channel_configs.begin(); it != graph->channel_configs.end(); ++it) { + draw_channel_config (*it, get_bounds (it->get(), ChannelConfigs, max_level)); + } + + for (list<ExportProfileManager::FormatNodePtr>::const_iterator it = graph->formats.begin(); it != graph->formats.end(); ++it) { + draw_format (*it, get_bounds (it->get(), Formats, max_level)); + } + + for (list<ExportProfileManager::FilenameNodePtr>::const_iterator it = graph->filenames.begin(); it != graph->filenames.end(); ++it) { + draw_filename (*it, get_bounds (it->get(), Filenames, max_level)); + } + + show_all_children (); +} + +std::pair<uint32_t, uint32_t> +ExportMultiplicator::get_bounds (ARDOUR::ExportProfileManager::GraphNode * node, GraphLevel current_level, GraphLevel max_level) const +{ + assert (current_level != NoLevel && max_level != NoLevel && graph); + + uint32_t left_bound = 0; + uint32_t right_bound = 0; + + bool left_bound_found = false; + + bool (ExportProfileManager::GraphNode::*relation_func) (ExportProfileManager::GraphNode const *) const; + if (max_level < current_level) { + std::cout << "using 'is_ancestor_of'" << std::endl; + relation_func = &ExportProfileManager::GraphNode::is_ancestor_of; + } else if (max_level > current_level) { + std::cout << "using 'is_descendant_of'" << std::endl; + relation_func = &ExportProfileManager::GraphNode::is_descendant_of; + } else { + std::cout << "using 'equals'" << std::endl; + relation_func = &ExportProfileManager::GraphNode::equals; + } + + switch (max_level) { + case Timespans: + for (list<ExportProfileManager::TimespanNodePtr>::const_iterator it = graph->timespans.begin(); it != graph->timespans.end(); ++it) { + if (CALL_MEMBER_FN(**it, relation_func) (node)) { + left_bound_found = true; + } else if (!left_bound_found) { + ++left_bound; + } + + if (left_bound_found && !CALL_MEMBER_FN(**it, relation_func) (node)) { + break; + } else { + ++right_bound; + } + } + break; + + case ChannelConfigs: + for (list<ExportProfileManager::ChannelConfigNodePtr>::const_iterator it = graph->channel_configs.begin(); it != graph->channel_configs.end(); ++it) { + if (CALL_MEMBER_FN(**it, relation_func) (node)) { + left_bound_found = true; + } else if (!left_bound_found) { + ++left_bound; + } + + if (left_bound_found && !CALL_MEMBER_FN(**it, relation_func) (node)) { + break; + } else { + ++right_bound; + } + } + break; + + case Formats: + for (list<ExportProfileManager::FormatNodePtr>::const_iterator it = graph->formats.begin(); it != graph->formats.end(); ++it) { + if (CALL_MEMBER_FN(**it, relation_func) (node)) { + left_bound_found = true; + } else if (!left_bound_found) { + ++left_bound; + } + + if (left_bound_found && !CALL_MEMBER_FN(**it, relation_func) (node)) { + break; + } else { + ++right_bound; + } + } + break; + + case Filenames: + for (list<ExportProfileManager::FilenameNodePtr>::const_iterator it = graph->filenames.begin(); it != graph->filenames.end(); ++it) { + if (CALL_MEMBER_FN(**it, relation_func) (node)) { + std::cout << "filename relation check returned true" << std::endl; + left_bound_found = true; + } else if (!left_bound_found) { + std::cout << "filename relation check returned false" << std::endl; + ++left_bound; + } + + if (left_bound_found && !CALL_MEMBER_FN(**it, relation_func) (node)) { + break; + } else { + ++right_bound; + } + } + break; + + case NoLevel: + // Not reached ! + break; + } + + return std::pair<uint32_t, uint32_t> (left_bound, right_bound); +} + +void +ExportMultiplicator::draw_timespan (ARDOUR::ExportProfileManager::TimespanNodePtr node, std::pair<uint32_t, uint32_t> bounds) +{ + ButtonWidget * button = Gtk::manage (new ButtonWidget (string_compose ("Timespan %1", node->id()), manager, node.get())); + get_hbox (TablePosition (bounds.first, bounds.second, Timespans))->pack_end (*button, true, true); +} + +void +ExportMultiplicator::draw_channel_config (ARDOUR::ExportProfileManager::ChannelConfigNodePtr node, std::pair<uint32_t, uint32_t> bounds) +{ + ButtonWidget * button = Gtk::manage (new ButtonWidget (string_compose ("Channel config %1", node->id()), manager, node.get())); + get_hbox (TablePosition (bounds.first, bounds.second, ChannelConfigs))->pack_end (*button, true, true); +} + +void +ExportMultiplicator::draw_format (ARDOUR::ExportProfileManager::FormatNodePtr node, std::pair<uint32_t, uint32_t> bounds) +{ + ButtonWidget * button = Gtk::manage (new ButtonWidget (string_compose ("Format %1", node->id()), manager, node.get())); + get_hbox (TablePosition (bounds.first, bounds.second, Formats))->pack_end (*button, true, true); +} + +void +ExportMultiplicator::draw_filename (ARDOUR::ExportProfileManager::FilenameNodePtr node, std::pair<uint32_t, uint32_t> bounds) +{ + ButtonWidget * button = Gtk::manage (new ButtonWidget (string_compose ("Filename %1", node->id()), manager, node.get())); + get_hbox (TablePosition (bounds.first, bounds.second, Filenames))->pack_end (*button, true, true); +} + +boost::shared_ptr<Gtk::HBox> +ExportMultiplicator::get_hbox (TablePosition position) +{ + WidgetMap::iterator it = widget_map.find (position); + if (it != widget_map.end()) { return it->second; } + + boost::shared_ptr<Gtk::HBox> widget = widget_map.insert (WidgetPair (position, boost::shared_ptr<Gtk::HBox> (new Gtk::HBox ()))).first->second; + table.attach (*widget, position.left, position.right, position.row - 1, position.row); + + return widget; +} + +ExportMultiplicator::ButtonWidget::ButtonWidget (Glib::ustring name, boost::shared_ptr<ExportProfileManager> m, ExportProfileManager::GraphNode * node) : + label (name), + node (node), + split_position (0.5) +{ + manager = m; + + menu_actions = Gtk::ActionGroup::create(); + menu_actions->add (Gtk::Action::create ("Split", _("_Split here")), sigc::mem_fun (*this, &ExportMultiplicator::ButtonWidget::split)); + menu_actions->add (Gtk::Action::create ("Remove", _("_Remove")), sigc::mem_fun (*this, &ExportMultiplicator::ButtonWidget::remove)); + + ui_manager = Gtk::UIManager::create(); + ui_manager->insert_action_group (menu_actions); + + Glib::ustring ui_info = + "<ui>" + " <popup name='PopupMenu'>" + " <menuitem action='Split'/>" + " <menuitem action='Remove'/>" + " </popup>" + "</ui>"; + + ui_manager->add_ui_from_string (ui_info); + menu = dynamic_cast<Gtk::Menu*> (ui_manager->get_widget ("/PopupMenu")); + + add_events (Gdk::BUTTON_PRESS_MASK); + signal_button_press_event ().connect (sigc::mem_fun (*this, &ExportMultiplicator::ButtonWidget::on_button_press_event)); + + modify_bg (Gtk::STATE_NORMAL, Gdk::Color ("#0000")); + set_border_width (1); + vbox.pack_start (label, true, true, 4); + add (vbox); +} + +bool +ExportMultiplicator::ButtonWidget::on_button_press_event (GdkEventButton* event) +{ + if(event->type != GDK_BUTTON_PRESS) { return false; } + if (event->button == 1) { + node->select (!node->selected ()); + + if (node->selected ()) { + unset_bg (Gtk::STATE_NORMAL); + modify_bg (Gtk::STATE_NORMAL, Gdk::Color ("#194756")); + } else { + unset_bg (Gtk::STATE_NORMAL); + modify_bg (Gtk::STATE_NORMAL, Gdk::Color ("#0000")); + } + + return true; + + } else if (event->button == 3) { + int x, y; + get_pointer (x, y); + split_position = (float) x / get_width(); + + menu->popup (event->button, event->time); + return true; + } + + return false; +} + +void +ExportMultiplicator::ButtonWidget::split () +{ + manager->split_node (node, split_position); +} + +void +ExportMultiplicator::ButtonWidget::remove () +{ + manager->remove_node (node); +} |