1 /* This file is not used at the moment. It includes code related to export a
2 * multiplication graph system that can be used together with the code in
3 * libs/ardour/export_multiplication.cc and libs/ardour/ardour/export_multiplication.h
4 * - Sakari Bergen 6.8.2008 -
8 Copyright (C) 2008 Paul Davis
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include "export_multiplicator.h"
31 #include "pbd/compose.h"
35 using namespace ARDOUR
;
38 #define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember))
40 ExportMultiplicator::ExportMultiplicator () :
46 ExportMultiplicator::~ExportMultiplicator ()
50 ExportMultiplicator::set_manager (boost::shared_ptr
<ARDOUR::ExportProfileManager
> _manager
)
53 manager
->GraphChanged
.connect (sigc::mem_fun (*this, &ExportMultiplicator::redraw
));
59 ExportMultiplicator::redraw ()
61 if (!manager
) { return; }
63 graph
= &manager
->get_graph();
67 table
.foreach (sigc::mem_fun (table
, &Gtk::Table::remove
));
70 /* Calculate table dimensions */
72 uint32_t max_width
= 0;
73 GraphLevel max_level
= NoLevel
;
75 if (graph
->timespans
.size() > max_width
) {
76 max_width
= graph
->timespans
.size();
77 max_level
= Timespans
;
80 if (graph
->channel_configs
.size() > max_width
) {
81 max_width
= graph
->channel_configs
.size();
82 max_level
= ChannelConfigs
;
85 if (graph
->formats
.size() > max_width
) {
86 max_width
= graph
->formats
.size();
90 if (graph
->filenames
.size() > max_width
) {
91 max_width
= graph
->filenames
.size();
92 max_level
= Filenames
;
95 table
.resize (4, max_width
);
97 std::cout
<< "Table width: " << max_width
<< std::endl
;
101 for (list
<ExportProfileManager::TimespanNodePtr
>::const_iterator it
= graph
->timespans
.begin(); it
!= graph
->timespans
.end(); ++it
) {
102 draw_timespan (*it
, get_bounds (it
->get(), Timespans
, max_level
));
105 for (list
<ExportProfileManager::ChannelConfigNodePtr
>::const_iterator it
= graph
->channel_configs
.begin(); it
!= graph
->channel_configs
.end(); ++it
) {
106 draw_channel_config (*it
, get_bounds (it
->get(), ChannelConfigs
, max_level
));
109 for (list
<ExportProfileManager::FormatNodePtr
>::const_iterator it
= graph
->formats
.begin(); it
!= graph
->formats
.end(); ++it
) {
110 draw_format (*it
, get_bounds (it
->get(), Formats
, max_level
));
113 for (list
<ExportProfileManager::FilenameNodePtr
>::const_iterator it
= graph
->filenames
.begin(); it
!= graph
->filenames
.end(); ++it
) {
114 draw_filename (*it
, get_bounds (it
->get(), Filenames
, max_level
));
117 show_all_children ();
120 std::pair
<uint32_t, uint32_t>
121 ExportMultiplicator::get_bounds (ARDOUR::ExportProfileManager::GraphNode
* node
, GraphLevel current_level
, GraphLevel max_level
) const
123 assert (current_level
!= NoLevel
&& max_level
!= NoLevel
&& graph
);
125 uint32_t left_bound
= 0;
126 uint32_t right_bound
= 0;
128 bool left_bound_found
= false;
130 bool (ExportProfileManager::GraphNode::*relation_func
) (ExportProfileManager::GraphNode
const *) const;
131 if (max_level
< current_level
) {
132 std::cout
<< "using 'is_ancestor_of'" << std::endl
;
133 relation_func
= &ExportProfileManager::GraphNode::is_ancestor_of
;
134 } else if (max_level
> current_level
) {
135 std::cout
<< "using 'is_descendant_of'" << std::endl
;
136 relation_func
= &ExportProfileManager::GraphNode::is_descendant_of
;
138 std::cout
<< "using 'equals'" << std::endl
;
139 relation_func
= &ExportProfileManager::GraphNode::equals
;
144 for (list
<ExportProfileManager::TimespanNodePtr
>::const_iterator it
= graph
->timespans
.begin(); it
!= graph
->timespans
.end(); ++it
) {
145 if (CALL_MEMBER_FN(**it
, relation_func
) (node
)) {
146 left_bound_found
= true;
147 } else if (!left_bound_found
) {
151 if (left_bound_found
&& !CALL_MEMBER_FN(**it
, relation_func
) (node
)) {
160 for (list
<ExportProfileManager::ChannelConfigNodePtr
>::const_iterator it
= graph
->channel_configs
.begin(); it
!= graph
->channel_configs
.end(); ++it
) {
161 if (CALL_MEMBER_FN(**it
, relation_func
) (node
)) {
162 left_bound_found
= true;
163 } else if (!left_bound_found
) {
167 if (left_bound_found
&& !CALL_MEMBER_FN(**it
, relation_func
) (node
)) {
176 for (list
<ExportProfileManager::FormatNodePtr
>::const_iterator it
= graph
->formats
.begin(); it
!= graph
->formats
.end(); ++it
) {
177 if (CALL_MEMBER_FN(**it
, relation_func
) (node
)) {
178 left_bound_found
= true;
179 } else if (!left_bound_found
) {
183 if (left_bound_found
&& !CALL_MEMBER_FN(**it
, relation_func
) (node
)) {
192 for (list
<ExportProfileManager::FilenameNodePtr
>::const_iterator it
= graph
->filenames
.begin(); it
!= graph
->filenames
.end(); ++it
) {
193 if (CALL_MEMBER_FN(**it
, relation_func
) (node
)) {
194 std::cout
<< "filename relation check returned true" << std::endl
;
195 left_bound_found
= true;
196 } else if (!left_bound_found
) {
197 std::cout
<< "filename relation check returned false" << std::endl
;
201 if (left_bound_found
&& !CALL_MEMBER_FN(**it
, relation_func
) (node
)) {
214 return std::pair
<uint32_t, uint32_t> (left_bound
, right_bound
);
218 ExportMultiplicator::draw_timespan (ARDOUR::ExportProfileManager::TimespanNodePtr node
, std::pair
<uint32_t, uint32_t> bounds
)
220 ButtonWidget
* button
= Gtk::manage (new ButtonWidget (string_compose ("Timespan %1", node
->id()), manager
, node
.get()));
221 get_hbox (TablePosition (bounds
.first
, bounds
.second
, Timespans
))->pack_end (*button
, true, true);
225 ExportMultiplicator::draw_channel_config (ARDOUR::ExportProfileManager::ChannelConfigNodePtr node
, std::pair
<uint32_t, uint32_t> bounds
)
227 ButtonWidget
* button
= Gtk::manage (new ButtonWidget (string_compose ("Channel config %1", node
->id()), manager
, node
.get()));
228 get_hbox (TablePosition (bounds
.first
, bounds
.second
, ChannelConfigs
))->pack_end (*button
, true, true);
232 ExportMultiplicator::draw_format (ARDOUR::ExportProfileManager::FormatNodePtr node
, std::pair
<uint32_t, uint32_t> bounds
)
234 ButtonWidget
* button
= Gtk::manage (new ButtonWidget (string_compose ("Format %1", node
->id()), manager
, node
.get()));
235 get_hbox (TablePosition (bounds
.first
, bounds
.second
, Formats
))->pack_end (*button
, true, true);
239 ExportMultiplicator::draw_filename (ARDOUR::ExportProfileManager::FilenameNodePtr node
, std::pair
<uint32_t, uint32_t> bounds
)
241 ButtonWidget
* button
= Gtk::manage (new ButtonWidget (string_compose ("Filename %1", node
->id()), manager
, node
.get()));
242 get_hbox (TablePosition (bounds
.first
, bounds
.second
, Filenames
))->pack_end (*button
, true, true);
245 boost::shared_ptr
<Gtk::HBox
>
246 ExportMultiplicator::get_hbox (TablePosition position
)
248 WidgetMap::iterator it
= widget_map
.find (position
);
249 if (it
!= widget_map
.end()) { return it
->second
; }
251 boost::shared_ptr
<Gtk::HBox
> widget
= widget_map
.insert (WidgetPair (position
, boost::shared_ptr
<Gtk::HBox
> (new Gtk::HBox ()))).first
->second
;
252 table
.attach (*widget
, position
.left
, position
.right
, position
.row
- 1, position
.row
);
257 ExportMultiplicator::ButtonWidget::ButtonWidget (Glib::ustring name
, boost::shared_ptr
<ExportProfileManager
> m
, ExportProfileManager::GraphNode
* node
) :
264 menu_actions
= Gtk::ActionGroup::create();
265 menu_actions
->add (Gtk::Action::create ("Split", _("_Split here")), sigc::mem_fun (*this, &ExportMultiplicator::ButtonWidget::split
));
266 menu_actions
->add (Gtk::Action::create ("Remove", _("_Remove")), sigc::mem_fun (*this, &ExportMultiplicator::ButtonWidget::remove
));
268 ui_manager
= Gtk::UIManager::create();
269 ui_manager
->insert_action_group (menu_actions
);
271 Glib::ustring ui_info
=
273 " <popup name='PopupMenu'>"
274 " <menuitem action='Split'/>"
275 " <menuitem action='Remove'/>"
279 ui_manager
->add_ui_from_string (ui_info
);
280 menu
= dynamic_cast<Gtk::Menu
*> (ui_manager
->get_widget ("/PopupMenu"));
282 add_events (Gdk::BUTTON_PRESS_MASK
);
283 signal_button_press_event ().connect (sigc::mem_fun (*this, &ExportMultiplicator::ButtonWidget::on_button_press_event
));
285 modify_bg (Gtk::STATE_NORMAL
, Gdk::Color ("#0000"));
286 set_border_width (1);
287 vbox
.pack_start (label
, true, true, 4);
292 ExportMultiplicator::ButtonWidget::on_button_press_event (GdkEventButton
* event
)
294 if(event
->type
!= GDK_BUTTON_PRESS
) { return false; }
295 if (event
->button
== 1) {
296 node
->select (!node
->selected ());
298 if (node
->selected ()) {
299 unset_bg (Gtk::STATE_NORMAL
);
300 modify_bg (Gtk::STATE_NORMAL
, Gdk::Color ("#194756"));
302 unset_bg (Gtk::STATE_NORMAL
);
303 modify_bg (Gtk::STATE_NORMAL
, Gdk::Color ("#0000"));
308 } else if (event
->button
== 3) {
311 split_position
= (float) x
/ get_width();
313 menu
->popup (event
->button
, event
->time
);
321 ExportMultiplicator::ButtonWidget::split ()
323 manager
->split_node (node
, split_position
);
327 ExportMultiplicator::ButtonWidget::remove ()
329 manager
->remove_node (node
);