2 * Copyright (c) 1999-2000, Eric Moon.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions, and the following disclaimer.
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.
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.
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.
35 #include "MediaNodePanel.h"
37 #include "InfoWindowManager.h"
39 #include "MediaRoutingView.h"
40 #include "MediaWire.h"
41 #include "RouteAppNodeManager.h"
44 #include "NodeGroup.h"
46 #include "ParameterWindow.h"
48 #include "cortex_ui.h"
49 #include "MediaIcon.h"
50 #include "MediaString.h"
52 #include "RouteWindow.h"
54 #include "TipManager.h"
57 #include <Application.h>
61 #include <PopUpMenu.h>
63 #include <MediaDefs.h>
64 #include <MediaRoster.h>
68 __USE_CORTEX_NAMESPACE
71 #define D_METHOD(x) //PRINT (x)
72 #define D_MESSAGE(x) //PRINT (x)
73 #define D_DRAW(x) //PRINT (x)
75 // -------------------------------------------------------- //
77 // -------------------------------------------------------- //
79 float MediaNodePanel::M_DEFAULT_WIDTH
= 90.0;
80 float MediaNodePanel::M_DEFAULT_HEIGHT
= 60.0;
81 float MediaNodePanel::M_LABEL_H_MARGIN
= 3.0;
82 float MediaNodePanel::M_LABEL_V_MARGIN
= 3.0;
83 float MediaNodePanel::M_BODY_H_MARGIN
= 5.0;
84 float MediaNodePanel::M_BODY_V_MARGIN
= 5.0;
87 const BPoint
MediaNodePanel::s_invalidPosition(-200.0, -200.0);
89 // -------------------------------------------------------- //
91 // -------------------------------------------------------- //
93 MediaNodePanel::MediaNodePanel(
96 : DiagramBox(BRect(position
, position
+ BPoint(M_DEFAULT_WIDTH
, M_DEFAULT_HEIGHT
))),
97 BHandler(nodeRef
->name()),
101 m_alternatePosition(s_invalidPosition
)
103 D_METHOD(("MediaNodePanel::MediaNodePanel()\n"));
107 MediaNodePanel::~MediaNodePanel()
109 D_METHOD(("MediaNodePanel::~MediaNodePanel()\n"));
120 // -------------------------------------------------------- //
121 // *** derived from DiagramBox
122 // -------------------------------------------------------- //
124 void MediaNodePanel::attachedToDiagram()
126 D_METHOD(("MediaNodePanel::attachedToDiagram()\n"));
128 resizeTo(M_DEFAULT_WIDTH
, M_DEFAULT_HEIGHT
);
129 _updateIcon(dynamic_cast<MediaRoutingView
*>(view())->getLayout());
134 view()->Looper()->AddHandler(this);
137 void MediaNodePanel::detachedFromDiagram()
139 D_METHOD(("MediaNodePanel::detachedFromDiagram()\n"));
141 BRect labelRect
= m_labelRect
.OffsetByCopy(Frame().LeftTop());
142 if (m_mouseOverLabel
&& m_labelTruncated
)
144 TipManager
*tips
= TipManager::Instance();
145 tips
->hideTip(view()->ConvertToScreen(labelRect
));
148 view()->Looper()->RemoveHandler(this);
151 void MediaNodePanel::DrawBox()
153 D_DRAW(("MediaNodePanel::DrawBox()\n"));
156 view()->DrawBitmap(m_bitmap
, Frame().LeftTop());
160 void MediaNodePanel::MouseDown(
165 D_METHOD(("MediaNodePanel::MouseDown()\n"));
167 _inherited::MouseDown(point
, buttons
, clicks
);
169 // +++ REALLY BAD WORKAROUND
170 MediaJack
*jack
= dynamic_cast<MediaJack
*>(_LastItemUnder());
171 if (jack
&& jack
->Frame().Contains(point
))
177 case B_PRIMARY_MOUSE_BUTTON
:
180 if (ref
->kind() & B_CONTROLLABLE
) {
181 BMessage
message(MediaRoutingView::M_NODE_TWEAK_PARAMETERS
);
182 DiagramView
* v
= view();
183 BMessenger(v
).SendMessage(&message
);
188 case B_SECONDARY_MOUSE_BUTTON
:
191 showContextMenu(point
);
198 void MediaNodePanel::MouseOver(
202 D_METHOD(("MediaNodePanel::MouseOver()\n"));
203 _inherited::MouseOver(point
, transit
);
213 BRect labelRect
= m_labelRect
.OffsetByCopy(Frame().LeftTop());
214 if (labelRect
.Contains(point
))
216 if (!m_mouseOverLabel
&& m_labelTruncated
)
218 TipManager
*tips
= TipManager::Instance();
219 tips
->showTip(m_fullLabel
.String(), view()->ConvertToScreen(labelRect
));
220 m_mouseOverLabel
= true;
225 m_mouseOverLabel
= false;
231 m_mouseOverLabel
= false;
237 void MediaNodePanel::MessageDropped(
241 D_METHOD(("MediaNodePanel::MessageDropped()\n"));
243 // +++ REALLY BAD WORKAROUND
244 MediaJack
*jack
= dynamic_cast<MediaJack
*>(ItemUnder(point
));
247 jack
->MessageDropped(point
, message
);
252 be_app
->SetCursor(B_HAND_CURSOR
);
256 void MediaNodePanel::selected()
258 D_METHOD(("MediaNodePanel::selected()\n"));
262 void MediaNodePanel::deselected()
264 D_METHOD(("MediaNodePanel::deselected()\n"));
268 // ---------------------------------------------------------------- //
270 // ---------------------------------------------------------------- //
272 void MediaNodePanel::layoutChanged(
275 D_METHOD(("MediaNodePanel::layoutChanged()\n"));
277 BPoint p
= Frame().LeftTop();
278 if (m_alternatePosition
== s_invalidPosition
)
280 m_alternatePosition
= dynamic_cast<MediaRoutingView
*>
281 (view())->findFreePositionFor(this);
283 moveTo(m_alternatePosition
);
284 m_alternatePosition
= p
;
286 resizeTo(M_DEFAULT_WIDTH
, M_DEFAULT_HEIGHT
);
287 for (uint32 i
= 0; i
< CountItems(); i
++)
289 MediaJack
*jack
= dynamic_cast<MediaJack
*>(ItemAt(i
));
290 jack
->layoutChanged(layout
);
298 void MediaNodePanel::populateInit()
300 D_METHOD(("MediaNodePanel::populateInit()\n"));
301 if (ref
->kind() & B_BUFFER_CONSUMER
)
303 vector
<media_input
> freeInputs
;
304 ref
->getFreeInputs(freeInputs
);
305 for (uint32 i
= 0; i
< freeInputs
.size(); i
++)
307 AddItem(new MediaJack(freeInputs
[i
]));
310 if (ref
->kind() & B_BUFFER_PRODUCER
)
312 vector
<media_output
> freeOutputs
;
313 ref
->getFreeOutputs(freeOutputs
);
314 for (uint32 i
= 0; i
< freeOutputs
.size(); i
++)
316 AddItem(new MediaJack(freeOutputs
[i
]));
321 void MediaNodePanel::updateIOJacks()
323 D_METHOD(("MediaNodePanel::updateIOJacks()\n"));
325 // remove all free inputs/outputs, they may be outdated
326 for (uint32 i
= 0; i
< CountItems(); i
++)
328 MediaJack
*jack
= dynamic_cast<MediaJack
*>(ItemAt(i
));
329 if (jack
&& !jack
->isConnected())
333 i
--; // account for reindexing in the BList
338 if (ref
->kind() & B_BUFFER_CONSUMER
)
340 vector
<media_input
> freeInputs
;
341 ref
->getFreeInputs(freeInputs
);
342 for (uint32 i
= 0; i
< freeInputs
.size(); i
++)
345 AddItem(jack
= new MediaJack(freeInputs
[i
]));
350 if (ref
->kind() & B_BUFFER_PRODUCER
)
352 vector
<media_output
> freeOutputs
;
353 ref
->getFreeOutputs(freeOutputs
);
354 for (uint32 i
= 0; i
< freeOutputs
.size(); i
++)
357 AddItem(jack
= new MediaJack(freeOutputs
[i
]));
361 // the supported media types might have changed -> this could
362 // require changing the icon
363 _updateIcon(dynamic_cast<MediaRoutingView
*>(view())->getLayout());
366 void MediaNodePanel::arrangeIOJacks()
368 D_METHOD(("MediaNodePanel::arrangeIOJacks()\n"));
369 SortItems(DiagramItem::M_ENDPOINT
, &compareTypeAndID
);
371 switch (dynamic_cast<MediaRoutingView
*>(view())->getLayout())
373 case MediaRoutingView::M_ICON_VIEW
:
375 BRegion updateRegion
;
377 view()->GetItemAlignment(0, &align
);
379 // adjust this panel's size
380 int32 numInputs
= 0, numOutputs
= 0;
381 for (uint32 i
= 0; i
< CountItems(); i
++)
383 MediaJack
*jack
= dynamic_cast<MediaJack
*>(ItemAt(i
));
390 if (jack
->isOutput())
396 float minHeight
= MediaJack::M_DEFAULT_HEIGHT
+ MediaJack::M_DEFAULT_GAP
;
397 minHeight
*= numInputs
> numOutputs
? numInputs
: numOutputs
;
398 minHeight
+= m_labelRect
.Height();
399 minHeight
+= 2 * MediaJack::M_DEFAULT_GAP
;
400 minHeight
= ((int)minHeight
/ (int)align
) * align
+ align
;
401 if ((Frame().Height() < minHeight
)
402 || ((Frame().Height() > minHeight
)
403 && (minHeight
>= MediaNodePanel::M_DEFAULT_HEIGHT
)))
405 updateRegion
.Include(Frame());
406 resizeTo(Frame().Width(), minHeight
);
407 updateRegion
.Include(Frame());
411 // adjust the placement of the jacks
412 BRect r
= m_bodyRect
;
413 r
.bottom
-= M_BODY_V_MARGIN
;
414 float inputOffset
= 0.0, outputOffset
= 0.0;
415 float center
= Frame().top
+ r
.top
+ (r
.Height() / 2.0);
416 center
+= MediaJack::M_DEFAULT_GAP
- (MediaJack::M_DEFAULT_HEIGHT
/ 2.0);
417 center
= ((int)center
/ (int)align
) * align
;
420 if (numInputs
% 2) // odd number of inputs
422 inputOffset
= center
- (numInputs
/ 2) * (MediaJack::M_DEFAULT_HEIGHT
+ MediaJack::M_DEFAULT_GAP
);
424 else // even number of inputs
426 inputOffset
= center
- ((numInputs
+ 1) / 2) * (MediaJack::M_DEFAULT_HEIGHT
+ MediaJack::M_DEFAULT_GAP
);
431 if (numOutputs
% 2) // odd number of outputs
433 outputOffset
= center
- (numOutputs
/ 2) * (MediaJack::M_DEFAULT_HEIGHT
+ MediaJack::M_DEFAULT_GAP
);
435 else // even number of outputs
437 outputOffset
= center
- ((numOutputs
+ 1) / 2) * (MediaJack::M_DEFAULT_HEIGHT
+ MediaJack::M_DEFAULT_GAP
);
440 for (uint32 i
= 0; i
< CountItems(); i
++)
442 MediaJack
*jack
= dynamic_cast<MediaJack
*>(ItemAt(i
));
447 jack
->setPosition(inputOffset
, Frame().left
, Frame().right
, &updateRegion
);
448 inputOffset
+= jack
->Frame().Height() + MediaJack::M_DEFAULT_GAP
;
450 if (jack
->isOutput())
452 jack
->setPosition(outputOffset
, Frame().left
, Frame().right
, &updateRegion
);
453 outputOffset
+= jack
->Frame().Height() + MediaJack::M_DEFAULT_GAP
;
457 for (int32 i
= 0; i
< updateRegion
.CountRects(); i
++)
459 view()->Invalidate(updateRegion
.RectAt(i
));
463 case MediaRoutingView::M_MINI_ICON_VIEW
:
465 BRegion updateRegion
;
467 view()->GetItemAlignment(&align
, 0);
469 // adjust this panel's size
470 int32 numInputs
= 0, numOutputs
= 0;
471 for (uint32 i
= 0; i
< CountItems(); i
++)
473 MediaJack
*jack
= dynamic_cast<MediaJack
*>(ItemAt(i
));
480 if (jack
->isOutput())
486 float minWidth
= MediaJack::M_DEFAULT_WIDTH
+ MediaJack::M_DEFAULT_GAP
;
487 minWidth
*= numInputs
> numOutputs
? numInputs
: numOutputs
;
488 minWidth
+= m_bodyRect
.Width();
489 minWidth
+= 2 * MediaJack::M_DEFAULT_GAP
;
490 minWidth
= ((int)minWidth
/ (int)align
) * align
+ align
;
491 if ((Frame().Width() < minWidth
)
492 || ((Frame().Width() > minWidth
)
493 && (minWidth
>= MediaNodePanel::M_DEFAULT_WIDTH
)))
495 updateRegion
.Include(Frame());
496 resizeTo(minWidth
, Frame().Height());
497 updateRegion
.Include(Frame());
500 // adjust the placement of the jacks
501 float inputOffset
= 0.0, outputOffset
= 0.0;
502 float center
= Frame().left
+ m_labelRect
.left
+ (m_labelRect
.Width() / 2.0);
503 center
+= MediaJack::M_DEFAULT_GAP
- (MediaJack::M_DEFAULT_WIDTH
/ 2.0);
504 center
= ((int)center
/ (int)align
) * align
;
507 if (numInputs
% 2) // odd number of inputs
509 inputOffset
= center
- (numInputs
/ 2) * (MediaJack::M_DEFAULT_WIDTH
+ MediaJack::M_DEFAULT_GAP
);
511 else // even number of inputs
513 inputOffset
= center
- ((numInputs
+ 1) / 2) * (MediaJack::M_DEFAULT_WIDTH
+ MediaJack::M_DEFAULT_GAP
);
518 if (numOutputs
% 2) // odd number of outputs
520 outputOffset
= center
- (numOutputs
/ 2) * (MediaJack::M_DEFAULT_WIDTH
+ MediaJack::M_DEFAULT_GAP
);
522 else // even number of outputs
524 outputOffset
= center
- ((numOutputs
+ 1) / 2) * (MediaJack::M_DEFAULT_WIDTH
+ MediaJack::M_DEFAULT_GAP
);
527 for (uint32 i
= 0; i
< CountItems(); i
++)
529 MediaJack
*jack
= dynamic_cast<MediaJack
*>(ItemAt(i
));
534 jack
->setPosition(inputOffset
, Frame().top
, Frame().bottom
, &updateRegion
);
535 inputOffset
+= jack
->Frame().Width() + MediaJack::M_DEFAULT_GAP
;
537 if (jack
->isOutput())
539 jack
->setPosition(outputOffset
, Frame().top
, Frame().bottom
, &updateRegion
);
540 outputOffset
+= jack
->Frame().Width() + MediaJack::M_DEFAULT_GAP
;
544 for (int32 i
= 0; i
< updateRegion
.CountRects(); i
++)
546 view()->Invalidate(updateRegion
.RectAt(i
));
554 void MediaNodePanel::showContextMenu(
557 D_METHOD(("MediaNodePanel::showContextMenu()\n"));
559 BPopUpMenu
*menu
= new BPopUpMenu("MediaNodePanel PopUp", false, false, B_ITEMS_IN_COLUMN
);
560 menu
->SetFont(be_plain_font
);
565 // add the "Tweak Parameters" item
566 message
= new BMessage(MediaRoutingView::M_NODE_TWEAK_PARAMETERS
);
567 menu
->AddItem(item
= new BMenuItem("Tweak parameters", message
, 'P'));
568 if (!(ref
->kind() & B_CONTROLLABLE
))
570 item
->SetEnabled(false);
573 message
= new BMessage(InfoWindowManager::M_INFO_WINDOW_REQUESTED
);
574 message
->AddInt32("nodeID", ref
->id());
575 menu
->AddItem(new BMenuItem("Get info", message
, 'I'));
576 menu
->AddSeparatorItem();
578 menu
->AddItem(item
= new BMenuItem("Release", new BMessage(MediaRoutingView::M_DELETE_SELECTION
), 'T'));
579 if (!ref
->isInternal())
581 item
->SetEnabled(false);
583 menu
->AddSeparatorItem();
585 // add the "Cycle" item
586 message
= new BMessage(MediaRoutingView::M_NODE_CHANGE_CYCLING
);
587 message
->AddBool("cycle", !ref
->isCycling());
588 menu
->AddItem(item
= new BMenuItem("Cycle", message
));
589 item
->SetMarked(ref
->isCycling());
590 if (ref
->flags() & NodeRef::NO_SEEK
)
592 item
->SetEnabled(false);
595 // add the "Run Mode" sub menu
596 BMenu
*subMenu
= new BMenu("Run mode");
597 subMenu
->SetFont(be_plain_font
);
598 for (uint32 runMode
= 1; runMode
<= BMediaNode::B_RECORDING
; runMode
++)
600 BString itemName
= MediaString::getStringFor(static_cast<BMediaNode::run_mode
>
602 message
= new BMessage(MediaRoutingView::M_NODE_CHANGE_RUN_MODE
);
603 message
->AddInt32("run_mode", runMode
);
604 subMenu
->AddItem(item
= new BMenuItem(itemName
.String(), message
));
605 if (ref
->runMode() == runMode
)
607 item
->SetMarked(true);
609 else if ((ref
->runMode() == 0)
610 && (ref
->group()) && (ref
->group()->runMode() == BMediaNode::run_mode(runMode
)))
612 item
->SetMarked(true);
615 subMenu
->AddSeparatorItem();
616 message
= new BMessage(MediaRoutingView::M_NODE_CHANGE_RUN_MODE
);
617 message
->AddInt32("run_mode", 0);
618 subMenu
->AddItem(item
= new BMenuItem("(same as group)", message
));
619 if (ref
->group() == 0)
621 item
->SetEnabled(false);
623 else if ((ref
->runMode() < 1) && (ref
->group()->runMode() > 0))
625 item
->SetMarked(true);
627 menu
->AddItem(subMenu
);
628 subMenu
->SetTargetForItems(view());
630 // [c.lenz 24dec99] hide rarely used commands in a 'Advanced' submenu
631 subMenu
= new BMenu("Advanced");
632 subMenu
->SetFont(be_plain_font
);
633 // [e.moon 5dec99] ad-hoc timesource support
634 if(ref
->kind() & B_TIME_SOURCE
) {
635 message
= new BMessage(MediaRoutingView::M_NODE_START_TIME_SOURCE
);
636 message
->AddInt32("nodeID", ref
->id());
637 subMenu
->AddItem(new BMenuItem(
640 message
= new BMessage(MediaRoutingView::M_NODE_START_TIME_SOURCE
);
641 message
->AddInt32("nodeID", ref
->id());
642 subMenu
->AddItem(new BMenuItem(
646 // [c.lenz 24dec99] support for BControllable::StartControlPanel()
647 if(ref
->kind() & B_CONTROLLABLE
) {
648 if (subMenu
->CountItems() > 0)
649 subMenu
->AddSeparatorItem();
650 message
= new BMessage(MediaRoutingView::M_NODE_START_CONTROL_PANEL
);
651 subMenu
->AddItem(new BMenuItem("Start Control Panel", message
,
652 'P', B_COMMAND_KEY
| B_SHIFT_KEY
));
654 // [em 1feb00] group tweaks
657 message
= new BMessage(MediaRoutingView::M_GROUP_SET_LOCKED
);
658 message
->AddInt32("groupID", ref
->group()->id());
659 bool isLocked
= (ref
->group()->groupFlags() & NodeGroup::GROUP_LOCKED
);
660 message
->AddBool("locked", !isLocked
);
661 if (subMenu
->CountItems() > 0)
662 subMenu
->AddSeparatorItem();
665 isLocked
? "Unlock group" : "Lock group", message
));
668 if (subMenu
->CountItems() > 0)
670 menu
->AddItem(subMenu
);
671 subMenu
->SetTargetForItems(view());
674 menu
->SetTargetForItems(view());
675 view()->ConvertToScreen(&point
);
676 point
-= BPoint(1.0, 1.0);
677 menu
->Go(point
, true, true, true);
680 // ---------------------------------------------------------------- //
682 // ---------------------------------------------------------------- //
684 void MediaNodePanel::MessageReceived(
687 D_METHOD(("MediaNodePanel::MessageReceived()\n"));
688 switch (message
->what
)
690 case NodeRef::M_INPUTS_CHANGED
:
692 D_MESSAGE(("MediaNodePanel::MessageReceived(NodeRef::M_INPUTS_CHANGED)\n"));
693 _updateIcon(dynamic_cast<MediaRoutingView
*>(view())->getLayout());
696 case NodeRef::M_OUTPUTS_CHANGED
:
698 D_MESSAGE(("MediaNodePanel::MessageReceived(NodeRef::M_OUTPUTS_CHANGED)\n"));
699 _updateIcon(dynamic_cast<MediaRoutingView
*>(view())->getLayout());
704 BHandler::MessageReceived(message
);
710 // -------------------------------------------------------- //
711 // *** IStateArchivable
712 // -------------------------------------------------------- //
714 status_t
MediaNodePanel::importState(
715 const BMessage
* archive
) {
717 BPoint
iconPos(s_invalidPosition
);
718 BPoint
miniIconPos(s_invalidPosition
);
720 MediaRoutingView
* v
= dynamic_cast<MediaRoutingView
*>(view());
722 MediaRoutingView::layout_t layoutMode
= v
->getLayout();
723 archive
->FindPoint("iconPos", &iconPos
);
724 archive
->FindPoint("miniIconPos", &miniIconPos
);
727 case MediaRoutingView::M_ICON_VIEW
:
728 if(iconPos
!= s_invalidPosition
)
730 m_alternatePosition
= miniIconPos
;
733 case MediaRoutingView::M_MINI_ICON_VIEW
:
734 if(miniIconPos
!= s_invalidPosition
)
736 m_alternatePosition
= iconPos
;
743 status_t
MediaNodePanel::exportState(
744 BMessage
* archive
) const {
746 BPoint iconPos
, miniIconPos
;
748 MediaRoutingView
* v
= dynamic_cast<MediaRoutingView
*>(view());
750 MediaRoutingView::layout_t layoutMode
= v
->getLayout();
752 case MediaRoutingView::M_ICON_VIEW
:
753 iconPos
= Frame().LeftTop();
754 miniIconPos
= m_alternatePosition
;
757 case MediaRoutingView::M_MINI_ICON_VIEW
:
758 miniIconPos
= Frame().LeftTop();
759 iconPos
= m_alternatePosition
;
763 if(iconPos
!= s_invalidPosition
)
764 archive
->AddPoint("iconPos", iconPos
);
765 if(miniIconPos
!= s_invalidPosition
)
766 archive
->AddPoint("miniIconPos", miniIconPos
);
768 // determine if I'm a 'system' node
772 if ((get_port_info(ref
->node().port
, &portInfo
) == B_OK
)
773 && (be_roster
->GetRunningAppInfo(portInfo
.team
, &appInfo
) == B_OK
)) {
774 BEntry
appEntry(&appInfo
.ref
);
775 char appName
[B_FILE_NAME_LENGTH
];
777 appEntry
.InitCheck() == B_OK
&&
778 appEntry
.GetName(appName
) == B_OK
&&
779 (!strcmp(appName
, "media_addon_server") ||
780 !strcmp(appName
, "audio_server"))) {
782 archive
->AddBool("sysOwned", true);
789 // ---------------------------------------------------------------- //
790 // *** internal operations
791 // ---------------------------------------------------------------- //
793 void MediaNodePanel::_prepareLabel()
795 // find out if its a file node first
796 if (ref
->kind() & B_FILE_INTERFACE
)
799 status_t error
= BMediaRoster::Roster()->GetRefFor(ref
->node(), &nodeFile
);
802 m_fullLabel
= ref
->name();
803 m_fullLabel
+= " (no file)";
807 BEntry
entry(&nodeFile
);
808 char fileName
[B_FILE_NAME_LENGTH
];
809 entry
.GetName(fileName
);
810 m_fullLabel
= fileName
;
815 m_fullLabel
= ref
->name();
818 int32 layout
= dynamic_cast<MediaRoutingView
*>(view())->getLayout();
820 // Construct labelRect
822 be_plain_font
->GetHeight(&fh
);
825 case MediaRoutingView::M_ICON_VIEW
:
827 m_labelRect
= Frame();
828 m_labelRect
.OffsetTo(0.0, 0.0);
829 m_labelRect
.bottom
= 2 * M_LABEL_V_MARGIN
+ (fh
.ascent
+ fh
.descent
+ fh
.leading
) + 1.0;
832 case MediaRoutingView::M_MINI_ICON_VIEW
:
834 m_labelRect
= Frame();
835 m_labelRect
.OffsetTo(0.0, 0.0);
836 m_labelRect
.left
= M_BODY_H_MARGIN
+ B_MINI_ICON
;
837 m_labelRect
.top
+= MediaJack::M_DEFAULT_HEIGHT
;
838 m_labelRect
.bottom
-= MediaJack::M_DEFAULT_HEIGHT
;
843 // truncate the label to fit in the panel
844 float maxWidth
= m_labelRect
.Width() - (2.0 * M_LABEL_H_MARGIN
) - 2.0;
845 if (be_plain_font
->StringWidth(m_fullLabel
.String()) > maxWidth
)
847 char *truncatedLabel
[1];
848 truncatedLabel
[0] = new char[B_MEDIA_NAME_LENGTH
];
849 const char *originalLabel
[1];
850 originalLabel
[0] = new char[B_MEDIA_NAME_LENGTH
];
851 m_fullLabel
.CopyInto(const_cast<char *>(originalLabel
[0]), 0, B_MEDIA_NAME_LENGTH
);
852 be_plain_font
->GetTruncatedStrings(originalLabel
, 1, B_TRUNCATE_END
, maxWidth
, (char **) truncatedLabel
);
853 m_label
= truncatedLabel
[0];
854 m_labelTruncated
= true;
855 delete [] originalLabel
[0];
856 delete [] truncatedLabel
[0];
860 m_label
= m_fullLabel
;
861 m_labelTruncated
= false;
864 // Construct labelOffset
865 float fw
= be_plain_font
->StringWidth(m_label
.String());
866 m_labelOffset
.x
= m_labelRect
.left
+ m_labelRect
.Width() / 2.0 - fw
/ 2.0;
867 m_labelOffset
.y
= m_labelRect
.bottom
- M_LABEL_V_MARGIN
- fh
.descent
- (fh
.leading
/ 2.0) - 1.0;
869 // Construct bodyRect
872 case MediaRoutingView::M_ICON_VIEW
:
874 m_bodyRect
= Frame();
875 m_bodyRect
.OffsetTo(0.0, 0.0);
876 m_bodyRect
.top
= m_labelRect
.bottom
;
879 case MediaRoutingView::M_MINI_ICON_VIEW
:
881 m_bodyRect
= Frame();
882 m_bodyRect
.OffsetTo(0.0, 0.0);
883 m_bodyRect
.right
= m_labelRect
.left
;
889 void MediaNodePanel::_updateBitmap()
895 BBitmap
*tempBitmap
= new BBitmap(Frame().OffsetToCopy(0.0, 0.0), B_CMAP8
, true);
898 BView
*tempView
= new BView(tempBitmap
->Bounds(), "", B_FOLLOW_NONE
, 0);
899 tempBitmap
->AddChild(tempView
);
900 tempView
->SetOrigin(0.0, 0.0);
902 int32 layout
= dynamic_cast<MediaRoutingView
*>(view())->getLayout();
903 _drawInto(tempView
, tempView
->Bounds(), layout
);
906 tempBitmap
->RemoveChild(tempView
);
909 tempBitmap
->Unlock();
910 m_bitmap
= new BBitmap(tempBitmap
);
914 void MediaNodePanel::_drawInto(
921 case MediaRoutingView::M_ICON_VIEW
:
928 target
->BeginLineArray(16);
929 target
->AddLine(r
.LeftTop(), r
.RightTop(), M_DARK_GRAY_COLOR
);
930 target
->AddLine(r
.RightTop(), r
.RightBottom(), M_DARK_GRAY_COLOR
);
931 target
->AddLine(r
.RightBottom(), r
.LeftBottom(), M_DARK_GRAY_COLOR
);
932 target
->AddLine(r
.LeftBottom(), r
.LeftTop(), M_DARK_GRAY_COLOR
);
934 target
->AddLine(r
.LeftTop(), r
.RightTop(), M_LIGHT_GRAY_COLOR
);
935 target
->AddLine(r
.RightTop(), r
.RightBottom(), M_MED_GRAY_COLOR
);
936 target
->AddLine(r
.RightBottom(), r
.LeftBottom(), M_MED_GRAY_COLOR
);
937 target
->AddLine(r
.LeftBottom(), r
.LeftTop(), M_LIGHT_GRAY_COLOR
);
938 target
->EndLineArray();
942 target
->SetLowColor(M_GRAY_COLOR
);
943 target
->FillRect(r
, B_SOLID_LOW
);
948 p
.x
= m_bodyRect
.left
+ m_bodyRect
.Width() / 2.0 - B_LARGE_ICON
/ 2.0;
949 p
.y
= m_labelRect
.bottom
+ m_bodyRect
.Height() / 2.0 - B_LARGE_ICON
/ 2.0;
952 target
->SetDrawingMode(B_OP_INVERT
);
953 target
->DrawBitmapAsync(m_icon
, p
);
954 target
->SetDrawingMode(B_OP_ALPHA
);
955 target
->SetHighColor(0, 0, 0, 180);
956 target
->SetBlendingMode(B_CONSTANT_ALPHA
, B_ALPHA_COMPOSITE
);
957 target
->DrawBitmapAsync(m_icon
, p
);
958 target
->SetDrawingMode(B_OP_OVER
);
962 target
->SetDrawingMode(B_OP_OVER
);
963 target
->DrawBitmapAsync(m_icon
, p
);
971 r
.InsetBy(M_LABEL_H_MARGIN
, M_LABEL_V_MARGIN
);
972 target
->BeginLineArray(4);
973 target
->AddLine(r
.LeftTop(), r
.RightTop(), M_LIGHT_BLUE_COLOR
);
974 target
->AddLine(r
.RightTop(), r
.RightBottom(), M_LIGHT_BLUE_COLOR
);
975 target
->AddLine(r
.RightBottom(), r
.LeftBottom(), M_LIGHT_BLUE_COLOR
);
976 target
->AddLine(r
.LeftBottom(), r
.LeftTop(), M_LIGHT_BLUE_COLOR
);
977 target
->EndLineArray();
979 target
->SetHighColor(M_DARK_BLUE_COLOR
);
980 target
->FillRect(r
, B_SOLID_HIGH
);
982 target
->SetDrawingMode(B_OP_OVER
);
983 target
->SetHighColor(isSelected() ? M_WHITE_COLOR
: M_BLACK_COLOR
);
984 target
->DrawString(m_label
.String(), m_labelOffset
);
987 case MediaRoutingView::M_MINI_ICON_VIEW
:
994 target
->BeginLineArray(16);
995 target
->AddLine(r
.LeftTop(), r
.RightTop(), M_DARK_GRAY_COLOR
);
996 target
->AddLine(r
.RightTop(), r
.RightBottom(), M_DARK_GRAY_COLOR
);
997 target
->AddLine(r
.RightBottom(), r
.LeftBottom(), M_DARK_GRAY_COLOR
);
998 target
->AddLine(r
.LeftBottom(), r
.LeftTop(), M_DARK_GRAY_COLOR
);
1000 target
->AddLine(r
.LeftTop(), r
.RightTop(), M_LIGHT_GRAY_COLOR
);
1001 target
->AddLine(r
.RightTop(), r
.RightBottom(), M_MED_GRAY_COLOR
);
1002 target
->AddLine(r
.RightBottom(), r
.LeftBottom(), M_MED_GRAY_COLOR
);
1003 target
->AddLine(r
.LeftBottom(), r
.LeftTop(), M_LIGHT_GRAY_COLOR
);
1004 target
->EndLineArray();
1007 r
.InsetBy(1.0, 1.0);
1008 target
->SetLowColor(M_GRAY_COLOR
);
1009 target
->FillRect(r
, B_SOLID_LOW
);
1014 p
.x
= m_bodyRect
.left
+ M_BODY_H_MARGIN
;
1015 p
.y
= m_bodyRect
.top
+ (m_bodyRect
.Height() / 2.0) - (B_MINI_ICON
/ 2.0);
1018 target
->SetDrawingMode(B_OP_INVERT
);
1019 target
->DrawBitmapAsync(m_icon
, p
);
1020 target
->SetDrawingMode(B_OP_ALPHA
);
1021 target
->SetHighColor(0, 0, 0, 180);
1022 target
->SetBlendingMode(B_CONSTANT_ALPHA
, B_ALPHA_COMPOSITE
);
1023 target
->DrawBitmapAsync(m_icon
, p
);
1024 target
->SetDrawingMode(B_OP_OVER
);
1028 target
->SetDrawingMode(B_OP_OVER
);
1029 target
->DrawBitmapAsync(m_icon
, p
);
1037 r
.InsetBy(M_LABEL_H_MARGIN
, M_LABEL_V_MARGIN
);
1038 target
->BeginLineArray(4);
1039 target
->AddLine(r
.LeftTop(), r
.RightTop(), M_LIGHT_BLUE_COLOR
);
1040 target
->AddLine(r
.RightTop(), r
.RightBottom(), M_LIGHT_BLUE_COLOR
);
1041 target
->AddLine(r
.RightBottom(), r
.LeftBottom(), M_LIGHT_BLUE_COLOR
);
1042 target
->AddLine(r
.LeftBottom(), r
.LeftTop(), M_LIGHT_BLUE_COLOR
);
1043 target
->EndLineArray();
1044 r
.InsetBy(1.0, 1.0);
1045 target
->SetHighColor(M_DARK_BLUE_COLOR
);
1046 target
->FillRect(r
, B_SOLID_HIGH
);
1048 target
->SetDrawingMode(B_OP_OVER
);
1049 target
->SetHighColor(isSelected() ? M_WHITE_COLOR
: M_BLACK_COLOR
);
1050 target
->DrawString(m_label
.String(), m_labelOffset
);
1056 void MediaNodePanel::_updateIcon(
1059 D_METHOD(("MediaNodePanel::_updateIcon()\n"));
1066 RouteAppNodeManager
*manager
;
1067 manager
= dynamic_cast<MediaRoutingView
*>(view())->manager
;
1070 case MediaRoutingView::M_ICON_VIEW
:
1072 const MediaIcon
*icon
= manager
->mediaIconFor(ref
->id(), B_LARGE_ICON
);
1073 m_icon
= new BBitmap(dynamic_cast<const BBitmap
*>(icon
));
1076 case MediaRoutingView::M_MINI_ICON_VIEW
:
1078 const MediaIcon
*icon
= manager
->mediaIconFor(ref
->id(), B_MINI_ICON
);
1079 m_icon
= new BBitmap(dynamic_cast<const BBitmap
*>(icon
));
1085 // -------------------------------------------------------- //
1086 // *** sorting methods (friend)
1087 // -------------------------------------------------------- //
1089 int __CORTEX_NAMESPACE__
compareID(
1094 const MediaNodePanel
*lPanel
= *(reinterpret_cast<MediaNodePanel
* const*>(reinterpret_cast<void * const*>(lValue
)));
1095 const MediaNodePanel
*rPanel
= *(reinterpret_cast<MediaNodePanel
* const*>(reinterpret_cast<void * const*>(rValue
)));
1096 if (lPanel
&& rPanel
)
1098 if (lPanel
->ref
->id() < rPanel
->ref
->id())
1102 else if (lPanel
->ref
->id() > rPanel
->ref
->id())
1110 // END -- MediaNodePanel.cpp --