1 /* 2 * MainWin.cpp - Media Player for the Haiku Operating System 3 * 4 * Copyright (C) 2006 Marcus Overhagen <marcus@overhagen.de> 5 * Copyright (C) 2007 Stephan Aßmus <superstippi@gmx.de> 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * version 2 as published by the Free Software Foundation. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 * 20 */ 21 #include "MainWin.h" 22 23 #include <View.h> 24 #include <Screen.h> 25 #include <Menu.h> 26 #include <MenuBar.h> 27 #include <MenuItem.h> 28 #include <Application.h> 29 #include <Alert.h> 30 #include <stdio.h> 31 #include <string.h> 32 #include <Messenger.h> 33 #include <PopUpMenu.h> 34 #include <String.h> 35 #include <Debug.h> 36 #include <math.h> 37 38 #include "ControllerObserver.h" 39 #include "PlaylistObserver.h" 40 #include "PlaylistWindow.h" 41 #include "MainApp.h" 42 43 #define NAME "MediaPlayer" 44 #define MIN_WIDTH 250 45 46 47 // XXX TODO: why is lround not defined? 48 #define lround(a) ((int)(0.99999 + (a))) 49 50 enum 51 { 52 M_DUMMY = 0x100, 53 M_FILE_OPEN = 0x1000, 54 M_FILE_NEWPLAYER, 55 M_FILE_INFO, 56 M_FILE_PLAYLIST, 57 M_FILE_ABOUT, 58 M_FILE_CLOSE, 59 M_FILE_QUIT, 60 M_VIEW_50, 61 M_VIEW_100, 62 M_VIEW_200, 63 M_VIEW_300, 64 M_VIEW_400, 65 M_TOGGLE_FULLSCREEN, 66 M_TOGGLE_NO_BORDER, 67 M_TOGGLE_NO_MENU, 68 M_TOGGLE_NO_CONTROLS, 69 M_TOGGLE_NO_BORDER_NO_MENU_NO_CONTROLS, 70 M_TOGGLE_ALWAYS_ON_TOP, 71 M_TOGGLE_KEEP_ASPECT_RATIO, 72 M_PREFERENCES, 73 M_VOLUME_UP, 74 M_VOLUME_DOWN, 75 M_CHANNEL_NEXT, 76 M_CHANNEL_PREV, 77 M_ASPECT_100000_1, 78 M_ASPECT_106666_1, 79 M_ASPECT_109091_1, 80 M_ASPECT_141176_1, 81 M_ASPECT_720_576, 82 M_ASPECT_704_576, 83 M_ASPECT_544_576, 84 M_SELECT_AUDIO_TRACK = 0x00000800, 85 M_SELECT_AUDIO_TRACK_END = 0x00000fff, 86 M_SELECT_VIDEO_TRACK = 0x00010000, 87 M_SELECT_VIDEO_TRACK_END = 0x000fffff, 88 89 M_SET_PLAYLIST_POSITION 90 }; 91 92 //#define printf(a...) 93 94 95 MainWin::MainWin() 96 : BWindow(BRect(100,100,350,300), NAME, B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS /* | B_WILL_ACCEPT_FIRST_CLICK */) 97 , fFilePanel(NULL) 98 , fInfoWin(NULL) 99 , fPlaylistWindow(NULL) 100 , fInfoWinShowing(false) 101 , fHasFile(false) 102 , fHasVideo(false) 103 , fHasAudio(false) 104 , fPlaylist(new Playlist) 105 , fPlaylistObserver(new PlaylistObserver(this)) 106 , fController(new Controller) 107 , fControllerObserver(new ControllerObserver(this, 108 OBSERVE_FILE_CHANGES | OBSERVE_TRACK_CHANGES 109 | OBSERVE_PLAYBACK_STATE_CHANGES | OBSERVE_POSITION_CHANGES)) 110 , fIsFullscreen(false) 111 , fKeepAspectRatio(true) 112 , fAlwaysOnTop(false) 113 , fNoMenu(false) 114 , fNoBorder(false) 115 , fNoControls(false) 116 , fSourceWidth(0) 117 , fSourceHeight(0) 118 , fWidthScale(1.0) 119 , fHeightScale(1.0) 120 , fMouseDownTracking(false) 121 { 122 static int pos = 0; 123 MoveBy(pos * 25, pos * 25); 124 pos = (pos + 1) % 15; 125 126 BRect rect = Bounds(); 127 128 // background 129 fBackground = new BView(rect, "background", B_FOLLOW_ALL, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE); 130 fBackground->SetViewColor(0,0,0); 131 AddChild(fBackground); 132 133 // menu 134 fMenuBar = new BMenuBar(fBackground->Bounds(), "menu"); 135 CreateMenu(); 136 fBackground->AddChild(fMenuBar); 137 fMenuBar->ResizeToPreferred(); 138 fMenuBarWidth = (int)fMenuBar->Frame().Width() + 1; 139 fMenuBarHeight = (int)fMenuBar->Frame().Height() + 1; 140 fMenuBar->SetResizingMode(B_FOLLOW_NONE); 141 142 // video view 143 rect = BRect(0, fMenuBarHeight, fBackground->Bounds().right, fMenuBarHeight + 10); 144 fVideoView = new VideoView(rect, "video display", B_FOLLOW_NONE, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE); 145 fBackground->AddChild(fVideoView); 146 147 // controls 148 rect = BRect(0, fMenuBarHeight + 11, fBackground->Bounds().right, fBackground->Bounds().bottom); 149 fControls = new ControllerView(rect, fController, fPlaylist); 150 fBackground->AddChild(fControls); 151 fControls->ResizeToPreferred(); 152 fControlsHeight = (int)fControls->Frame().Height() + 1; 153 fControlsWidth = (int)fControls->Frame().Width() + 1; 154 fControls->SetResizingMode(B_FOLLOW_BOTTOM | B_FOLLOW_LEFT_RIGHT); 155 // fControls->MoveTo(0, fBackground->Bounds().bottom - fControlsHeight + 1); 156 157 // fVideoView->ResizeTo(fBackground->Bounds().Width(), fBackground->Bounds().Height() - fMenuBarHeight - fControlsHeight); 158 159 fPlaylist->AddListener(fPlaylistObserver); 160 fController->SetVideoView(fVideoView); 161 fController->AddListener(fControllerObserver); 162 fVideoView->IsOverlaySupported(); 163 164 // printf("fMenuBarHeight %d\n", fMenuBarHeight); 165 // printf("fControlsHeight %d\n", fControlsHeight); 166 // printf("fControlsWidth %d\n", fControlsWidth); 167 168 SetupWindow(); 169 170 Show(); 171 } 172 173 174 MainWin::~MainWin() 175 { 176 printf("MainWin::~MainWin\n"); 177 178 fPlaylist->RemoveListener(fPlaylistObserver); 179 fController->RemoveListener(fControllerObserver); 180 181 // give the views a chance to detach from any notifiers 182 // before we delete them 183 fBackground->RemoveSelf(); 184 delete fBackground; 185 186 if (fInfoWin) { 187 fInfoWin->Lock(); 188 fInfoWin->Quit(); 189 } 190 if (fPlaylistWindow) { 191 fPlaylistWindow->Lock(); 192 fPlaylistWindow->Quit(); 193 } 194 195 delete fPlaylist; 196 delete fController; 197 delete fFilePanel; 198 } 199 200 201 void 202 MainWin::OpenFile(const entry_ref &ref) 203 { 204 printf("MainWin::OpenFile\n"); 205 206 status_t err = fController->SetTo(ref); 207 if (err != B_OK) { 208 if (fPlaylist->CountItems() == 1) { 209 // display error if this is the only file we're supposed to play 210 char s[300]; 211 sprintf(s, "Can't open file\n\n%s\n\nError 0x%08lx\n(%s)\n", 212 ref.name, err, strerror(err)); 213 (new BAlert("error", s, "OK"))->Go(); 214 } else { 215 // just go to the next file and don't bother user 216 // TODO: this makes it impossible to skip backwards 217 // over a non recognized file! 218 fPlaylist->SetCurrentRefIndex(fPlaylist->CurrentRefIndex() + 1); 219 } 220 fHasFile = false; 221 fHasVideo = false; 222 fHasAudio = false; 223 SetTitle(NAME); 224 } else { 225 fHasFile = true; 226 fHasVideo = fController->VideoTrackCount() != 0; 227 fHasAudio = fController->AudioTrackCount() != 0; 228 SetTitle(ref.name); 229 } 230 SetupWindow(); 231 } 232 233 void 234 MainWin::SetupWindow() 235 { 236 printf("MainWin::SetupWindow\n"); 237 238 // Populate the track menus 239 SetupTrackMenus(); 240 // Enable both if a file was loaded 241 fAudioTrackMenu->SetEnabled(fHasFile); 242 fVideoTrackMenu->SetEnabled(fHasFile); 243 // Select first track (might be "none") in both 244 fAudioTrackMenu->ItemAt(0)->SetMarked(true); 245 fVideoTrackMenu->ItemAt(0)->SetMarked(true); 246 247 fVideoMenu->SetEnabled(fHasVideo); 248 fAudioMenu->SetEnabled(fHasAudio); 249 fDebugMenu->SetEnabled(fHasVideo); 250 251 if (fHasVideo) { 252 fController->GetSize(&fSourceWidth, &fSourceHeight); 253 fWidthScale = 1.0; 254 fHeightScale = 1.0; 255 } else { 256 fSourceWidth = 0; 257 fSourceHeight = 0; 258 fWidthScale = 1.0; 259 fHeightScale = 1.0; 260 } 261 262 UpdateControlsEnabledStatus(); 263 264 ResizeWindow(100); 265 266 fVideoView->MakeFocus(); 267 268 MaybeUpdateFileInfo(); 269 } 270 271 272 void 273 MainWin::ResizeWindow(int percent) 274 { 275 int video_width; 276 int video_height; 277 278 // Get required window size 279 video_width = lround(fSourceWidth * fWidthScale); 280 video_height = lround(fSourceHeight * fHeightScale); 281 282 video_width = (video_width * percent) / 100; 283 video_height = (video_height * percent) / 100; 284 285 // Calculate and set the initial window size 286 int width = max_c(fControlsWidth, video_width); 287 int height = (fNoControls ? 0 : fControlsHeight) + video_height; 288 if (!fNoMenu) { 289 width = max_c(width, fMenuBarWidth); 290 height += fMenuBarHeight; 291 } 292 SetWindowSizeLimits(); 293 ResizeTo(width - 1, height - 1); 294 } 295 296 297 void 298 MainWin::SetWindowSizeLimits() 299 { 300 int minWidth = fNoControls ? MIN_WIDTH : fControlsWidth; 301 if (!fNoMenu) 302 minWidth = max_c(minWidth, fMenuBarWidth); 303 int minHeight = (fNoMenu ? 0 : fMenuBarHeight) + (fNoControls ? 0 : fControlsHeight); 304 305 SetSizeLimits(minWidth - 1, 32000, minHeight - 1, fHasVideo ? 32000 : minHeight - 1); 306 } 307 308 309 void 310 MainWin::CreateMenu() 311 { 312 fFileMenu = new BMenu(NAME); 313 fPlaylistMenu = new BMenu("Playlist"B_UTF8_ELLIPSIS); 314 fAudioMenu = new BMenu("Audio"); 315 fVideoMenu = new BMenu("Video"); 316 fSettingsMenu = new BMenu("Settings"); 317 fAudioTrackMenu = new BMenu("Track"); 318 fVideoTrackMenu = new BMenu("Track"); 319 fDebugMenu = new BMenu("Debug"); 320 321 fMenuBar->AddItem(fFileMenu); 322 fMenuBar->AddItem(fAudioMenu); 323 fMenuBar->AddItem(fVideoMenu); 324 fMenuBar->AddItem(fSettingsMenu); 325 // fMenuBar->AddItem(fDebugMenu); 326 327 fFileMenu->AddItem(new BMenuItem("New Player"B_UTF8_ELLIPSIS, new BMessage(M_FILE_NEWPLAYER), 'N', B_COMMAND_KEY)); 328 fFileMenu->AddSeparatorItem(); 329 fFileMenu->AddItem(new BMenuItem("Open File"B_UTF8_ELLIPSIS, new BMessage(M_FILE_OPEN), 'O', B_COMMAND_KEY)); 330 fFileMenu->AddItem(new BMenuItem("File Info"B_UTF8_ELLIPSIS, new BMessage(M_FILE_INFO), 'I', B_COMMAND_KEY)); 331 fFileMenu->AddItem(fPlaylistMenu); 332 fPlaylistMenu->Superitem()->SetShortcut('P', B_COMMAND_KEY); 333 fPlaylistMenu->Superitem()->SetMessage(new BMessage(M_FILE_PLAYLIST)); 334 335 fFileMenu->AddSeparatorItem(); 336 fFileMenu->AddItem(new BMenuItem("About" NAME B_UTF8_ELLIPSIS, new BMessage(M_FILE_ABOUT))); 337 fFileMenu->AddSeparatorItem(); 338 fFileMenu->AddItem(new BMenuItem("Close", new BMessage(M_FILE_CLOSE), 'W', B_COMMAND_KEY)); 339 fFileMenu->AddItem(new BMenuItem("Quit", new BMessage(M_FILE_QUIT), 'Q', B_COMMAND_KEY)); 340 341 fPlaylistMenu->SetRadioMode(true); 342 343 fAudioMenu->AddItem(fAudioTrackMenu); 344 345 fVideoMenu->AddItem(fVideoTrackMenu); 346 fVideoMenu->AddSeparatorItem(); 347 fVideoMenu->AddItem(new BMenuItem("50% scale", new BMessage(M_VIEW_50), '0', B_COMMAND_KEY)); 348 fVideoMenu->AddItem(new BMenuItem("100% scale", new BMessage(M_VIEW_100), '1', B_COMMAND_KEY)); 349 fVideoMenu->AddItem(new BMenuItem("200% scale", new BMessage(M_VIEW_200), '2', B_COMMAND_KEY)); 350 fVideoMenu->AddItem(new BMenuItem("300% scale", new BMessage(M_VIEW_300), '3', B_COMMAND_KEY)); 351 fVideoMenu->AddItem(new BMenuItem("400% scale", new BMessage(M_VIEW_400), '4', B_COMMAND_KEY)); 352 fVideoMenu->AddSeparatorItem(); 353 fVideoMenu->AddItem(new BMenuItem("Full Screen", new BMessage(M_TOGGLE_FULLSCREEN), 'F', B_COMMAND_KEY)); 354 fVideoMenu->AddItem(new BMenuItem("Keep Aspect Ratio", new BMessage(M_TOGGLE_KEEP_ASPECT_RATIO), 'K', B_COMMAND_KEY)); 355 356 fSettingsMenu->AddItem(new BMenuItem("No Menu", new BMessage(M_TOGGLE_NO_MENU), 'M', B_COMMAND_KEY)); 357 fSettingsMenu->AddItem(new BMenuItem("No Border", new BMessage(M_TOGGLE_NO_BORDER), 'B', B_COMMAND_KEY)); 358 fSettingsMenu->AddItem(new BMenuItem("No Controls", new BMessage(M_TOGGLE_NO_CONTROLS), 'C', B_COMMAND_KEY)); 359 fSettingsMenu->AddItem(new BMenuItem("Always on Top", new BMessage(M_TOGGLE_ALWAYS_ON_TOP), 'T', B_COMMAND_KEY)); 360 // fSettingsMenu->AddSeparatorItem(); 361 // fSettingsMenu->AddItem(new BMenuItem("Preferences"B_UTF8_ELLIPSIS, new BMessage(M_PREFERENCES), 'P', B_COMMAND_KEY)); 362 363 fDebugMenu->AddItem(new BMenuItem("pixel aspect ratio 1.00000:1", new BMessage(M_ASPECT_100000_1))); 364 fDebugMenu->AddItem(new BMenuItem("pixel aspect ratio 1.06666:1", new BMessage(M_ASPECT_106666_1))); 365 fDebugMenu->AddItem(new BMenuItem("pixel aspect ratio 1.09091:1", new BMessage(M_ASPECT_109091_1))); 366 fDebugMenu->AddItem(new BMenuItem("pixel aspect ratio 1.41176:1", new BMessage(M_ASPECT_141176_1))); 367 fDebugMenu->AddItem(new BMenuItem("force 720 x 576, display aspect 4:3", new BMessage(M_ASPECT_720_576))); 368 fDebugMenu->AddItem(new BMenuItem("force 704 x 576, display aspect 4:3", new BMessage(M_ASPECT_704_576))); 369 fDebugMenu->AddItem(new BMenuItem("force 544 x 576, display aspect 4:3", new BMessage(M_ASPECT_544_576))); 370 371 fAudioTrackMenu->SetRadioMode(true); 372 fVideoTrackMenu->SetRadioMode(true); 373 /* 374 fSettingsMenu->ItemAt(3)->SetMarked(fIsFullscreen); 375 fSettingsMenu->ItemAt(5)->SetMarked(fNoMenu); 376 fSettingsMenu->ItemAt(6)->SetMarked(fNoBorder); 377 fSettingsMenu->ItemAt(7)->SetMarked(fAlwaysOnTop); 378 fSettingsMenu->ItemAt(8)->SetMarked(fKeepAspectRatio); 379 fSettingsMenu->ItemAt(10)->SetEnabled(false); // XXX disable unused preference menu 380 */ 381 } 382 383 384 void 385 MainWin::SetupTrackMenus() 386 { 387 fAudioTrackMenu->RemoveItems(0, fAudioTrackMenu->CountItems(), true); 388 fVideoTrackMenu->RemoveItems(0, fVideoTrackMenu->CountItems(), true); 389 390 int c, i; 391 char s[100]; 392 393 c = fController->AudioTrackCount(); 394 for (i = 0; i < c; i++) { 395 sprintf(s, "Track %d", i + 1); 396 fAudioTrackMenu->AddItem(new BMenuItem(s, new BMessage(M_SELECT_AUDIO_TRACK + i))); 397 } 398 if (!c) 399 fAudioTrackMenu->AddItem(new BMenuItem("none", new BMessage(M_DUMMY))); 400 401 c = fController->VideoTrackCount(); 402 for (i = 0; i < c; i++) { 403 sprintf(s, "Track %d", i + 1); 404 fVideoTrackMenu->AddItem(new BMenuItem(s, new BMessage(M_SELECT_VIDEO_TRACK + i))); 405 } 406 if (!c) 407 fVideoTrackMenu->AddItem(new BMenuItem("none", new BMessage(M_DUMMY))); 408 } 409 410 411 bool 412 MainWin::QuitRequested() 413 { 414 be_app->PostMessage(M_PLAYER_QUIT); 415 return true; 416 } 417 418 419 void 420 MainWin::MouseDown(BMessage *msg, BView* originalHandler) 421 { 422 BPoint screen_where; 423 uint32 buttons = msg->FindInt32("buttons"); 424 425 // On Zeta, only "screen_where" is relyable, "where" and "be:view_where" seem to be broken 426 if (B_OK != msg->FindPoint("screen_where", &screen_where)) { 427 // Workaround for BeOS R5, it has no "screen_where" 428 if (!originalHandler || msg->FindPoint("where", &screen_where) < B_OK) 429 return; 430 originalHandler->ConvertToScreen(&screen_where); 431 } 432 433 // msg->PrintToStream(); 434 435 // if (1 == msg->FindInt32("buttons") && msg->FindInt32("clicks") == 1) { 436 437 if (1 == buttons && msg->FindInt32("clicks") % 2 == 0) { 438 BRect r(screen_where.x - 1, screen_where.y - 1, screen_where.x + 1, screen_where.y + 1); 439 if (r.Contains(fMouseDownMousePos)) { 440 PostMessage(M_TOGGLE_FULLSCREEN); 441 return; 442 } 443 } 444 445 if (2 == buttons && msg->FindInt32("clicks") % 2 == 0) { 446 BRect r(screen_where.x - 1, screen_where.y - 1, screen_where.x + 1, screen_where.y + 1); 447 if (r.Contains(fMouseDownMousePos)) { 448 PostMessage(M_TOGGLE_NO_BORDER_NO_MENU_NO_CONTROLS); 449 return; 450 } 451 } 452 453 /* 454 // very broken in Zeta: 455 fMouseDownMousePos = fVideoView->ConvertToScreen(msg->FindPoint("where")); 456 */ 457 fMouseDownMousePos = screen_where; 458 fMouseDownWindowPos = Frame().LeftTop(); 459 460 if (buttons == 1 && !fIsFullscreen) { 461 // start mouse tracking 462 fVideoView->SetMouseEventMask(B_POINTER_EVENTS | B_NO_POINTER_HISTORY /* | B_LOCK_WINDOW_FOCUS */); 463 fMouseDownTracking = true; 464 } 465 466 // pop up a context menu if right mouse button is down for 200 ms 467 468 if ((buttons & 2) == 0) 469 return; 470 bigtime_t start = system_time(); 471 bigtime_t delay = 200000; 472 BPoint location; 473 do { 474 fVideoView->GetMouse(&location, &buttons); 475 if ((buttons & 2) == 0) 476 break; 477 snooze(1000); 478 } while (system_time() - start < delay); 479 480 if (buttons & 2) 481 ShowContextMenu(screen_where); 482 } 483 484 485 void 486 MainWin::MouseMoved(BMessage *msg, BView* originalHandler) 487 { 488 // msg->PrintToStream(); 489 490 BPoint mousePos; 491 uint32 buttons = msg->FindInt32("buttons"); 492 493 if (1 == buttons && fMouseDownTracking && !fIsFullscreen) { 494 /* 495 // very broken in Zeta: 496 BPoint mousePos = msg->FindPoint("where"); 497 printf("view where: %.0f, %.0f => ", mousePos.x, mousePos.y); 498 fVideoView->ConvertToScreen(&mousePos); 499 */ 500 // On Zeta, only "screen_where" is relyable, "where" 501 // and "be:view_where" seem to be broken 502 if (B_OK != msg->FindPoint("screen_where", &mousePos)) { 503 // Workaround for BeOS R5, it has no "screen_where" 504 if (!originalHandler || msg->FindPoint("where", &mousePos) < B_OK) 505 return; 506 originalHandler->ConvertToScreen(&mousePos); 507 } 508 // printf("screen where: %.0f, %.0f => ", mousePos.x, mousePos.y); 509 float delta_x = mousePos.x - fMouseDownMousePos.x; 510 float delta_y = mousePos.y - fMouseDownMousePos.y; 511 float x = fMouseDownWindowPos.x + delta_x; 512 float y = fMouseDownWindowPos.y + delta_y; 513 // printf("move window to %.0f, %.0f\n", x, y); 514 MoveTo(x, y); 515 } 516 } 517 518 519 void 520 MainWin::MouseUp(BMessage *msg) 521 { 522 // msg->PrintToStream(); 523 fMouseDownTracking = false; 524 } 525 526 527 void 528 MainWin::ShowContextMenu(const BPoint &screen_point) 529 { 530 printf("Show context menu\n"); 531 BPopUpMenu *menu = new BPopUpMenu("context menu", false, false); 532 BMenuItem *item; 533 menu->AddItem(item = new BMenuItem("Full Screen", new BMessage(M_TOGGLE_FULLSCREEN), 'F', B_COMMAND_KEY)); 534 item->SetMarked(fIsFullscreen); 535 item->SetEnabled(fHasVideo); 536 menu->AddItem(item = new BMenuItem("Keep Aspect Ratio", new BMessage(M_TOGGLE_KEEP_ASPECT_RATIO), 'K', B_COMMAND_KEY)); 537 item->SetMarked(fKeepAspectRatio); 538 item->SetEnabled(fHasVideo); 539 540 menu->AddSeparatorItem(); 541 menu->AddItem(item = new BMenuItem("No Menu", new BMessage(M_TOGGLE_NO_MENU), 'M', B_COMMAND_KEY)); 542 item->SetMarked(fNoMenu); 543 menu->AddItem(item = new BMenuItem("No Border", new BMessage(M_TOGGLE_NO_BORDER), 'B', B_COMMAND_KEY)); 544 item->SetMarked(fNoBorder); 545 menu->AddItem(item = new BMenuItem("Always on Top", new BMessage(M_TOGGLE_ALWAYS_ON_TOP), 'T', B_COMMAND_KEY)); 546 item->SetMarked(fAlwaysOnTop); 547 548 menu->AddSeparatorItem(); 549 menu->AddItem(new BMenuItem("About" NAME B_UTF8_ELLIPSIS, new BMessage(M_FILE_ABOUT))); 550 menu->AddSeparatorItem(); 551 menu->AddItem(new BMenuItem("Quit", new BMessage(M_FILE_QUIT), 'Q', B_COMMAND_KEY)); 552 553 menu->AddSeparatorItem(); 554 menu->AddItem(new BMenuItem("pixel aspect ratio 1.00000:1", new BMessage(M_ASPECT_100000_1))); 555 menu->AddItem(new BMenuItem("pixel aspect ratio 1.06666:1", new BMessage(M_ASPECT_106666_1))); 556 menu->AddItem(new BMenuItem("pixel aspect ratio 1.09091:1", new BMessage(M_ASPECT_109091_1))); 557 menu->AddItem(new BMenuItem("pixel aspect ratio 1.41176:1", new BMessage(M_ASPECT_141176_1))); 558 menu->AddItem(new BMenuItem("force 720 x 576, display aspect 4:3", new BMessage(M_ASPECT_720_576))); 559 menu->AddItem(new BMenuItem("force 704 x 576, display aspect 4:3", new BMessage(M_ASPECT_704_576))); 560 menu->AddItem(new BMenuItem("force 544 x 576, display aspect 4:3", new BMessage(M_ASPECT_544_576))); 561 562 menu->SetTargetForItems(this); 563 BRect r(screen_point.x - 5, screen_point.y - 5, screen_point.x + 5, screen_point.y + 5); 564 menu->Go(screen_point, true, true, r, true); 565 } 566 567 568 void 569 MainWin::VideoFormatChange(int width, int height, float width_scale, float height_scale) 570 { 571 // called when video format or aspect ratio changes 572 573 printf("VideoFormatChange enter: width %d, height %d, width_scale %.6f, height_scale %.6f\n", width, height, width_scale, height_scale); 574 575 if (width_scale < 1.0 && height_scale >= 1.0) { 576 width_scale = 1.0 / width_scale; 577 height_scale = 1.0 / height_scale; 578 printf("inverting! new values: width_scale %.6f, height_scale %.6f\n", width_scale, height_scale); 579 } 580 581 fSourceWidth = width; 582 fSourceHeight = height; 583 fWidthScale = width_scale; 584 fHeightScale = height_scale; 585 586 FrameResized(Bounds().Width(), Bounds().Height()); 587 588 printf("VideoFormatChange leave\n"); 589 } 590 591 592 void 593 MainWin::Zoom(BPoint rec_position, float rec_width, float rec_height) 594 { 595 PostMessage(M_TOGGLE_FULLSCREEN); 596 } 597 598 599 void 600 MainWin::FrameResized(float new_width, float new_height) 601 { 602 if (new_width != Bounds().Width() || new_height != Bounds().Height()) { 603 debugger("size wrong\n"); 604 } 605 606 bool no_menu = fNoMenu || fIsFullscreen; 607 bool no_controls = fNoControls || fIsFullscreen; 608 609 printf("FrameResized enter: new_width %.0f, new_height %.0f\n", new_width, new_height); 610 611 int max_video_width = int(new_width) + 1; 612 int max_video_height = int(new_height) + 1 - (no_menu ? 0 : fMenuBarHeight) - (no_controls ? 0 : fControlsHeight); 613 614 ASSERT(max_video_height >= 0); 615 616 int y = 0; 617 618 if (no_menu) { 619 if (!fMenuBar->IsHidden()) 620 fMenuBar->Hide(); 621 } else { 622 // fMenuBar->MoveTo(0, y); 623 fMenuBar->ResizeTo(new_width, fMenuBarHeight - 1); 624 if (fMenuBar->IsHidden()) 625 fMenuBar->Show(); 626 y += fMenuBarHeight; 627 } 628 629 if (max_video_height == 0) { 630 if (!fVideoView->IsHidden()) 631 fVideoView->Hide(); 632 } else { 633 // fVideoView->MoveTo(0, y); 634 // fVideoView->ResizeTo(max_video_width - 1, max_video_height - 1); 635 ResizeVideoView(0, y, max_video_width, max_video_height); 636 if (fVideoView->IsHidden()) 637 fVideoView->Show(); 638 y += max_video_height; 639 } 640 641 if (no_controls) { 642 if (!fControls->IsHidden()) 643 fControls->Hide(); 644 } else { 645 fControls->MoveTo(0, y); 646 fControls->ResizeTo(new_width, fControlsHeight - 1); 647 if (fControls->IsHidden()) 648 fControls->Show(); 649 // y += fControlsHeight; 650 } 651 652 printf("FrameResized leave\n"); 653 } 654 655 656 void 657 MainWin::ShowFileInfo() 658 { 659 if (!fInfoWin) 660 fInfoWin = new InfoWin(this); 661 662 if (fInfoWin->Lock()) { 663 if (fInfoWin->IsHidden()) 664 fInfoWin->Show(); 665 else 666 fInfoWin->Activate(); 667 fInfoWin->Unlock(); 668 } 669 670 BMessenger msgr(fInfoWin); 671 BMessage m(M_UPDATE_INFO); 672 m.AddInt32("which", INFO_ALL); 673 msgr.SendMessage(&m); 674 msgr.SendMessage(B_WINDOW_ACTIVATED); 675 } 676 677 678 void 679 MainWin::ShowPlaylistWindow() 680 { 681 if (!fPlaylistWindow) { 682 fPlaylistWindow = new PlaylistWindow(BRect(150, 150, 400, 500), 683 fPlaylist); 684 fPlaylistWindow->Show(); 685 return; 686 } 687 688 if (fPlaylistWindow->Lock()) { 689 if (fPlaylistWindow->IsHidden()) 690 fPlaylistWindow->Show(); 691 else 692 fPlaylistWindow->Activate(); 693 fPlaylistWindow->Unlock(); 694 } 695 } 696 697 698 void 699 MainWin::MaybeUpdateFileInfo(uint32 which) 700 { 701 // Update the Info Window if it's displayed. 702 if (!fInfoWinShowing) 703 return; 704 BMessenger msgr(fInfoWin); 705 BMessage m(M_UPDATE_INFO); 706 m.AddInt32("which", which); 707 msgr.SendMessage(&m); 708 } 709 710 void 711 MainWin::ResizeVideoView(int x, int y, int width, int height) 712 { 713 printf("ResizeVideoView: %d,%d, width %d, height %d\n", x, y, width, height); 714 715 if (fKeepAspectRatio) { 716 // Keep aspect ratio, place video view inside 717 // the background area (may create black bars). 718 float scaled_width = fSourceWidth * fWidthScale; 719 float scaled_height = fSourceHeight * fHeightScale; 720 float factor = min_c(width / scaled_width, height / scaled_height); 721 int render_width = lround(scaled_width * factor); 722 int render_height = lround(scaled_height * factor); 723 if (render_width > width) 724 render_width = width; 725 if (render_height > height) 726 render_height = height; 727 728 int x_ofs = x + (width - render_width) / 2; 729 int y_ofs = y + (height - render_height) / 2; 730 731 fVideoView->MoveTo(x_ofs, y_ofs); 732 fVideoView->ResizeTo(render_width - 1, render_height - 1); 733 734 } else { 735 fVideoView->MoveTo(x, y); 736 fVideoView->ResizeTo(width - 1, height - 1); 737 } 738 } 739 740 741 void 742 MainWin::ToggleNoBorderNoMenu() 743 { 744 if (!fNoMenu && !fNoBorder && !fNoControls) { 745 PostMessage(M_TOGGLE_NO_MENU); 746 PostMessage(M_TOGGLE_NO_BORDER); 747 PostMessage(M_TOGGLE_NO_CONTROLS); 748 } else { 749 if (!fNoMenu) 750 PostMessage(M_TOGGLE_NO_MENU); 751 if (!fNoBorder) 752 PostMessage(M_TOGGLE_NO_BORDER); 753 if (!fNoControls) 754 PostMessage(M_TOGGLE_NO_CONTROLS); 755 } 756 } 757 758 759 void 760 MainWin::ToggleFullscreen() 761 { 762 printf("ToggleFullscreen enter\n"); 763 764 if (!fHasVideo) { 765 printf("ToggleFullscreen - ignoring, as we don't have a video\n"); 766 return; 767 } 768 769 fIsFullscreen = !fIsFullscreen; 770 771 if (fIsFullscreen) { 772 // switch to fullscreen 773 774 fSavedFrame = Frame(); 775 printf("saving current frame: %d %d %d %d\n", int(fSavedFrame.left), int(fSavedFrame.top), int(fSavedFrame.right), int(fSavedFrame.bottom)); 776 BScreen screen(this); 777 BRect rect(screen.Frame()); 778 779 Hide(); 780 MoveTo(rect.left, rect.top); 781 ResizeTo(rect.Width(), rect.Height()); 782 Show(); 783 784 } else { 785 // switch back from full screen mode 786 787 Hide(); 788 MoveTo(fSavedFrame.left, fSavedFrame.top); 789 ResizeTo(fSavedFrame.Width(), fSavedFrame.Height()); 790 Show(); 791 } 792 793 printf("ToggleFullscreen leave\n"); 794 } 795 796 void 797 MainWin::ToggleNoControls() 798 { 799 printf("ToggleNoControls enter\n"); 800 801 if (fIsFullscreen) { 802 // fullscreen is always without menu 803 printf("ToggleNoControls leave, doing nothing, we are fullscreen\n"); 804 return; 805 } 806 807 fNoControls = !fNoControls; 808 SetWindowSizeLimits(); 809 810 if (fNoControls) { 811 ResizeBy(0, - fControlsHeight); 812 } else { 813 ResizeBy(0, fControlsHeight); 814 } 815 816 printf("ToggleNoControls leave\n"); 817 } 818 819 void 820 MainWin::ToggleNoMenu() 821 { 822 printf("ToggleNoMenu enter\n"); 823 824 if (fIsFullscreen) { 825 // fullscreen is always without menu 826 printf("ToggleNoMenu leave, doing nothing, we are fullscreen\n"); 827 return; 828 } 829 830 fNoMenu = !fNoMenu; 831 SetWindowSizeLimits(); 832 833 if (fNoMenu) { 834 MoveBy(0, fMenuBarHeight); 835 ResizeBy(0, - fMenuBarHeight); 836 } else { 837 MoveBy(0, - fMenuBarHeight); 838 ResizeBy(0, fMenuBarHeight); 839 } 840 841 printf("ToggleNoMenu leave\n"); 842 } 843 844 845 void 846 MainWin::ToggleNoBorder() 847 { 848 printf("ToggleNoBorder enter\n"); 849 fNoBorder = !fNoBorder; 850 SetLook(fNoBorder ? B_BORDERED_WINDOW_LOOK : B_TITLED_WINDOW_LOOK); 851 printf("ToggleNoBorder leave\n"); 852 } 853 854 855 void 856 MainWin::ToggleAlwaysOnTop() 857 { 858 printf("ToggleAlwaysOnTop enter\n"); 859 fAlwaysOnTop = !fAlwaysOnTop; 860 SetFeel(fAlwaysOnTop ? B_FLOATING_ALL_WINDOW_FEEL : B_NORMAL_WINDOW_FEEL); 861 printf("ToggleAlwaysOnTop leave\n"); 862 } 863 864 865 void 866 MainWin::ToggleKeepAspectRatio() 867 { 868 printf("ToggleKeepAspectRatio enter\n"); 869 fKeepAspectRatio = !fKeepAspectRatio; 870 FrameResized(Bounds().Width(), Bounds().Height()); 871 printf("ToggleKeepAspectRatio leave\n"); 872 } 873 874 875 void 876 MainWin::UpdateControlsEnabledStatus() 877 { 878 uint32 enabledButtons = 0; 879 if (fHasVideo || fHasAudio) { 880 enabledButtons |= PLAYBACK_ENABLED | SEEK_ENABLED 881 | SEEK_BACK_ENABLED | SEEK_FORWARD_ENABLED; 882 } 883 if (fHasAudio) 884 enabledButtons |= VOLUME_ENABLED; 885 886 bool canSkipPrevious, canSkipNext; 887 fPlaylist->GetSkipInfo(&canSkipPrevious, &canSkipNext); 888 if (canSkipPrevious) 889 enabledButtons |= SKIP_BACK_ENABLED; 890 if (canSkipNext) 891 enabledButtons |= SKIP_FORWARD_ENABLED; 892 893 fControls->SetEnabled(enabledButtons); 894 } 895 896 897 void 898 MainWin::_UpdatePlaylistMenu() 899 { 900 fPlaylistMenu->RemoveItems(0, fPlaylistMenu->CountItems(), true); 901 902 // TODO: lock fPlaylist 903 904 int32 count = fPlaylist->CountItems(); 905 for (int32 i = 0; i < count; i++) { 906 entry_ref ref; 907 if (fPlaylist->GetRefAt(i, &ref) < B_OK) 908 continue; 909 _AddPlaylistItem(ref, i); 910 } 911 fPlaylistMenu->SetTargetForItems(this); 912 913 _MarkPlaylistItem(fPlaylist->CurrentRefIndex()); 914 } 915 916 917 void 918 MainWin::_AddPlaylistItem(const entry_ref& ref, int32 index) 919 { 920 BMessage* message = new BMessage(M_SET_PLAYLIST_POSITION); 921 message->AddInt32("index", index); 922 BMenuItem* item = new BMenuItem(ref.name, message); 923 fPlaylistMenu->AddItem(item, index); 924 } 925 926 927 void 928 MainWin::_RemovePlaylistItem(int32 index) 929 { 930 delete fPlaylistMenu->RemoveItem(index); 931 } 932 933 934 void 935 MainWin::_MarkPlaylistItem(int32 index) 936 { 937 if (BMenuItem* item = fPlaylistMenu->ItemAt(index)) { 938 item->SetMarked(true); 939 // ... and in case the menu is currently on screen: 940 if (fPlaylistMenu->LockLooper()) { 941 fPlaylistMenu->Invalidate(); 942 fPlaylistMenu->UnlockLooper(); 943 } 944 } 945 } 946 947 948 void 949 MainWin::RefsReceived(BMessage *msg) 950 { 951 printf("MainWin::RefsReceived\n"); 952 953 // the playlist ist replaced by dropped files 954 // or the dropped files are appended to the end 955 // of the existing playlist if <shift> is pressed 956 bool add = modifiers() & B_SHIFT_KEY; 957 958 if (!add) 959 fPlaylist->MakeEmpty(); 960 961 bool startPlaying = fPlaylist->CountItems() == 0; 962 963 Playlist temporaryPlaylist; 964 Playlist* playlist = add ? &temporaryPlaylist : fPlaylist; 965 966 entry_ref ref; 967 for (int i = 0; B_OK == msg->FindRef("refs", i, &ref); i++) 968 _AppendToPlaylist(ref, playlist); 969 970 playlist->Sort(); 971 972 if (add) 973 fPlaylist->AdoptPlaylist(temporaryPlaylist); 974 975 if (startPlaying) { 976 // open first file 977 fPlaylist->SetCurrentRefIndex(0); 978 } 979 } 980 981 982 /* Trap keys that are about to be send to background or renderer view. 983 * Return B_OK if it shouldn't be passed to the view 984 */ 985 status_t 986 MainWin::KeyDown(BMessage *msg) 987 { 988 // msg->PrintToStream(); 989 990 uint32 key = msg->FindInt32("key"); 991 uint32 raw_char = msg->FindInt32("raw_char"); 992 uint32 modifiers = msg->FindInt32("modifiers"); 993 994 printf("key 0x%lx, raw_char 0x%lx, modifiers 0x%lx\n", key, raw_char, modifiers); 995 996 switch (raw_char) { 997 case B_SPACE: 998 if (fController->IsPaused() || fController->IsStopped()) 999 fController->Play(); 1000 else 1001 fController->Pause(); 1002 return B_OK; 1003 1004 case B_ESCAPE: 1005 if (fIsFullscreen) { 1006 PostMessage(M_TOGGLE_FULLSCREEN); 1007 return B_OK; 1008 } else 1009 break; 1010 1011 case B_ENTER: // Enter / Return 1012 if (modifiers & B_COMMAND_KEY) { 1013 PostMessage(M_TOGGLE_FULLSCREEN); 1014 return B_OK; 1015 } else 1016 break; 1017 1018 case B_TAB: 1019 if ((modifiers & (B_COMMAND_KEY | B_CONTROL_KEY | B_OPTION_KEY | B_MENU_KEY)) == 0) { 1020 PostMessage(M_TOGGLE_FULLSCREEN); 1021 return B_OK; 1022 } else 1023 break; 1024 1025 case B_UP_ARROW: 1026 if (modifiers & B_COMMAND_KEY) { 1027 PostMessage(M_CHANNEL_NEXT); 1028 } else { 1029 PostMessage(M_VOLUME_UP); 1030 } 1031 return B_OK; 1032 1033 case B_DOWN_ARROW: 1034 if (modifiers & B_COMMAND_KEY) { 1035 PostMessage(M_CHANNEL_PREV); 1036 } else { 1037 PostMessage(M_VOLUME_DOWN); 1038 } 1039 return B_OK; 1040 1041 case B_RIGHT_ARROW: 1042 if (modifiers & B_COMMAND_KEY) { 1043 PostMessage(M_VOLUME_UP); 1044 } else { 1045 PostMessage(M_CHANNEL_NEXT); 1046 } 1047 return B_OK; 1048 1049 case B_LEFT_ARROW: 1050 if (modifiers & B_COMMAND_KEY) { 1051 PostMessage(M_VOLUME_DOWN); 1052 } else { 1053 PostMessage(M_CHANNEL_PREV); 1054 } 1055 return B_OK; 1056 1057 case B_PAGE_UP: 1058 PostMessage(M_CHANNEL_NEXT); 1059 return B_OK; 1060 1061 case B_PAGE_DOWN: 1062 PostMessage(M_CHANNEL_PREV); 1063 return B_OK; 1064 } 1065 1066 switch (key) { 1067 case 0x3a: // numeric keypad + 1068 if ((modifiers & B_COMMAND_KEY) == 0) { 1069 printf("if\n"); 1070 PostMessage(M_VOLUME_UP); 1071 return B_OK; 1072 } else { 1073 printf("else\n"); 1074 break; 1075 } 1076 1077 case 0x25: // numeric keypad - 1078 if ((modifiers & B_COMMAND_KEY) == 0) { 1079 PostMessage(M_VOLUME_DOWN); 1080 return B_OK; 1081 } else { 1082 break; 1083 } 1084 1085 case 0x38: // numeric keypad up arrow 1086 PostMessage(M_VOLUME_UP); 1087 return B_OK; 1088 1089 case 0x59: // numeric keypad down arrow 1090 PostMessage(M_VOLUME_DOWN); 1091 return B_OK; 1092 1093 case 0x39: // numeric keypad page up 1094 case 0x4a: // numeric keypad right arrow 1095 PostMessage(M_CHANNEL_NEXT); 1096 return B_OK; 1097 1098 case 0x5a: // numeric keypad page down 1099 case 0x48: // numeric keypad left arrow 1100 PostMessage(M_CHANNEL_PREV); 1101 return B_OK; 1102 } 1103 1104 return B_ERROR; 1105 } 1106 1107 1108 void 1109 MainWin::DispatchMessage(BMessage *msg, BHandler *handler) 1110 { 1111 if ((msg->what == B_MOUSE_DOWN) 1112 && (handler == fBackground || handler == fVideoView 1113 || handler == fControls)) 1114 MouseDown(msg, dynamic_cast<BView*>(handler)); 1115 1116 if ((msg->what == B_MOUSE_MOVED) 1117 && (handler == fBackground || handler == fVideoView 1118 || handler == fControls)) 1119 MouseMoved(msg, dynamic_cast<BView*>(handler)); 1120 1121 if ((msg->what == B_MOUSE_UP) 1122 && (handler == fBackground || handler == fVideoView)) 1123 MouseUp(msg); 1124 1125 if ((msg->what == B_KEY_DOWN) 1126 && (handler == fBackground || handler == fVideoView)) { 1127 1128 // special case for PrintScreen key 1129 if (msg->FindInt32("key") == B_PRINT_KEY) { 1130 fVideoView->OverlayScreenshotPrepare(); 1131 BWindow::DispatchMessage(msg, handler); 1132 fVideoView->OverlayScreenshotCleanup(); 1133 return; 1134 } 1135 1136 // every other key gets dispatched to our KeyDown first 1137 if (KeyDown(msg) == B_OK) { 1138 // it got handled, don't pass it on 1139 return; 1140 } 1141 } 1142 1143 BWindow::DispatchMessage(msg, handler); 1144 } 1145 1146 1147 void 1148 MainWin::MessageReceived(BMessage *msg) 1149 { 1150 switch (msg->what) { 1151 case B_REFS_RECEIVED: 1152 printf("MainWin::MessageReceived: B_REFS_RECEIVED\n"); 1153 RefsReceived(msg); 1154 break; 1155 case B_SIMPLE_DATA: 1156 printf("MainWin::MessageReceived: B_SIMPLE_DATA\n"); 1157 if (msg->HasRef("refs")) 1158 RefsReceived(msg); 1159 break; 1160 1161 // PlaylistObserver messages 1162 case MSG_PLAYLIST_REF_ADDED: { 1163 entry_ref ref; 1164 int32 index; 1165 if (msg->FindRef("refs", &ref) == B_OK 1166 && msg->FindInt32("index", &index) == B_OK) { 1167 _AddPlaylistItem(ref, index); 1168 } 1169 break; 1170 } 1171 case MSG_PLAYLIST_REF_REMOVED: { 1172 int32 index; 1173 if (msg->FindInt32("index", &index) == B_OK) { 1174 _RemovePlaylistItem(index); 1175 } 1176 break; 1177 } 1178 case MSG_PLAYLIST_CURRENT_REF_CHANGED: { 1179 entry_ref ref; 1180 int32 index = fPlaylist->CurrentRefIndex(); 1181 if (fPlaylist->GetRefAt(index, &ref) == B_OK) { 1182 printf("open ref: %s\n", ref.name); 1183 OpenFile(ref); 1184 _MarkPlaylistItem(index); 1185 } 1186 break; 1187 } 1188 1189 // ControllerObserver messages 1190 case MSG_CONTROLLER_FILE_FINISHED: 1191 fPlaylist->SetCurrentRefIndex(fPlaylist->CurrentRefIndex() + 1); 1192 break; 1193 case MSG_CONTROLLER_FILE_CHANGED: 1194 // TODO: move all other GUI changes as a reaction to this notification 1195 // _UpdatePlaylistMenu(); 1196 break; 1197 case MSG_CONTROLLER_VIDEO_TRACK_CHANGED: { 1198 int32 index; 1199 if (msg->FindInt32("index", &index) == B_OK) { 1200 BMenuItem* item = fVideoTrackMenu->ItemAt(index); 1201 if (item) 1202 item->SetMarked(true); 1203 } 1204 break; 1205 } 1206 case MSG_CONTROLLER_AUDIO_TRACK_CHANGED: { 1207 int32 index; 1208 if (msg->FindInt32("index", &index) == B_OK) { 1209 BMenuItem* item = fAudioTrackMenu->ItemAt(index); 1210 if (item) 1211 item->SetMarked(true); 1212 } 1213 break; 1214 } 1215 case MSG_CONTROLLER_PLAYBACK_STATE_CHANGED: { 1216 uint32 state; 1217 if (msg->FindInt32("state", (int32*)&state) == B_OK) 1218 fControls->SetPlaybackState(state); 1219 break; 1220 } 1221 case MSG_CONTROLLER_POSITION_CHANGED: { 1222 float position; 1223 if (msg->FindFloat("position", &position) == B_OK) 1224 fControls->SetPosition(position); 1225 break; 1226 } 1227 1228 // menu item messages 1229 case M_FILE_NEWPLAYER: 1230 gMainApp->NewWindow(); 1231 break; 1232 case M_FILE_OPEN: 1233 if (!fFilePanel) { 1234 fFilePanel = new BFilePanel(); 1235 fFilePanel->SetTarget(BMessenger(0, this)); 1236 fFilePanel->SetPanelDirectory("/boot/home/"); 1237 } 1238 fFilePanel->Show(); 1239 break; 1240 case M_FILE_INFO: 1241 ShowFileInfo(); 1242 break; 1243 case M_FILE_PLAYLIST: 1244 ShowPlaylistWindow(); 1245 break; 1246 case M_FILE_ABOUT: 1247 BAlert *alert; 1248 alert = new BAlert("about", NAME"\n\n Written by Marcus Overhagen","Thanks"); 1249 if (fAlwaysOnTop) { 1250 ToggleAlwaysOnTop(); 1251 alert->Go(); 1252 ToggleAlwaysOnTop(); 1253 } else { 1254 alert->Go(); 1255 } 1256 break; 1257 case M_FILE_CLOSE: 1258 PostMessage(B_QUIT_REQUESTED); 1259 break; 1260 case M_FILE_QUIT: 1261 be_app->PostMessage(B_QUIT_REQUESTED); 1262 break; 1263 1264 case M_TOGGLE_FULLSCREEN: 1265 ToggleFullscreen(); 1266 // fSettingsMenu->ItemAt(1)->SetMarked(fIsFullscreen); 1267 break; 1268 1269 case M_TOGGLE_NO_MENU: 1270 ToggleNoMenu(); 1271 // fSettingsMenu->ItemAt(3)->SetMarked(fNoMenu); 1272 break; 1273 1274 case M_TOGGLE_NO_CONTROLS: 1275 ToggleNoControls(); 1276 // fSettingsMenu->ItemAt(3)->SetMarked(fNoControls); 1277 break; 1278 1279 case M_TOGGLE_NO_BORDER: 1280 ToggleNoBorder(); 1281 // fSettingsMenu->ItemAt(4)->SetMarked(fNoBorder); 1282 break; 1283 1284 case M_TOGGLE_ALWAYS_ON_TOP: 1285 ToggleAlwaysOnTop(); 1286 // fSettingsMenu->ItemAt(5)->SetMarked(fAlwaysOnTop); 1287 break; 1288 1289 case M_TOGGLE_KEEP_ASPECT_RATIO: 1290 ToggleKeepAspectRatio(); 1291 // fSettingsMenu->ItemAt(6)->SetMarked(fKeepAspectRatio); 1292 break; 1293 1294 case M_TOGGLE_NO_BORDER_NO_MENU_NO_CONTROLS: 1295 ToggleNoBorderNoMenu(); 1296 break; 1297 1298 case M_VIEW_50: 1299 if (!fHasVideo) 1300 break; 1301 if (fIsFullscreen) 1302 ToggleFullscreen(); 1303 ResizeWindow(50); 1304 break; 1305 1306 case M_VIEW_100: 1307 if (!fHasVideo) 1308 break; 1309 if (fIsFullscreen) 1310 ToggleFullscreen(); 1311 ResizeWindow(100); 1312 break; 1313 1314 case M_VIEW_200: 1315 if (!fHasVideo) 1316 break; 1317 if (fIsFullscreen) 1318 ToggleFullscreen(); 1319 ResizeWindow(200); 1320 break; 1321 1322 case M_VIEW_300: 1323 if (!fHasVideo) 1324 break; 1325 if (fIsFullscreen) 1326 ToggleFullscreen(); 1327 ResizeWindow(300); 1328 break; 1329 1330 case M_VIEW_400: 1331 if (!fHasVideo) 1332 break; 1333 if (fIsFullscreen) 1334 ToggleFullscreen(); 1335 ResizeWindow(400); 1336 break; 1337 1338 /* 1339 1340 case B_ACQUIRE_OVERLAY_LOCK: 1341 printf("B_ACQUIRE_OVERLAY_LOCK\n"); 1342 fVideoView->OverlayLockAcquire(); 1343 break; 1344 1345 case B_RELEASE_OVERLAY_LOCK: 1346 printf("B_RELEASE_OVERLAY_LOCK\n"); 1347 fVideoView->OverlayLockRelease(); 1348 break; 1349 1350 case B_MOUSE_WHEEL_CHANGED: 1351 { 1352 printf("B_MOUSE_WHEEL_CHANGED\n"); 1353 float dx = msg->FindFloat("be:wheel_delta_x"); 1354 float dy = msg->FindFloat("be:wheel_delta_y"); 1355 bool inv = modifiers() & B_COMMAND_KEY; 1356 if (dx > 0.1) PostMessage(inv ? M_VOLUME_DOWN : M_CHANNEL_PREV); 1357 if (dx < -0.1) PostMessage(inv ? M_VOLUME_UP : M_CHANNEL_NEXT); 1358 if (dy > 0.1) PostMessage(inv ? M_CHANNEL_PREV : M_VOLUME_DOWN); 1359 if (dy < -0.1) PostMessage(inv ? M_CHANNEL_NEXT : M_VOLUME_UP); 1360 break; 1361 } 1362 1363 case M_CHANNEL_NEXT: 1364 { 1365 printf("M_CHANNEL_NEXT\n"); 1366 int chan = fController->CurrentChannel(); 1367 if (chan != -1) { 1368 chan++; 1369 if (chan < fController->ChannelCount()) 1370 SelectChannel(chan); 1371 } 1372 break; 1373 } 1374 1375 case M_CHANNEL_PREV: 1376 { 1377 printf("M_CHANNEL_PREV\n"); 1378 int chan = fController->CurrentChannel(); 1379 if (chan != -1) { 1380 chan--; 1381 if (chan >= 0) 1382 SelectChannel(chan); 1383 } 1384 break; 1385 } 1386 1387 case M_VOLUME_UP: 1388 printf("M_VOLUME_UP\n"); 1389 fController->VolumeUp(); 1390 break; 1391 1392 case M_VOLUME_DOWN: 1393 printf("M_VOLUME_DOWN\n"); 1394 fController->VolumeDown(); 1395 break; 1396 */ 1397 1398 case M_ASPECT_100000_1: 1399 VideoFormatChange(fSourceWidth, fSourceHeight, 1.0, 1.0); 1400 break; 1401 1402 case M_ASPECT_106666_1: 1403 VideoFormatChange(fSourceWidth, fSourceHeight, 1.06666, 1.0); 1404 break; 1405 1406 case M_ASPECT_109091_1: 1407 VideoFormatChange(fSourceWidth, fSourceHeight, 1.09091, 1.0); 1408 break; 1409 1410 case M_ASPECT_141176_1: 1411 VideoFormatChange(fSourceWidth, fSourceHeight, 1.41176, 1.0); 1412 break; 1413 1414 case M_ASPECT_720_576: 1415 VideoFormatChange(720, 576, 1.06666, 1.0); 1416 break; 1417 1418 case M_ASPECT_704_576: 1419 VideoFormatChange(704, 576, 1.09091, 1.0); 1420 break; 1421 1422 case M_ASPECT_544_576: 1423 VideoFormatChange(544, 576, 1.41176, 1.0); 1424 break; 1425 /* 1426 case M_PREFERENCES: 1427 break; 1428 1429 default: 1430 if (msg->what >= M_SELECT_CHANNEL && msg->what <= M_SELECT_CHANNEL_END) { 1431 SelectChannel(msg->what - M_SELECT_CHANNEL); 1432 break; 1433 } 1434 if (msg->what >= M_SELECT_INTERFACE && msg->what <= M_SELECT_INTERFACE_END) { 1435 SelectInterface(msg->what - M_SELECT_INTERFACE - 1); 1436 break; 1437 } 1438 */ 1439 case M_SET_PLAYLIST_POSITION: { 1440 int32 index; 1441 if (msg->FindInt32("index", &index) == B_OK) 1442 fPlaylist->SetCurrentRefIndex(index); 1443 break; 1444 } 1445 1446 default: 1447 // let BWindow handle the rest 1448 BWindow::MessageReceived(msg); 1449 } 1450 } 1451 1452 1453 void 1454 MainWin::_AppendToPlaylist(const entry_ref& ref, Playlist* playlist) 1455 { 1456 // recursively append the ref (dive into folders) 1457 BEntry entry(&ref, true); 1458 if (entry.InitCheck() < B_OK) 1459 return; 1460 if (!entry.Exists()) 1461 return; 1462 if (entry.IsDirectory()) { 1463 BDirectory dir(&entry); 1464 if (dir.InitCheck() < B_OK) 1465 return; 1466 entry.Unset(); 1467 entry_ref subRef; 1468 while (dir.GetNextRef(&subRef) == B_OK) 1469 _AppendToPlaylist(subRef, playlist); 1470 } else if (entry.IsFile()) { 1471 playlist->AddRef(ref); 1472 } 1473 } 1474 1475