xref: /haiku/src/apps/cortex/MediaRoutingView/MediaNodePanel.cpp (revision a0795c6fe30e25338049a952326c61deb7a343b6)
1*a0795c6fSMarcus Overhagen // MediaNodePanel.cpp
2*a0795c6fSMarcus Overhagen // c.lenz 10oct99
3*a0795c6fSMarcus Overhagen 
4*a0795c6fSMarcus Overhagen #include "MediaNodePanel.h"
5*a0795c6fSMarcus Overhagen // InfoWindow
6*a0795c6fSMarcus Overhagen #include "InfoWindowManager.h"
7*a0795c6fSMarcus Overhagen // MediaRoutingView
8*a0795c6fSMarcus Overhagen #include "MediaRoutingView.h"
9*a0795c6fSMarcus Overhagen #include "MediaWire.h"
10*a0795c6fSMarcus Overhagen #include "RouteAppNodeManager.h"
11*a0795c6fSMarcus Overhagen // NodeManager
12*a0795c6fSMarcus Overhagen #include "NodeRef.h"
13*a0795c6fSMarcus Overhagen #include "NodeGroup.h"
14*a0795c6fSMarcus Overhagen // ParameterWindow
15*a0795c6fSMarcus Overhagen #include "ParameterWindow.h"
16*a0795c6fSMarcus Overhagen // Support
17*a0795c6fSMarcus Overhagen #include "cortex_ui.h"
18*a0795c6fSMarcus Overhagen #include "MediaIcon.h"
19*a0795c6fSMarcus Overhagen #include "MediaString.h"
20*a0795c6fSMarcus Overhagen // RouteApp
21*a0795c6fSMarcus Overhagen #include "RouteWindow.h"
22*a0795c6fSMarcus Overhagen // TipManager
23*a0795c6fSMarcus Overhagen #include "TipManager.h"
24*a0795c6fSMarcus Overhagen 
25*a0795c6fSMarcus Overhagen // App Kit
26*a0795c6fSMarcus Overhagen #include <Application.h>
27*a0795c6fSMarcus Overhagen #include <Roster.h>
28*a0795c6fSMarcus Overhagen // Interface Kit
29*a0795c6fSMarcus Overhagen #include <MenuItem.h>
30*a0795c6fSMarcus Overhagen #include <PopUpMenu.h>
31*a0795c6fSMarcus Overhagen // Media Kit
32*a0795c6fSMarcus Overhagen #include <MediaDefs.h>
33*a0795c6fSMarcus Overhagen #include <MediaRoster.h>
34*a0795c6fSMarcus Overhagen 
35*a0795c6fSMarcus Overhagen __USE_CORTEX_NAMESPACE
36*a0795c6fSMarcus Overhagen 
37*a0795c6fSMarcus Overhagen #include <Debug.h>
38*a0795c6fSMarcus Overhagen #define D_METHOD(x) //PRINT (x)
39*a0795c6fSMarcus Overhagen #define D_MESSAGE(x) //PRINT (x)
40*a0795c6fSMarcus Overhagen #define D_DRAW(x) //PRINT (x)
41*a0795c6fSMarcus Overhagen 
42*a0795c6fSMarcus Overhagen // -------------------------------------------------------- //
43*a0795c6fSMarcus Overhagen // constants
44*a0795c6fSMarcus Overhagen // -------------------------------------------------------- //
45*a0795c6fSMarcus Overhagen 
46*a0795c6fSMarcus Overhagen float	MediaNodePanel::M_DEFAULT_WIDTH		= 90.0;
47*a0795c6fSMarcus Overhagen float	MediaNodePanel::M_DEFAULT_HEIGHT	= 60.0;
48*a0795c6fSMarcus Overhagen float	MediaNodePanel::M_LABEL_H_MARGIN	= 3.0;
49*a0795c6fSMarcus Overhagen float	MediaNodePanel::M_LABEL_V_MARGIN	= 3.0;
50*a0795c6fSMarcus Overhagen float	MediaNodePanel::M_BODY_H_MARGIN		= 5.0;
51*a0795c6fSMarcus Overhagen float	MediaNodePanel::M_BODY_V_MARGIN		= 5.0;
52*a0795c6fSMarcus Overhagen 
53*a0795c6fSMarcus Overhagen // [e.moon 7dec99]
54*a0795c6fSMarcus Overhagen const BPoint MediaNodePanel::s_invalidPosition(-200.0, -200.0);
55*a0795c6fSMarcus Overhagen 
56*a0795c6fSMarcus Overhagen // -------------------------------------------------------- //
57*a0795c6fSMarcus Overhagen // *** ctor/dtor
58*a0795c6fSMarcus Overhagen // -------------------------------------------------------- //
59*a0795c6fSMarcus Overhagen 
60*a0795c6fSMarcus Overhagen MediaNodePanel::MediaNodePanel(
61*a0795c6fSMarcus Overhagen 	BPoint position,
62*a0795c6fSMarcus Overhagen 	NodeRef *nodeRef)
63*a0795c6fSMarcus Overhagen 	: DiagramBox(BRect(position, position + BPoint(M_DEFAULT_WIDTH, M_DEFAULT_HEIGHT))),
64*a0795c6fSMarcus Overhagen 	  BHandler(nodeRef->name()),
65*a0795c6fSMarcus Overhagen 	  ref(nodeRef),
66*a0795c6fSMarcus Overhagen 	  m_bitmap(0),
67*a0795c6fSMarcus Overhagen 	  m_icon(0),
68*a0795c6fSMarcus Overhagen 	  m_alternatePosition(s_invalidPosition)
69*a0795c6fSMarcus Overhagen {
70*a0795c6fSMarcus Overhagen 	D_METHOD(("MediaNodePanel::MediaNodePanel()\n"));
71*a0795c6fSMarcus Overhagen 	ASSERT(ref);
72*a0795c6fSMarcus Overhagen }
73*a0795c6fSMarcus Overhagen 
74*a0795c6fSMarcus Overhagen MediaNodePanel::~MediaNodePanel()
75*a0795c6fSMarcus Overhagen {
76*a0795c6fSMarcus Overhagen 	D_METHOD(("MediaNodePanel::~MediaNodePanel()\n"));
77*a0795c6fSMarcus Overhagen 	if (m_icon)
78*a0795c6fSMarcus Overhagen 	{
79*a0795c6fSMarcus Overhagen 		delete m_icon;
80*a0795c6fSMarcus Overhagen 	}
81*a0795c6fSMarcus Overhagen 	if (m_bitmap)
82*a0795c6fSMarcus Overhagen 	{
83*a0795c6fSMarcus Overhagen 		delete m_bitmap;
84*a0795c6fSMarcus Overhagen 	}
85*a0795c6fSMarcus Overhagen }
86*a0795c6fSMarcus Overhagen 
87*a0795c6fSMarcus Overhagen // -------------------------------------------------------- //
88*a0795c6fSMarcus Overhagen // *** derived from DiagramBox
89*a0795c6fSMarcus Overhagen // -------------------------------------------------------- //
90*a0795c6fSMarcus Overhagen 
91*a0795c6fSMarcus Overhagen void MediaNodePanel::attachedToDiagram()
92*a0795c6fSMarcus Overhagen {
93*a0795c6fSMarcus Overhagen 	D_METHOD(("MediaNodePanel::attachedToDiagram()\n"));
94*a0795c6fSMarcus Overhagen 
95*a0795c6fSMarcus Overhagen 	resizeTo(M_DEFAULT_WIDTH, M_DEFAULT_HEIGHT);
96*a0795c6fSMarcus Overhagen 	_updateIcon(dynamic_cast<MediaRoutingView *>(view())->getLayout());
97*a0795c6fSMarcus Overhagen 	_prepareLabel();
98*a0795c6fSMarcus Overhagen 	populateInit();
99*a0795c6fSMarcus Overhagen 	arrangeIOJacks();
100*a0795c6fSMarcus Overhagen 
101*a0795c6fSMarcus Overhagen 	view()->Looper()->AddHandler(this);
102*a0795c6fSMarcus Overhagen }
103*a0795c6fSMarcus Overhagen 
104*a0795c6fSMarcus Overhagen void MediaNodePanel::detachedFromDiagram()
105*a0795c6fSMarcus Overhagen {
106*a0795c6fSMarcus Overhagen 	D_METHOD(("MediaNodePanel::detachedFromDiagram()\n"));
107*a0795c6fSMarcus Overhagen 
108*a0795c6fSMarcus Overhagen 	BRect labelRect = m_labelRect.OffsetByCopy(frame().LeftTop());
109*a0795c6fSMarcus Overhagen 	if (m_mouseOverLabel && m_labelTruncated)
110*a0795c6fSMarcus Overhagen 	{
111*a0795c6fSMarcus Overhagen 		TipManager *tips = TipManager::Instance();
112*a0795c6fSMarcus Overhagen 		tips->hideTip(view()->ConvertToScreen(labelRect));
113*a0795c6fSMarcus Overhagen 	}
114*a0795c6fSMarcus Overhagen 
115*a0795c6fSMarcus Overhagen 	view()->Looper()->RemoveHandler(this);
116*a0795c6fSMarcus Overhagen }
117*a0795c6fSMarcus Overhagen 
118*a0795c6fSMarcus Overhagen void MediaNodePanel::drawBox()
119*a0795c6fSMarcus Overhagen {
120*a0795c6fSMarcus Overhagen 	D_DRAW(("MediaNodePanel::drawBox()\n"));
121*a0795c6fSMarcus Overhagen 	if (m_bitmap)
122*a0795c6fSMarcus Overhagen 	{
123*a0795c6fSMarcus Overhagen 		view()->DrawBitmap(m_bitmap, frame().LeftTop());
124*a0795c6fSMarcus Overhagen 	}
125*a0795c6fSMarcus Overhagen }
126*a0795c6fSMarcus Overhagen 
127*a0795c6fSMarcus Overhagen void MediaNodePanel::mouseDown(
128*a0795c6fSMarcus Overhagen 	BPoint point,
129*a0795c6fSMarcus Overhagen 	uint32 buttons,
130*a0795c6fSMarcus Overhagen 	uint32 clicks)
131*a0795c6fSMarcus Overhagen {
132*a0795c6fSMarcus Overhagen 	D_METHOD(("MediaNodePanel::mouseDown()\n"));
133*a0795c6fSMarcus Overhagen 
134*a0795c6fSMarcus Overhagen 	_inherited::mouseDown(point, buttons, clicks);
135*a0795c6fSMarcus Overhagen 
136*a0795c6fSMarcus Overhagen 	// +++ REALLY BAD WORKAROUND
137*a0795c6fSMarcus Overhagen 	MediaJack *jack = dynamic_cast<MediaJack *>(lastItemUnder());
138*a0795c6fSMarcus Overhagen 	if (jack && jack->frame().Contains(point))
139*a0795c6fSMarcus Overhagen 	{
140*a0795c6fSMarcus Overhagen 		return;
141*a0795c6fSMarcus Overhagen 	}
142*a0795c6fSMarcus Overhagen 
143*a0795c6fSMarcus Overhagen 	switch (buttons) {
144*a0795c6fSMarcus Overhagen 		case B_PRIMARY_MOUSE_BUTTON:
145*a0795c6fSMarcus Overhagen 		{
146*a0795c6fSMarcus Overhagen 			if (clicks == 2) {
147*a0795c6fSMarcus Overhagen 				if (ref->kind() & B_CONTROLLABLE) {
148*a0795c6fSMarcus Overhagen 					BMessage message(MediaRoutingView::M_NODE_TWEAK_PARAMETERS);
149*a0795c6fSMarcus Overhagen 					DiagramView* v = view();
150*a0795c6fSMarcus Overhagen 					BMessenger(v).SendMessage(&message);
151*a0795c6fSMarcus Overhagen 				}
152*a0795c6fSMarcus Overhagen 			}
153*a0795c6fSMarcus Overhagen 			break;
154*a0795c6fSMarcus Overhagen 		}
155*a0795c6fSMarcus Overhagen 		case B_SECONDARY_MOUSE_BUTTON:
156*a0795c6fSMarcus Overhagen 		{
157*a0795c6fSMarcus Overhagen 			if (clicks == 1) {
158*a0795c6fSMarcus Overhagen 				showContextMenu(point);
159*a0795c6fSMarcus Overhagen 			}
160*a0795c6fSMarcus Overhagen 			break;
161*a0795c6fSMarcus Overhagen 		}
162*a0795c6fSMarcus Overhagen 	}
163*a0795c6fSMarcus Overhagen }
164*a0795c6fSMarcus Overhagen 
165*a0795c6fSMarcus Overhagen void MediaNodePanel::mouseOver(
166*a0795c6fSMarcus Overhagen 	BPoint point,
167*a0795c6fSMarcus Overhagen 	uint32 transit)
168*a0795c6fSMarcus Overhagen {
169*a0795c6fSMarcus Overhagen 	D_METHOD(("MediaNodePanel::mouseOver()\n"));
170*a0795c6fSMarcus Overhagen 	_inherited::mouseOver(point, transit);
171*a0795c6fSMarcus Overhagen 
172*a0795c6fSMarcus Overhagen 	switch (transit)
173*a0795c6fSMarcus Overhagen 	{
174*a0795c6fSMarcus Overhagen 		case B_ENTERED_VIEW:
175*a0795c6fSMarcus Overhagen 		{
176*a0795c6fSMarcus Overhagen 			break;
177*a0795c6fSMarcus Overhagen 		}
178*a0795c6fSMarcus Overhagen 		case B_INSIDE_VIEW:
179*a0795c6fSMarcus Overhagen 		{
180*a0795c6fSMarcus Overhagen 			BRect labelRect = m_labelRect.OffsetByCopy(frame().LeftTop());
181*a0795c6fSMarcus Overhagen 			if (labelRect.Contains(point))
182*a0795c6fSMarcus Overhagen 			{
183*a0795c6fSMarcus Overhagen 				if (!m_mouseOverLabel && m_labelTruncated)
184*a0795c6fSMarcus Overhagen 				{
185*a0795c6fSMarcus Overhagen 					TipManager *tips = TipManager::Instance();
186*a0795c6fSMarcus Overhagen 					tips->showTip(m_fullLabel.String(), view()->ConvertToScreen(labelRect));
187*a0795c6fSMarcus Overhagen 					m_mouseOverLabel = true;
188*a0795c6fSMarcus Overhagen 				}
189*a0795c6fSMarcus Overhagen 			}
190*a0795c6fSMarcus Overhagen 			else
191*a0795c6fSMarcus Overhagen 			{
192*a0795c6fSMarcus Overhagen 				m_mouseOverLabel = false;
193*a0795c6fSMarcus Overhagen 			}
194*a0795c6fSMarcus Overhagen 			break;
195*a0795c6fSMarcus Overhagen 		}
196*a0795c6fSMarcus Overhagen 		case B_EXITED_VIEW:
197*a0795c6fSMarcus Overhagen 		{
198*a0795c6fSMarcus Overhagen 			m_mouseOverLabel = false;
199*a0795c6fSMarcus Overhagen 			break;
200*a0795c6fSMarcus Overhagen 		}
201*a0795c6fSMarcus Overhagen 	}
202*a0795c6fSMarcus Overhagen }
203*a0795c6fSMarcus Overhagen 
204*a0795c6fSMarcus Overhagen void MediaNodePanel::messageDropped(
205*a0795c6fSMarcus Overhagen 	BPoint point,
206*a0795c6fSMarcus Overhagen 	BMessage *message)
207*a0795c6fSMarcus Overhagen {
208*a0795c6fSMarcus Overhagen 	D_METHOD(("MediaNodePanel::messageDropped()\n"));
209*a0795c6fSMarcus Overhagen 
210*a0795c6fSMarcus Overhagen 	// +++ REALLY BAD WORKAROUND
211*a0795c6fSMarcus Overhagen 	MediaJack *jack = dynamic_cast<MediaJack *>(itemUnder(point));
212*a0795c6fSMarcus Overhagen 	if (jack)
213*a0795c6fSMarcus Overhagen 	{
214*a0795c6fSMarcus Overhagen 		jack->messageDropped(point, message);
215*a0795c6fSMarcus Overhagen 		return;
216*a0795c6fSMarcus Overhagen 	}
217*a0795c6fSMarcus Overhagen 	else
218*a0795c6fSMarcus Overhagen 	{
219*a0795c6fSMarcus Overhagen 		be_app->SetCursor(B_HAND_CURSOR);
220*a0795c6fSMarcus Overhagen 	}
221*a0795c6fSMarcus Overhagen }
222*a0795c6fSMarcus Overhagen 
223*a0795c6fSMarcus Overhagen void MediaNodePanel::selected()
224*a0795c6fSMarcus Overhagen {
225*a0795c6fSMarcus Overhagen 	D_METHOD(("MediaNodePanel::selected()\n"));
226*a0795c6fSMarcus Overhagen 	_updateBitmap();
227*a0795c6fSMarcus Overhagen }
228*a0795c6fSMarcus Overhagen 
229*a0795c6fSMarcus Overhagen void MediaNodePanel::deselected()
230*a0795c6fSMarcus Overhagen {
231*a0795c6fSMarcus Overhagen 	D_METHOD(("MediaNodePanel::deselected()\n"));
232*a0795c6fSMarcus Overhagen 	_updateBitmap();
233*a0795c6fSMarcus Overhagen }
234*a0795c6fSMarcus Overhagen 
235*a0795c6fSMarcus Overhagen // ---------------------------------------------------------------- //
236*a0795c6fSMarcus Overhagen // *** updating
237*a0795c6fSMarcus Overhagen // ---------------------------------------------------------------- //
238*a0795c6fSMarcus Overhagen 
239*a0795c6fSMarcus Overhagen void MediaNodePanel::layoutChanged(
240*a0795c6fSMarcus Overhagen 	int32 layout)
241*a0795c6fSMarcus Overhagen {
242*a0795c6fSMarcus Overhagen 	D_METHOD(("MediaNodePanel::layoutChanged()\n"));
243*a0795c6fSMarcus Overhagen 
244*a0795c6fSMarcus Overhagen 	BPoint p = frame().LeftTop();
245*a0795c6fSMarcus Overhagen 	if (m_alternatePosition == s_invalidPosition)
246*a0795c6fSMarcus Overhagen 	{
247*a0795c6fSMarcus Overhagen 		m_alternatePosition = dynamic_cast<MediaRoutingView *>
248*a0795c6fSMarcus Overhagen 							  (view())->findFreePositionFor(this);
249*a0795c6fSMarcus Overhagen 	}
250*a0795c6fSMarcus Overhagen 	moveTo(m_alternatePosition);
251*a0795c6fSMarcus Overhagen 	m_alternatePosition = p;
252*a0795c6fSMarcus Overhagen 
253*a0795c6fSMarcus Overhagen 	resizeTo(M_DEFAULT_WIDTH, M_DEFAULT_HEIGHT);
254*a0795c6fSMarcus Overhagen 	for (uint32 i = 0; i < countItems(); i++)
255*a0795c6fSMarcus Overhagen 	{
256*a0795c6fSMarcus Overhagen 		MediaJack *jack = dynamic_cast<MediaJack *>(itemAt(i));
257*a0795c6fSMarcus Overhagen 		jack->layoutChanged(layout);
258*a0795c6fSMarcus Overhagen 	}
259*a0795c6fSMarcus Overhagen 	_updateIcon(layout);
260*a0795c6fSMarcus Overhagen 	_prepareLabel();
261*a0795c6fSMarcus Overhagen 	arrangeIOJacks();
262*a0795c6fSMarcus Overhagen 	_updateBitmap();
263*a0795c6fSMarcus Overhagen }
264*a0795c6fSMarcus Overhagen 
265*a0795c6fSMarcus Overhagen void MediaNodePanel::populateInit()
266*a0795c6fSMarcus Overhagen {
267*a0795c6fSMarcus Overhagen 	D_METHOD(("MediaNodePanel::populateInit()\n"));
268*a0795c6fSMarcus Overhagen 	if (ref->kind() & B_BUFFER_CONSUMER)
269*a0795c6fSMarcus Overhagen 	{
270*a0795c6fSMarcus Overhagen 		vector<media_input> freeInputs;
271*a0795c6fSMarcus Overhagen 		ref->getFreeInputs(freeInputs);
272*a0795c6fSMarcus Overhagen 		for (uint32 i = 0; i < freeInputs.size(); i++)
273*a0795c6fSMarcus Overhagen 		{
274*a0795c6fSMarcus Overhagen 			addItem(new MediaJack(freeInputs[i]));
275*a0795c6fSMarcus Overhagen 		}
276*a0795c6fSMarcus Overhagen 	}
277*a0795c6fSMarcus Overhagen 	if (ref->kind() & B_BUFFER_PRODUCER)
278*a0795c6fSMarcus Overhagen 	{
279*a0795c6fSMarcus Overhagen 		vector<media_output> freeOutputs;
280*a0795c6fSMarcus Overhagen 		ref->getFreeOutputs(freeOutputs);
281*a0795c6fSMarcus Overhagen 		for (uint32 i = 0; i < freeOutputs.size(); i++)
282*a0795c6fSMarcus Overhagen 		{
283*a0795c6fSMarcus Overhagen 			addItem(new MediaJack(freeOutputs[i]));
284*a0795c6fSMarcus Overhagen 		}
285*a0795c6fSMarcus Overhagen 	}
286*a0795c6fSMarcus Overhagen }
287*a0795c6fSMarcus Overhagen 
288*a0795c6fSMarcus Overhagen void MediaNodePanel::updateIOJacks()
289*a0795c6fSMarcus Overhagen {
290*a0795c6fSMarcus Overhagen 	D_METHOD(("MediaNodePanel::updateIOJacks()\n"));
291*a0795c6fSMarcus Overhagen 
292*a0795c6fSMarcus Overhagen 	// remove all free inputs/outputs, they may be outdated
293*a0795c6fSMarcus Overhagen 	for (uint32 i = 0; i < countItems(); i++)
294*a0795c6fSMarcus Overhagen 	{
295*a0795c6fSMarcus Overhagen 		MediaJack *jack = dynamic_cast<MediaJack *>(itemAt(i));
296*a0795c6fSMarcus Overhagen 		if (jack && !jack->isConnected())
297*a0795c6fSMarcus Overhagen 		{
298*a0795c6fSMarcus Overhagen 			removeItem(jack);
299*a0795c6fSMarcus Overhagen 			delete jack;
300*a0795c6fSMarcus Overhagen 			i--; // account for reindexing in the BList
301*a0795c6fSMarcus Overhagen 		}
302*a0795c6fSMarcus Overhagen 	}
303*a0795c6fSMarcus Overhagen 
304*a0795c6fSMarcus Overhagen 	// add free inputs
305*a0795c6fSMarcus Overhagen 	if (ref->kind() & B_BUFFER_CONSUMER)
306*a0795c6fSMarcus Overhagen 	{
307*a0795c6fSMarcus Overhagen 		vector<media_input> freeInputs;
308*a0795c6fSMarcus Overhagen 		ref->getFreeInputs(freeInputs);
309*a0795c6fSMarcus Overhagen 		for (uint32 i = 0; i < freeInputs.size(); i++)
310*a0795c6fSMarcus Overhagen 		{
311*a0795c6fSMarcus Overhagen 			MediaJack *jack;
312*a0795c6fSMarcus Overhagen 			addItem(jack = new MediaJack(freeInputs[i]));
313*a0795c6fSMarcus Overhagen 		}
314*a0795c6fSMarcus Overhagen 	}
315*a0795c6fSMarcus Overhagen 
316*a0795c6fSMarcus Overhagen 	// add free outputs
317*a0795c6fSMarcus Overhagen 	if (ref->kind() & B_BUFFER_PRODUCER)
318*a0795c6fSMarcus Overhagen 	{
319*a0795c6fSMarcus Overhagen 		vector<media_output> freeOutputs;
320*a0795c6fSMarcus Overhagen 		ref->getFreeOutputs(freeOutputs);
321*a0795c6fSMarcus Overhagen 		for (uint32 i = 0; i < freeOutputs.size(); i++)
322*a0795c6fSMarcus Overhagen 		{
323*a0795c6fSMarcus Overhagen 			MediaJack *jack;
324*a0795c6fSMarcus Overhagen 			addItem(jack = new MediaJack(freeOutputs[i]));
325*a0795c6fSMarcus Overhagen 		}
326*a0795c6fSMarcus Overhagen 	}
327*a0795c6fSMarcus Overhagen 
328*a0795c6fSMarcus Overhagen 	// the supported media types might have changed -> this could
329*a0795c6fSMarcus Overhagen 	// require changing the icon
330*a0795c6fSMarcus Overhagen 	_updateIcon(dynamic_cast<MediaRoutingView *>(view())->getLayout());
331*a0795c6fSMarcus Overhagen }
332*a0795c6fSMarcus Overhagen 
333*a0795c6fSMarcus Overhagen void MediaNodePanel::arrangeIOJacks()
334*a0795c6fSMarcus Overhagen {
335*a0795c6fSMarcus Overhagen 	D_METHOD(("MediaNodePanel::arrangeIOJacks()\n"));
336*a0795c6fSMarcus Overhagen 	sortItems(DiagramItem::M_ENDPOINT, &compareTypeAndID);
337*a0795c6fSMarcus Overhagen 
338*a0795c6fSMarcus Overhagen 	switch (dynamic_cast<MediaRoutingView *>(view())->getLayout())
339*a0795c6fSMarcus Overhagen 	{
340*a0795c6fSMarcus Overhagen 		case MediaRoutingView::M_ICON_VIEW:
341*a0795c6fSMarcus Overhagen 		{
342*a0795c6fSMarcus Overhagen 			BRegion updateRegion;
343*a0795c6fSMarcus Overhagen 			float align = 1.0;
344*a0795c6fSMarcus Overhagen 			view()->getItemAlignment(0, &align);
345*a0795c6fSMarcus Overhagen 
346*a0795c6fSMarcus Overhagen 			// adjust this panel's size
347*a0795c6fSMarcus Overhagen 			int32 numInputs = 0, numOutputs = 0;
348*a0795c6fSMarcus Overhagen 			for (uint32 i = 0; i < countItems(); i++)
349*a0795c6fSMarcus Overhagen 			{
350*a0795c6fSMarcus Overhagen 				MediaJack *jack = dynamic_cast<MediaJack *>(itemAt(i));
351*a0795c6fSMarcus Overhagen 				if (jack)
352*a0795c6fSMarcus Overhagen 				{
353*a0795c6fSMarcus Overhagen 					if (jack->isInput())
354*a0795c6fSMarcus Overhagen 					{
355*a0795c6fSMarcus Overhagen 						numInputs++;
356*a0795c6fSMarcus Overhagen 					}
357*a0795c6fSMarcus Overhagen 					if (jack->isOutput())
358*a0795c6fSMarcus Overhagen 					{
359*a0795c6fSMarcus Overhagen 						numOutputs++;
360*a0795c6fSMarcus Overhagen 					}
361*a0795c6fSMarcus Overhagen 				}
362*a0795c6fSMarcus Overhagen 			}
363*a0795c6fSMarcus Overhagen 			float minHeight = MediaJack::M_DEFAULT_HEIGHT + MediaJack::M_DEFAULT_GAP;
364*a0795c6fSMarcus Overhagen 			minHeight *= numInputs > numOutputs ? numInputs : numOutputs;
365*a0795c6fSMarcus Overhagen 			minHeight += m_labelRect.Height();
366*a0795c6fSMarcus Overhagen 			minHeight += 2 * MediaJack::M_DEFAULT_GAP;
367*a0795c6fSMarcus Overhagen 			minHeight = ((int)minHeight / (int)align) * align + align;
368*a0795c6fSMarcus Overhagen 			if ((frame().Height() < minHeight)
369*a0795c6fSMarcus Overhagen 			 || ((frame().Height() > minHeight)
370*a0795c6fSMarcus Overhagen 			 && (minHeight >= MediaNodePanel::M_DEFAULT_HEIGHT)))
371*a0795c6fSMarcus Overhagen 			{
372*a0795c6fSMarcus Overhagen 				updateRegion.Include(frame());
373*a0795c6fSMarcus Overhagen 				resizeTo(frame().Width(), minHeight);
374*a0795c6fSMarcus Overhagen 				updateRegion.Include(frame());
375*a0795c6fSMarcus Overhagen 				_prepareLabel();
376*a0795c6fSMarcus Overhagen 			}
377*a0795c6fSMarcus Overhagen 
378*a0795c6fSMarcus Overhagen 			// adjust the placement of the jacks
379*a0795c6fSMarcus Overhagen 			BRect r = m_bodyRect;
380*a0795c6fSMarcus Overhagen 			r.bottom -= M_BODY_V_MARGIN;
381*a0795c6fSMarcus Overhagen 			float inputOffset = 0.0, outputOffset = 0.0;
382*a0795c6fSMarcus Overhagen 			float center = frame().top + r.top + (r.Height() / 2.0);
383*a0795c6fSMarcus Overhagen 			center += MediaJack::M_DEFAULT_GAP - (MediaJack::M_DEFAULT_HEIGHT / 2.0);
384*a0795c6fSMarcus Overhagen 			center = ((int)center / (int)align) * align;
385*a0795c6fSMarcus Overhagen 			if (numInputs)
386*a0795c6fSMarcus Overhagen 			{
387*a0795c6fSMarcus Overhagen 				if (numInputs % 2) // odd number of inputs
388*a0795c6fSMarcus Overhagen 				{
389*a0795c6fSMarcus Overhagen 					inputOffset = center - (numInputs / 2) * (MediaJack::M_DEFAULT_HEIGHT + MediaJack::M_DEFAULT_GAP);
390*a0795c6fSMarcus Overhagen 				}
391*a0795c6fSMarcus Overhagen 				else // even number of inputs
392*a0795c6fSMarcus Overhagen 				{
393*a0795c6fSMarcus Overhagen 					inputOffset = center - ((numInputs + 1) / 2) * (MediaJack::M_DEFAULT_HEIGHT + MediaJack::M_DEFAULT_GAP);
394*a0795c6fSMarcus Overhagen 				}
395*a0795c6fSMarcus Overhagen 			}
396*a0795c6fSMarcus Overhagen 			if (numOutputs)
397*a0795c6fSMarcus Overhagen 			{
398*a0795c6fSMarcus Overhagen 				if (numOutputs % 2) // odd number of outputs
399*a0795c6fSMarcus Overhagen 				{
400*a0795c6fSMarcus Overhagen 					outputOffset = center - (numOutputs / 2) * (MediaJack::M_DEFAULT_HEIGHT + MediaJack::M_DEFAULT_GAP);
401*a0795c6fSMarcus Overhagen 				}
402*a0795c6fSMarcus Overhagen 				else // even number of outputs
403*a0795c6fSMarcus Overhagen 				{
404*a0795c6fSMarcus Overhagen 					outputOffset = center - ((numOutputs + 1) / 2) * (MediaJack::M_DEFAULT_HEIGHT + MediaJack::M_DEFAULT_GAP);
405*a0795c6fSMarcus Overhagen 				}
406*a0795c6fSMarcus Overhagen 			}
407*a0795c6fSMarcus Overhagen 			for (uint32 i = 0; i < countItems(); i++)
408*a0795c6fSMarcus Overhagen 			{
409*a0795c6fSMarcus Overhagen 				MediaJack *jack = dynamic_cast<MediaJack *>(itemAt(i));
410*a0795c6fSMarcus Overhagen 				if (jack)
411*a0795c6fSMarcus Overhagen 				{
412*a0795c6fSMarcus Overhagen 					if (jack->isInput())
413*a0795c6fSMarcus Overhagen 					{
414*a0795c6fSMarcus Overhagen 						jack->setPosition(inputOffset, frame().left, frame().right, &updateRegion);
415*a0795c6fSMarcus Overhagen 						inputOffset += jack->frame().Height() + MediaJack::M_DEFAULT_GAP;
416*a0795c6fSMarcus Overhagen 					}
417*a0795c6fSMarcus Overhagen 					if (jack->isOutput())
418*a0795c6fSMarcus Overhagen 					{
419*a0795c6fSMarcus Overhagen 						jack->setPosition(outputOffset, frame().left, frame().right, &updateRegion);
420*a0795c6fSMarcus Overhagen 						outputOffset += jack->frame().Height() + MediaJack::M_DEFAULT_GAP;
421*a0795c6fSMarcus Overhagen 					}
422*a0795c6fSMarcus Overhagen 				}
423*a0795c6fSMarcus Overhagen 			}
424*a0795c6fSMarcus Overhagen 			for (int32 i = 0; i < updateRegion.CountRects(); i++)
425*a0795c6fSMarcus Overhagen 			{
426*a0795c6fSMarcus Overhagen 				view()->Invalidate(updateRegion.RectAt(i));
427*a0795c6fSMarcus Overhagen 			}
428*a0795c6fSMarcus Overhagen 			break;
429*a0795c6fSMarcus Overhagen 		}
430*a0795c6fSMarcus Overhagen 		case MediaRoutingView::M_MINI_ICON_VIEW:
431*a0795c6fSMarcus Overhagen 		{
432*a0795c6fSMarcus Overhagen 			BRegion updateRegion;
433*a0795c6fSMarcus Overhagen 			float align = 1.0;
434*a0795c6fSMarcus Overhagen 			view()->getItemAlignment(&align, 0);
435*a0795c6fSMarcus Overhagen 
436*a0795c6fSMarcus Overhagen 			// adjust this panel's size
437*a0795c6fSMarcus Overhagen 			int32 numInputs = 0, numOutputs = 0;
438*a0795c6fSMarcus Overhagen 			for (uint32 i = 0; i < countItems(); i++)
439*a0795c6fSMarcus Overhagen 			{
440*a0795c6fSMarcus Overhagen 				MediaJack *jack = dynamic_cast<MediaJack *>(itemAt(i));
441*a0795c6fSMarcus Overhagen 				if (jack)
442*a0795c6fSMarcus Overhagen 				{
443*a0795c6fSMarcus Overhagen 					if (jack->isInput())
444*a0795c6fSMarcus Overhagen 					{
445*a0795c6fSMarcus Overhagen 						numInputs++;
446*a0795c6fSMarcus Overhagen 					}
447*a0795c6fSMarcus Overhagen 					if (jack->isOutput())
448*a0795c6fSMarcus Overhagen 					{
449*a0795c6fSMarcus Overhagen 						numOutputs++;
450*a0795c6fSMarcus Overhagen 					}
451*a0795c6fSMarcus Overhagen 				}
452*a0795c6fSMarcus Overhagen 			}
453*a0795c6fSMarcus Overhagen 			float minWidth = MediaJack::M_DEFAULT_WIDTH + MediaJack::M_DEFAULT_GAP;
454*a0795c6fSMarcus Overhagen 			minWidth *= numInputs > numOutputs ? numInputs : numOutputs;
455*a0795c6fSMarcus Overhagen 			minWidth += m_bodyRect.Width();
456*a0795c6fSMarcus Overhagen 			minWidth += 2 * MediaJack::M_DEFAULT_GAP;
457*a0795c6fSMarcus Overhagen 			minWidth = ((int)minWidth / (int)align) * align + align;
458*a0795c6fSMarcus Overhagen 			if ((frame().Width() < minWidth)
459*a0795c6fSMarcus Overhagen 			 || ((frame().Width() > minWidth)
460*a0795c6fSMarcus Overhagen 			 && (minWidth >= MediaNodePanel::M_DEFAULT_WIDTH)))
461*a0795c6fSMarcus Overhagen 			{
462*a0795c6fSMarcus Overhagen 				updateRegion.Include(frame());
463*a0795c6fSMarcus Overhagen 				resizeTo(minWidth, frame().Height());
464*a0795c6fSMarcus Overhagen 				updateRegion.Include(frame());
465*a0795c6fSMarcus Overhagen 				_prepareLabel();
466*a0795c6fSMarcus Overhagen 			}
467*a0795c6fSMarcus Overhagen 			// adjust the placement of the jacks
468*a0795c6fSMarcus Overhagen 			float inputOffset = 0.0, outputOffset = 0.0;
469*a0795c6fSMarcus Overhagen 			float center = frame().left + m_labelRect.left + (m_labelRect.Width() / 2.0);
470*a0795c6fSMarcus Overhagen 			center += MediaJack::M_DEFAULT_GAP - (MediaJack::M_DEFAULT_WIDTH / 2.0);
471*a0795c6fSMarcus Overhagen 			center = ((int)center / (int)align) * align;
472*a0795c6fSMarcus Overhagen 			if (numInputs)
473*a0795c6fSMarcus Overhagen 			{
474*a0795c6fSMarcus Overhagen 				if (numInputs % 2) // odd number of inputs
475*a0795c6fSMarcus Overhagen 				{
476*a0795c6fSMarcus Overhagen 					inputOffset = center - (numInputs / 2) * (MediaJack::M_DEFAULT_WIDTH + MediaJack::M_DEFAULT_GAP);
477*a0795c6fSMarcus Overhagen 				}
478*a0795c6fSMarcus Overhagen 				else // even number of inputs
479*a0795c6fSMarcus Overhagen 				{
480*a0795c6fSMarcus Overhagen 					inputOffset = center - ((numInputs + 1) / 2) * (MediaJack::M_DEFAULT_WIDTH + MediaJack::M_DEFAULT_GAP);
481*a0795c6fSMarcus Overhagen 				}
482*a0795c6fSMarcus Overhagen 			}
483*a0795c6fSMarcus Overhagen 			if (numOutputs)
484*a0795c6fSMarcus Overhagen 			{
485*a0795c6fSMarcus Overhagen 				if (numOutputs % 2) // odd number of outputs
486*a0795c6fSMarcus Overhagen 				{
487*a0795c6fSMarcus Overhagen 					outputOffset = center - (numOutputs / 2) * (MediaJack::M_DEFAULT_WIDTH + MediaJack::M_DEFAULT_GAP);
488*a0795c6fSMarcus Overhagen 				}
489*a0795c6fSMarcus Overhagen 				else // even number of outputs
490*a0795c6fSMarcus Overhagen 				{
491*a0795c6fSMarcus Overhagen 					outputOffset = center - ((numOutputs + 1) / 2) * (MediaJack::M_DEFAULT_WIDTH + MediaJack::M_DEFAULT_GAP);
492*a0795c6fSMarcus Overhagen 				}
493*a0795c6fSMarcus Overhagen 			}
494*a0795c6fSMarcus Overhagen 			for (uint32 i = 0; i < countItems(); i++)
495*a0795c6fSMarcus Overhagen 			{
496*a0795c6fSMarcus Overhagen 				MediaJack *jack = dynamic_cast<MediaJack *>(itemAt(i));
497*a0795c6fSMarcus Overhagen 				if (jack)
498*a0795c6fSMarcus Overhagen 				{
499*a0795c6fSMarcus Overhagen 					if (jack->isInput())
500*a0795c6fSMarcus Overhagen 					{
501*a0795c6fSMarcus Overhagen 						jack->setPosition(inputOffset, frame().top, frame().bottom, &updateRegion);
502*a0795c6fSMarcus Overhagen 						inputOffset += jack->frame().Width() + MediaJack::M_DEFAULT_GAP;
503*a0795c6fSMarcus Overhagen 					}
504*a0795c6fSMarcus Overhagen 					if (jack->isOutput())
505*a0795c6fSMarcus Overhagen 					{
506*a0795c6fSMarcus Overhagen 						jack->setPosition(outputOffset, frame().top, frame().bottom, &updateRegion);
507*a0795c6fSMarcus Overhagen 						outputOffset += jack->frame().Width() + MediaJack::M_DEFAULT_GAP;
508*a0795c6fSMarcus Overhagen 					}
509*a0795c6fSMarcus Overhagen 				}
510*a0795c6fSMarcus Overhagen 			}
511*a0795c6fSMarcus Overhagen 			for (int32 i = 0; i < updateRegion.CountRects(); i++)
512*a0795c6fSMarcus Overhagen 			{
513*a0795c6fSMarcus Overhagen 				view()->Invalidate(updateRegion.RectAt(i));
514*a0795c6fSMarcus Overhagen 			}
515*a0795c6fSMarcus Overhagen 			break;
516*a0795c6fSMarcus Overhagen 		}
517*a0795c6fSMarcus Overhagen 	}
518*a0795c6fSMarcus Overhagen 	_updateBitmap();
519*a0795c6fSMarcus Overhagen }
520*a0795c6fSMarcus Overhagen 
521*a0795c6fSMarcus Overhagen void MediaNodePanel::showContextMenu(
522*a0795c6fSMarcus Overhagen 	BPoint point)
523*a0795c6fSMarcus Overhagen {
524*a0795c6fSMarcus Overhagen 	D_METHOD(("MediaNodePanel::showContextMenu()\n"));
525*a0795c6fSMarcus Overhagen 
526*a0795c6fSMarcus Overhagen 	BPopUpMenu *menu = new BPopUpMenu("MediaNodePanel PopUp", false, false, B_ITEMS_IN_COLUMN);
527*a0795c6fSMarcus Overhagen 	menu->SetFont(be_plain_font);
528*a0795c6fSMarcus Overhagen 
529*a0795c6fSMarcus Overhagen 	BMenuItem *item;
530*a0795c6fSMarcus Overhagen 	BMessage *message;
531*a0795c6fSMarcus Overhagen 
532*a0795c6fSMarcus Overhagen 	// add the "Tweak Parameters" item
533*a0795c6fSMarcus Overhagen 	message = new BMessage(MediaRoutingView::M_NODE_TWEAK_PARAMETERS);
534*a0795c6fSMarcus Overhagen 	menu->AddItem(item = new BMenuItem("Tweak Parameters", message, 'P'));
535*a0795c6fSMarcus Overhagen 	if (!(ref->kind() & B_CONTROLLABLE))
536*a0795c6fSMarcus Overhagen 	{
537*a0795c6fSMarcus Overhagen 		item->SetEnabled(false);
538*a0795c6fSMarcus Overhagen 	}
539*a0795c6fSMarcus Overhagen 
540*a0795c6fSMarcus Overhagen 	message = new BMessage(InfoWindowManager::M_INFO_WINDOW_REQUESTED);
541*a0795c6fSMarcus Overhagen 	message->AddInt32("nodeID", ref->id());
542*a0795c6fSMarcus Overhagen 	menu->AddItem(new BMenuItem("Get Info", message, 'I'));
543*a0795c6fSMarcus Overhagen 	menu->AddSeparatorItem();
544*a0795c6fSMarcus Overhagen 
545*a0795c6fSMarcus Overhagen 	menu->AddItem(item = new BMenuItem("Release", new BMessage(MediaRoutingView::M_DELETE_SELECTION), 'T'));
546*a0795c6fSMarcus Overhagen 	if (!ref->isInternal())
547*a0795c6fSMarcus Overhagen 	{
548*a0795c6fSMarcus Overhagen 		item->SetEnabled(false);
549*a0795c6fSMarcus Overhagen 	}
550*a0795c6fSMarcus Overhagen 	menu->AddSeparatorItem();
551*a0795c6fSMarcus Overhagen 
552*a0795c6fSMarcus Overhagen 	// add the "Cycle" item
553*a0795c6fSMarcus Overhagen 	message = new BMessage(MediaRoutingView::M_NODE_CHANGE_CYCLING);
554*a0795c6fSMarcus Overhagen 	message->AddBool("cycle", !ref->isCycling());
555*a0795c6fSMarcus Overhagen 	menu->AddItem(item = new BMenuItem("Cycle", message));
556*a0795c6fSMarcus Overhagen 	item->SetMarked(ref->isCycling());
557*a0795c6fSMarcus Overhagen 	if (ref->flags() & NodeRef::NO_SEEK)
558*a0795c6fSMarcus Overhagen 	{
559*a0795c6fSMarcus Overhagen 		item->SetEnabled(false);
560*a0795c6fSMarcus Overhagen 	}
561*a0795c6fSMarcus Overhagen 
562*a0795c6fSMarcus Overhagen 	// add the "Run Mode" sub menu
563*a0795c6fSMarcus Overhagen 	BMenu *subMenu = new BMenu("Run Mode");
564*a0795c6fSMarcus Overhagen 	subMenu->SetFont(be_plain_font);
565*a0795c6fSMarcus Overhagen 	for (uint32 runMode = 1; runMode <= BMediaNode::B_RECORDING; runMode++)
566*a0795c6fSMarcus Overhagen 	{
567*a0795c6fSMarcus Overhagen 		BString itemName = MediaString::getStringFor(static_cast<BMediaNode::run_mode>
568*a0795c6fSMarcus Overhagen 													 (runMode));
569*a0795c6fSMarcus Overhagen 		message = new BMessage(MediaRoutingView::M_NODE_CHANGE_RUN_MODE);
570*a0795c6fSMarcus Overhagen 		message->AddInt32("run_mode", runMode);
571*a0795c6fSMarcus Overhagen 		subMenu->AddItem(item = new BMenuItem(itemName.String(), message));
572*a0795c6fSMarcus Overhagen 		if (ref->runMode() == runMode)
573*a0795c6fSMarcus Overhagen 		{
574*a0795c6fSMarcus Overhagen 			item->SetMarked(true);
575*a0795c6fSMarcus Overhagen 		}
576*a0795c6fSMarcus Overhagen 		else if ((ref->runMode() == 0)
577*a0795c6fSMarcus Overhagen 			  && (ref->group()) && (ref->group()->runMode() == BMediaNode::run_mode(runMode)))
578*a0795c6fSMarcus Overhagen 		{
579*a0795c6fSMarcus Overhagen 			item->SetMarked(true);
580*a0795c6fSMarcus Overhagen 		}
581*a0795c6fSMarcus Overhagen 	}
582*a0795c6fSMarcus Overhagen 	subMenu->AddSeparatorItem();
583*a0795c6fSMarcus Overhagen 	message = new BMessage(MediaRoutingView::M_NODE_CHANGE_RUN_MODE);
584*a0795c6fSMarcus Overhagen 	message->AddInt32("run_mode", 0);
585*a0795c6fSMarcus Overhagen 	subMenu->AddItem(item = new BMenuItem("(same as group)", message));
586*a0795c6fSMarcus Overhagen 	if (ref->group() == 0)
587*a0795c6fSMarcus Overhagen 	{
588*a0795c6fSMarcus Overhagen 		item->SetEnabled(false);
589*a0795c6fSMarcus Overhagen 	}
590*a0795c6fSMarcus Overhagen 	else if ((ref->runMode() < 1) && (ref->group()->runMode() > 0))
591*a0795c6fSMarcus Overhagen 	{
592*a0795c6fSMarcus Overhagen 		item->SetMarked(true);
593*a0795c6fSMarcus Overhagen 	}
594*a0795c6fSMarcus Overhagen 	menu->AddItem(subMenu);
595*a0795c6fSMarcus Overhagen 	subMenu->SetTargetForItems(view());
596*a0795c6fSMarcus Overhagen 
597*a0795c6fSMarcus Overhagen 	// [c.lenz 24dec99] hide rarely used commands in a 'Advanced' submenu
598*a0795c6fSMarcus Overhagen 	subMenu = new BMenu("Advanced");
599*a0795c6fSMarcus Overhagen 	subMenu->SetFont(be_plain_font);
600*a0795c6fSMarcus Overhagen 	// [e.moon 5dec99] ad-hoc timesource support
601*a0795c6fSMarcus Overhagen 	if(ref->kind() & B_TIME_SOURCE) {
602*a0795c6fSMarcus Overhagen 		message = new BMessage(MediaRoutingView::M_NODE_START_TIME_SOURCE);
603*a0795c6fSMarcus Overhagen 		message->AddInt32("nodeID", ref->id());
604*a0795c6fSMarcus Overhagen 		subMenu->AddItem(new BMenuItem(
605*a0795c6fSMarcus Overhagen 			"Start Time Source",
606*a0795c6fSMarcus Overhagen 			message));
607*a0795c6fSMarcus Overhagen 		message = new BMessage(MediaRoutingView::M_NODE_START_TIME_SOURCE);
608*a0795c6fSMarcus Overhagen 		message->AddInt32("nodeID", ref->id());
609*a0795c6fSMarcus Overhagen 		subMenu->AddItem(new BMenuItem(
610*a0795c6fSMarcus Overhagen 			"Stop Time Source",
611*a0795c6fSMarcus Overhagen 			message));
612*a0795c6fSMarcus Overhagen 	}
613*a0795c6fSMarcus Overhagen 	// [c.lenz 24dec99] support for BControllable::StartControlPanel()
614*a0795c6fSMarcus Overhagen 	if(ref->kind() & B_CONTROLLABLE) {
615*a0795c6fSMarcus Overhagen 		if (subMenu->CountItems() > 0)
616*a0795c6fSMarcus Overhagen 			subMenu->AddSeparatorItem();
617*a0795c6fSMarcus Overhagen 		message = new BMessage(MediaRoutingView::M_NODE_START_CONTROL_PANEL);
618*a0795c6fSMarcus Overhagen 		subMenu->AddItem(new BMenuItem("Start Control Panel", message,
619*a0795c6fSMarcus Overhagen 									   'P', B_COMMAND_KEY | B_SHIFT_KEY));
620*a0795c6fSMarcus Overhagen 	}
621*a0795c6fSMarcus Overhagen 	// [em 1feb00] group tweaks
622*a0795c6fSMarcus Overhagen 	if(ref->group())
623*a0795c6fSMarcus Overhagen 	{
624*a0795c6fSMarcus Overhagen 		message = new BMessage(MediaRoutingView::M_GROUP_SET_LOCKED);
625*a0795c6fSMarcus Overhagen 		message->AddInt32("groupID", ref->group()->id());
626*a0795c6fSMarcus Overhagen 		bool isLocked = (ref->group()->groupFlags() & NodeGroup::GROUP_LOCKED);
627*a0795c6fSMarcus Overhagen 		message->AddBool("locked", !isLocked);
628*a0795c6fSMarcus Overhagen 		if (subMenu->CountItems() > 0)
629*a0795c6fSMarcus Overhagen 			subMenu->AddSeparatorItem();
630*a0795c6fSMarcus Overhagen 		subMenu->AddItem(
631*a0795c6fSMarcus Overhagen 			new BMenuItem(
632*a0795c6fSMarcus Overhagen 				isLocked ? "Unlock Group" : "Lock Group", message));
633*a0795c6fSMarcus Overhagen 	}
634*a0795c6fSMarcus Overhagen 
635*a0795c6fSMarcus Overhagen 	if (subMenu->CountItems() > 0)
636*a0795c6fSMarcus Overhagen 	{
637*a0795c6fSMarcus Overhagen 		menu->AddItem(subMenu);
638*a0795c6fSMarcus Overhagen 		subMenu->SetTargetForItems(view());
639*a0795c6fSMarcus Overhagen 	}
640*a0795c6fSMarcus Overhagen 
641*a0795c6fSMarcus Overhagen 	menu->SetTargetForItems(view());
642*a0795c6fSMarcus Overhagen 	view()->ConvertToScreen(&point);
643*a0795c6fSMarcus Overhagen 	point -= BPoint(1.0, 1.0);
644*a0795c6fSMarcus Overhagen 	menu->Go(point, true, true, true);
645*a0795c6fSMarcus Overhagen }
646*a0795c6fSMarcus Overhagen 
647*a0795c6fSMarcus Overhagen // ---------------------------------------------------------------- //
648*a0795c6fSMarcus Overhagen // BHandler impl
649*a0795c6fSMarcus Overhagen // ---------------------------------------------------------------- //
650*a0795c6fSMarcus Overhagen 
651*a0795c6fSMarcus Overhagen void MediaNodePanel::MessageReceived(
652*a0795c6fSMarcus Overhagen 	BMessage *message)
653*a0795c6fSMarcus Overhagen {
654*a0795c6fSMarcus Overhagen 	D_METHOD(("MediaNodePanel::MessageReceived()\n"));
655*a0795c6fSMarcus Overhagen 	switch (message->what)
656*a0795c6fSMarcus Overhagen 	{
657*a0795c6fSMarcus Overhagen 		case NodeRef::M_INPUTS_CHANGED:
658*a0795c6fSMarcus Overhagen 		{
659*a0795c6fSMarcus Overhagen 			D_MESSAGE(("MediaNodePanel::MessageReceived(NodeRef::M_INPUTS_CHANGED)\n"));
660*a0795c6fSMarcus Overhagen 			_updateIcon(dynamic_cast<MediaRoutingView *>(view())->getLayout());
661*a0795c6fSMarcus Overhagen 			break;
662*a0795c6fSMarcus Overhagen 		}
663*a0795c6fSMarcus Overhagen 		case NodeRef::M_OUTPUTS_CHANGED:
664*a0795c6fSMarcus Overhagen 		{
665*a0795c6fSMarcus Overhagen 			D_MESSAGE(("MediaNodePanel::MessageReceived(NodeRef::M_OUTPUTS_CHANGED)\n"));
666*a0795c6fSMarcus Overhagen 			_updateIcon(dynamic_cast<MediaRoutingView *>(view())->getLayout());
667*a0795c6fSMarcus Overhagen 			break;
668*a0795c6fSMarcus Overhagen 		}
669*a0795c6fSMarcus Overhagen 		default:
670*a0795c6fSMarcus Overhagen 		{
671*a0795c6fSMarcus Overhagen 			BHandler::MessageReceived(message);
672*a0795c6fSMarcus Overhagen 			break;
673*a0795c6fSMarcus Overhagen 		}
674*a0795c6fSMarcus Overhagen 	}
675*a0795c6fSMarcus Overhagen }
676*a0795c6fSMarcus Overhagen 
677*a0795c6fSMarcus Overhagen // -------------------------------------------------------- //
678*a0795c6fSMarcus Overhagen // *** IStateArchivable
679*a0795c6fSMarcus Overhagen // -------------------------------------------------------- //
680*a0795c6fSMarcus Overhagen 
681*a0795c6fSMarcus Overhagen status_t MediaNodePanel::importState(
682*a0795c6fSMarcus Overhagen 	const BMessage*						archive) {
683*a0795c6fSMarcus Overhagen 
684*a0795c6fSMarcus Overhagen 	BPoint iconPos(s_invalidPosition);
685*a0795c6fSMarcus Overhagen 	BPoint miniIconPos(s_invalidPosition);
686*a0795c6fSMarcus Overhagen 
687*a0795c6fSMarcus Overhagen 	MediaRoutingView* v = dynamic_cast<MediaRoutingView*>(view());
688*a0795c6fSMarcus Overhagen 	ASSERT(v);
689*a0795c6fSMarcus Overhagen 	MediaRoutingView::layout_t layoutMode = v->getLayout();
690*a0795c6fSMarcus Overhagen 	archive->FindPoint("iconPos", &iconPos);
691*a0795c6fSMarcus Overhagen 	archive->FindPoint("miniIconPos", &miniIconPos);
692*a0795c6fSMarcus Overhagen 
693*a0795c6fSMarcus Overhagen 	switch(layoutMode) {
694*a0795c6fSMarcus Overhagen 		case MediaRoutingView::M_ICON_VIEW:
695*a0795c6fSMarcus Overhagen 			if(iconPos != s_invalidPosition)
696*a0795c6fSMarcus Overhagen 				moveTo(iconPos);
697*a0795c6fSMarcus Overhagen 			m_alternatePosition = miniIconPos;
698*a0795c6fSMarcus Overhagen 			break;
699*a0795c6fSMarcus Overhagen 
700*a0795c6fSMarcus Overhagen 		case MediaRoutingView::M_MINI_ICON_VIEW:
701*a0795c6fSMarcus Overhagen 			if(miniIconPos != s_invalidPosition)
702*a0795c6fSMarcus Overhagen 				moveTo(miniIconPos);
703*a0795c6fSMarcus Overhagen 			m_alternatePosition = iconPos;
704*a0795c6fSMarcus Overhagen 			break;
705*a0795c6fSMarcus Overhagen 	}
706*a0795c6fSMarcus Overhagen 
707*a0795c6fSMarcus Overhagen 	return B_OK;
708*a0795c6fSMarcus Overhagen }
709*a0795c6fSMarcus Overhagen 
710*a0795c6fSMarcus Overhagen status_t MediaNodePanel::exportState(
711*a0795c6fSMarcus Overhagen 	BMessage*									archive) const {
712*a0795c6fSMarcus Overhagen 
713*a0795c6fSMarcus Overhagen 	BPoint iconPos, miniIconPos;
714*a0795c6fSMarcus Overhagen 
715*a0795c6fSMarcus Overhagen 	MediaRoutingView* v = dynamic_cast<MediaRoutingView*>(view());
716*a0795c6fSMarcus Overhagen 	ASSERT(v);
717*a0795c6fSMarcus Overhagen 	MediaRoutingView::layout_t layoutMode = v->getLayout();
718*a0795c6fSMarcus Overhagen 	switch(layoutMode) {
719*a0795c6fSMarcus Overhagen 		case MediaRoutingView::M_ICON_VIEW:
720*a0795c6fSMarcus Overhagen 			iconPos = frame().LeftTop();
721*a0795c6fSMarcus Overhagen 			miniIconPos = m_alternatePosition;
722*a0795c6fSMarcus Overhagen 			break;
723*a0795c6fSMarcus Overhagen 
724*a0795c6fSMarcus Overhagen 		case MediaRoutingView::M_MINI_ICON_VIEW:
725*a0795c6fSMarcus Overhagen 			miniIconPos = frame().LeftTop();
726*a0795c6fSMarcus Overhagen 			iconPos = m_alternatePosition;
727*a0795c6fSMarcus Overhagen 			break;
728*a0795c6fSMarcus Overhagen 	}
729*a0795c6fSMarcus Overhagen 
730*a0795c6fSMarcus Overhagen 	if(iconPos != s_invalidPosition)
731*a0795c6fSMarcus Overhagen 		archive->AddPoint("iconPos", iconPos);
732*a0795c6fSMarcus Overhagen 	if(miniIconPos != s_invalidPosition)
733*a0795c6fSMarcus Overhagen 		archive->AddPoint("miniIconPos", miniIconPos);
734*a0795c6fSMarcus Overhagen 
735*a0795c6fSMarcus Overhagen 	// determine if I'm a 'system' node
736*a0795c6fSMarcus Overhagen 	port_info portInfo;
737*a0795c6fSMarcus Overhagen 	app_info appInfo;
738*a0795c6fSMarcus Overhagen 
739*a0795c6fSMarcus Overhagen 	if ((get_port_info(ref->node().port, &portInfo) == B_OK)
740*a0795c6fSMarcus Overhagen 		&& (be_roster->GetRunningAppInfo(portInfo.team, &appInfo) == B_OK)) {
741*a0795c6fSMarcus Overhagen 		BEntry appEntry(&appInfo.ref);
742*a0795c6fSMarcus Overhagen 		char appName[B_FILE_NAME_LENGTH];
743*a0795c6fSMarcus Overhagen 		if(
744*a0795c6fSMarcus Overhagen 			appEntry.InitCheck() == B_OK &&
745*a0795c6fSMarcus Overhagen 			appEntry.GetName(appName) == B_OK &&
746*a0795c6fSMarcus Overhagen 			(!strcmp(appName, "media_addon_server") ||
747*a0795c6fSMarcus Overhagen 			 !strcmp(appName, "audio_server"))) {
748*a0795c6fSMarcus Overhagen 
749*a0795c6fSMarcus Overhagen 			archive->AddBool("sysOwned", true);
750*a0795c6fSMarcus Overhagen 		}
751*a0795c6fSMarcus Overhagen 	}
752*a0795c6fSMarcus Overhagen 
753*a0795c6fSMarcus Overhagen 	return B_OK;
754*a0795c6fSMarcus Overhagen }
755*a0795c6fSMarcus Overhagen 
756*a0795c6fSMarcus Overhagen // ---------------------------------------------------------------- //
757*a0795c6fSMarcus Overhagen // *** internal operations
758*a0795c6fSMarcus Overhagen // ---------------------------------------------------------------- //
759*a0795c6fSMarcus Overhagen 
760*a0795c6fSMarcus Overhagen void MediaNodePanel::_prepareLabel()
761*a0795c6fSMarcus Overhagen {
762*a0795c6fSMarcus Overhagen 	// find out if its a file node first
763*a0795c6fSMarcus Overhagen 	if (ref->kind() & B_FILE_INTERFACE)
764*a0795c6fSMarcus Overhagen 	{
765*a0795c6fSMarcus Overhagen 		entry_ref nodeFile;
766*a0795c6fSMarcus Overhagen 		status_t error = BMediaRoster::Roster()->GetRefFor(ref->node(),	&nodeFile);
767*a0795c6fSMarcus Overhagen 		if (error)
768*a0795c6fSMarcus Overhagen 		{
769*a0795c6fSMarcus Overhagen 			m_fullLabel = ref->name();
770*a0795c6fSMarcus Overhagen 			m_fullLabel += " (no file)";
771*a0795c6fSMarcus Overhagen 		}
772*a0795c6fSMarcus Overhagen 		else
773*a0795c6fSMarcus Overhagen 		{
774*a0795c6fSMarcus Overhagen 			BEntry entry(&nodeFile);
775*a0795c6fSMarcus Overhagen 			char fileName[B_FILE_NAME_LENGTH];
776*a0795c6fSMarcus Overhagen 			entry.GetName(fileName);
777*a0795c6fSMarcus Overhagen 			m_fullLabel = fileName;
778*a0795c6fSMarcus Overhagen 		}
779*a0795c6fSMarcus Overhagen 	}
780*a0795c6fSMarcus Overhagen 	else
781*a0795c6fSMarcus Overhagen 	{
782*a0795c6fSMarcus Overhagen 		m_fullLabel = ref->name();
783*a0795c6fSMarcus Overhagen 	}
784*a0795c6fSMarcus Overhagen 
785*a0795c6fSMarcus Overhagen 	int32 layout = dynamic_cast<MediaRoutingView *>(view())->getLayout();
786*a0795c6fSMarcus Overhagen 
787*a0795c6fSMarcus Overhagen 	// Construct labelRect
788*a0795c6fSMarcus Overhagen 	font_height fh;
789*a0795c6fSMarcus Overhagen 	be_plain_font->GetHeight(&fh);
790*a0795c6fSMarcus Overhagen 	switch (layout)
791*a0795c6fSMarcus Overhagen 	{
792*a0795c6fSMarcus Overhagen 		case MediaRoutingView::M_ICON_VIEW:
793*a0795c6fSMarcus Overhagen 		{
794*a0795c6fSMarcus Overhagen 			m_labelRect = frame();
795*a0795c6fSMarcus Overhagen 			m_labelRect.OffsetTo(0.0, 0.0);
796*a0795c6fSMarcus Overhagen 			m_labelRect.bottom = 2 * M_LABEL_V_MARGIN + (fh.ascent + fh.descent + fh.leading) + 1.0;
797*a0795c6fSMarcus Overhagen 			break;
798*a0795c6fSMarcus Overhagen 		}
799*a0795c6fSMarcus Overhagen 		case MediaRoutingView::M_MINI_ICON_VIEW:
800*a0795c6fSMarcus Overhagen 		{
801*a0795c6fSMarcus Overhagen 			m_labelRect = frame();
802*a0795c6fSMarcus Overhagen 			m_labelRect.OffsetTo(0.0, 0.0);
803*a0795c6fSMarcus Overhagen 			m_labelRect.left = M_BODY_H_MARGIN + B_MINI_ICON;
804*a0795c6fSMarcus Overhagen 			m_labelRect.top += MediaJack::M_DEFAULT_HEIGHT;
805*a0795c6fSMarcus Overhagen 			m_labelRect.bottom -= MediaJack::M_DEFAULT_HEIGHT;
806*a0795c6fSMarcus Overhagen 			break;
807*a0795c6fSMarcus Overhagen 		}
808*a0795c6fSMarcus Overhagen 	}
809*a0795c6fSMarcus Overhagen 
810*a0795c6fSMarcus Overhagen 	// truncate the label to fit in the panel
811*a0795c6fSMarcus Overhagen 	float maxWidth = m_labelRect.Width() - (2.0 * M_LABEL_H_MARGIN) - 2.0;
812*a0795c6fSMarcus Overhagen 	if (be_plain_font->StringWidth(m_fullLabel.String()) > maxWidth)
813*a0795c6fSMarcus Overhagen 	{
814*a0795c6fSMarcus Overhagen 		char *truncatedLabel[1];
815*a0795c6fSMarcus Overhagen 		truncatedLabel[0] = new char[B_MEDIA_NAME_LENGTH];
816*a0795c6fSMarcus Overhagen 		const char *originalLabel[1];
817*a0795c6fSMarcus Overhagen 		originalLabel[0] = new char[B_MEDIA_NAME_LENGTH];
818*a0795c6fSMarcus Overhagen 		m_fullLabel.CopyInto(const_cast<char *>(originalLabel[0]), 0, B_MEDIA_NAME_LENGTH);
819*a0795c6fSMarcus Overhagen 		be_plain_font->GetTruncatedStrings(originalLabel, 1, B_TRUNCATE_END, maxWidth, (char **) truncatedLabel);
820*a0795c6fSMarcus Overhagen 		m_label = truncatedLabel[0];
821*a0795c6fSMarcus Overhagen 		m_labelTruncated = true;
822*a0795c6fSMarcus Overhagen 		delete [] originalLabel[0];
823*a0795c6fSMarcus Overhagen 		delete [] truncatedLabel[0];
824*a0795c6fSMarcus Overhagen 	}
825*a0795c6fSMarcus Overhagen 	else
826*a0795c6fSMarcus Overhagen 	{
827*a0795c6fSMarcus Overhagen 		m_label = m_fullLabel;
828*a0795c6fSMarcus Overhagen 		m_labelTruncated = false;
829*a0795c6fSMarcus Overhagen 	}
830*a0795c6fSMarcus Overhagen 
831*a0795c6fSMarcus Overhagen 	// Construct labelOffset
832*a0795c6fSMarcus Overhagen 	float fw = be_plain_font->StringWidth(m_label.String());
833*a0795c6fSMarcus Overhagen 	m_labelOffset.x = m_labelRect.left + m_labelRect.Width() / 2.0 - fw / 2.0;
834*a0795c6fSMarcus Overhagen 	m_labelOffset.y = m_labelRect.bottom - M_LABEL_V_MARGIN - fh.descent - (fh.leading / 2.0) - 1.0;
835*a0795c6fSMarcus Overhagen 
836*a0795c6fSMarcus Overhagen 	// Construct bodyRect
837*a0795c6fSMarcus Overhagen 	switch (layout)
838*a0795c6fSMarcus Overhagen 	{
839*a0795c6fSMarcus Overhagen 		case MediaRoutingView::M_ICON_VIEW:
840*a0795c6fSMarcus Overhagen 		{
841*a0795c6fSMarcus Overhagen 			m_bodyRect = frame();
842*a0795c6fSMarcus Overhagen 			m_bodyRect.OffsetTo(0.0, 0.0);
843*a0795c6fSMarcus Overhagen 			m_bodyRect.top = m_labelRect.bottom;
844*a0795c6fSMarcus Overhagen 			break;
845*a0795c6fSMarcus Overhagen 		}
846*a0795c6fSMarcus Overhagen 		case MediaRoutingView::M_MINI_ICON_VIEW:
847*a0795c6fSMarcus Overhagen 		{
848*a0795c6fSMarcus Overhagen 			m_bodyRect = frame();
849*a0795c6fSMarcus Overhagen 			m_bodyRect.OffsetTo(0.0, 0.0);
850*a0795c6fSMarcus Overhagen 			m_bodyRect.right = m_labelRect.left;
851*a0795c6fSMarcus Overhagen 			break;
852*a0795c6fSMarcus Overhagen 		}
853*a0795c6fSMarcus Overhagen 	}
854*a0795c6fSMarcus Overhagen }
855*a0795c6fSMarcus Overhagen 
856*a0795c6fSMarcus Overhagen void MediaNodePanel::_updateBitmap()
857*a0795c6fSMarcus Overhagen {
858*a0795c6fSMarcus Overhagen 	if (m_bitmap)
859*a0795c6fSMarcus Overhagen 	{
860*a0795c6fSMarcus Overhagen 		delete m_bitmap;
861*a0795c6fSMarcus Overhagen 	}
862*a0795c6fSMarcus Overhagen 	BBitmap *tempBitmap = new BBitmap(frame().OffsetToCopy(0.0, 0.0), B_CMAP8, true);
863*a0795c6fSMarcus Overhagen 	tempBitmap->Lock();
864*a0795c6fSMarcus Overhagen 	{
865*a0795c6fSMarcus Overhagen 		BView *tempView = new BView(tempBitmap->Bounds(), "", B_FOLLOW_NONE, 0);
866*a0795c6fSMarcus Overhagen 		tempBitmap->AddChild(tempView);
867*a0795c6fSMarcus Overhagen 		tempView->SetOrigin(0.0, 0.0);
868*a0795c6fSMarcus Overhagen 
869*a0795c6fSMarcus Overhagen 		int32 layout = dynamic_cast<MediaRoutingView *>(view())->getLayout();
870*a0795c6fSMarcus Overhagen 		_drawInto(tempView, tempView->Bounds(), layout);
871*a0795c6fSMarcus Overhagen 
872*a0795c6fSMarcus Overhagen 		tempView->Sync();
873*a0795c6fSMarcus Overhagen 		tempBitmap->RemoveChild(tempView);
874*a0795c6fSMarcus Overhagen 		delete tempView;
875*a0795c6fSMarcus Overhagen 	}
876*a0795c6fSMarcus Overhagen 	tempBitmap->Unlock();
877*a0795c6fSMarcus Overhagen 	m_bitmap = new BBitmap(tempBitmap);
878*a0795c6fSMarcus Overhagen 	delete tempBitmap;
879*a0795c6fSMarcus Overhagen }
880*a0795c6fSMarcus Overhagen 
881*a0795c6fSMarcus Overhagen void MediaNodePanel::_drawInto(
882*a0795c6fSMarcus Overhagen 	BView *target,
883*a0795c6fSMarcus Overhagen 	BRect targetRect,
884*a0795c6fSMarcus Overhagen 	int32 layout)
885*a0795c6fSMarcus Overhagen {
886*a0795c6fSMarcus Overhagen 	switch (layout)
887*a0795c6fSMarcus Overhagen 	{
888*a0795c6fSMarcus Overhagen 		case MediaRoutingView::M_ICON_VIEW:
889*a0795c6fSMarcus Overhagen 		{
890*a0795c6fSMarcus Overhagen 			BRect r;
891*a0795c6fSMarcus Overhagen 			BPoint p;
892*a0795c6fSMarcus Overhagen 
893*a0795c6fSMarcus Overhagen 			// Draw borders
894*a0795c6fSMarcus Overhagen 			r = targetRect;
895*a0795c6fSMarcus Overhagen 			target->BeginLineArray(16);
896*a0795c6fSMarcus Overhagen 				target->AddLine(r.LeftTop(), r.RightTop(), M_DARK_GRAY_COLOR);
897*a0795c6fSMarcus Overhagen 				target->AddLine(r.RightTop(), r.RightBottom(), M_DARK_GRAY_COLOR);
898*a0795c6fSMarcus Overhagen 				target->AddLine(r.RightBottom(), r.LeftBottom(), M_DARK_GRAY_COLOR);
899*a0795c6fSMarcus Overhagen 				target->AddLine(r.LeftBottom(), r.LeftTop(), M_DARK_GRAY_COLOR);
900*a0795c6fSMarcus Overhagen 				r.InsetBy(1.0, 1.0);
901*a0795c6fSMarcus Overhagen 				target->AddLine(r.LeftTop(), r.RightTop(), M_LIGHT_GRAY_COLOR);
902*a0795c6fSMarcus Overhagen 				target->AddLine(r.RightTop(), r.RightBottom(), M_MED_GRAY_COLOR);
903*a0795c6fSMarcus Overhagen 				target->AddLine(r.RightBottom(), r.LeftBottom(), M_MED_GRAY_COLOR);
904*a0795c6fSMarcus Overhagen 				target->AddLine(r.LeftBottom(), r.LeftTop(), M_LIGHT_GRAY_COLOR);
905*a0795c6fSMarcus Overhagen 			target->EndLineArray();
906*a0795c6fSMarcus Overhagen 
907*a0795c6fSMarcus Overhagen 			// Fill background
908*a0795c6fSMarcus Overhagen 			r.InsetBy(1.0, 1.0);
909*a0795c6fSMarcus Overhagen 			target->SetLowColor(M_GRAY_COLOR);
910*a0795c6fSMarcus Overhagen 			target->FillRect(r, B_SOLID_LOW);
911*a0795c6fSMarcus Overhagen 
912*a0795c6fSMarcus Overhagen 			// Draw icon
913*a0795c6fSMarcus Overhagen 			if (m_icon)
914*a0795c6fSMarcus Overhagen 			{
915*a0795c6fSMarcus Overhagen 				p.x = m_bodyRect.left + m_bodyRect.Width() / 2.0 - B_LARGE_ICON / 2.0;
916*a0795c6fSMarcus Overhagen 				p.y = m_labelRect.bottom + m_bodyRect.Height() / 2.0 - B_LARGE_ICON / 2.0;
917*a0795c6fSMarcus Overhagen 				if (isSelected())
918*a0795c6fSMarcus Overhagen 				{
919*a0795c6fSMarcus Overhagen 					target->SetDrawingMode(B_OP_INVERT);
920*a0795c6fSMarcus Overhagen 					target->DrawBitmapAsync(m_icon, p);
921*a0795c6fSMarcus Overhagen 					target->SetDrawingMode(B_OP_ALPHA);
922*a0795c6fSMarcus Overhagen 					target->SetHighColor(0, 0, 0, 180);
923*a0795c6fSMarcus Overhagen 					target->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_COMPOSITE);
924*a0795c6fSMarcus Overhagen 					target->DrawBitmapAsync(m_icon, p);
925*a0795c6fSMarcus Overhagen 					target->SetDrawingMode(B_OP_OVER);
926*a0795c6fSMarcus Overhagen 				}
927*a0795c6fSMarcus Overhagen 				else
928*a0795c6fSMarcus Overhagen 				{
929*a0795c6fSMarcus Overhagen 					target->SetDrawingMode(B_OP_OVER);
930*a0795c6fSMarcus Overhagen 					target->DrawBitmapAsync(m_icon, p);
931*a0795c6fSMarcus Overhagen 				}
932*a0795c6fSMarcus Overhagen 			}
933*a0795c6fSMarcus Overhagen 
934*a0795c6fSMarcus Overhagen 			// Draw label
935*a0795c6fSMarcus Overhagen 			if (isSelected())
936*a0795c6fSMarcus Overhagen 			{
937*a0795c6fSMarcus Overhagen 				r = m_labelRect;
938*a0795c6fSMarcus Overhagen 				r.InsetBy(M_LABEL_H_MARGIN, M_LABEL_V_MARGIN);
939*a0795c6fSMarcus Overhagen 				target->BeginLineArray(4);
940*a0795c6fSMarcus Overhagen 					target->AddLine(r.LeftTop(), r.RightTop(), M_LIGHT_BLUE_COLOR);
941*a0795c6fSMarcus Overhagen 					target->AddLine(r.RightTop(), r.RightBottom(), M_LIGHT_BLUE_COLOR);
942*a0795c6fSMarcus Overhagen 					target->AddLine(r.RightBottom(), r.LeftBottom(), M_LIGHT_BLUE_COLOR);
943*a0795c6fSMarcus Overhagen 					target->AddLine(r.LeftBottom(), r.LeftTop(), M_LIGHT_BLUE_COLOR);
944*a0795c6fSMarcus Overhagen 				target->EndLineArray();
945*a0795c6fSMarcus Overhagen 				r.InsetBy(1.0, 1.0);
946*a0795c6fSMarcus Overhagen 				target->SetHighColor(M_DARK_BLUE_COLOR);
947*a0795c6fSMarcus Overhagen 				target->FillRect(r, B_SOLID_HIGH);
948*a0795c6fSMarcus Overhagen 			}
949*a0795c6fSMarcus Overhagen 			target->SetDrawingMode(B_OP_OVER);
950*a0795c6fSMarcus Overhagen 			target->SetHighColor(isSelected() ? M_WHITE_COLOR : M_BLACK_COLOR);
951*a0795c6fSMarcus Overhagen 			target->DrawString(m_label.String(), m_labelOffset);
952*a0795c6fSMarcus Overhagen 			break;
953*a0795c6fSMarcus Overhagen 		}
954*a0795c6fSMarcus Overhagen 		case MediaRoutingView::M_MINI_ICON_VIEW:
955*a0795c6fSMarcus Overhagen 		{
956*a0795c6fSMarcus Overhagen 			BRect r;
957*a0795c6fSMarcus Overhagen 			BPoint p;
958*a0795c6fSMarcus Overhagen 
959*a0795c6fSMarcus Overhagen 			// Draw borders
960*a0795c6fSMarcus Overhagen 			r = targetRect;
961*a0795c6fSMarcus Overhagen 			target->BeginLineArray(16);
962*a0795c6fSMarcus Overhagen 				target->AddLine(r.LeftTop(), r.RightTop(), M_DARK_GRAY_COLOR);
963*a0795c6fSMarcus Overhagen 				target->AddLine(r.RightTop(), r.RightBottom(), M_DARK_GRAY_COLOR);
964*a0795c6fSMarcus Overhagen 				target->AddLine(r.RightBottom(), r.LeftBottom(), M_DARK_GRAY_COLOR);
965*a0795c6fSMarcus Overhagen 				target->AddLine(r.LeftBottom(), r.LeftTop(), M_DARK_GRAY_COLOR);
966*a0795c6fSMarcus Overhagen 				r.InsetBy(1.0, 1.0);
967*a0795c6fSMarcus Overhagen 				target->AddLine(r.LeftTop(), r.RightTop(), M_LIGHT_GRAY_COLOR);
968*a0795c6fSMarcus Overhagen 				target->AddLine(r.RightTop(), r.RightBottom(), M_MED_GRAY_COLOR);
969*a0795c6fSMarcus Overhagen 				target->AddLine(r.RightBottom(), r.LeftBottom(), M_MED_GRAY_COLOR);
970*a0795c6fSMarcus Overhagen 				target->AddLine(r.LeftBottom(), r.LeftTop(), M_LIGHT_GRAY_COLOR);
971*a0795c6fSMarcus Overhagen 			target->EndLineArray();
972*a0795c6fSMarcus Overhagen 
973*a0795c6fSMarcus Overhagen 			// Fill background
974*a0795c6fSMarcus Overhagen 			r.InsetBy(1.0, 1.0);
975*a0795c6fSMarcus Overhagen 			target->SetLowColor(M_GRAY_COLOR);
976*a0795c6fSMarcus Overhagen 			target->FillRect(r, B_SOLID_LOW);
977*a0795c6fSMarcus Overhagen 
978*a0795c6fSMarcus Overhagen 			// Draw icon
979*a0795c6fSMarcus Overhagen 			if (m_icon)
980*a0795c6fSMarcus Overhagen 			{
981*a0795c6fSMarcus Overhagen 				p.x = m_bodyRect.left + M_BODY_H_MARGIN;
982*a0795c6fSMarcus Overhagen 				p.y = m_bodyRect.top + (m_bodyRect.Height() / 2.0) - (B_MINI_ICON / 2.0);
983*a0795c6fSMarcus Overhagen 				if (isSelected())
984*a0795c6fSMarcus Overhagen 				{
985*a0795c6fSMarcus Overhagen 					target->SetDrawingMode(B_OP_INVERT);
986*a0795c6fSMarcus Overhagen 					target->DrawBitmapAsync(m_icon, p);
987*a0795c6fSMarcus Overhagen 					target->SetDrawingMode(B_OP_ALPHA);
988*a0795c6fSMarcus Overhagen 					target->SetHighColor(0, 0, 0, 180);
989*a0795c6fSMarcus Overhagen 					target->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_COMPOSITE);
990*a0795c6fSMarcus Overhagen 					target->DrawBitmapAsync(m_icon, p);
991*a0795c6fSMarcus Overhagen 					target->SetDrawingMode(B_OP_OVER);
992*a0795c6fSMarcus Overhagen 				}
993*a0795c6fSMarcus Overhagen 				else
994*a0795c6fSMarcus Overhagen 				{
995*a0795c6fSMarcus Overhagen 					target->SetDrawingMode(B_OP_OVER);
996*a0795c6fSMarcus Overhagen 					target->DrawBitmapAsync(m_icon, p);
997*a0795c6fSMarcus Overhagen 				}
998*a0795c6fSMarcus Overhagen 			}
999*a0795c6fSMarcus Overhagen 
1000*a0795c6fSMarcus Overhagen 			// Draw label
1001*a0795c6fSMarcus Overhagen 			if (isSelected())
1002*a0795c6fSMarcus Overhagen 			{
1003*a0795c6fSMarcus Overhagen 				r = m_labelRect;
1004*a0795c6fSMarcus Overhagen 				r.InsetBy(M_LABEL_H_MARGIN, M_LABEL_V_MARGIN);
1005*a0795c6fSMarcus Overhagen 				target->BeginLineArray(4);
1006*a0795c6fSMarcus Overhagen 					target->AddLine(r.LeftTop(), r.RightTop(), M_LIGHT_BLUE_COLOR);
1007*a0795c6fSMarcus Overhagen 					target->AddLine(r.RightTop(), r.RightBottom(), M_LIGHT_BLUE_COLOR);
1008*a0795c6fSMarcus Overhagen 					target->AddLine(r.RightBottom(), r.LeftBottom(), M_LIGHT_BLUE_COLOR);
1009*a0795c6fSMarcus Overhagen 					target->AddLine(r.LeftBottom(), r.LeftTop(), M_LIGHT_BLUE_COLOR);
1010*a0795c6fSMarcus Overhagen 				target->EndLineArray();
1011*a0795c6fSMarcus Overhagen 				r.InsetBy(1.0, 1.0);
1012*a0795c6fSMarcus Overhagen 				target->SetHighColor(M_DARK_BLUE_COLOR);
1013*a0795c6fSMarcus Overhagen 				target->FillRect(r, B_SOLID_HIGH);
1014*a0795c6fSMarcus Overhagen 			}
1015*a0795c6fSMarcus Overhagen 			target->SetDrawingMode(B_OP_OVER);
1016*a0795c6fSMarcus Overhagen 			target->SetHighColor(isSelected() ? M_WHITE_COLOR : M_BLACK_COLOR);
1017*a0795c6fSMarcus Overhagen 			target->DrawString(m_label.String(), m_labelOffset);
1018*a0795c6fSMarcus Overhagen 			break;
1019*a0795c6fSMarcus Overhagen 		}
1020*a0795c6fSMarcus Overhagen 	}
1021*a0795c6fSMarcus Overhagen }
1022*a0795c6fSMarcus Overhagen 
1023*a0795c6fSMarcus Overhagen void MediaNodePanel::_updateIcon(
1024*a0795c6fSMarcus Overhagen 	int32 layout)
1025*a0795c6fSMarcus Overhagen {
1026*a0795c6fSMarcus Overhagen 	D_METHOD(("MediaNodePanel::_updateIcon()\n"));
1027*a0795c6fSMarcus Overhagen 
1028*a0795c6fSMarcus Overhagen 	if (m_icon)
1029*a0795c6fSMarcus Overhagen 	{
1030*a0795c6fSMarcus Overhagen 		delete m_icon;
1031*a0795c6fSMarcus Overhagen 		m_icon = 0;
1032*a0795c6fSMarcus Overhagen 	}
1033*a0795c6fSMarcus Overhagen 	RouteAppNodeManager *manager;
1034*a0795c6fSMarcus Overhagen 	manager = dynamic_cast<MediaRoutingView *>(view())->manager;
1035*a0795c6fSMarcus Overhagen 	switch (layout)
1036*a0795c6fSMarcus Overhagen 	{
1037*a0795c6fSMarcus Overhagen 		case MediaRoutingView::M_ICON_VIEW:
1038*a0795c6fSMarcus Overhagen 		{
1039*a0795c6fSMarcus Overhagen 			const MediaIcon *icon = manager->mediaIconFor(ref->id(), B_LARGE_ICON);
1040*a0795c6fSMarcus Overhagen 			m_icon = new BBitmap(dynamic_cast<const BBitmap *>(icon));
1041*a0795c6fSMarcus Overhagen 			break;
1042*a0795c6fSMarcus Overhagen 		}
1043*a0795c6fSMarcus Overhagen 		case MediaRoutingView::M_MINI_ICON_VIEW:
1044*a0795c6fSMarcus Overhagen 		{
1045*a0795c6fSMarcus Overhagen 			const MediaIcon *icon = manager->mediaIconFor(ref->id(), B_MINI_ICON);
1046*a0795c6fSMarcus Overhagen 			m_icon = new BBitmap(dynamic_cast<const BBitmap *>(icon));
1047*a0795c6fSMarcus Overhagen 			break;
1048*a0795c6fSMarcus Overhagen 		}
1049*a0795c6fSMarcus Overhagen 	}
1050*a0795c6fSMarcus Overhagen }
1051*a0795c6fSMarcus Overhagen 
1052*a0795c6fSMarcus Overhagen // -------------------------------------------------------- //
1053*a0795c6fSMarcus Overhagen // *** sorting methods (friend)
1054*a0795c6fSMarcus Overhagen // -------------------------------------------------------- //
1055*a0795c6fSMarcus Overhagen 
1056*a0795c6fSMarcus Overhagen int __CORTEX_NAMESPACE__ compareID(
1057*a0795c6fSMarcus Overhagen 	const void *lValue,
1058*a0795c6fSMarcus Overhagen 	const void *rValue)
1059*a0795c6fSMarcus Overhagen {
1060*a0795c6fSMarcus Overhagen 	int retValue = 0;
1061*a0795c6fSMarcus Overhagen 	const MediaNodePanel *lPanel = *(reinterpret_cast<MediaNodePanel * const*>(reinterpret_cast<void * const*>(lValue)));
1062*a0795c6fSMarcus Overhagen 	const MediaNodePanel *rPanel = *(reinterpret_cast<MediaNodePanel * const*>(reinterpret_cast<void * const*>(rValue)));
1063*a0795c6fSMarcus Overhagen 	if (lPanel && rPanel)
1064*a0795c6fSMarcus Overhagen 	{
1065*a0795c6fSMarcus Overhagen 		if (lPanel->ref->id() < rPanel->ref->id())
1066*a0795c6fSMarcus Overhagen 		{
1067*a0795c6fSMarcus Overhagen 			retValue = -1;
1068*a0795c6fSMarcus Overhagen 		}
1069*a0795c6fSMarcus Overhagen 		else if (lPanel->ref->id() > rPanel->ref->id())
1070*a0795c6fSMarcus Overhagen 		{
1071*a0795c6fSMarcus Overhagen 			retValue = 1;
1072*a0795c6fSMarcus Overhagen 		}
1073*a0795c6fSMarcus Overhagen 	}
1074*a0795c6fSMarcus Overhagen 	return retValue;
1075*a0795c6fSMarcus Overhagen }
1076*a0795c6fSMarcus Overhagen 
1077*a0795c6fSMarcus Overhagen // END -- MediaNodePanel.cpp --
1078