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.
32 // MediaRoutingView.cpp
34 #include "MediaRoutingView.h"
38 #include "RouteAppNodeManager.h"
39 #include "RouteWindow.h"
40 #include "NodeSetIOContext.h"
42 #include "DormantNodeView.h"
44 #include "InfoWindowManager.h"
46 #include "TransportWindow.h"
48 #include "MediaNodePanel.h"
49 #include "MediaWire.h"
51 #include "NodeGroup.h"
53 #include "Connection.h"
55 #include "ParameterWindowManager.h"
58 #include <Application.h>
63 #include <PopUpMenu.h>
66 #include <MediaRoster.h>
72 #include <BitmapStream.h>
73 #include <TranslatorRoster.h>
75 __USE_CORTEX_NAMESPACE
78 #define D_METHOD(x) //PRINT (x)
79 #define D_MESSAGE(x) //PRINT (x)
80 #define D_MOUSE(x) //PRINT (x)
81 #define D_KEY(x) //PRINT (x)
83 // ---------------------------------------------------------------- //
85 // ---------------------------------------------------------------- //
87 float MediaRoutingView::M_CLEANUP_H_GAP
= 25.0;
88 float MediaRoutingView::M_CLEANUP_V_GAP
= 10.0;
89 float MediaRoutingView::M_CLEANUP_H_MARGIN
= 15.0;
90 float MediaRoutingView::M_CLEANUP_V_MARGIN
= 10.0;
92 // ---------------------------------------------------------------- //
93 // m_inactiveNodeState content
94 // ---------------------------------------------------------------- //
96 struct _inactive_node_state_entry
{
97 _inactive_node_state_entry(
98 const char* _name
, int32 _kind
, const BMessage
& _state
) :
99 name(_name
), kind(_kind
), state(_state
) {}
106 // ---------------------------------------------------------------- //
108 // ---------------------------------------------------------------- //
110 MediaRoutingView::MediaRoutingView(
111 RouteAppNodeManager
*nodeManager
,
115 : DiagramView(frame
, "MediaRoutingView", true, B_FOLLOW_ALL_SIDES
),
116 manager(nodeManager
),
117 m_layout(M_ICON_VIEW
),
118 m_nextGroupNumber(1),
119 m_lastDroppedNode(0),
122 D_METHOD(("MediaRoutingView::MediaRoutingView()\n"));
125 setBackgroundColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR
), B_DARKEN_2_TINT
));
126 SetItemAlignment(5.0, 5.0);
130 MediaRoutingView::~MediaRoutingView() {
131 D_METHOD(("MediaRoutingView::~MediaRoutingView()\n"));
133 _emptyInactiveNodeState();
135 // quit ParameterWindowManager if necessary
136 ParameterWindowManager::shutDown();
138 // quit InfoWindowManager if necessary
139 InfoWindowManager::shutDown();
142 // -------------------------------------------------------- //
143 // *** derived from DiagramView
144 // -------------------------------------------------------- //
146 void MediaRoutingView::connectionAborted(
147 DiagramEndPoint
*fromWhich
)
149 D_METHOD(("MediaRoutingView::connectionAborted()\n"));
151 be_app
->SetCursor(B_HAND_CURSOR
);
154 void MediaRoutingView::connectionEstablished(
155 DiagramEndPoint
*fromWhich
,
156 DiagramEndPoint
*toWhich
)
158 D_METHOD(("MediaRoutingView::connectionEstablished()\n"));
160 be_app
->SetCursor(B_HAND_CURSOR
);
163 DiagramWire
*MediaRoutingView::createWire(
164 DiagramEndPoint
*fromWhich
,
165 DiagramEndPoint
*toWhich
)
167 D_METHOD(("MediaRoutingView::createWire()\n"));
169 MediaJack
*outputJack
, *inputJack
;
170 MediaJack
*jack
= dynamic_cast<MediaJack
*>(fromWhich
);
175 if (jack
->isOutput())
178 inputJack
= dynamic_cast<MediaJack
*>(toWhich
);
179 if (!inputJack
|| !inputJack
->isInput())
187 outputJack
= dynamic_cast<MediaJack
*>(toWhich
);
188 if (!outputJack
|| !outputJack
->isOutput())
193 if (!outputJack
->isConnected() && !inputJack
->isConnected())
197 if ((outputJack
->getOutput(&output
) == B_OK
)
198 && (inputJack
->getInput(&input
) == B_OK
))
201 Connection connection
;
202 error
= manager
->connect(output
, input
, &connection
);
205 showErrorMessage("Could not connect", error);
212 DiagramWire
*MediaRoutingView::createWire(
213 DiagramEndPoint
*fromWhich
)
215 D_METHOD(("MediaRoutingView::createWire(temp)\n"));
217 MediaJack
*jack
= dynamic_cast<MediaJack
*>(fromWhich
);
220 if (jack
->isOutput()) // this is the start point
222 return new MediaWire(jack
, true);
226 return new MediaWire(jack
, false);
234 MediaRoutingView::BackgroundMouseDown(BPoint point
, uint32 buttons
,
237 D_MOUSE(("MediaRoutingView::BackgroundMouseDown()\n"));
239 if ((buttons
== B_SECONDARY_MOUSE_BUTTON
)
240 || (modifiers() & B_CONTROL_KEY
)) {
242 showContextMenu(point
);
248 MediaRoutingView::MessageDropped(BPoint point
, BMessage
*message
)
250 D_METHOD(("MediaRoutingView::MessageDropped()\n"));
252 switch (message
->what
) {
253 case DormantNodeView::M_INSTANTIATE_NODE
:
255 D_MESSAGE(("MediaRoutingView::MessageDropped(DormantNodeView::M_INSTANTIATE_NODE)\n"));
258 if (message
->GetInfo("which", &type
, &count
) == B_OK
) {
259 for (int32 n
= 0; n
< count
; n
++) {
260 dormant_node_info info
;
263 if (message
->FindData("which", B_RAW_TYPE
, &data
, &dataSize
) == B_OK
) {
264 memcpy(reinterpret_cast<void *>(&info
), data
, dataSize
);
265 NodeRef
* droppedNode
;
267 error
= manager
->instantiate(info
, &droppedNode
);
269 m_lastDroppedNode
= droppedNode
->id();
270 BPoint dropPoint
, dropOffset
;
271 dropPoint
= message
->DropPoint(&dropOffset
);
272 m_lastDropPoint
= Align(ConvertFromScreen(dropPoint
- dropOffset
));
275 s
<< "Could not instantiate '" << info
.name
<< "'";
276 showErrorMessage(s
, error
);
286 D_MESSAGE(("MediaRoutingView::MessageDropped(B_SIMPLE_DATA)\n"));
288 if (message
->FindRef("refs", &fileRef
) == B_OK
)
289 _checkDroppedFile(&fileRef
, ConvertFromScreen(message
->DropPoint()));
295 D_MESSAGE(("MediaRoutingView::MessageDropped(B_PASTE)\n"));
297 const rgb_color
*color
; // [e.moon 21nov99] fixed const error
298 if (message
->FindData("RGBColor", B_RGB_COLOR_TYPE
,
299 reinterpret_cast<const void **>(&color
), &size
) == B_OK
)
300 _changeBackground(*color
);
305 DiagramView::MessageDropped(point
, message
);
311 MediaRoutingView::SelectionChanged()
313 D_METHOD(("MediaRoutingView::selectionChanged()\n"));
314 _broadcastSelection();
317 // ---------------------------------------------------------------- //
319 // ---------------------------------------------------------------- //
321 void MediaRoutingView::AttachedToWindow()
323 D_METHOD(("MediaRoutingView::AttachedToWindow()\n"));
324 _inherited::AttachedToWindow();
328 add_observer(this, manager
);
330 // add the context-menu shortcuts to the window
333 // populate with existing nodes & connections
336 // [e.moon 29nov99] moved from AllAttached()
340 void MediaRoutingView::AllAttached()
342 D_METHOD(("MediaRoutingView::AllAttached()\n"));
343 _inherited::AllAttached();
347 // grab keyboard events
351 void MediaRoutingView::DetachedFromWindow()
353 D_METHOD(("MediaRoutingView::DetachedFromWindow()\n"));
354 _inherited::DetachedFromWindow();
358 // detach from manager
361 Autolock
lock(manager
);
364 while (manager
->getNextRef(&ref
, &cookie
) == B_OK
)
366 remove_observer(this, ref
);
368 error
= remove_observer(this, manager
);
369 const_cast<RouteAppNodeManager
*&>(manager
) = 0;
373 void MediaRoutingView::KeyDown(
377 D_METHOD(("MediaRoutingView::KeyDown()\n"));
383 D_KEY(("MediaRoutingView::KeyDown(B_ENTER)\n"));
384 _openParameterWindowsForSelection();
389 D_KEY(("MediaRoutingView::KeyDown(B_DELETE)\n"));
396 BWindow
* w
= Window();
398 BMessenger(w
).SendMessage(RouteWindow::M_TOGGLE_GROUP_ROLLING
);
403 DiagramView::KeyDown(bytes
, numBytes
);
409 void MediaRoutingView::Pulse()
414 // ---------------------------------------------------------------- //
416 // ---------------------------------------------------------------- //
418 void MediaRoutingView::MessageReceived(
421 D_METHOD(("MediaRoutingView::MessageReceived()\n"));
423 switch (message
->what
)
425 case B_MEDIA_NODE_CREATED
:
427 D_MESSAGE(("MediaRoutingView::MessageReceived(B_MEDIA_NODE_CREATED)\n"));
430 if (message
->GetInfo("media_node_id", &type
, &count
) == B_OK
)
432 for(int32 n
= 0; n
< count
; n
++)
435 if (message
->FindInt32("media_node_id", n
, &id
) == B_OK
)
437 // [e.moon 8dec99] allow for existing panel
438 MediaNodePanel
* panel
;
439 if(_findPanelFor(id
, &panel
) < B_OK
)
440 _addPanelFor(id
, BPoint(5.0, 5.0));
446 case B_MEDIA_NODE_DELETED
:
448 D_MESSAGE(("MediaRoutingView::MessageReceived(B_MEDIA_NODE_DELETED)\n"));
451 if (message
->GetInfo("media_node_id", &type
, &count
) == B_OK
)
453 for (int32 n
= 0; n
< count
; n
++)
456 if (message
->FindInt32("media_node_id", n
, &id
) == B_OK
)
464 case B_MEDIA_CONNECTION_MADE
:
466 D_MESSAGE(("MediaRoutingView::MessageReceived(B_MEDIA_CONNECTION_MADE)\n"));
469 if (message
->GetInfo("output", &type
, &count
) == B_OK
)
471 for (int32 n
= 0; n
< count
; n
++)
476 if (message
->FindData("output", B_RAW_TYPE
, n
, &data
, &dataSize
) == B_OK
)
478 output
= *reinterpret_cast<const media_output
*>(data
);
479 Connection connection
;
480 if (manager
->findConnection(output
.node
.node
, output
.source
, &connection
) == B_OK
)
482 _addWireFor(connection
);
489 case B_MEDIA_CONNECTION_BROKEN
:
491 D_MESSAGE(("MediaRoutingView::MessageReceived(B_MEDIA_CONNECTION_BROKEN)\n"));
494 if (message
->GetInfo("__connection_id", &type
, &count
) == B_OK
)
496 for (int32 n
= 0; n
< count
; n
++)
499 if (message
->FindInt32("__connection_id", n
, &id
) == B_OK
)
507 case B_MEDIA_FORMAT_CHANGED
:
509 D_MESSAGE(("MediaRoutingView::MessageReceived(B_MEDIA_FORMAT_CHANGED)\n"));
511 media_node_id nodeID
;
512 if(message
->FindInt32("__source_node_id", &nodeID
) < B_OK
)
516 if(message
->FindInt32("__connection_id", (int32
*)&connectionID
) < B_OK
)
519 media_source
* source
;
521 if(message
->FindData("be:source", B_RAW_TYPE
, (const void**)&source
, &dataSize
) < B_OK
)
525 if(_findWireFor(connectionID
, &wire
) == B_OK
) {
526 // copy new connection data
527 manager
->findConnection(nodeID
, *source
, &wire
->connection
);
531 case M_CLEANUP_REQUESTED
:
533 D_MESSAGE(("MediaRoutingView::MessageReceived(M_M_CLEANUP_REQUESTED)\n"));
539 D_MESSAGE(("MediaRoutingView::MessageReceived(M_SELECT_ALL)\n"));
540 SelectAll(DiagramItem::M_BOX
);
543 case M_DELETE_SELECTION
:
545 D_MESSAGE(("MediaRoutingView::MessageReceived(M_DELETE_SELECTION)\n"));
549 case M_NODE_CHANGE_CYCLING
:
551 D_MESSAGE(("MediaRoutingView::MessageReceived(M_NODE_CYCLING_CHANGED)\n"));
553 if (message
->FindBool("cycle", &cycle
) == B_OK
)
555 _changeCyclingForSelection(cycle
);
559 case M_NODE_CHANGE_RUN_MODE
:
561 D_MESSAGE(("MediaRoutingView::MessageReceived(M_NODE_RUNMODE_CHANGED)\n"));
563 if (message
->FindInt32("run_mode", &mode
) == B_OK
)
565 _changeRunModeForSelection(static_cast<uint32
>(mode
));
569 case M_LAYOUT_CHANGED
:
571 D_MESSAGE(("MediaRoutingView::MessageReceived(M_LAYOUT_CHANGED)\n"));
573 if (message
->FindInt32("layout", (int32
*)&layout
) == B_OK
)
575 if (layout
!= m_layout
)
577 layoutChanged(layout
);
584 case M_NODE_START_TIME_SOURCE
:
586 D_MESSAGE(("MediaRoutingView::MessageReceived(M_NODE_START_TIME_SOURCE)\n"));
588 if(message
->FindInt32("nodeID", &id
) < B_OK
)
591 if(manager
->getNodeRef(id
, &ref
) < B_OK
)
594 bigtime_t when
= system_time();
595 status_t err
= manager
->roster
->StartTimeSource(ref
->node(), when
);
598 "! StartTimeSource(%" B_PRId32
"): '%s'\n",
599 ref
->id(), strerror(err
)));
603 case M_NODE_STOP_TIME_SOURCE
:
605 D_MESSAGE(("MediaRoutingView::MessageReceived(M_NODE_STOP_TIME_SOURCE)\n"));
607 if(message
->FindInt32("nodeID", &id
) < B_OK
)
610 if(manager
->getNodeRef(id
, &ref
) < B_OK
)
613 bigtime_t when
= system_time();
614 status_t err
= manager
->roster
->StopTimeSource(ref
->node(), when
);
617 "! StopTimeSource(%" B_PRId32
"): '%s'\n",
618 ref
->id(), strerror(err
)));
622 case M_NODE_TWEAK_PARAMETERS
: {
623 D_MESSAGE((" -> M_NODE_TWEAK_PARAMETERS\n"));
624 _openParameterWindowsForSelection();
627 case M_NODE_START_CONTROL_PANEL
: {
628 D_MESSAGE((" -> M_NODE_START_CONTROL_PANEL\n"));
629 _startControlPanelsForSelection();
632 case M_GROUP_SET_LOCKED
:
634 D_MESSAGE(("MediaRoutingView::MessageReceived(M_GROUP_SET_LOCKED)\n"));
636 if(message
->FindInt32("groupID", &groupID
) < B_OK
)
639 if(message
->FindBool("locked", &locked
) < B_OK
)
642 if(manager
->findGroup(groupID
, &group
) < B_OK
)
645 group
->groupFlags() | NodeGroup::GROUP_LOCKED
:
646 group
->groupFlags() & ~NodeGroup::GROUP_LOCKED
;
647 group
->setGroupFlags(f
);
650 case M_BROADCAST_SELECTION
: {
651 D_MESSAGE((" -> M_BROADCAST_SELECTION\n"));
652 _broadcastSelection();
655 case InfoWindowManager::M_INFO_WINDOW_REQUESTED
:
657 D_MESSAGE(("MediaRoutingView::MessageReceived(InfoView::M_INFO_WINDOW_REQUESTED)\n"));
660 if (message
->GetInfo("input", &type
, &count
) == B_OK
)
662 for (int32 i
= 0; i
< count
; i
++)
667 if (message
->FindData("input", B_RAW_TYPE
, i
, &data
, &dataSize
) == B_OK
)
669 input
= *reinterpret_cast<const media_input
*>(data
);
670 InfoWindowManager
*manager
= InfoWindowManager::Instance();
671 if (manager
&& manager
->Lock()) {
672 manager
->openWindowFor(input
);
678 else if (message
->GetInfo("output", &type
, &count
) == B_OK
)
680 for (int32 i
= 0; i
< count
; i
++)
685 if (message
->FindData("output", B_RAW_TYPE
, i
, &data
, &dataSize
) == B_OK
)
687 output
= *reinterpret_cast<const media_output
*>(data
);
688 InfoWindowManager
*manager
= InfoWindowManager::Instance();
689 if (manager
&& manager
->Lock()) {
690 manager
->openWindowFor(output
);
698 _openInfoWindowsForSelection();
702 case NodeManager::M_RELEASED
:
704 D_MESSAGE(("MediaRoutingView::MessageReceived(NodeManager::M_RELEASED)\n"));
705 remove_observer(this, manager
);
706 const_cast<RouteAppNodeManager
*&>(manager
) = 0;
707 // +++++ disable view!
710 case NodeRef::M_RELEASED
:
712 D_MESSAGE(("MediaRoutingView::MessageReceived(NodeRef::M_RELEASED)\n"));
713 // only relevant on shutdown; do nothing
718 DiagramView::MessageReceived(message
);
723 // ---------------------------------------------------------------- //
724 // *** operations (public)
725 // ---------------------------------------------------------------- //
727 BPoint
MediaRoutingView::findFreePositionFor(
728 const MediaNodePanel
* panel
) const
730 D_METHOD(("MediaRoutingView::_findFreeSpotFor()\n"));
732 BPoint
p(M_CLEANUP_H_MARGIN
, M_CLEANUP_V_MARGIN
);
739 // find the target column by node_kind
740 p
.x
+= M_CLEANUP_H_GAP
+ MediaNodePanel::M_DEFAULT_WIDTH
;
741 if (panel
->ref
->kind() & B_BUFFER_PRODUCER
)
743 p
.x
-= M_CLEANUP_H_GAP
+ MediaNodePanel::M_DEFAULT_WIDTH
;
745 if (panel
->ref
->kind() & B_BUFFER_CONSUMER
)
747 p
.x
+= M_CLEANUP_H_GAP
+ MediaNodePanel::M_DEFAULT_WIDTH
;
749 // find the bottom item in the column
751 for (uint32 i
= 0; i
< CountItems(DiagramItem::M_BOX
); i
++)
753 BRect r
= ItemAt(i
, DiagramItem::M_BOX
)->Frame();
755 && (r
.left
<= p
.x
+ MediaNodePanel::M_DEFAULT_WIDTH
))
757 bottom
= (r
.bottom
> bottom
) ? r
.bottom
: bottom
;
762 p
.y
= bottom
+ M_CLEANUP_V_GAP
;
766 case M_MINI_ICON_VIEW
:
768 // find the target row by node_kind
769 p
.y
+= M_CLEANUP_V_GAP
+ MediaNodePanel::M_DEFAULT_HEIGHT
;
770 if (panel
->ref
->kind() & B_BUFFER_PRODUCER
)
772 p
.y
-= M_CLEANUP_V_GAP
+ MediaNodePanel::M_DEFAULT_HEIGHT
;
774 if (panel
->ref
->kind() & B_BUFFER_CONSUMER
)
776 p
.y
+= M_CLEANUP_V_GAP
+ MediaNodePanel::M_DEFAULT_HEIGHT
;
778 // find the right-most item in the row
780 for (uint32 i
= 0; i
< CountItems(DiagramItem::M_BOX
); i
++)
782 BRect r
= ItemAt(i
, DiagramItem::M_BOX
)->Frame();
784 && (r
.top
<= p
.y
+ MediaNodePanel::M_DEFAULT_HEIGHT
))
786 right
= (r
.right
> right
) ? r
.right
: right
;
791 p
.x
= right
+ M_CLEANUP_H_GAP
;
800 // ---------------------------------------------------------------- //
801 // *** operations (protected)
802 // ---------------------------------------------------------------- //
804 void MediaRoutingView::layoutChanged(
807 D_METHOD(("MediaRoutingView::layoutChanged()\n"));
815 // swap the cleanup defaults
816 temp
= M_CLEANUP_H_GAP
;
817 M_CLEANUP_H_GAP
= M_CLEANUP_V_GAP
;
818 M_CLEANUP_V_GAP
= temp
;
819 temp
= M_CLEANUP_H_MARGIN
;
820 M_CLEANUP_H_MARGIN
= M_CLEANUP_V_MARGIN
;
821 M_CLEANUP_V_MARGIN
= temp
;
823 // swap the default dimensions for MediaJacks
824 temp
= MediaJack::M_DEFAULT_WIDTH
;
825 MediaJack::M_DEFAULT_WIDTH
= MediaJack::M_DEFAULT_HEIGHT
;
826 MediaJack::M_DEFAULT_HEIGHT
= temp
;
828 // Add space for the 3-letter i/o-abbreviation
829 BFont
font(be_plain_font
);
830 font
.SetSize(font
.Size() - 2.0);
831 for (int i
= 0; i
< MediaJack::M_MAX_ABBR_LENGTH
; i
++)
833 MediaJack::M_DEFAULT_WIDTH
+= font
.StringWidth("M");
835 MediaJack::M_DEFAULT_WIDTH
+= 2.0; // add some padding
837 // Adjust the default size for MediaNodePanels
838 float labelWidth
, bodyWidth
;
839 float labelHeight
, bodyHeight
;
841 be_plain_font
->GetHeight(&fh
);
842 labelWidth
= 4 * MediaNodePanel::M_LABEL_H_MARGIN
843 + be_plain_font
->StringWidth(" Be Audio Mixer ");
844 bodyWidth
= 2 * MediaNodePanel::M_BODY_H_MARGIN
+ B_LARGE_ICON
845 + 2 * MediaJack::M_DEFAULT_WIDTH
;
846 labelHeight
= 2 * MediaNodePanel::M_LABEL_V_MARGIN
847 + fh
.ascent
+ fh
.descent
+ fh
.leading
+ 1.0;
848 bodyHeight
= 2 * MediaNodePanel::M_BODY_V_MARGIN
+ B_LARGE_ICON
;
849 MediaNodePanel::M_DEFAULT_WIDTH
= labelWidth
> bodyWidth
? labelWidth
: bodyWidth
;
850 MediaNodePanel::M_DEFAULT_HEIGHT
= labelHeight
+ bodyHeight
;
851 Align(&MediaNodePanel::M_DEFAULT_WIDTH
, &MediaNodePanel::M_DEFAULT_HEIGHT
);
854 case M_MINI_ICON_VIEW
:
858 // Swap the cleanup defaults
859 temp
= M_CLEANUP_H_GAP
;
860 M_CLEANUP_H_GAP
= M_CLEANUP_V_GAP
;
861 M_CLEANUP_V_GAP
= temp
;
862 temp
= M_CLEANUP_H_MARGIN
;
863 M_CLEANUP_H_MARGIN
= M_CLEANUP_V_MARGIN
;
864 M_CLEANUP_V_MARGIN
= temp
;
866 // Subtract space for the 3-letter i/o-abbreviation
867 BFont
font(be_plain_font
);
868 font
.SetSize(font
.Size() - 2.0);
869 for (int i
= 0; i
< MediaJack::M_MAX_ABBR_LENGTH
; i
++)
871 MediaJack::M_DEFAULT_WIDTH
-= font
.StringWidth("M");
873 MediaJack::M_DEFAULT_WIDTH
-= 2.0; // substract the padding
875 // Swap the default dimensions for MediaJacks
876 temp
= MediaJack::M_DEFAULT_WIDTH
;
877 MediaJack::M_DEFAULT_WIDTH
= MediaJack::M_DEFAULT_HEIGHT
;
878 MediaJack::M_DEFAULT_HEIGHT
= temp
;
880 // Adjust the default size for MediaNodePanels
881 float labelWidth
, bodyWidth
;
882 float labelHeight
, bodyHeight
;
884 be_plain_font
->GetHeight(&fh
);
885 labelWidth
= 4 * MediaNodePanel::M_LABEL_H_MARGIN
886 + be_plain_font
->StringWidth(" Be Audio Mixer ");
887 bodyWidth
= 2 * MediaNodePanel::M_BODY_H_MARGIN
+ B_MINI_ICON
;
888 labelHeight
= 3 * MediaNodePanel::M_LABEL_V_MARGIN
889 + fh
.ascent
+ fh
.descent
+ fh
.leading
890 + 2 * MediaJack::M_DEFAULT_HEIGHT
;
891 bodyHeight
= 2 * MediaNodePanel::M_BODY_V_MARGIN
+ B_MINI_ICON
;
892 MediaNodePanel::M_DEFAULT_WIDTH
= labelWidth
+ bodyWidth
;
893 MediaNodePanel::M_DEFAULT_HEIGHT
= labelHeight
> bodyHeight
? labelHeight
: bodyHeight
;
894 Align(&MediaNodePanel::M_DEFAULT_WIDTH
, &MediaNodePanel::M_DEFAULT_HEIGHT
);
899 for (uint32 i
= 0; i
< CountItems(DiagramItem::M_BOX
); i
++)
901 MediaNodePanel
*panel
= dynamic_cast<MediaNodePanel
*>(ItemAt(i
, DiagramItem::M_BOX
));
904 panel
->layoutChanged(layout
);
911 void MediaRoutingView::cleanUp()
913 D_METHOD(("MediaRoutingView::cleanUp()\n"));
915 SortItems(DiagramItem::M_BOX
, compareID
);
917 // move all the panels offscreen
918 for (uint32 i
= 0; i
< CountItems(DiagramItem::M_BOX
); i
++)
920 ItemAt(i
, DiagramItem::M_BOX
)->moveTo(BPoint(-200.0, -200.0));
923 // move all panels to their 'ideal' position
924 for (uint32 i
= 0; i
< CountItems(DiagramItem::M_BOX
); i
++)
926 MediaNodePanel
*panel
;
927 panel
= dynamic_cast<MediaNodePanel
*>(ItemAt(i
, DiagramItem::M_BOX
));
928 BPoint p
= findFreePositionFor(panel
);
932 SortItems(DiagramItem::M_BOX
, compareSelectionTime
);
937 void MediaRoutingView::showContextMenu(
940 D_METHOD(("MediaRoutingView::showContextMenu()\n"));
942 BPopUpMenu
*menu
= new BPopUpMenu("MediaRoutingView PopUp", false, false, B_ITEMS_IN_COLUMN
);
943 menu
->SetFont(be_plain_font
);
945 // add layout options
947 BMessage
*message
= new BMessage(M_LAYOUT_CHANGED
);
948 message
->AddInt32("layout", M_ICON_VIEW
);
949 menu
->AddItem(item
= new BMenuItem("Icon view", message
));
950 if (m_layout
== M_ICON_VIEW
)
952 item
->SetMarked(true);
954 message
= new BMessage(M_LAYOUT_CHANGED
);
955 message
->AddInt32("layout", M_MINI_ICON_VIEW
);
956 menu
->AddItem(item
= new BMenuItem("Mini icon view", message
));
957 if (m_layout
== M_MINI_ICON_VIEW
)
959 item
->SetMarked(true);
961 menu
->AddSeparatorItem();
963 // add 'CleanUp' command
964 menu
->AddItem(new BMenuItem("Clean up", new BMessage(M_CLEANUP_REQUESTED
), 'K'));
966 // add 'Select All' command
967 menu
->AddItem(new BMenuItem("Select all", new BMessage(M_SELECT_ALL
), 'A'));
969 menu
->SetTargetForItems(this);
970 ConvertToScreen(&point
);
971 point
-= BPoint(1.0, 1.0);
972 menu
->Go(point
, true, true, true);
975 void MediaRoutingView::showErrorMessage(
979 D_METHOD(("MediaRoutingView::showErrorMessage()\n"));
982 text
<< " (" << strerror(error
) << ")";
985 BMessage
message(M_SHOW_ERROR_MESSAGE
);
986 message
.AddString("text", text
.String());
988 message
.AddBool("error", true);
990 BMessenger
messenger(0, Window());
991 if (!messenger
.IsValid()
992 || (messenger
.SendMessage(&message
) != B_OK
)) {
993 BAlert
*alert
= new BAlert("Error", text
.String(), "OK", 0, 0,
994 B_WIDTH_AS_USUAL
, B_WARNING_ALERT
);
995 alert
->SetFlags(alert
->Flags() | B_CLOSE_ON_ESCAPE
);
1000 // -------------------------------------------------------- //
1001 // *** IStateArchivable
1002 // -------------------------------------------------------- //
1004 status_t
MediaRoutingView::importState(
1005 const BMessage
* archive
) {
1009 _emptyInactiveNodeState();
1012 err
= archive
->FindInt32("layout", (int32
*)&layout
);
1013 if(err
== B_OK
&& layout
!= m_layout
) {
1014 layoutChanged(layout
);
1018 err
= archive
->FindString("bgBitmap", &path
);
1022 err
= entry
.GetRef(&ref
);
1024 _changeBackground(&ref
);
1030 archive
->FindInt8("bgRed", (int8
*)&color
.red
) == B_OK
&&
1031 archive
->FindInt8("bgGreen", (int8
*)&color
.green
) == B_OK
&&
1032 archive
->FindInt8("bgBlue", (int8
*)&color
.blue
) == B_OK
)
1033 _changeBackground(color
);
1036 for(int32 n
= 0; ; ++n
) {
1038 // find panel state info; stop when exhausted
1040 err
= archive
->FindMessage("panel", n
, &m
);
1044 const char* nodeName
;
1045 err
= archive
->FindString("nodeName", n
, &nodeName
);
1050 err
= archive
->FindInt32("nodeKind", n
, (int32
*)&nodeKind
);
1054 // look up matching panel +++++ SLOW +++++
1056 uint32 items
= CountItems(DiagramItem::M_BOX
);
1062 MediaNodePanel
* panel
= dynamic_cast<MediaNodePanel
*>(
1063 ItemAt(panelIndex
, DiagramItem::M_BOX
));
1066 !strcmp(panel
->ref
->name(), nodeName
) &&
1067 panel
->ref
->kind() == nodeKind
) {
1069 // found match; hand message to panel
1070 panel
->importState(&m
);
1074 if(panelIndex
== items
) {
1076 // if a "system node" hang onto (and re-export) state info
1078 if(m
.FindBool("sysOwned", &sysOwned
) == B_OK
&& sysOwned
) {
1079 m_inactiveNodeState
.AddItem(
1080 new _inactive_node_state_entry(
1081 nodeName
, nodeKind
, m
));
1091 // +++++ export state info for currently inactive system nodes +++++
1092 status_t
MediaRoutingView::exportState(
1093 BMessage
* archive
) const {
1095 // store layout mode
1096 archive
->AddInt32("layout", m_layout
);
1098 // store background settings
1099 if(m_backgroundBitmapEntry
.InitCheck() == B_OK
) {
1101 m_backgroundBitmapEntry
.GetPath(&path
);
1102 archive
->AddString("bgBitmap", path
.Path());
1104 rgb_color c
= backgroundColor();
1105 archive
->AddInt8("bgRed", c
.red
);
1106 archive
->AddInt8("bgGreen", c
.green
);
1107 archive
->AddInt8("bgBlue", c
.blue
);
1110 // store panel positions w/ node names & signatures
1111 for(uint32 n
= 0; n
< CountItems(DiagramItem::M_BOX
); ++n
) {
1112 MediaNodePanel
* panel
= dynamic_cast<MediaNodePanel
*>(
1113 ItemAt(n
, DiagramItem::M_BOX
));
1117 if(panel
->ref
->isInternal())
1118 // skip internal nodes
1122 panel
->exportState(&m
);
1123 archive
->AddString("nodeName", panel
->ref
->name());
1124 archive
->AddInt32("nodeKind", panel
->ref
->kind());
1125 archive
->AddMessage("panel", &m
);
1128 // copy inactive node state info
1129 for(int32 n
= 0; n
< m_inactiveNodeState
.CountItems(); ++n
) {
1130 _inactive_node_state_entry
* e
= reinterpret_cast<_inactive_node_state_entry
*>(
1131 m_inactiveNodeState
.ItemAt(n
));
1133 archive
->AddString("nodeName", e
->name
.String());
1134 archive
->AddInt32("nodeKind", e
->kind
);
1135 archive
->AddMessage("panel", &e
->state
);
1141 // [e.moon 8dec99] subset support
1143 status_t
MediaRoutingView::importStateFor(
1144 const NodeSetIOContext
* context
,
1145 const BMessage
* archive
) {
1149 for(int32 archiveIndex
= 0;; ++archiveIndex
) {
1151 // fetch archived key & panel data
1153 err
= archive
->FindString("nodeKey", archiveIndex
, &key
);
1158 err
= archive
->FindMessage("panel", archiveIndex
, &m
);
1161 "!!! MediaRoutingView::importStateFor(): missing panel %"
1162 B_PRId32
"\n", archiveIndex
));
1166 // find corresponding node
1168 err
= context
->getNodeFor(key
, &id
);
1171 "!!! MediaRoutingView::importStateFor(): missing node '%s'\n",
1176 // look for panel, create it if necessary
1177 MediaNodePanel
* panel
;
1178 err
= _findPanelFor(id
, &panel
);
1186 "!!! MediaRoutingView::importStateFor(): _addPanelFor():\n"
1187 " %s\n", strerror(err
)));
1191 err
= _findPanelFor(id
, &panel
);
1194 "!!! MediaRoutingView::importStateFor(): _findPanelFor():\n"
1195 " %s\n", strerror(err
)));
1200 // pass state data along
1201 panel
->importState(&m
);
1204 SelectItem(panel
, false);
1210 status_t
MediaRoutingView::exportStateFor(
1211 const NodeSetIOContext
* context
,
1212 BMessage
* archive
) const {
1216 for(uint32 n
= 0; n
< context
->countNodes(); ++n
) {
1217 MediaNodePanel
* panel
;
1218 err
= _findPanelFor(
1223 "!!! MediaRoutingView::exportStateFor():\n"
1224 " no panel for node %" B_PRId32
"\n",
1225 context
->nodeAt(n
)));
1229 const char* key
= context
->keyAt(n
);
1231 archive
->AddString("nodeKey", key
);
1233 panel
->exportState(&m
);
1234 archive
->AddMessage("panel", &m
);
1240 // -------------------------------------------------------- //
1241 // *** children management
1242 // -------------------------------------------------------- //
1244 status_t
MediaRoutingView::_addPanelFor(
1248 D_METHOD(("MediaRoutingView::_addPanelFor()\n"));
1252 status_t error
= manager
->getNodeRef(id
, &ref
);
1256 add_observer(this, ref
);
1257 MediaNodePanel
*panel
= 0;
1258 if (id
== m_lastDroppedNode
) // this was instantiated thru drag & drop
1260 AddItem(panel
= new MediaNodePanel(m_lastDropPoint
, ref
));
1261 SelectItem(panel
, true);
1262 m_lastDroppedNode
= 0;
1264 else // this was an externally created node, must find a nice position first
1266 panel
= new MediaNodePanel(BPoint(0.0, 0.0), ref
);
1269 if(_fetchInactiveNodeState(panel
, &state
) == B_OK
)
1270 panel
->importState(&state
);
1272 BPoint p
= findFreePositionFor(panel
);
1275 Invalidate(panel
->Frame());
1282 status_t
MediaRoutingView::_findPanelFor(
1284 MediaNodePanel
**outPanel
) const
1286 D_METHOD(("MediaRoutingView::_findPanelFor()\n"));
1288 for (uint32 i
= 0; i
< CountItems(DiagramItem::M_BOX
); i
++)
1290 MediaNodePanel
*panel
= dynamic_cast<MediaNodePanel
*>(ItemAt(i
, DiagramItem::M_BOX
));
1293 if (panel
->ref
->id() == id
)
1303 status_t
MediaRoutingView::_removePanelFor(
1306 D_METHOD(("MediaRoutingView::_removePanelFor()\n"));
1308 MediaNodePanel
*panel
;
1309 if (_findPanelFor(id
, &panel
) == B_OK
)
1311 if (RemoveItem(panel
))
1313 remove_observer(this, panel
->ref
);
1314 Invalidate(panel
->Frame());
1322 status_t
MediaRoutingView::_addWireFor(
1323 Connection
& connection
)
1325 D_METHOD(("MediaRoutingView::_addWireFor()\n"));
1327 MediaNodePanel
*source
, *destination
;
1328 if ((_findPanelFor(connection
.sourceNode(), &source
) == B_OK
)
1329 && (_findPanelFor(connection
.destinationNode(), &destination
) == B_OK
))
1333 media_output output
;
1334 error
= connection
.getOutput(&output
);
1339 MediaJack
*outputJack
= new MediaJack(output
);
1340 source
->AddItem(outputJack
);
1343 error
= connection
.getInput(&input
);
1348 MediaJack
*inputJack
= new MediaJack(input
);
1349 destination
->AddItem(inputJack
);
1351 MediaWire
*wire
= new MediaWire(connection
, outputJack
, inputJack
);
1353 source
->updateIOJacks();
1354 source
->arrangeIOJacks();
1355 destination
->updateIOJacks();
1356 destination
->arrangeIOJacks();
1359 // [e.moon 21nov99] group creation/merging now performed by
1360 // RouteAppNodeManager
1362 Invalidate(source
->Frame());
1363 Invalidate(destination
->Frame());
1364 Invalidate(wire
->Frame());
1373 status_t
MediaRoutingView::_findWireFor(
1374 uint32 connectionID
,
1375 MediaWire
**outWire
) const
1377 D_METHOD(("MediaRoutingView::_findWireFor()\n"));
1379 for (uint32 i
= 0; i
< CountItems(DiagramItem::M_WIRE
); i
++)
1381 MediaWire
*wire
= dynamic_cast<MediaWire
*>(ItemAt(i
, DiagramItem::M_WIRE
));
1382 if (wire
&& wire
->connection
.id() == connectionID
)
1391 status_t
MediaRoutingView::_removeWireFor(
1392 uint32 connectionID
)
1394 D_METHOD(("MediaRoutingView::_removeWireFor()\n"));
1397 if (_findWireFor(connectionID
, &wire
) == B_OK
)
1399 MediaNodePanel
*source
, *destination
;
1400 _findPanelFor(wire
->connection
.sourceNode(), &source
);
1401 _findPanelFor(wire
->connection
.destinationNode(), &destination
);
1403 Invalidate(wire
->Frame());
1407 source
->updateIOJacks();
1408 source
->arrangeIOJacks();
1409 Invalidate(source
->Frame());
1413 destination
->updateIOJacks();
1414 destination
->arrangeIOJacks();
1415 Invalidate(destination
->Frame());
1418 // [e.moon 21nov99] group split/remove now performed by
1419 // RouteAppNodeManager
1427 // -------------------------------------------------------- //
1428 // *** internal methods
1429 // -------------------------------------------------------- //
1431 void MediaRoutingView::_addShortcuts()
1433 Window()->AddShortcut('A', B_COMMAND_KEY
,
1434 new BMessage(M_SELECT_ALL
), this);
1435 Window()->AddShortcut('K', B_COMMAND_KEY
,
1436 new BMessage(M_CLEANUP_REQUESTED
), this);
1437 Window()->AddShortcut('T', B_COMMAND_KEY
,
1438 new BMessage(M_DELETE_SELECTION
), this);
1439 Window()->AddShortcut('P', B_COMMAND_KEY
,
1440 new BMessage(M_NODE_TWEAK_PARAMETERS
), this);
1441 Window()->AddShortcut('P', B_COMMAND_KEY
| B_SHIFT_KEY
,
1442 new BMessage(M_NODE_START_CONTROL_PANEL
), this);
1443 Window()->AddShortcut('I', B_COMMAND_KEY
,
1444 new BMessage(InfoWindowManager::M_INFO_WINDOW_REQUESTED
), this);
1447 void MediaRoutingView::_initLayout()
1449 D_METHOD(("MediaRoutingView::_initLayout()\n"));
1455 // Adjust the jack width for displaying the abbreviated
1456 // input/output name
1457 BFont
font(be_plain_font
);
1458 font
.SetSize(font
.Size() - 2.0);
1459 for (int i
= 0; i
< MediaJack::M_MAX_ABBR_LENGTH
; i
++)
1461 MediaJack::M_DEFAULT_WIDTH
+= font
.StringWidth("M");
1463 MediaJack::M_DEFAULT_WIDTH
+= 2.0; // add some padding
1465 // Adjust the default size for MediaNodePanels to fit the
1466 // size of be_plain_font
1467 float labelWidth
, bodyWidth
;
1468 float labelHeight
, bodyHeight
;
1470 be_plain_font
->GetHeight(&fh
);
1471 labelWidth
= 4 * MediaNodePanel::M_LABEL_H_MARGIN
1472 + be_plain_font
->StringWidth(" Be Audio Mixer ");
1473 bodyWidth
= 2 * MediaNodePanel::M_BODY_H_MARGIN
+ B_LARGE_ICON
1474 + 2 * MediaJack::M_DEFAULT_WIDTH
;
1475 labelHeight
= 2 * MediaNodePanel::M_LABEL_V_MARGIN
1476 + fh
.ascent
+ fh
.descent
+ fh
.leading
+ 1.0;
1477 bodyHeight
= 2 * MediaNodePanel::M_BODY_V_MARGIN
+ B_LARGE_ICON
;
1478 MediaNodePanel::M_DEFAULT_WIDTH
= labelWidth
> bodyWidth
? labelWidth
: bodyWidth
;
1479 MediaNodePanel::M_DEFAULT_HEIGHT
= labelHeight
+ bodyHeight
;
1480 Align(&MediaNodePanel::M_DEFAULT_WIDTH
, &MediaNodePanel::M_DEFAULT_HEIGHT
);
1482 // Adjust the cleanup settings
1483 M_CLEANUP_H_GAP
+= MediaNodePanel::M_DEFAULT_WIDTH
;
1486 case M_MINI_ICON_VIEW
:
1488 // Adjust the default size for MediaNodePanels to fit the
1489 // size of be_plain_font
1490 float labelWidth
, bodyWidth
;
1491 float labelHeight
, bodyHeight
;
1493 be_plain_font
->GetHeight(&fh
);
1494 labelWidth
= 4 * MediaNodePanel::M_LABEL_H_MARGIN
1495 + be_plain_font
->StringWidth(" Be Audio Mixer ");
1496 bodyWidth
= 2 * MediaNodePanel::M_BODY_H_MARGIN
+ B_MINI_ICON
;
1497 labelHeight
= 3 * MediaNodePanel::M_LABEL_V_MARGIN
1498 + fh
.ascent
+ fh
.descent
+ fh
.leading
1499 + 2 * MediaJack::M_DEFAULT_HEIGHT
;
1500 bodyHeight
= 2 * MediaNodePanel::M_BODY_V_MARGIN
+ B_MINI_ICON
;
1501 MediaNodePanel::M_DEFAULT_WIDTH
= labelWidth
+ bodyWidth
;
1502 MediaNodePanel::M_DEFAULT_HEIGHT
= labelHeight
> bodyHeight
? labelHeight
: bodyHeight
;
1503 Align(&MediaNodePanel::M_DEFAULT_WIDTH
, &MediaNodePanel::M_DEFAULT_HEIGHT
);
1505 // Adjust the cleanup settings
1506 M_CLEANUP_V_GAP
+= MediaNodePanel::M_DEFAULT_HEIGHT
;
1512 void MediaRoutingView::_initContent()
1514 D_METHOD(("MediaRoutingView::_initContent()\n"));
1516 Autolock
lock(manager
);
1520 while (manager
->getNextRef(&ref
, &cookie
) == B_OK
)
1522 // add self as observer
1523 add_observer(this, ref
);
1524 // create & place node view (+++++ defer until observer status confirmed!)
1525 _addPanelFor(ref
->id(), BPoint(M_CLEANUP_H_MARGIN
, M_CLEANUP_V_MARGIN
));
1528 Connection connection
;
1529 while (manager
->getNextConnection(&connection
, &cookie
) == B_OK
)
1531 _addWireFor(connection
);
1534 // create default groups
1536 NodeRef
* videoIn
= manager
->videoInputNode();
1539 group
= manager
->createGroup("Video input");
1540 group
->setRunMode(BMediaNode::B_RECORDING
);
1541 group
->addNode(videoIn
);
1543 NodeRef
* audioIn
= manager
->audioInputNode();
1546 group
= manager
->createGroup("Audio input");
1547 group
->setRunMode(BMediaNode::B_RECORDING
);
1548 group
->addNode(audioIn
);
1550 NodeRef
* videoOut
= manager
->videoOutputNode();
1553 group
= manager
->createGroup("Video output");
1554 group
->addNode(videoOut
);
1558 void MediaRoutingView::_changeCyclingForSelection(
1561 D_METHOD(("MediaRoutingView::_changeCyclingForSelection()\n"));
1563 if (SelectedType() == DiagramItem::M_BOX
)
1566 for (uint32 i
= 0; i
< CountSelectedItems(); i
++)
1568 MediaNodePanel
*panel
= dynamic_cast<MediaNodePanel
*>(SelectedItemAt(i
));
1569 if (panel
&& (panel
->ref
->isCycling() != cycle
))
1571 panel
->ref
->setCycling(cycle
);
1578 void MediaRoutingView::_changeRunModeForSelection(
1581 D_METHOD(("MediaRoutingView::_changeRunModeForSelection()\n"));
1583 if (SelectedType() == DiagramItem::M_BOX
)
1586 for (uint32 i
= 0; i
< CountSelectedItems(); i
++)
1588 MediaNodePanel
*panel
= dynamic_cast<MediaNodePanel
*>(SelectedItemAt(i
));
1589 if (panel
&& (panel
->ref
->runMode() != mode
))
1591 panel
->ref
->setRunMode(mode
);
1598 void MediaRoutingView::_openInfoWindowsForSelection() {
1599 D_METHOD(("MediaRoutingView::_openInfoWindowsForSelection()\n"));
1601 InfoWindowManager
*manager
= InfoWindowManager::Instance();
1606 if (SelectedType() == DiagramItem::M_BOX
) {
1607 for (uint32 i
= 0; i
< CountSelectedItems(); i
++) {
1608 MediaNodePanel
*panel
= dynamic_cast<MediaNodePanel
*>(SelectedItemAt(i
));
1609 if (panel
&& manager
->Lock()) {
1610 manager
->openWindowFor(panel
->ref
);
1615 else if (SelectedType() == DiagramItem::M_WIRE
) {
1616 for (uint32 i
= 0; i
< CountSelectedItems(); i
++) {
1617 MediaWire
*wire
= dynamic_cast<MediaWire
*>(SelectedItemAt(i
));
1618 if (wire
&& manager
->Lock()) {
1619 manager
->openWindowFor(wire
->connection
);
1626 void MediaRoutingView::_openParameterWindowsForSelection() {
1627 D_METHOD(("MediaRoutingView::_openParameterWindowsForSelection()\n"));
1629 if (SelectedType() != DiagramItem::M_BOX
) {
1630 // can only open parameter window for nodes
1634 for (uint32 i
= 0; i
< CountSelectedItems(); i
++) {
1635 MediaNodePanel
*panel
= dynamic_cast<MediaNodePanel
*>(SelectedItemAt(i
));
1636 if (panel
&& (panel
->ref
->kind() & B_CONTROLLABLE
)) {
1637 ParameterWindowManager
*paramMgr
= ParameterWindowManager::Instance();
1638 if (paramMgr
&& paramMgr
->Lock()) {
1639 paramMgr
->openWindowFor(panel
->ref
);
1646 void MediaRoutingView::_startControlPanelsForSelection() {
1647 D_METHOD(("MediaRoutingView::_startControlPanelsForSelection()\n"));
1649 if (SelectedType() != DiagramItem::M_BOX
) {
1650 // can only start control panel for nodes
1654 for (uint32 i
= 0; i
< CountSelectedItems(); i
++) {
1655 MediaNodePanel
*panel
= dynamic_cast<MediaNodePanel
*>(SelectedItemAt(i
));
1656 if (panel
&& (panel
->ref
->kind() & B_CONTROLLABLE
)) {
1657 ParameterWindowManager
*paramMgr
= ParameterWindowManager::Instance();
1658 if (paramMgr
&& paramMgr
->Lock()) {
1659 paramMgr
->startControlPanelFor(panel
->ref
);
1666 void MediaRoutingView::_deleteSelection()
1668 D_METHOD(("MediaRoutingView::_deleteSelection()\n"));
1669 if (SelectedType() == DiagramItem::M_BOX
)
1671 for (uint32 i
= 0; i
< CountSelectedItems(); i
++)
1673 MediaNodePanel
*panel
= dynamic_cast<MediaNodePanel
*>(SelectedItemAt(i
));
1674 if (panel
&& panel
->ref
->isInternal())
1676 status_t error
= panel
->ref
->releaseNode();
1680 s
<< "Could not release '" << panel
->ref
->name() << "'";
1681 showErrorMessage(s
, error
);
1686 else if (SelectedType() == DiagramItem::M_WIRE
)
1688 for (uint32 i
= 0; i
< CountSelectedItems(); i
++)
1690 MediaWire
*wire
= dynamic_cast<MediaWire
*>(SelectedItemAt(i
));
1691 if (wire
&& !(wire
->connection
.flags() & Connection::LOCKED
))
1693 status_t error
= manager
->disconnect(wire
->connection
);
1696 showErrorMessage("Could not disconnect", error
);
1701 // make sure none of the deleted items is still displaying its mouse cursor !
1702 be_app
->SetCursor(B_HAND_CURSOR
);
1705 void MediaRoutingView::_checkDroppedFile(
1709 D_METHOD(("MediaRoutingView::_checkDroppedFile()\n"));
1711 // [cell 26apr00] traverse links
1712 BEntry
entry(ref
, true);
1716 if (node
.InitCheck() == B_OK
)
1718 BNodeInfo
nodeInfo(&node
);
1719 if (nodeInfo
.InitCheck() == B_OK
)
1721 char mimeString
[B_MIME_TYPE_LENGTH
];
1722 if (nodeInfo
.GetType(mimeString
) == B_OK
)
1724 BMimeType
mimeType(mimeString
);
1725 BMimeType superType
;
1727 // [e.moon 22dec99] handle dropped node-set files
1728 if(mimeType
== RouteApp::s_nodeSetType
) {
1729 BMessage
m(B_REFS_RECEIVED
);
1730 m
.AddRef("refs", ref
);
1731 be_app_messenger
.SendMessage(&m
);
1733 else if (mimeType
.GetSupertype(&superType
) == B_OK
)
1735 if (superType
== "image")
1737 _changeBackground(ref
);
1739 else if ((superType
== "audio") || (superType
== "video"))
1741 NodeRef
* droppedNode
;
1743 error
= manager
->instantiate(*ref
, B_BUFFER_PRODUCER
, &droppedNode
);
1746 media_output encVideoOutput
;
1747 if (droppedNode
->findFreeOutput(&encVideoOutput
, B_MEDIA_ENCODED_VIDEO
) == B_OK
)
1749 droppedNode
->setFlags(droppedNode
->flags() | NodeRef::NO_POSITION_REPORTING
);
1751 m_lastDroppedNode
= droppedNode
->id();
1752 m_lastDropPoint
= Align(dropPoint
);
1756 char fileName
[B_FILE_NAME_LENGTH
];
1758 entry
.GetName(fileName
);
1760 s
<< "Could not load '" << fileName
<< "'";
1761 showErrorMessage(s
, error
);
1770 void MediaRoutingView::_changeBackground(
1773 D_METHOD(("MediaRoutingView::_changeBackground()\n"));
1776 BBitmap
*background
= 0;
1777 BFile
file(ref
, B_READ_ONLY
);
1778 error
= file
.InitCheck();
1781 BTranslatorRoster
*roster
= BTranslatorRoster::Default();
1782 BBitmapStream stream
;
1783 error
= roster
->Translate(&file
, NULL
, NULL
, &stream
, B_TRANSLATOR_BITMAP
);
1786 stream
.DetachBitmap(&background
);
1787 setBackgroundBitmap(background
);
1790 // [e.moon 1dec99] persistence, yay
1791 m_backgroundBitmapEntry
.SetTo(ref
);
1797 void MediaRoutingView::_changeBackground(
1800 D_METHOD(("MediaRoutingView::_changeBackground()\n"));
1801 setBackgroundColor(color
);
1804 // [e.moon 1dec99] persistence, yay
1805 m_backgroundBitmapEntry
.Unset();
1809 MediaRoutingView::_adjustScrollBars()
1811 D_METHOD(("MediaRoutingView::_adjustScrollBars()\n"));
1813 BScrollBar
*scrollBar
;
1815 // adjust horizontal scroll bar
1816 scrollBar
= ScrollBar(B_HORIZONTAL
);
1818 float bigStep
= floor(MediaNodePanel::M_DEFAULT_WIDTH
+ M_CLEANUP_H_GAP
);
1819 scrollBar
->SetSteps(floor(bigStep
/ 10.0), bigStep
);
1822 // adjust vertical scroll bar
1823 scrollBar
= ScrollBar(B_VERTICAL
);
1825 float bigStep
= floor(MediaNodePanel::M_DEFAULT_HEIGHT
+ M_CLEANUP_V_GAP
);
1826 scrollBar
->SetSteps(floor(bigStep
/ 10.0), bigStep
);
1831 MediaRoutingView::_broadcastSelection() const
1833 int32 selectedGroup
= 0;
1835 if (SelectedType() == DiagramItem::M_BOX
) {
1836 // iterate thru the list of selected node panels and make the
1837 // first group we find the selected group
1838 for (uint32 i
= 0; i
< CountSelectedItems(); i
++) {
1839 MediaNodePanel
*panel
= dynamic_cast<MediaNodePanel
*>(SelectedItemAt(i
));
1840 if (panel
&& panel
->ref
->group()) {
1841 selectedGroup
= panel
->ref
->group()->id();
1842 BMessenger
messenger(Window());
1843 BMessage
groupMsg(M_GROUP_SELECTED
);
1844 groupMsg
.AddInt32("groupID", selectedGroup
);
1845 messenger
.SendMessage(&groupMsg
);
1851 // currently no group is selected
1852 BMessenger
messenger(Window());
1853 BMessage
groupMsg(M_GROUP_SELECTED
);
1854 groupMsg
.AddInt32("groupID", selectedGroup
);
1855 messenger
.SendMessage(&groupMsg
);
1859 MediaRoutingView::_fetchInactiveNodeState(MediaNodePanel
*forPanel
, BMessage
*outMessage
)
1861 // copy inactive node state info
1862 int32 c
= m_inactiveNodeState
.CountItems();
1863 for(int32 n
= 0; n
< c
; n
++) {
1864 _inactive_node_state_entry
* e
= reinterpret_cast<_inactive_node_state_entry
*>(
1865 m_inactiveNodeState
.ItemAt(n
));
1867 if(e
->name
!= forPanel
->ref
->name())
1870 if(e
->kind
!= forPanel
->ref
->kind())
1873 // found match; extract message & remove entry
1874 *outMessage
= e
->state
;
1875 m_inactiveNodeState
.RemoveItem(n
);
1883 MediaRoutingView::_emptyInactiveNodeState()
1885 int32 c
= m_inactiveNodeState
.CountItems();
1886 for(int32 n
= 0; n
< c
; n
++) {
1887 _inactive_node_state_entry
* e
= reinterpret_cast<_inactive_node_state_entry
*>(
1888 m_inactiveNodeState
.ItemAt(n
));
1892 m_inactiveNodeState
.MakeEmpty();
1896 // END -- MediaRoutingView.cpp --