xref: /haiku/src/apps/cortex/MediaRoutingView/MediaWire.cpp (revision 93a78ecaa45114d68952d08c4778f073515102f2)
1 // MediaWire.cpp
2 
3 #include "MediaWire.h"
4 // InfoWindow
5 #include "InfoWindowManager.h"
6 // MediaRoutingView
7 #include "MediaJack.h"
8 #include "MediaRoutingDefs.h"
9 #include "MediaRoutingView.h"
10 // Support
11 #include "cortex_ui.h"
12 #include "MediaString.h"
13 // TipManager
14 #include "TipManager.h"
15 
16 // Application Kit
17 #include <Application.h>
18 // Interface Kit
19 #include <MenuItem.h>
20 #include <PopUpMenu.h>
21 // Media Kit
22 #include <MediaDefs.h>
23 
24 __USE_CORTEX_NAMESPACE
25 
26 #include <Debug.h>
27 #define D_METHOD(x) //PRINT (x)
28 #define D_DRAW(x) //PRINT (x)
29 #define D_MOUSE(x) //PRINT (x)
30 
31 // -------------------------------------------------------- //
32 // constants
33 // -------------------------------------------------------- //
34 
35 const float MediaWire::M_WIRE_OFFSET		= 4.0;
36 
37 // -------------------------------------------------------- //
38 // *** ctor/dtor
39 // -------------------------------------------------------- //
40 
41 MediaWire::MediaWire(
42 	Connection connection,
43 	MediaJack *outputJack,
44 	MediaJack *inputJack)
45 	: DiagramWire(outputJack, inputJack),
46 	  connection(connection)
47 {
48 	D_METHOD(("MediaWire::MediaWire()\n"));
49 }
50 
51 MediaWire::MediaWire(
52 	MediaJack *jack,
53 	bool isStartPoint)
54 	: DiagramWire(jack, isStartPoint)
55 {
56 	D_METHOD(("MediaWire::MediaWire(temp)\n"));
57 }
58 
59 MediaWire::~MediaWire()
60 {
61 	D_METHOD(("MediaWire::~MediaWire()\n"));
62 }
63 
64 // -------------------------------------------------------- //
65 // *** derived from DiagramWire (public)
66 // -------------------------------------------------------- //
67 
68 void MediaWire::attachedToDiagram()
69 {
70 	D_METHOD(("MediaWire::detachedFromDiagram()\n"));
71 
72 	endPointMoved(startPoint());
73 	endPointMoved(endPoint());
74 }
75 
76 void MediaWire::detachedFromDiagram()
77 {
78 	D_METHOD(("MediaWire::detachedFromDiagram()\n"));
79 
80 	// make sure we're no longer displaying a tooltip
81 	TipManager *tips = TipManager::Instance();
82 	tips->hideTip(view()->ConvertToScreen(Frame()));
83 }
84 
85 BRect MediaWire::Frame() const
86 {
87 	D_DRAW(("MediaWire::Frame()\n"));
88 	return m_frame;
89 }
90 
91 float MediaWire::howCloseTo(
92 	BPoint point) const
93 {
94 	D_MOUSE(("MediaWire::howCloseTo()\n"));
95 	if (Frame().Contains(point))
96 	{
97 		BPoint sp = m_startPoint;
98 		BPoint ep = m_endPoint;
99 		BPoint so = m_startOffset;
100 		BPoint eo = m_endOffset;
101 		BRect wireFrame, startFrame, endFrame;
102 		wireFrame.left = so.x < eo.x ? so.x : eo.x;
103 		wireFrame.top = so.y < eo.y ? so.y : eo.y;
104 		wireFrame.right = so.x > eo.x ? so.x : eo.x;
105 		wireFrame.bottom = so.y > eo.y ? so.y : eo.y;
106 		startFrame.Set(sp.x, sp.y, so.x, so.y);
107 		endFrame.Set(ep.x, ep.y, eo.x, eo.y);
108 		wireFrame.InsetBy(-1.0, -1.0);
109 		startFrame.InsetBy(-1.0, -1.0);
110 		endFrame.InsetBy(-1.0, -1.0);
111 		if ((wireFrame.Width() <= 5.0) || (wireFrame.Height() <= 5.0) || startFrame.Contains(point) || endFrame.Contains(point))
112 		{
113 			return 1.0;
114 		}
115 		else
116 		{
117 			float length, result;
118 			length = sqrt(pow(eo.x - so.x, 2) + pow(eo.y - so.y, 2));
119  			result = ((so.y - point.y) * (eo.x - so.x)) - ((so.x - point.x) * (eo.y - so.y));
120 			result = 3.0 - fabs(result / length);
121 			return result;
122 		}
123 	}
124 	return 0.0;
125 }
126 
127 void MediaWire::drawWire()
128 {
129 	D_DRAW(("MediaWire::drawWire()\n"));
130 
131 	rgb_color border = isSelected() ? M_BLUE_COLOR : M_DARK_GRAY_COLOR;
132 	rgb_color fill = isSelected() ? M_LIGHT_BLUE_COLOR : M_LIGHT_GRAY_COLOR;
133 	view()->SetPenSize(3.0);
134 	view()->BeginLineArray(3);
135 		view()->AddLine(m_startPoint, m_startOffset, border);
136 		view()->AddLine(m_startOffset, m_endOffset, border);
137 		view()->AddLine(m_endOffset, m_endPoint, border);
138 	view()->EndLineArray();
139 	view()->SetPenSize(1.0);
140 	view()->BeginLineArray(3);
141 		view()->AddLine(m_startPoint, m_startOffset, fill);
142 		view()->AddLine(m_startOffset, m_endOffset, fill);
143 		view()->AddLine(m_endOffset, m_endPoint, fill);
144 	view()->EndLineArray();
145 }
146 
147 void MediaWire::MouseDown(
148 	BPoint point,
149 	uint32 buttons,
150 	uint32 clicks)
151 {
152 	D_MOUSE(("MediaWire::MouseDown()\n"));
153 	_inherited::MouseDown(point, buttons, clicks);
154 
155 	switch (buttons)
156 	{
157 		case B_SECONDARY_MOUSE_BUTTON:
158 		{
159 			if (clicks == 1)
160 			{
161 				showContextMenu(point);
162 			}
163 		}
164 	}
165 }
166 
167 void MediaWire::MouseOver(
168 	BPoint point,
169 	uint32 transit)
170 {
171 	D_MOUSE(("MediaWire::MouseOver()\n"));
172 
173 	if (isDragging())
174 	{
175 		return;
176 	}
177 	switch (transit)
178 	{
179 		case B_ENTERED_VIEW:
180 		{
181 			TipManager *tips = TipManager::Instance();
182 			BString tipText = MediaString::getStringFor(connection.format(), false);
183 			tips->showTip(tipText.String(), view()->ConvertToScreen(Frame()),
184 						  TipManager::LEFT_OFFSET_FROM_POINTER, BPoint(12.0, 8.0));
185 			be_app->SetCursor(M_CABLE_CURSOR);
186 			break;
187 		}
188 		case B_EXITED_VIEW:
189 		{
190 			be_app->SetCursor(B_HAND_CURSOR);
191 			TipManager *tips = TipManager::Instance();
192 			tips->hideTip(view()->ConvertToScreen(Frame()));
193 			break;
194 		}
195 	}
196 }
197 
198 void MediaWire::selected()
199 {
200 	D_METHOD(("MediaWire::selected()\n"));
201 	if (startPoint())
202 	{
203 		MediaJack *outputJack = dynamic_cast<MediaJack *>(startPoint());
204 		outputJack->select();
205 	}
206 	if (endPoint())
207 	{
208 		MediaJack *inputJack = dynamic_cast<MediaJack *>(endPoint());
209 		inputJack->select();
210 	}
211 }
212 
213 void MediaWire::deselected()
214 {
215 	D_METHOD(("MediaWire::deselected()\n"));
216 	if (startPoint())
217 	{
218 		MediaJack *outputJack = dynamic_cast<MediaJack *>(startPoint());
219 		outputJack->deselect();
220 	}
221 	if (endPoint())
222 	{
223 		MediaJack *inputJack = dynamic_cast<MediaJack *>(endPoint());
224 		inputJack->deselect();
225 	}
226 }
227 
228 void MediaWire::endPointMoved(
229 	DiagramEndPoint *which)
230 {
231 	if (which == startPoint())
232 	{
233 		m_startPoint = startConnectionPoint();
234 		switch (dynamic_cast<MediaRoutingView *>(view())->getLayout())
235 		{
236 			case MediaRoutingView::M_ICON_VIEW:
237 			{
238 				m_startOffset = m_startPoint + BPoint(M_WIRE_OFFSET, 0.0);
239 				break;
240 			}
241 			case MediaRoutingView::M_MINI_ICON_VIEW:
242 			{
243 				m_startOffset = m_startPoint + BPoint(0.0, M_WIRE_OFFSET);
244 				break;
245 			}
246 		}
247 		m_frame.left = m_startPoint.x < m_endOffset.x ? m_startPoint.x - 2.0: m_endOffset.x - 2.0;
248 		m_frame.top = m_startPoint.y < m_endOffset.y ? m_startPoint.y - 2.0 : m_endOffset.y - 2.0;
249 		m_frame.right = m_startOffset.x > m_endPoint.x ? m_startOffset.x + 2.0 : m_endPoint.x + 2.0;
250 		m_frame.bottom = m_startOffset.y > m_endPoint.y ? m_startOffset.y + 2.0 : m_endPoint.y + 2.0;
251 	}
252 	else if (which == endPoint())
253 	{
254 		m_endPoint = endConnectionPoint();
255 		switch (dynamic_cast<MediaRoutingView *>(view())->getLayout())
256 		{
257 			case MediaRoutingView::M_ICON_VIEW:
258 			{
259 				m_endOffset = m_endPoint - BPoint(M_WIRE_OFFSET, 0.0);
260 				break;
261 			}
262 			case MediaRoutingView::M_MINI_ICON_VIEW:
263 			{
264 				m_endOffset = m_endPoint - BPoint(0.0, M_WIRE_OFFSET);
265 				break;
266 			}
267 		}
268 		m_frame.left = m_startPoint.x < m_endOffset.x ? m_startPoint.x - 2.0: m_endOffset.x - 2.0;
269 		m_frame.top = m_startPoint.y < m_endOffset.y ? m_startPoint.y - 2.0 : m_endOffset.y - 2.0;
270 		m_frame.right = m_startOffset.x > m_endPoint.x ? m_startOffset.x + 2.0 : m_endPoint.x + 2.0;
271 		m_frame.bottom = m_startOffset.y > m_endPoint.y ? m_startOffset.y + 2.0 : m_endPoint.y + 2.0;
272 	}
273 }
274 
275 // -------------------------------------------------------- //
276 // *** internal operations (protected)
277 // -------------------------------------------------------- //
278 
279 void MediaWire::showContextMenu(
280 	BPoint point)
281 {
282 	D_METHOD(("MediaWire::showContextMenu()\n"));
283 
284 	BPopUpMenu *menu = new BPopUpMenu("MediaWire PopUp", false, false, B_ITEMS_IN_COLUMN);
285 	menu->SetFont(be_plain_font);
286 	BMenuItem *item;
287 
288 	// add the "Get Info" item
289 	media_output output;
290 	connection.getOutput(&output);
291 	BMessage *message = new BMessage(InfoWindowManager::M_INFO_WINDOW_REQUESTED);
292 	message->AddData("connection", B_RAW_TYPE,
293 					 reinterpret_cast<const void *>(&output), sizeof(output));
294 	menu->AddItem(item = new BMenuItem("Get Info", message, 'I'));
295 
296 	// add the "Disconnect" item
297 	menu->AddItem(item = new BMenuItem("Disconnect", new BMessage(MediaRoutingView::M_DELETE_SELECTION), 'T'));
298 	if (connection.flags() & Connection::LOCKED)
299 	{
300 		item->SetEnabled(false);
301 	}
302 
303 	menu->SetTargetForItems(view());
304 	view()->ConvertToScreen(&point);
305 	point -= BPoint(1.0, 1.0);
306 	menu->Go(point, true, true, true);
307 }
308 
309 // END -- MediaWire.cpp --
310