new stacktrace function in libpbd3; variable size GUI request thread queues
[ardour.git] / libs / flowcanvas / src / Port.cpp
1 /* This file is part of FlowCanvas.  Copyright (C) 2005 Dave Robillard.
2  * 
3  * FlowCanvas is free software; you can redistribute it and/or modify it under the
4  * terms of the GNU General Public License as published by the Free Software
5  * Foundation; either version 2 of the License, or (at your option) any later
6  * version.
7  * 
8  * FlowCanvas is distributed in the hope that it will be useful, but WITHOUT ANY
9  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for details.
11  * 
12  * You should have received a copy of the GNU General Public License along
13  * with this program; if not, write to the Free Software Foundation, Inc.,
14  * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  */
16
17
18 #include <libgnomecanvasmm/libgnomecanvasmm.h>
19 #include "flowcanvas/Port.h"
20 #include "flowcanvas/Module.h"
21 #include "flowcanvas/FlowCanvas.h"
22
23 namespace LibFlowCanvas {
24         
25
26 Port::Port(Module* module, const string& name, bool is_input, int color)
27 : Gnome::Canvas::Group(*module, 0, 0),
28   m_module(module),
29   m_name(name),
30   m_is_input(is_input),
31   m_colour(color),
32   m_label(*this, 1, 1, m_name),
33   m_rect(*this, 0, 0, 0, 0)
34 {
35         m_menu.items().push_back(Gtk::Menu_Helpers::MenuElem(
36                 "Disconnect All", sigc::mem_fun(this, &Port::disconnect_all)));
37
38         m_rect.property_fill_color_rgba() = color;
39         
40         // Make rectangle pretty
41         //m_rect.property_outline_color_rgba() = 0x8899AAFF;
42         m_rect.property_outline_color_rgba() = color;
43         m_rect.property_join_style() = Gdk::JOIN_MITER;
44         border_width(1.0);
45         
46         // Make label pretty
47         m_label.property_size() = PORT_LABEL_SIZE;
48         m_label.property_fill_color_rgba() = 0xFFFFFFFF;
49         m_label.property_weight() = 200;
50         
51         m_width = m_label.property_text_width() + 4.0;
52         m_height = m_label.property_text_height();
53
54         // Place everything
55         m_rect.property_x1() = 0;
56         m_rect.property_y1() = 0;
57         m_rect.property_x2() = m_width; 
58         m_rect.property_y2() = m_height;
59         m_label.property_x() = m_label.property_text_width() / 2 + 1;
60         m_label.property_y() = m_height / 2;
61
62         m_label.raise_to_top();
63
64 }
65
66
67 /** Set the border width of the port's rectangle.
68  *
69  * Do NOT directly set the width_units property on the rect, use this function.
70  */
71 void
72 Port::border_width(double w)
73 {
74         m_border_width = w;
75         m_rect.property_width_units() = w;
76 }
77
78
79 void
80 Port::name(const string& n)
81 {
82         m_name = n;
83         
84         // Reposition label
85         m_label.property_text() = m_name;
86         m_width = m_label.property_text_width() + 4.0;
87         m_height = m_label.property_text_height();
88         m_rect.property_x2() = m_width; 
89         m_rect.property_y2() = m_height;
90         m_label.property_x() = m_label.property_text_width() / 2 + 1;
91         m_label.property_y() = m_height / 2;
92
93         m_module->resize();
94 }
95
96
97 void
98 Port::zoom(float z)
99 {
100         m_label.property_size() = static_cast<int>(8000 * z);
101 }
102
103
104 /** Update the location of all connections to/from this port if this port has moved */
105 void
106 Port::move_connections()
107 {
108         for (list<Connection*>::iterator i = m_connections.begin(); i != m_connections.end(); i++) {
109                 ((Connection*)(*i))->update_location();
110         }
111 }
112
113
114 void
115 Port::remove_connection(Connection* c)
116 {
117         m_connections.erase(
118                 find(m_connections.begin(), m_connections.end(), c)
119         );
120 }
121
122
123 void
124 Port::disconnect_all()
125 {
126         Connection* c = NULL;
127         list<Connection*> temp_list = m_connections;
128         for (list<Connection*>::iterator i = temp_list.begin(); i != temp_list.end(); ++i) {
129                 c = *i;
130                 m_module->patch_bay()->disconnect(c->source_port(), c->dest_port());
131         }
132 }
133
134
135 void
136 Port::hilite(bool b)
137 {
138         m_module->hilite(b);
139
140         for (list<Connection*>::iterator i = m_connections.begin(); i != m_connections.end(); ++i) {
141                 (*i)->hilite(b);
142                 if (b)
143                         (*i)->raise_to_top();
144         }
145         
146         if (b) {
147                 raise_to_top();
148                 m_rect.raise_to_top();
149                 m_label.raise_to_top();
150                 m_rect.property_fill_color_rgba() = m_colour + 0x33333300;
151         } else {
152                 m_rect.property_fill_color_rgba() = m_colour;
153         }
154 }
155         
156
157 void
158 Port::raise_connections()
159 {
160         for (list<Connection*>::iterator i = m_connections.begin(); i != m_connections.end(); ++i) {
161                 (*i)->raise_to_top();
162         }
163 }
164
165
166 // Returns the world-relative coordinates of where a connection line
167 // should attach
168 Gnome::Art::Point
169 Port::connection_coords()
170 {
171         double x = (is_input()) ? m_rect.property_x1()-1.0 : m_rect.property_x2()+1.0;
172         double y = m_rect.property_y1() + m_height / 2;
173         
174         i2w(x, y); // convert to world-relative coords
175         
176         return Gnome::Art::Point(x, y);
177 }
178
179
180 void
181 Port::width(double w)
182 {
183         double diff = w - m_width;
184         m_rect.property_x2() = m_rect.property_x2() + diff;
185         m_width = w;
186 }
187
188
189 } // namespace LibFlowCanvas