1 /*
2 * Copyright (c) 1999-2000, Eric Moon.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions, and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions, and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31
32 // RouteWindow.cpp
33 // e.moon 14may99
34
35 #include "RouteApp.h"
36 #include "RouteWindow.h"
37 #include "MediaRoutingView.h"
38 #include "StatusView.h"
39
40 #include "DormantNodeWindow.h"
41 #include "TransportWindow.h"
42
43 #include "RouteAppNodeManager.h"
44 #include "NodeGroup.h"
45 #include "TipManager.h"
46
47 #include <Alert.h>
48 #include <Autolock.h>
49 #include <Debug.h>
50 #include <Font.h>
51 #include <MenuBar.h>
52 #include <Menu.h>
53 #include <MenuItem.h>
54 #include <Message.h>
55 #include <Messenger.h>
56 #include <Roster.h>
57 #include <Screen.h>
58 #include <ScrollView.h>
59 #include <StringView.h>
60
61 #include <algorithm>
62
63 #define D_HOOK(x) //PRINT (x)
64 #define D_INTERNAL(x) //PRINT (x)
65
66 // Locale Kit
67 #include <Catalog.h>
68
69 #undef B_TRANSLATION_CONTEXT
70 #define B_TRANSLATION_CONTEXT "CortexRouteApp"
71
72 __USE_CORTEX_NAMESPACE
73
74
75 const char* const RouteWindow::s_windowName = B_TRANSLATE("Cortex");
76
77 const BRect RouteWindow::s_initFrame(100,100,700,550);
78
79 const char* const g_aboutText =
80 B_TRANSLATE("Cortex/Route 2.1.2\n\n"
81 "Copyright 1999-2000 Eric Moon\n"
82 "All rights reserved.\n\n"
83 "The Cortex Team:\n\n"
84 "Christopher Lenz: UI\n"
85 "Eric Moon: UI, back-end\n\n"
86 "Thanks to:\nJohn Ashmun\nJon Watte\nDoug Wright\n<your name here>\n\n"
87 "Certain icons used herein are the property of\n"
88 "Be, Inc. and are used by permission.");
89
90
~RouteWindow()91 RouteWindow::~RouteWindow()
92 {
93 }
94
95
RouteWindow(RouteAppNodeManager * manager)96 RouteWindow::RouteWindow(RouteAppNodeManager* manager)
97 :
98 BWindow(s_initFrame, s_windowName, B_DOCUMENT_WINDOW, 0),
99 m_hScrollBar(0),
100 m_vScrollBar(0),
101 m_transportWindow(0),
102 m_dormantNodeWindow(0),
103 m_selectedGroupID(0),
104 m_zoomed(false),
105 m_zooming(false)
106 {
107 BRect b = Bounds();
108
109 // initialize the menu bar: add all menus that target this window
110 BMenuBar* pMenuBar = new BMenuBar(b, "menuBar");
111 BMenu* pFileMenu = new BMenu(B_TRANSLATE("File"));
112 BMenuItem* item = new BMenuItem(B_TRANSLATE("Open" B_UTF8_ELLIPSIS),
113 new BMessage(RouteApp::M_SHOW_OPEN_PANEL), 'O');
114 item->SetTarget(be_app);
115 pFileMenu->AddItem(item);
116 pFileMenu->AddItem(new BSeparatorItem());
117 item = new BMenuItem(B_TRANSLATE("Save nodes" B_UTF8_ELLIPSIS),
118 new BMessage(RouteApp::M_SHOW_SAVE_PANEL), 'S');
119 item->SetTarget(be_app);
120 pFileMenu->AddItem(item);
121 pFileMenu->AddItem(new BSeparatorItem());
122 pFileMenu->AddItem(new BMenuItem(
123 B_TRANSLATE("About Cortex/Route" B_UTF8_ELLIPSIS),
124 new BMessage(B_ABOUT_REQUESTED)));
125 pFileMenu->AddItem(new BSeparatorItem());
126 pFileMenu->AddItem(new BMenuItem(B_TRANSLATE("Quit"),
127 new BMessage(B_QUIT_REQUESTED)));
128 pMenuBar->AddItem(pFileMenu);
129 AddChild(pMenuBar);
130
131 // build the routing view
132 BRect rvBounds = b;
133 rvBounds.top = pMenuBar->Frame().bottom+1;
134 rvBounds.right -= B_V_SCROLL_BAR_WIDTH;
135 rvBounds.bottom -= B_H_SCROLL_BAR_HEIGHT;
136 m_routingView = new MediaRoutingView(manager, rvBounds, "routingView");
137
138 BRect hsBounds = rvBounds;
139 hsBounds.left = rvBounds.left + 199;
140 hsBounds.top = hsBounds.bottom + 1;
141 hsBounds.right++;
142 hsBounds.bottom = b.bottom + 1;
143
144 m_hScrollBar = new BScrollBar(hsBounds, "hScrollBar", m_routingView,
145 0, 0, B_HORIZONTAL);
146 AddChild(m_hScrollBar);
147
148 BRect vsBounds = rvBounds;
149 vsBounds.left = vsBounds.right + 1;
150 vsBounds.top--;
151 vsBounds.right = b.right + 1;
152 vsBounds.bottom++;
153
154 m_vScrollBar = new BScrollBar(vsBounds, "vScrollBar", m_routingView,
155 0, 0, B_VERTICAL);
156 AddChild(m_vScrollBar);
157
158 BRect svBounds = rvBounds;
159 svBounds.left -= 1;
160 svBounds.right = hsBounds.left - 1;
161 svBounds.top = svBounds.bottom + 1;
162 svBounds.bottom = b.bottom + 1;
163
164 m_statusView = new StatusView(svBounds, manager, m_hScrollBar);
165 AddChild(m_statusView);
166
167 AddChild(m_routingView);
168
169 float minWidth, maxWidth, minHeight, maxHeight;
170 GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight);
171 minWidth = m_statusView->Frame().Width() + 6 * B_V_SCROLL_BAR_WIDTH;
172 minHeight = 6 * B_H_SCROLL_BAR_HEIGHT;
173 SetSizeLimits(minWidth, maxWidth, minHeight, maxHeight);
174
175 // construct the Window menu
176 BMenu* windowMenu = new BMenu(B_TRANSLATE("Window"));
177 m_transportWindowItem = new BMenuItem(
178 B_TRANSLATE("Show transport"),
179 new BMessage(M_TOGGLE_TRANSPORT_WINDOW));
180 windowMenu->AddItem(m_transportWindowItem);
181
182 m_dormantNodeWindowItem = new BMenuItem(
183 B_TRANSLATE("Show add-ons"),
184 new BMessage(M_TOGGLE_DORMANT_NODE_WINDOW));
185 windowMenu->AddItem(m_dormantNodeWindowItem);
186
187 windowMenu->AddItem(new BSeparatorItem());
188
189 m_pullPalettesItem = new BMenuItem(
190 B_TRANSLATE("Pull palettes"),
191 new BMessage(M_TOGGLE_PULLING_PALETTES));
192 windowMenu->AddItem(m_pullPalettesItem);
193
194 pMenuBar->AddItem(windowMenu);
195
196 // create the dormant-nodes palette
197 _toggleDormantNodeWindow();
198
199 // display group inspector
200 _toggleTransportWindow();
201 }
202
203
204 // #pragma mark - operations
205
206
207 /*! Enable/disable palette position-locking (when the main
208 window is moved, all palettes follow).
209 */
210 bool
isPullPalettes() const211 RouteWindow::isPullPalettes() const
212 {
213 return m_pullPalettesItem->IsMarked();
214 }
215
216
217 void
setPullPalettes(bool enabled)218 RouteWindow::setPullPalettes(bool enabled)
219 {
220 m_pullPalettesItem->SetMarked(enabled);
221 }
222
223
224 void
constrainToScreen()225 RouteWindow::constrainToScreen()
226 {
227 BScreen screen(this);
228
229 const BRect sr = screen.Frame();
230
231 // [c.lenz 1mar2000] this should be handled by every window
232 // itself. will probably change soon ;-)
233 _constrainToScreen();
234 /* // main window
235 BRect r = Frame();
236 BPoint offset(0.0, 0.0);
237 if(r.left < 0.0)
238 offset.x = -r.left;
239 if(r.top < 0.0)
240 offset.y = -r.top;
241 if(r.left >= (sr.right - 20.0))
242 offset.x -= (r.left - (sr.Width()/2));
243 if(r.top >= (sr.bottom - 20.0))
244 offset.y -= (r.top - (sr.Height()/2));
245 if(offset.x != 0.0 || offset.y != 0.0) {
246 setPullPalettes(false);
247 MoveBy(offset.x, offset.y);
248 }*/
249
250 // transport window
251 BPoint offset = BPoint(0.0, 0.0);
252 BRect r = (m_transportWindow) ?
253 m_transportWindow->Frame() :
254 m_transportWindowFrame;
255 if(r.left < 0.0)
256 offset.x = (sr.Width()*.75) - r.left;
257 if(r.top < 0.0)
258 offset.y = (sr.Height()*.25) - r.top;
259 if(r.left >= (sr.right - 20.0))
260 offset.x -= (r.left - (sr.Width()/2));
261 if(r.top >= (sr.bottom - 20.0))
262 offset.y -= (r.top - (sr.Height()/2));
263
264 if(offset.x != 0.0 || offset.y != 0.0) {
265 if(m_transportWindow)
266 m_transportWindow->MoveBy(offset.x, offset.y);
267 else
268 m_transportWindowFrame.OffsetBy(offset.x, offset.y);
269 }
270
271 // addon palette
272 offset = BPoint(0.0, 0.0);
273 r = (m_dormantNodeWindow) ?
274 m_dormantNodeWindow->Frame() :
275 m_dormantNodeWindowFrame;
276 if(r.left < 0.0)
277 offset.x = (sr.Width()*.25) - r.left;
278 if(r.top < 0.0)
279 offset.y = (sr.Height()*.125) - r.top;
280 if(r.left >= (sr.right - 20.0))
281 offset.x -= (r.left - (sr.Width()/2));
282 if(r.top >= (sr.bottom - 20.0))
283 offset.y -= (r.top - (sr.Height()/2));
284
285 if(offset.x != 0.0 || offset.y != 0.0) {
286 if(m_dormantNodeWindow)
287 m_dormantNodeWindow->MoveBy(offset.x, offset.y);
288 else
289 m_dormantNodeWindowFrame.OffsetBy(offset.x, offset.y);
290 }
291
292 }
293
294
295 // #pragma mark - BWindow implementation
296
297
298 void
FrameMoved(BPoint point)299 RouteWindow::FrameMoved(BPoint point)
300 {
301 // ignore notification if the window isn't yet visible
302 if(IsHidden())
303 return;
304
305 BPoint delta = point - m_lastFramePosition;
306 m_lastFramePosition = point;
307
308
309 if (m_pullPalettesItem->IsMarked())
310 _movePalettesBy(delta.x, delta.y);
311 }
312
313
314 void
FrameResized(float width,float height)315 RouteWindow::FrameResized(float width, float height)
316 {
317 D_HOOK(("RouteWindow::FrameResized()\n"));
318
319 if (!m_zooming) {
320 m_zoomed = false;
321 }
322 else {
323 m_zooming = false;
324 }
325 }
326
327
328 bool
QuitRequested()329 RouteWindow::QuitRequested()
330 {
331 be_app->PostMessage(B_QUIT_REQUESTED);
332 return false; // [e.moon 20oct99] app now quits window
333 }
334
335
336 void
Zoom(BPoint origin,float width,float height)337 RouteWindow::Zoom(BPoint origin, float width, float height)
338 {
339 D_HOOK(("RouteWindow::Zoom()\n"));
340
341 m_zooming = true;
342
343 BScreen screen(this);
344 if (!screen.Frame().Contains(Frame())) {
345 m_zoomed = false;
346 }
347
348 if (!m_zoomed) {
349 // resize to the ideal size
350 m_manualSize = Bounds();
351 float width, height;
352 m_routingView->GetPreferredSize(&width, &height);
353 width += B_V_SCROLL_BAR_WIDTH;
354 height += B_H_SCROLL_BAR_HEIGHT;
355 if (KeyMenuBar()) {
356 height += KeyMenuBar()->Frame().Height();
357 }
358 ResizeTo(width, height);
359 _constrainToScreen();
360 m_zoomed = true;
361 }
362 else {
363 // resize to the most recent manual size
364 ResizeTo(m_manualSize.Width(), m_manualSize.Height());
365 m_zoomed = false;
366 }
367 }
368
369
370 // #pragma mark - BHandler implemenation
371
372
373 void
MessageReceived(BMessage * pMsg)374 RouteWindow::MessageReceived(BMessage* pMsg)
375 {
376 // PRINT((
377 // "RouteWindow::MessageReceived()\n"));
378 // pMsg->PrintToStream();
379 //
380 switch (pMsg->what) {
381 case B_ABOUT_REQUESTED:
382 {
383 BAlert* alert = new BAlert("About", g_aboutText, B_TRANSLATE("OK"));
384 alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
385 alert->Go();
386 break;
387 }
388 case MediaRoutingView::M_GROUP_SELECTED:
389 _handleGroupSelected(pMsg);
390 break;
391
392 case MediaRoutingView::M_SHOW_ERROR_MESSAGE:
393 _handleShowErrorMessage(pMsg);
394 break;
395
396 case M_TOGGLE_TRANSPORT_WINDOW:
397 _toggleTransportWindow();
398 break;
399
400 case M_REFRESH_TRANSPORT_SETTINGS:
401 _refreshTransportSettings(pMsg);
402 break;
403
404 case M_TOGGLE_PULLING_PALETTES:
405 _togglePullPalettes();
406 break;
407
408 case M_TOGGLE_DORMANT_NODE_WINDOW:
409 _toggleDormantNodeWindow();
410 break;
411
412 case M_TOGGLE_GROUP_ROLLING:
413 _toggleGroupRolling();
414 break;
415
416 default:
417 _inherited::MessageReceived(pMsg);
418 break;
419 }
420 }
421
422
423 // #pragma mark - IStateArchivable
424
425
426 status_t
importState(const BMessage * archive)427 RouteWindow::importState(const BMessage* archive)
428 {
429 status_t err;
430
431 // frame rect
432 BRect r;
433 err = archive->FindRect("frame", &r);
434 if(err == B_OK) {
435 MoveTo(r.LeftTop());
436 ResizeTo(r.Width(), r.Height());
437 m_lastFramePosition = r.LeftTop();
438 }
439
440 // status view width
441 int32 i;
442 err = archive->FindInt32("statusViewWidth", &i);
443 if (err == B_OK) {
444 float diff = i - m_statusView->Bounds().IntegerWidth();
445 m_statusView->ResizeBy(diff, 0.0);
446 m_hScrollBar->ResizeBy(-diff, 0.0);
447 m_hScrollBar->MoveBy(diff, 0.0);
448 }
449
450 // settings
451 bool b;
452 err = archive->FindBool("pullPalettes", &b);
453 if(err == B_OK)
454 m_pullPalettesItem->SetMarked(b);
455
456 // const char* p;
457 // err = archive->FindString("saveDir", &p);
458 // if(err == B_OK) {
459 // m_openPanel.SetPanelDirectory(p);
460 // m_savePanel.SetPanelDirectory(p);
461 // }
462 //
463 // dormant-node window
464 err = archive->FindRect("addonPaletteFrame", &r);
465 if (err == B_OK)
466 m_dormantNodeWindowFrame = r;
467 err = archive->FindBool("addonPaletteVisible", &b);
468 if (err == B_OK && (b != (m_dormantNodeWindow != 0))) {
469 _toggleDormantNodeWindow();
470 if(!m_dormantNodeWindow)
471 m_dormantNodeWindowFrame = r;
472 }
473
474 if (m_dormantNodeWindow) {
475 m_dormantNodeWindow->MoveTo(m_dormantNodeWindowFrame.LeftTop());
476 m_dormantNodeWindow->ResizeTo(
477 m_dormantNodeWindowFrame.Width(),
478 m_dormantNodeWindowFrame.Height());
479 }
480
481 // transport window
482 err = archive->FindRect("transportFrame", &r);
483 if (err == B_OK)
484 m_transportWindowFrame = r;
485 err = archive->FindBool("transportVisible", &b);
486 if (err == B_OK && (b != (m_transportWindow != 0))) {
487 _toggleTransportWindow();
488 if (!m_transportWindow)
489 m_transportWindowFrame = r;
490 }
491
492 if (m_transportWindow) {
493 m_transportWindow->MoveTo(m_transportWindowFrame.LeftTop());
494 m_transportWindow->ResizeTo(
495 m_transportWindowFrame.Width(),
496 m_transportWindowFrame.Height());
497 }
498
499 return B_OK;
500 }
501
502
503 status_t
exportState(BMessage * archive) const504 RouteWindow::exportState(BMessage* archive) const
505 {
506 BRect r = Frame();
507 archive->AddRect("frame", r);
508 archive->AddBool("pullPalettes", m_pullPalettesItem->IsMarked());
509
510 bool b = (m_dormantNodeWindow != 0);
511 r = b ? m_dormantNodeWindow->Frame() : m_dormantNodeWindowFrame;
512 archive->AddRect("addonPaletteFrame", r);
513 archive->AddBool("addonPaletteVisible", b);
514
515 b = (m_transportWindow != 0);
516 r = b ? m_transportWindow->Frame() : m_transportWindowFrame;
517
518 archive->AddRect("transportFrame", r);
519 archive->AddBool("transportVisible", b);
520
521 // [c.lenz 23may00] remember status view width
522 int i = m_statusView->Bounds().IntegerWidth();
523 archive->AddInt32("statusViewWidth", i);
524
525 // entry_ref saveRef;
526 // m_savePanel.GetPanelDirectory(&saveRef);
527 // BEntry saveEntry(&saveRef);
528 // if(saveEntry.InitCheck() == B_OK) {
529 // BPath p;
530 // saveEntry.GetPath(&p);
531 // archive->AddString("saveDir", p.Path());
532 // }
533
534 return B_OK;
535 }
536
537
538 // #pragma mark - implementation
539
540
541 void
_constrainToScreen()542 RouteWindow::_constrainToScreen()
543 {
544 D_INTERNAL(("RouteWindow::_constrainToScreen()\n"));
545
546 BScreen screen(this);
547 BRect screenRect = screen.Frame();
548 BRect windowRect = Frame();
549
550 // if the window is outside the screen rect
551 // move it to the default position
552 if (!screenRect.Intersects(windowRect)) {
553 windowRect.OffsetTo(screenRect.LeftTop());
554 MoveTo(windowRect.LeftTop());
555 windowRect = Frame();
556 }
557
558 // if the window is larger than the screen rect
559 // resize it to fit at each side
560 if (!screenRect.Contains(windowRect)) {
561 if (windowRect.left < screenRect.left) {
562 windowRect.left = screenRect.left + 5.0;
563 MoveTo(windowRect.LeftTop());
564 windowRect = Frame();
565 }
566 if (windowRect.top < screenRect.top) {
567 windowRect.top = screenRect.top + 5.0;
568 MoveTo(windowRect.LeftTop());
569 windowRect = Frame();
570 }
571 if (windowRect.right > screenRect.right) {
572 windowRect.right = screenRect.right - 5.0;
573 }
574 if (windowRect.bottom > screenRect.bottom) {
575 windowRect.bottom = screenRect.bottom - 5.0;
576 }
577 ResizeTo(windowRect.Width(), windowRect.Height());
578 }
579 }
580
581
582 void
_toggleTransportWindow()583 RouteWindow::_toggleTransportWindow()
584 {
585 if (m_transportWindow) {
586 m_transportWindowFrame = m_transportWindow->Frame();
587 m_transportWindow->Lock();
588 m_transportWindow->Quit();
589 m_transportWindow = 0;
590 m_transportWindowItem->SetMarked(false);
591 } else {
592 m_transportWindow = new TransportWindow(m_routingView->manager,
593 this, B_TRANSLATE("Transport"));
594
595 // ask for a selection update
596 BMessenger(m_routingView).SendMessage(
597 MediaRoutingView::M_BROADCAST_SELECTION);
598
599 // place & display the window
600 if (m_transportWindowFrame.IsValid()) {
601 m_transportWindow->MoveTo(m_transportWindowFrame.LeftTop());
602 m_transportWindow->ResizeTo(m_transportWindowFrame.Width(),
603 m_transportWindowFrame.Height());
604 }
605
606 m_transportWindow->Show();
607 m_transportWindowItem->SetMarked(true);
608 }
609 }
610
611
612 void
_togglePullPalettes()613 RouteWindow::_togglePullPalettes()
614 {
615 m_pullPalettesItem->SetMarked(!m_pullPalettesItem->IsMarked());
616 }
617
618
619 void
_toggleDormantNodeWindow()620 RouteWindow::_toggleDormantNodeWindow()
621 {
622 if (m_dormantNodeWindow) {
623 m_dormantNodeWindowFrame = m_dormantNodeWindow->Frame();
624 m_dormantNodeWindow->Lock();
625 m_dormantNodeWindow->Quit();
626 m_dormantNodeWindow = 0;
627 m_dormantNodeWindowItem->SetMarked(false);
628 } else {
629 m_dormantNodeWindow = new DormantNodeWindow(this);
630 if (m_dormantNodeWindowFrame.IsValid()) {
631 m_dormantNodeWindow->MoveTo(m_dormantNodeWindowFrame.LeftTop());
632 m_dormantNodeWindow->ResizeTo(m_dormantNodeWindowFrame.Width(),
633 m_dormantNodeWindowFrame.Height());
634 }
635 m_dormantNodeWindow->Show();
636 m_dormantNodeWindowItem->SetMarked(true);
637 }
638 }
639
640
641 void
_handleGroupSelected(BMessage * message)642 RouteWindow::_handleGroupSelected(BMessage* message)
643 {
644 status_t err;
645 uint32 groupID;
646
647 err = message->FindInt32("groupID", (int32*)&groupID);
648 if (err < B_OK) {
649 PRINT((
650 "! RouteWindow::_handleGroupSelected(): no groupID in message!\n"));
651 return;
652 }
653
654 if (!m_transportWindow)
655 return;
656
657 BMessage m(TransportWindow::M_SELECT_GROUP);
658 m.AddInt32("groupID", groupID);
659 BMessenger(m_transportWindow).SendMessage(&m);
660
661 m_selectedGroupID = groupID;
662 }
663
664
665 void
_handleShowErrorMessage(BMessage * message)666 RouteWindow::_handleShowErrorMessage(BMessage* message)
667 {
668 status_t err;
669 BString text;
670
671 err = message->FindString("text", &text);
672 if (err < B_OK) {
673 PRINT((
674 "! RouteWindow::_handleShowErrorMessage(): no text in message!\n"));
675 return;
676 }
677
678 m_statusView->setErrorMessage(text.String(), message->HasBool("error"));
679 }
680
681
682 //! Refresh the transport window for the given group, if any
683 void
_refreshTransportSettings(BMessage * message)684 RouteWindow::_refreshTransportSettings(BMessage* message)
685 {
686 status_t err;
687 uint32 groupID;
688
689 err = message->FindInt32("groupID", (int32*)&groupID);
690 if (err < B_OK) {
691 PRINT((
692 "! RouteWindow::_refreshTransportSettings(): no groupID in message!\n"));
693 return;
694 }
695
696 if(m_transportWindow) {
697 // relay the message
698 BMessenger(m_transportWindow).SendMessage(message);
699 }
700 }
701
702
703 void
_closePalettes()704 RouteWindow::_closePalettes()
705 {
706 BAutolock _l(this);
707
708 if (m_transportWindow) {
709 m_transportWindow->Lock();
710 m_transportWindow->Quit();
711 m_transportWindow = 0;
712 }
713 }
714
715
716 //! Move all palette windows by the specified amounts
_movePalettesBy(float xDelta,float yDelta)717 void RouteWindow::_movePalettesBy(float xDelta, float yDelta)
718 {
719 if (m_transportWindow)
720 m_transportWindow->MoveBy(xDelta, yDelta);
721
722 if (m_dormantNodeWindow)
723 m_dormantNodeWindow->MoveBy(xDelta, yDelta);
724 }
725
726
727 //! Toggle group playback
728 void
_toggleGroupRolling()729 RouteWindow::_toggleGroupRolling()
730 {
731 if (!m_selectedGroupID)
732 return;
733
734 NodeGroup* g;
735 status_t err = m_routingView->manager->findGroup(m_selectedGroupID, &g);
736 if (err < B_OK)
737 return;
738
739 Autolock _l(g);
740 uint32 startAction = (g->runMode() == BMediaNode::B_OFFLINE)
741 ? NodeGroup::M_ROLL : NodeGroup::M_START;
742
743 BMessenger m(g);
744 switch (g->transportState()) {
745 case NodeGroup::TRANSPORT_STOPPED:
746 m.SendMessage(startAction);
747 break;
748
749 case NodeGroup::TRANSPORT_RUNNING:
750 case NodeGroup::TRANSPORT_ROLLING:
751 m.SendMessage(NodeGroup::M_STOP);
752 break;
753
754 default:
755 break;
756 }
757 }
758