fix conflicts caused by meterbridge merge
[ardour.git] / libs / canvas / arrow.cc
1 /*
2     Copyright (C) 2011 Paul Davis
3     Author: Carl Hetherington <cth@carlh.net>
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 */
20
21 /** @file  canvas/arrow.cc
22  *  @brief Implementation of the Arrow canvas object.
23  */
24
25 #include "canvas/arrow.h"
26 #include "canvas/polygon.h"
27 #include "canvas/line.h"
28
29 using namespace ArdourCanvas;
30
31 /** Construct an Arrow.
32  *  @param parent Parent canvas group.
33  */
34 Arrow::Arrow (Group* parent)
35         : Group (parent)
36 {
37         assert (parent);
38
39         /* set up default arrow heads at each end */
40         for (int i = 0; i < 2; ++i) {
41                 _heads[i].polygon = new Polygon (this);
42                 _heads[i].show = true;
43                 _heads[i].outward = true;
44                 _heads[i].width = 4;
45                 _heads[i].height = 4;
46                 setup_polygon (i);
47         }
48         
49         _line = new Line (this);
50 }
51
52 /** Set whether to show an arrow head at one end or other
53  *  of the line.
54  *  @param which 0 or 1 to specify the arrow head to set up.
55  *  @param true if this arrow head should be shown.
56  */
57 void
58 Arrow::set_show_head (int which, bool show)
59 {
60         assert (which == 0 || which == 1);
61         
62         begin_change ();
63         
64         _heads[which].show = show;
65
66         setup_polygon (which);
67         _bounding_box_dirty = true;
68         end_change ();
69 }
70
71 /** Set whether a given arrow head points into the line or
72  *  away from it.
73  *  @param which 0 or 1 to specify the arrow head to set up.
74  *  @param true if this arrow head should point out from the line,
75  *  otherwise false to point in.
76  */
77 void
78 Arrow::set_head_outward (int which, bool outward)
79 {
80         assert (which == 0 || which == 1);
81         
82         begin_change ();
83
84         _heads[which].outward = outward;
85
86         setup_polygon (which);
87         _bounding_box_dirty = true;
88         end_change ();
89 }
90
91 /** Set the height of a given arrow head.
92  *  @param which 0 or 1 to specify the arrow head to set up.
93  *  @param height Height of the arrow head in pixels.
94  */
95 void
96 Arrow::set_head_height (int which, Distance height)
97 {
98         assert (which == 0 || which == 1);
99         
100         begin_change ();
101         
102         _heads[which].height = height;
103
104         setup_polygon (which);
105         _bounding_box_dirty = true;
106         end_change ();
107 }
108
109 /** Set the width of a given arrow head.
110  *  @param which 0 or 1 to specify the arrow head to set up.
111  *  @param width Width of the arrow head in pixels.
112  */
113 void
114 Arrow::set_head_width (int which, Distance width)
115 {
116         assert (which == 0 || which == 1);
117         
118         begin_change ();
119         
120         _heads[which].width = width;
121
122         setup_polygon (which);
123         _bounding_box_dirty = true;
124         end_change ();
125 }
126
127 /** Set the width of our line, and the outline of our arrow(s).
128  *  @param width New width in pixels.
129  */
130 void
131 Arrow::set_outline_width (Distance width)
132 {
133         _line->set_outline_width (width);
134         _heads[0].polygon->set_outline_width (width);
135         _heads[1].polygon->set_outline_width (width);
136 }
137
138 /** Set the x position of our line.
139  *  @param x New x position in pixels (in our coordinate system).
140  */
141 void
142 Arrow::set_x (Coord x)
143 {
144         _line->set_x0 (x);
145         _line->set_x1 (x);
146         for (int i = 0; i < 2; ++i) {
147                 _heads[i].polygon->set_x_position (x - _heads[i].width / 2);
148         }
149                 
150 }
151
152 /** Set the y position of end 0 of our line.
153  *  @param y0 New y0 position in pixels (in our coordinate system).
154  */
155 void
156 Arrow::set_y0 (Coord y0)
157 {
158         _line->set_y0 (y0);
159         _heads[0].polygon->set_y_position (y0);
160 }
161
162 /** Set the y position of end 1 of our line.
163  *  @param y1 New y1 position in pixels (in our coordinate system).
164  */
165 void
166 Arrow::set_y1 (Coord y1)
167 {
168         _line->set_y1 (y1);
169         _heads[1].polygon->set_y_position (y1 - _heads[1].height);
170 }
171
172 /** @return x position of our line in pixels (in our coordinate system) */
173 Coord
174 Arrow::x () const
175 {
176         return _line->x0 ();
177 }
178
179 /** @return y position of end 1 of our line in pixels (in our coordinate system) */
180 Coord
181 Arrow::y1 () const
182 {
183         return _line->y1 ();
184 }
185
186 /** Set up the polygon used to represent a particular arrow head.
187  *  @param which 0 or 1 to specify the arrow head to set up.
188  */
189 void
190 Arrow::setup_polygon (int which)
191 {
192         assert (which == 0 || which == 1);
193         
194         Points points;
195
196         if ((which == 0 && _heads[which].outward) || (which == 1 && !_heads[which].outward)) {
197                 /* this is an arrow head pointing towards -ve y */
198                 points.push_back (Duple (_heads[which].width / 2, 0));
199                 points.push_back (Duple (_heads[which].width, _heads[which].height));
200                 points.push_back (Duple (0, _heads[which].height));
201         } else {
202                 /* this is an arrow head pointing towards +ve y */
203                 points.push_back (Duple (0, 0));
204                 points.push_back (Duple (_heads[which].width, 0));
205                 points.push_back (Duple (_heads[which].width / 2, _heads[which].height));
206                 points.push_back (Duple (0, 0));
207         }
208
209         _heads[which].polygon->set (points);
210 }
211
212 /** Set the color of our line and arrow heads.
213  *  @param color New color.
214  */
215 void
216 Arrow::set_color (Color color)
217 {
218         _line->set_outline_color (color);
219         for (int i = 0; i < 2; ++i) {
220                 _heads[i].polygon->set_outline_color (color);
221                 _heads[i].polygon->set_fill_color (color);
222         }
223 }