1 /*
2 * Copyright (c) 1999-2000, Eric Moon.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions, and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions, and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31
32 // MediaWire.cpp
33
34 #include "MediaWire.h"
35 // InfoWindow
36 #include "InfoWindowManager.h"
37 // MediaRoutingView
38 #include "MediaJack.h"
39 #include "MediaRoutingDefs.h"
40 #include "MediaRoutingView.h"
41 // Support
42 #include "cortex_ui.h"
43 #include "MediaString.h"
44 // TipManager
45 #include "TipManager.h"
46
47 // Application Kit
48 #include <Application.h>
49 // Interface Kit
50 #include <MenuItem.h>
51 #include <PopUpMenu.h>
52 // Media Kit
53 #include <MediaDefs.h>
54 // Locale Kit
55 #undef B_CATALOG
56 #define B_CATALOG (&sCatalog)
57 #include <Catalog.h>
58
59 #undef B_TRANSLATION_CONTEXT
60 #define B_TRANSLATION_CONTEXT "MediaRoutingView"
61
62 __USE_CORTEX_NAMESPACE
63
64 #include <Debug.h>
65 #define D_METHOD(x) //PRINT (x)
66 #define D_DRAW(x) //PRINT (x)
67 #define D_MOUSE(x) //PRINT (x)
68
69 static BCatalog sCatalog("x-vnd.Cortex.MediaRoutingView");
70
71 // -------------------------------------------------------- //
72 // constants
73 // -------------------------------------------------------- //
74
75 const float MediaWire::M_WIRE_OFFSET = 4.0;
76
77 // -------------------------------------------------------- //
78 // *** ctor/dtor
79 // -------------------------------------------------------- //
80
MediaWire(Connection connection,MediaJack * outputJack,MediaJack * inputJack)81 MediaWire::MediaWire(
82 Connection connection,
83 MediaJack *outputJack,
84 MediaJack *inputJack)
85 : DiagramWire(outputJack, inputJack),
86 connection(connection)
87 {
88 D_METHOD(("MediaWire::MediaWire()\n"));
89 }
90
MediaWire(MediaJack * jack,bool isStartPoint)91 MediaWire::MediaWire(
92 MediaJack *jack,
93 bool isStartPoint)
94 : DiagramWire(jack, isStartPoint)
95 {
96 D_METHOD(("MediaWire::MediaWire(temp)\n"));
97 }
98
~MediaWire()99 MediaWire::~MediaWire()
100 {
101 D_METHOD(("MediaWire::~MediaWire()\n"));
102 }
103
104 // -------------------------------------------------------- //
105 // *** derived from DiagramWire (public)
106 // -------------------------------------------------------- //
107
attachedToDiagram()108 void MediaWire::attachedToDiagram()
109 {
110 D_METHOD(("MediaWire::detachedFromDiagram()\n"));
111
112 endPointMoved(startPoint());
113 endPointMoved(endPoint());
114 }
115
detachedFromDiagram()116 void MediaWire::detachedFromDiagram()
117 {
118 D_METHOD(("MediaWire::detachedFromDiagram()\n"));
119
120 // make sure we're no longer displaying a tooltip
121 TipManager *tips = TipManager::Instance();
122 tips->hideTip(view()->ConvertToScreen(Frame()));
123 }
124
Frame() const125 BRect MediaWire::Frame() const
126 {
127 D_DRAW(("MediaWire::Frame()\n"));
128 return m_frame;
129 }
130
howCloseTo(BPoint point) const131 float MediaWire::howCloseTo(
132 BPoint point) const
133 {
134 D_MOUSE(("MediaWire::howCloseTo()\n"));
135 if (Frame().Contains(point))
136 {
137 BPoint sp = m_startPoint;
138 BPoint ep = m_endPoint;
139 BPoint so = m_startOffset;
140 BPoint eo = m_endOffset;
141 BRect wireFrame, startFrame, endFrame;
142 wireFrame.left = so.x < eo.x ? so.x : eo.x;
143 wireFrame.top = so.y < eo.y ? so.y : eo.y;
144 wireFrame.right = so.x > eo.x ? so.x : eo.x;
145 wireFrame.bottom = so.y > eo.y ? so.y : eo.y;
146 startFrame.Set(sp.x, sp.y, so.x, so.y);
147 endFrame.Set(ep.x, ep.y, eo.x, eo.y);
148 wireFrame.InsetBy(-1.0, -1.0);
149 startFrame.InsetBy(-1.0, -1.0);
150 endFrame.InsetBy(-1.0, -1.0);
151 if ((wireFrame.Width() <= 5.0) || (wireFrame.Height() <= 5.0) || startFrame.Contains(point) || endFrame.Contains(point))
152 {
153 return 1.0;
154 }
155 else
156 {
157 float length, result;
158 length = sqrt(pow(eo.x - so.x, 2) + pow(eo.y - so.y, 2));
159 result = ((so.y - point.y) * (eo.x - so.x)) - ((so.x - point.x) * (eo.y - so.y));
160 result = 3.0 - fabs(result / length);
161 return result;
162 }
163 }
164 return 0.0;
165 }
166
drawWire()167 void MediaWire::drawWire()
168 {
169 D_DRAW(("MediaWire::drawWire()\n"));
170
171 rgb_color border = isSelected() ? M_BLUE_COLOR : M_DARK_GRAY_COLOR;
172 rgb_color fill = isSelected() ? M_LIGHT_BLUE_COLOR : M_LIGHT_GRAY_COLOR;
173 view()->SetPenSize(3.0);
174 view()->BeginLineArray(3);
175 view()->AddLine(m_startPoint, m_startOffset, border);
176 view()->AddLine(m_startOffset, m_endOffset, border);
177 view()->AddLine(m_endOffset, m_endPoint, border);
178 view()->EndLineArray();
179 view()->SetPenSize(1.0);
180 view()->BeginLineArray(3);
181 view()->AddLine(m_startPoint, m_startOffset, fill);
182 view()->AddLine(m_startOffset, m_endOffset, fill);
183 view()->AddLine(m_endOffset, m_endPoint, fill);
184 view()->EndLineArray();
185 }
186
MouseDown(BPoint point,uint32 buttons,uint32 clicks)187 void MediaWire::MouseDown(
188 BPoint point,
189 uint32 buttons,
190 uint32 clicks)
191 {
192 D_MOUSE(("MediaWire::MouseDown()\n"));
193 _inherited::MouseDown(point, buttons, clicks);
194
195 switch (buttons)
196 {
197 case B_SECONDARY_MOUSE_BUTTON:
198 {
199 if (clicks == 1)
200 {
201 showContextMenu(point);
202 }
203 }
204 }
205 }
206
MouseOver(BPoint point,uint32 transit)207 void MediaWire::MouseOver(
208 BPoint point,
209 uint32 transit)
210 {
211 D_MOUSE(("MediaWire::MouseOver()\n"));
212
213 if (isDragging())
214 {
215 return;
216 }
217 switch (transit)
218 {
219 case B_ENTERED_VIEW:
220 {
221 TipManager *tips = TipManager::Instance();
222 BString tipText = MediaString::getStringFor(connection.format(), false);
223 tips->showTip(tipText.String(), view()->ConvertToScreen(Frame()),
224 TipManager::LEFT_OFFSET_FROM_POINTER, BPoint(12.0, 8.0));
225 be_app->SetCursor(M_CABLE_CURSOR);
226 break;
227 }
228 case B_EXITED_VIEW:
229 {
230 be_app->SetCursor(B_HAND_CURSOR);
231 TipManager *tips = TipManager::Instance();
232 tips->hideTip(view()->ConvertToScreen(Frame()));
233 break;
234 }
235 }
236 }
237
selected()238 void MediaWire::selected()
239 {
240 D_METHOD(("MediaWire::selected()\n"));
241 if (startPoint())
242 {
243 MediaJack *outputJack = static_cast<MediaJack *>(startPoint());
244 outputJack->select();
245 }
246 if (endPoint())
247 {
248 MediaJack *inputJack = static_cast<MediaJack *>(endPoint());
249 inputJack->select();
250 }
251 }
252
deselected()253 void MediaWire::deselected()
254 {
255 D_METHOD(("MediaWire::deselected()\n"));
256 if (startPoint())
257 {
258 MediaJack *outputJack = static_cast<MediaJack *>(startPoint());
259 outputJack->deselect();
260 }
261 if (endPoint())
262 {
263 MediaJack *inputJack = static_cast<MediaJack *>(endPoint());
264 inputJack->deselect();
265 }
266 }
267
endPointMoved(DiagramEndPoint * which)268 void MediaWire::endPointMoved(
269 DiagramEndPoint *which)
270 {
271 if (which == startPoint())
272 {
273 m_startPoint = startConnectionPoint();
274 switch (dynamic_cast<MediaRoutingView *>(view())->getLayout())
275 {
276 case MediaRoutingView::M_ICON_VIEW:
277 {
278 m_startOffset = m_startPoint + BPoint(M_WIRE_OFFSET, 0.0);
279 break;
280 }
281 case MediaRoutingView::M_MINI_ICON_VIEW:
282 {
283 m_startOffset = m_startPoint + BPoint(0.0, M_WIRE_OFFSET);
284 break;
285 }
286 }
287 m_frame.left = m_startPoint.x < m_endOffset.x ? m_startPoint.x - 2.0: m_endOffset.x - 2.0;
288 m_frame.top = m_startPoint.y < m_endOffset.y ? m_startPoint.y - 2.0 : m_endOffset.y - 2.0;
289 m_frame.right = m_startOffset.x > m_endPoint.x ? m_startOffset.x + 2.0 : m_endPoint.x + 2.0;
290 m_frame.bottom = m_startOffset.y > m_endPoint.y ? m_startOffset.y + 2.0 : m_endPoint.y + 2.0;
291 }
292 else if (which == endPoint())
293 {
294 m_endPoint = endConnectionPoint();
295 switch (dynamic_cast<MediaRoutingView *>(view())->getLayout())
296 {
297 case MediaRoutingView::M_ICON_VIEW:
298 {
299 m_endOffset = m_endPoint - BPoint(M_WIRE_OFFSET, 0.0);
300 break;
301 }
302 case MediaRoutingView::M_MINI_ICON_VIEW:
303 {
304 m_endOffset = m_endPoint - BPoint(0.0, M_WIRE_OFFSET);
305 break;
306 }
307 }
308 m_frame.left = m_startPoint.x < m_endOffset.x ? m_startPoint.x - 2.0: m_endOffset.x - 2.0;
309 m_frame.top = m_startPoint.y < m_endOffset.y ? m_startPoint.y - 2.0 : m_endOffset.y - 2.0;
310 m_frame.right = m_startOffset.x > m_endPoint.x ? m_startOffset.x + 2.0 : m_endPoint.x + 2.0;
311 m_frame.bottom = m_startOffset.y > m_endPoint.y ? m_startOffset.y + 2.0 : m_endPoint.y + 2.0;
312 }
313 }
314
315 // -------------------------------------------------------- //
316 // *** internal operations (protected)
317 // -------------------------------------------------------- //
318
showContextMenu(BPoint point)319 void MediaWire::showContextMenu(
320 BPoint point)
321 {
322 D_METHOD(("MediaWire::showContextMenu()\n"));
323
324 BPopUpMenu *menu = new BPopUpMenu("MediaWire PopUp", false, false, B_ITEMS_IN_COLUMN);
325 menu->SetFont(be_plain_font);
326 BMenuItem *item;
327
328 // add the "Get Info" item
329 media_output output;
330 connection.getOutput(&output);
331 BMessage *message = new BMessage(InfoWindowManager::M_INFO_WINDOW_REQUESTED);
332 message->AddData("connection", B_RAW_TYPE,
333 reinterpret_cast<const void *>(&output), sizeof(output));
334 menu->AddItem(new BMenuItem(B_TRANSLATE("Get info"), message, 'I'));
335
336 // add the "Disconnect" item
337 menu->AddItem(item = new BMenuItem(B_TRANSLATE("Disconnect"),
338 new BMessage(MediaRoutingView::M_DELETE_SELECTION), 'T'));
339 if (connection.flags() & Connection::LOCKED)
340 {
341 item->SetEnabled(false);
342 }
343
344 menu->SetTargetForItems(view());
345 view()->ConvertToScreen(&point);
346 point -= BPoint(1.0, 1.0);
347 menu->Go(point, true, true, true);
348 }
349
350 // END -- MediaWire.cpp --
351