113afa642SPhil Greenway /* 213afa642SPhil Greenway OBOS ShowImage 0.1 - 17/02/2002 - 22:22 - Fernando Francisco de Oliveira 313afa642SPhil Greenway */ 413afa642SPhil Greenway 513afa642SPhil Greenway #include <algobase.h> 6*07caaa8eSMatthew Wilber #include <stdio.h> 713afa642SPhil Greenway #include <Application.h> 813afa642SPhil Greenway #include <Bitmap.h> 9fc0a275bSMatthew Wilber #include <BitmapStream.h> 1013afa642SPhil Greenway #include <Entry.h> 11fc0a275bSMatthew Wilber #include <File.h> 1213afa642SPhil Greenway #include <Menu.h> 1313afa642SPhil Greenway #include <MenuBar.h> 1413afa642SPhil Greenway #include <MenuItem.h> 1513afa642SPhil Greenway #include <Path.h> 1613afa642SPhil Greenway #include <ScrollView.h> 1713afa642SPhil Greenway #include <TranslationUtils.h> 1813afa642SPhil Greenway #include <TranslatorRoster.h> 1913afa642SPhil Greenway #include <Alert.h> 20*07caaa8eSMatthew Wilber #include <SupportDefs.h> 2113afa642SPhil Greenway 2213afa642SPhil Greenway #include "ShowImageConstants.h" 2313afa642SPhil Greenway #include "ShowImageWindow.h" 2413afa642SPhil Greenway #include "ShowImageView.h" 2513afa642SPhil Greenway #include "ShowImageStatusView.h" 2613afa642SPhil Greenway 2713afa642SPhil Greenway status_t ShowImageWindow::NewWindow(const entry_ref* ref) 2813afa642SPhil Greenway { 29*07caaa8eSMatthew Wilber // Get identify string (image type) 30*07caaa8eSMatthew Wilber BString strId = "Unknown"; 31*07caaa8eSMatthew Wilber BTranslatorRoster *proster = BTranslatorRoster::Default(); 32*07caaa8eSMatthew Wilber if (!proster) 33*07caaa8eSMatthew Wilber return B_ERROR; 34*07caaa8eSMatthew Wilber BFile file(ref, B_READ_ONLY); 35*07caaa8eSMatthew Wilber translator_info info; 36*07caaa8eSMatthew Wilber if (proster->Identify(&file, NULL, &info) == B_OK) 37*07caaa8eSMatthew Wilber strId = info.name; 38*07caaa8eSMatthew Wilber 39*07caaa8eSMatthew Wilber // Translate image data and create a new ShowImage window 40*07caaa8eSMatthew Wilber file.Seek(0, SEEK_SET); 41*07caaa8eSMatthew Wilber BBitmap* pBitmap = BTranslationUtils::GetBitmap(&file); 4213afa642SPhil Greenway if (pBitmap) { 43*07caaa8eSMatthew Wilber ShowImageWindow* pWin = new ShowImageWindow(ref, pBitmap, strId); 4413afa642SPhil Greenway return pWin->InitCheck(); 4513afa642SPhil Greenway } 46fc0a275bSMatthew Wilber 4713afa642SPhil Greenway return B_ERROR; 4813afa642SPhil Greenway } 4913afa642SPhil Greenway 50*07caaa8eSMatthew Wilber ShowImageWindow::ShowImageWindow(const entry_ref* ref, BBitmap* pBitmap, BString &strId) 5113afa642SPhil Greenway : BWindow(BRect(50, 50, 350, 250), "", B_DOCUMENT_WINDOW, 0), 5213afa642SPhil Greenway m_pReferences(0) 5313afa642SPhil Greenway { 54fc0a275bSMatthew Wilber fpsavePanel = NULL; 55fc0a275bSMatthew Wilber 5613afa642SPhil Greenway // create menu bar 5713afa642SPhil Greenway pBar = new BMenuBar( BRect(0,0, Bounds().right, 20), "menu_bar"); 5813afa642SPhil Greenway LoadMenus(pBar); 5913afa642SPhil Greenway AddChild(pBar); 6013afa642SPhil Greenway 6113afa642SPhil Greenway BRect viewFrame = Bounds(); 6213afa642SPhil Greenway viewFrame.top = pBar->Bounds().bottom+1; 6313afa642SPhil Greenway viewFrame.right -= B_V_SCROLL_BAR_WIDTH; 6413afa642SPhil Greenway viewFrame.bottom -= B_H_SCROLL_BAR_HEIGHT; 6513afa642SPhil Greenway 6613afa642SPhil Greenway // create the image view 6713afa642SPhil Greenway m_PrivateView = new ShowImageView(viewFrame, "image_view", B_FOLLOW_ALL, 6813afa642SPhil Greenway B_WILL_DRAW | B_FRAME_EVENTS | B_PULSE_NEEDED); 6913afa642SPhil Greenway m_PrivateView->SetBitmap(pBitmap); 7013afa642SPhil Greenway 7113afa642SPhil Greenway // wrap a scroll view around the view 7213afa642SPhil Greenway BScrollView* pScrollView = new BScrollView("image_scroller", m_PrivateView, B_FOLLOW_ALL, 7313afa642SPhil Greenway 0, false, false, B_PLAIN_BORDER); 7413afa642SPhil Greenway 7513afa642SPhil Greenway AddChild(pScrollView); 7613afa642SPhil Greenway 7713afa642SPhil Greenway BScrollBar *hor_scroll; 7813afa642SPhil Greenway 7913afa642SPhil Greenway BRect rect; 8013afa642SPhil Greenway 81*07caaa8eSMatthew Wilber const int32 kstatusWidth = 190; 8213afa642SPhil Greenway rect = Bounds(); 8313afa642SPhil Greenway rect.top = viewFrame.bottom + 1; 84*07caaa8eSMatthew Wilber rect.left = viewFrame.left + kstatusWidth; 8513afa642SPhil Greenway rect.right = viewFrame.right; 8613afa642SPhil Greenway 8713afa642SPhil Greenway hor_scroll = new BScrollBar( rect, "hor_scroll", m_PrivateView, 0,150, B_HORIZONTAL ); 8813afa642SPhil Greenway AddChild( hor_scroll ); 8913afa642SPhil Greenway 9013afa642SPhil Greenway ShowImageStatusView * status_bar; 9113afa642SPhil Greenway 9213afa642SPhil Greenway rect.left = 0; 93*07caaa8eSMatthew Wilber rect.right = kstatusWidth - 1; 9413afa642SPhil Greenway 9513afa642SPhil Greenway status_bar = new ShowImageStatusView( rect, "status_bar", B_FOLLOW_BOTTOM, B_WILL_DRAW ); 9613afa642SPhil Greenway status_bar->SetViewColor( ui_color( B_MENU_BACKGROUND_COLOR ) ); 97*07caaa8eSMatthew Wilber status_bar->SetText(strId); 9813afa642SPhil Greenway 9913afa642SPhil Greenway AddChild( status_bar ); 10013afa642SPhil Greenway 10113afa642SPhil Greenway BScrollBar *vert_scroll; 10213afa642SPhil Greenway 10313afa642SPhil Greenway rect = Bounds(); 10413afa642SPhil Greenway rect.top = viewFrame.top; 10513afa642SPhil Greenway rect.left = viewFrame.right + 1; 10613afa642SPhil Greenway rect.bottom = viewFrame.bottom; 10713afa642SPhil Greenway 10813afa642SPhil Greenway vert_scroll = new BScrollBar( rect, "vert_scroll", m_PrivateView, 0,150, B_VERTICAL ); 10913afa642SPhil Greenway AddChild( vert_scroll ); 11013afa642SPhil Greenway 11113afa642SPhil Greenway WindowRedimension( pBitmap ); 11213afa642SPhil Greenway 11313afa642SPhil Greenway // finish creating window 11413afa642SPhil Greenway SetRef(ref); 11513afa642SPhil Greenway UpdateTitle(); 11613afa642SPhil Greenway 11713afa642SPhil Greenway m_PrivateView->pBar = pBar; 11813afa642SPhil Greenway 11913afa642SPhil Greenway Show(); 12013afa642SPhil Greenway } 12113afa642SPhil Greenway 12213afa642SPhil Greenway ShowImageWindow::~ShowImageWindow() 12313afa642SPhil Greenway { 12413afa642SPhil Greenway delete m_pReferences; 12513afa642SPhil Greenway } 12613afa642SPhil Greenway 12713afa642SPhil Greenway void ShowImageWindow::WindowActivated(bool active) 12813afa642SPhil Greenway { 12913afa642SPhil Greenway // WindowRedimension( pBitmap ); 13013afa642SPhil Greenway } 13113afa642SPhil Greenway 13213afa642SPhil Greenway status_t ShowImageWindow::InitCheck() 13313afa642SPhil Greenway { 13413afa642SPhil Greenway if (! m_pReferences) { 13513afa642SPhil Greenway return B_ERROR; 13613afa642SPhil Greenway } else { 13713afa642SPhil Greenway return B_OK; 13813afa642SPhil Greenway } 13913afa642SPhil Greenway } 14013afa642SPhil Greenway 14113afa642SPhil Greenway void ShowImageWindow::SetRef(const entry_ref* ref) 14213afa642SPhil Greenway { 14313afa642SPhil Greenway if (! m_pReferences) { 14413afa642SPhil Greenway m_pReferences = new entry_ref(*ref); 14513afa642SPhil Greenway } else { 14613afa642SPhil Greenway *m_pReferences = *ref; 14713afa642SPhil Greenway } 14813afa642SPhil Greenway } 14913afa642SPhil Greenway 15013afa642SPhil Greenway void ShowImageWindow::UpdateTitle() 15113afa642SPhil Greenway { 15213afa642SPhil Greenway BEntry entry(m_pReferences); 15313afa642SPhil Greenway if (entry.InitCheck() == B_OK) { 15413afa642SPhil Greenway BPath path; 15513afa642SPhil Greenway entry.GetPath(&path); 15613afa642SPhil Greenway if (path.InitCheck() == B_OK) { 15713afa642SPhil Greenway SetTitle(path.Path()); 15813afa642SPhil Greenway } 15913afa642SPhil Greenway } 16013afa642SPhil Greenway } 16113afa642SPhil Greenway 16213afa642SPhil Greenway void ShowImageWindow::LoadMenus(BMenuBar* pBar) 16313afa642SPhil Greenway { 16413afa642SPhil Greenway BMenu* pMenu = new BMenu("File"); 16513afa642SPhil Greenway 16613afa642SPhil Greenway AddItemMenu( pMenu, "Open", MSG_FILE_OPEN, 'O', 0, 'A', true ); 16713afa642SPhil Greenway pMenu->AddSeparatorItem(); 16813afa642SPhil Greenway 16913afa642SPhil Greenway BMenu* pMenuSaveAs = new BMenu( "Save As...", B_ITEMS_IN_COLUMN ); 170fc0a275bSMatthew Wilber BTranslationUtils::AddTranslationItems(pMenuSaveAs, B_TRANSLATOR_BITMAP); 171fc0a275bSMatthew Wilber // Fill Save As submenu with all types that can be converted 172fc0a275bSMatthew Wilber // to from the Be bitmap image format 17313afa642SPhil Greenway pMenu->AddItem( pMenuSaveAs ); 17413afa642SPhil Greenway 175*07caaa8eSMatthew Wilber AddItemMenu( pMenu, "Close", MSG_CLOSE, 'W', 0, 'W', true); 17613afa642SPhil Greenway pMenu->AddSeparatorItem(); 177*07caaa8eSMatthew Wilber AddItemMenu( pMenu, "About ShowImage...", B_ABOUT_REQUESTED, 0, 0, 'A', true); 17813afa642SPhil Greenway pMenu->AddSeparatorItem(); 179*07caaa8eSMatthew Wilber AddItemMenu( pMenu, "Quit", B_QUIT_REQUESTED, 'Q', 0, 'A', true); 18013afa642SPhil Greenway 18113afa642SPhil Greenway pBar->AddItem(pMenu); 18213afa642SPhil Greenway 18313afa642SPhil Greenway pMenu = new BMenu("Edit"); 18413afa642SPhil Greenway 18513afa642SPhil Greenway AddItemMenu( pMenu, "Undo", B_UNDO, 'Z', 0, 'W', false); 18613afa642SPhil Greenway pMenu->AddSeparatorItem(); 18713afa642SPhil Greenway AddItemMenu( pMenu, "Cut", B_CUT, 'X', 0, 'W', false); 18813afa642SPhil Greenway AddItemMenu( pMenu, "Copy", B_COPY, 'C', 0, 'W', false); 18913afa642SPhil Greenway AddItemMenu( pMenu, "Paste", B_PASTE, 'V', 0, 'W', false); 19013afa642SPhil Greenway AddItemMenu( pMenu, "Clear", MSG_CLEAR_SELECT, 0, 0, 'W', false); 19113afa642SPhil Greenway pMenu->AddSeparatorItem(); 19213afa642SPhil Greenway AddItemMenu( pMenu, "Select All", MSG_SELECT_ALL, 'A', 0, 'W', true); 19313afa642SPhil Greenway 19413afa642SPhil Greenway pBar->AddItem(pMenu); 19513afa642SPhil Greenway 19613afa642SPhil Greenway pMenu = new BMenu("Image"); 19713afa642SPhil Greenway AddItemMenu( pMenu, "Dither Image", MSG_DITHER_IMAGE, 0, 0, 'W', true); 19813afa642SPhil Greenway pBar->AddItem(pMenu); 19913afa642SPhil Greenway } 20013afa642SPhil Greenway 20113afa642SPhil Greenway BMenuItem * ShowImageWindow::AddItemMenu( BMenu *pMenu, char *Caption, long unsigned int msg, 20213afa642SPhil Greenway char shortcut, uint32 modifier, char target, bool enabled ) { 20313afa642SPhil Greenway 20413afa642SPhil Greenway BMenuItem* pItem; 20513afa642SPhil Greenway 20613afa642SPhil Greenway pItem = new BMenuItem( Caption, new BMessage(msg), shortcut ); 20713afa642SPhil Greenway 20813afa642SPhil Greenway if ( target == 'A' ) 20913afa642SPhil Greenway pItem->SetTarget(be_app); 21013afa642SPhil Greenway 21113afa642SPhil Greenway pItem->SetEnabled( enabled ); 21213afa642SPhil Greenway pMenu->AddItem(pItem); 21313afa642SPhil Greenway 21413afa642SPhil Greenway return( pItem ); 21513afa642SPhil Greenway } 21613afa642SPhil Greenway 21713afa642SPhil Greenway void ShowImageWindow::WindowRedimension( BBitmap *pBitmap ) 21813afa642SPhil Greenway { 21913afa642SPhil Greenway // set the window's min & max size limits 22013afa642SPhil Greenway // based on document's data bounds 22113afa642SPhil Greenway float maxWidth = pBitmap->Bounds().Width() + B_V_SCROLL_BAR_WIDTH; 22213afa642SPhil Greenway float maxHeight = pBitmap->Bounds().Height() 22313afa642SPhil Greenway + pBar->Frame().Height() 22413afa642SPhil Greenway + B_H_SCROLL_BAR_HEIGHT + 1; 22513afa642SPhil Greenway float minWidth = min(maxWidth, 100.0f); 22613afa642SPhil Greenway float minHeight = min(maxHeight, 100.0f); 22713afa642SPhil Greenway 22813afa642SPhil Greenway // adjust the window's current size based on new min/max values 22913afa642SPhil Greenway float curWidth = Bounds().Width(); 23013afa642SPhil Greenway float curHeight = Bounds().Height(); 23113afa642SPhil Greenway if (curWidth < minWidth) { 23213afa642SPhil Greenway curWidth = minWidth; 23313afa642SPhil Greenway } else if (curWidth > maxWidth) { 23413afa642SPhil Greenway curWidth = maxWidth; 23513afa642SPhil Greenway } 23613afa642SPhil Greenway if (curHeight < minHeight) { 23713afa642SPhil Greenway curHeight = minHeight; 23813afa642SPhil Greenway } else if (curHeight > maxHeight) { 23913afa642SPhil Greenway curHeight = maxHeight; 24013afa642SPhil Greenway } 24113afa642SPhil Greenway if ( minWidth < 250 ) { 24213afa642SPhil Greenway minWidth = 250; 24313afa642SPhil Greenway } 24413afa642SPhil Greenway SetSizeLimits(minWidth, maxWidth, minHeight, maxHeight); 24513afa642SPhil Greenway ResizeTo(curWidth, curHeight); 24613afa642SPhil Greenway } 24713afa642SPhil Greenway 24813afa642SPhil Greenway void ShowImageWindow::FrameResized( float new_width, float new_height ) 24913afa642SPhil Greenway { 25013afa642SPhil Greenway } 25113afa642SPhil Greenway 25213afa642SPhil Greenway void ShowImageWindow::MessageReceived(BMessage* message) 25313afa642SPhil Greenway { 25413afa642SPhil Greenway BAlert* pAlert; 25513afa642SPhil Greenway 25613afa642SPhil Greenway switch (message->what) { 257fc0a275bSMatthew Wilber case MSG_OUTPUT_TYPE: 258fc0a275bSMatthew Wilber // User clicked Save As then choose an output format 259fc0a275bSMatthew Wilber SaveAs(message); 26013afa642SPhil Greenway break; 261fc0a275bSMatthew Wilber 262fc0a275bSMatthew Wilber case MSG_SAVE_PANEL: 263fc0a275bSMatthew Wilber // User specified where to save the output image 264fc0a275bSMatthew Wilber SaveToFile(message); 265fc0a275bSMatthew Wilber break; 266fc0a275bSMatthew Wilber 267*07caaa8eSMatthew Wilber case MSG_CLOSE: 268*07caaa8eSMatthew Wilber Quit(); 269*07caaa8eSMatthew Wilber break; 270*07caaa8eSMatthew Wilber 27113afa642SPhil Greenway case B_UNDO : 27213afa642SPhil Greenway pAlert = new BAlert( "Edit/Undo", 27313afa642SPhil Greenway "Edit/Undo not implemented yet", "OK"); 27413afa642SPhil Greenway pAlert->Go(); 27513afa642SPhil Greenway break; 27613afa642SPhil Greenway case B_CUT : 27713afa642SPhil Greenway pAlert = new BAlert( "Edit/Cut", 27813afa642SPhil Greenway "Edit/Cut not implemented yet", "OK"); 27913afa642SPhil Greenway pAlert->Go(); 28013afa642SPhil Greenway break; 28113afa642SPhil Greenway case B_COPY : 28213afa642SPhil Greenway pAlert = new BAlert( "Edit/Copy", 28313afa642SPhil Greenway "Edit/Copy not implemented yet", "OK"); 28413afa642SPhil Greenway pAlert->Go(); 28513afa642SPhil Greenway break; 28613afa642SPhil Greenway case B_PASTE : 28713afa642SPhil Greenway pAlert = new BAlert( "Edit/Paste", 28813afa642SPhil Greenway "Edit/Paste not implemented yet", "OK"); 28913afa642SPhil Greenway pAlert->Go(); 29013afa642SPhil Greenway break; 29113afa642SPhil Greenway case MSG_CLEAR_SELECT : 29213afa642SPhil Greenway pAlert = new BAlert( "Edit/Clear Select", 29313afa642SPhil Greenway "Edit/Clear Select not implemented yet", "OK"); 29413afa642SPhil Greenway pAlert->Go(); 29513afa642SPhil Greenway break; 29613afa642SPhil Greenway case MSG_SELECT_ALL : 29713afa642SPhil Greenway pAlert = new BAlert( "Edit/Select All", 29813afa642SPhil Greenway "Edit/Select All not implemented yet", "OK"); 29913afa642SPhil Greenway pAlert->Go(); 30013afa642SPhil Greenway break; 30113afa642SPhil Greenway case MSG_DITHER_IMAGE : 30213afa642SPhil Greenway BMenuItem * pMenuDither; 30313afa642SPhil Greenway pMenuDither = pBar->FindItem( message->what ); 30413afa642SPhil Greenway pMenuDither->SetMarked( ! pMenuDither->IsMarked() ); 30513afa642SPhil Greenway 30613afa642SPhil Greenway break; 30713afa642SPhil Greenway 30813afa642SPhil Greenway default: 30913afa642SPhil Greenway BWindow::MessageReceived(message); 31013afa642SPhil Greenway break; 31113afa642SPhil Greenway } 31213afa642SPhil Greenway } 313fc0a275bSMatthew Wilber 314fc0a275bSMatthew Wilber void 315fc0a275bSMatthew Wilber ShowImageWindow::SaveAs(BMessage *pmsg) 316fc0a275bSMatthew Wilber { 317fc0a275bSMatthew Wilber // Handle SaveAs menu choice by setting the 318fc0a275bSMatthew Wilber // translator and desired output format 319fc0a275bSMatthew Wilber // and giving the user a save panel 320fc0a275bSMatthew Wilber 321fc0a275bSMatthew Wilber if (pmsg->FindInt32("be:translator", 322fc0a275bSMatthew Wilber reinterpret_cast<int32 *>(&foutTranslator)) != B_OK) 323fc0a275bSMatthew Wilber return; 324fc0a275bSMatthew Wilber if (pmsg->FindInt32("be:type", 325fc0a275bSMatthew Wilber reinterpret_cast<int32 *>(&foutType)) != B_OK) 326fc0a275bSMatthew Wilber return; 327fc0a275bSMatthew Wilber 328fc0a275bSMatthew Wilber if (!fpsavePanel) { 329fc0a275bSMatthew Wilber fpsavePanel = new BFilePanel(B_SAVE_PANEL, new BMessenger(this), NULL, 0, 330fc0a275bSMatthew Wilber false, new BMessage(MSG_SAVE_PANEL)); 331fc0a275bSMatthew Wilber if (!fpsavePanel) 332fc0a275bSMatthew Wilber return; 333fc0a275bSMatthew Wilber } 334fc0a275bSMatthew Wilber 335fc0a275bSMatthew Wilber fpsavePanel->Window()->SetWorkspaces(B_CURRENT_WORKSPACE); 336fc0a275bSMatthew Wilber fpsavePanel->Show(); 337fc0a275bSMatthew Wilber } 338fc0a275bSMatthew Wilber 339fc0a275bSMatthew Wilber void 340fc0a275bSMatthew Wilber ShowImageWindow::SaveToFile(BMessage *pmsg) 341fc0a275bSMatthew Wilber { 342fc0a275bSMatthew Wilber // After the user has chosen which format 343fc0a275bSMatthew Wilber // to output to and where to save the file, 344fc0a275bSMatthew Wilber // this function is called to save the currently 345fc0a275bSMatthew Wilber // open image to a file in the desired format. 346fc0a275bSMatthew Wilber 347fc0a275bSMatthew Wilber entry_ref dirref; 348fc0a275bSMatthew Wilber if (pmsg->FindRef("directory", &dirref) != B_OK) 349fc0a275bSMatthew Wilber return; 350fc0a275bSMatthew Wilber const char *filename; 351fc0a275bSMatthew Wilber if (pmsg->FindString("name", &filename) != B_OK) 352fc0a275bSMatthew Wilber return; 353fc0a275bSMatthew Wilber 354fc0a275bSMatthew Wilber BDirectory dir(&dirref); 355fc0a275bSMatthew Wilber BFile file(&dir, filename, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); 356fc0a275bSMatthew Wilber if (file.InitCheck() != B_OK) 357fc0a275bSMatthew Wilber return; 358fc0a275bSMatthew Wilber 359fc0a275bSMatthew Wilber BBitmapStream stream(m_PrivateView->GetBitmap()); 360fc0a275bSMatthew Wilber BTranslatorRoster *proster = BTranslatorRoster::Default(); 361fc0a275bSMatthew Wilber if (proster->Translate(foutTranslator, &stream, NULL, 362fc0a275bSMatthew Wilber &file, foutType) != B_OK) { 363fc0a275bSMatthew Wilber BAlert *palert = new BAlert(NULL, "Error writing image file.", "Ok"); 364fc0a275bSMatthew Wilber palert->Go(); 365fc0a275bSMatthew Wilber } 366fc0a275bSMatthew Wilber 367fc0a275bSMatthew Wilber BBitmap *pout = NULL; 368fc0a275bSMatthew Wilber stream.DetachBitmap(&pout); 369fc0a275bSMatthew Wilber // bitmap used by stream still belongs to the view, 370fc0a275bSMatthew Wilber // detach so it doesn't get deleted 371fc0a275bSMatthew Wilber } 372fc0a275bSMatthew Wilber 373*07caaa8eSMatthew Wilber void 374*07caaa8eSMatthew Wilber ShowImageWindow::Quit() 375*07caaa8eSMatthew Wilber { 376*07caaa8eSMatthew Wilber // tell the app to forget about this window 377*07caaa8eSMatthew Wilber be_app->PostMessage(MSG_WINDOW_QUIT); 378*07caaa8eSMatthew Wilber BWindow::Quit(); 379*07caaa8eSMatthew Wilber } 380fc0a275bSMatthew Wilber 38113afa642SPhil Greenway // BMenu* pMenuDither = ; 382