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 91 RouteWindow::~RouteWindow() 92 { 93 } 94 95 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 211 RouteWindow::isPullPalettes() const 212 { 213 return m_pullPalettesItem->IsMarked(); 214 } 215 216 217 void 218 RouteWindow::setPullPalettes(bool enabled) 219 { 220 m_pullPalettesItem->SetMarked(enabled); 221 } 222 223 224 void 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 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 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 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 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 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 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 504 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 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 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 613 RouteWindow::_togglePullPalettes() 614 { 615 m_pullPalettesItem->SetMarked(!m_pullPalettesItem->IsMarked()); 616 } 617 618 619 void 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 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 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 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 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 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 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