1cdb89ebbSMatthew Wilber /*****************************************************************************/ 2cdb89ebbSMatthew Wilber // ShowImageWindow 3ad13f387SMichael Pfeiffer // Written by Fernando Francisco de Oliveira, Michael Wilber, Michael Pfeiffer 4cdb89ebbSMatthew Wilber // 5cdb89ebbSMatthew Wilber // ShowImageWindow.cpp 6cdb89ebbSMatthew Wilber // 7cdb89ebbSMatthew Wilber // 8cdb89ebbSMatthew Wilber // Copyright (c) 2003 OpenBeOS Project 9cdb89ebbSMatthew Wilber // 10cdb89ebbSMatthew Wilber // Permission is hereby granted, free of charge, to any person obtaining a 11cdb89ebbSMatthew Wilber // copy of this software and associated documentation files (the "Software"), 12cdb89ebbSMatthew Wilber // to deal in the Software without restriction, including without limitation 13cdb89ebbSMatthew Wilber // the rights to use, copy, modify, merge, publish, distribute, sublicense, 14cdb89ebbSMatthew Wilber // and/or sell copies of the Software, and to permit persons to whom the 15cdb89ebbSMatthew Wilber // Software is furnished to do so, subject to the following conditions: 16cdb89ebbSMatthew Wilber // 17cdb89ebbSMatthew Wilber // The above copyright notice and this permission notice shall be included 18cdb89ebbSMatthew Wilber // in all copies or substantial portions of the Software. 19cdb89ebbSMatthew Wilber // 20cdb89ebbSMatthew Wilber // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 21cdb89ebbSMatthew Wilber // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22cdb89ebbSMatthew Wilber // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23cdb89ebbSMatthew Wilber // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24cdb89ebbSMatthew Wilber // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25cdb89ebbSMatthew Wilber // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26cdb89ebbSMatthew Wilber // DEALINGS IN THE SOFTWARE. 27cdb89ebbSMatthew Wilber /*****************************************************************************/ 2813afa642SPhil Greenway 2913afa642SPhil Greenway #include <algobase.h> 3007caaa8eSMatthew Wilber #include <stdio.h> 3113afa642SPhil Greenway #include <Application.h> 3213afa642SPhil Greenway #include <Bitmap.h> 33fc0a275bSMatthew Wilber #include <BitmapStream.h> 3413afa642SPhil Greenway #include <Entry.h> 35fc0a275bSMatthew Wilber #include <File.h> 3613afa642SPhil Greenway #include <Menu.h> 3713afa642SPhil Greenway #include <MenuBar.h> 3813afa642SPhil Greenway #include <MenuItem.h> 3913afa642SPhil Greenway #include <Path.h> 4013afa642SPhil Greenway #include <ScrollView.h> 4113afa642SPhil Greenway #include <TranslationUtils.h> 4213afa642SPhil Greenway #include <TranslatorRoster.h> 4313afa642SPhil Greenway #include <Alert.h> 4407caaa8eSMatthew Wilber #include <SupportDefs.h> 45ad13f387SMichael Pfeiffer #include <Screen.h> 46*d10d5947SMichael Pfeiffer #include <Roster.h> 4713afa642SPhil Greenway 4813afa642SPhil Greenway #include "ShowImageConstants.h" 4913afa642SPhil Greenway #include "ShowImageWindow.h" 5013afa642SPhil Greenway #include "ShowImageView.h" 5113afa642SPhil Greenway #include "ShowImageStatusView.h" 5213afa642SPhil Greenway 5303839579SMatthew Wilber ShowImageWindow::ShowImageWindow(const entry_ref *pref) 54cdb89ebbSMatthew Wilber : BWindow(BRect(50, 50, 350, 250), "", B_DOCUMENT_WINDOW, 0) 5513afa642SPhil Greenway { 567eca0987SMichael Pfeiffer fpSavePanel = NULL; 577eca0987SMichael Pfeiffer fpRef = NULL; 58ad13f387SMichael Pfeiffer fFullScreen = false; 59fc0a275bSMatthew Wilber 6013afa642SPhil Greenway // create menu bar 617eca0987SMichael Pfeiffer fpBar = new BMenuBar(BRect(0, 0, Bounds().right, 20), "menu_bar"); 627eca0987SMichael Pfeiffer LoadMenus(fpBar); 637eca0987SMichael Pfeiffer AddChild(fpBar); 6413afa642SPhil Greenway 6513afa642SPhil Greenway BRect viewFrame = Bounds(); 667eca0987SMichael Pfeiffer viewFrame.top = fpBar->Bounds().bottom + 1; 6713afa642SPhil Greenway viewFrame.right -= B_V_SCROLL_BAR_WIDTH; 6813afa642SPhil Greenway viewFrame.bottom -= B_H_SCROLL_BAR_HEIGHT; 6913afa642SPhil Greenway 7013afa642SPhil Greenway // create the image view 717eca0987SMichael Pfeiffer fpImageView = new ShowImageView(viewFrame, "image_view", B_FOLLOW_ALL, 727eca0987SMichael Pfeiffer B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE | B_PULSE_NEEDED); 7313afa642SPhil Greenway // wrap a scroll view around the view 747eca0987SMichael Pfeiffer BScrollView *pscrollView = new BScrollView("image_scroller", fpImageView, 75cdb89ebbSMatthew Wilber B_FOLLOW_ALL, 0, false, false, B_PLAIN_BORDER); 76cdb89ebbSMatthew Wilber AddChild(pscrollView); 7713afa642SPhil Greenway 7807caaa8eSMatthew Wilber const int32 kstatusWidth = 190; 79cdb89ebbSMatthew Wilber BRect rect; 8013afa642SPhil Greenway rect = Bounds(); 8113afa642SPhil Greenway rect.top = viewFrame.bottom + 1; 8207caaa8eSMatthew Wilber rect.left = viewFrame.left + kstatusWidth; 8313afa642SPhil Greenway rect.right = viewFrame.right; 84cdb89ebbSMatthew Wilber BScrollBar *phscroll; 857eca0987SMichael Pfeiffer phscroll = new BScrollBar(rect, "hscroll", fpImageView, 0, 150, 86cdb89ebbSMatthew Wilber B_HORIZONTAL); 87cdb89ebbSMatthew Wilber AddChild(phscroll); 8813afa642SPhil Greenway 8913afa642SPhil Greenway rect.left = 0; 9007caaa8eSMatthew Wilber rect.right = kstatusWidth - 1; 917eca0987SMichael Pfeiffer fpStatusView = new ShowImageStatusView(rect, "status_view", B_FOLLOW_BOTTOM, 92cdb89ebbSMatthew Wilber B_WILL_DRAW); 937eca0987SMichael Pfeiffer fpStatusView->SetViewColor(ui_color(B_MENU_BACKGROUND_COLOR)); 947eca0987SMichael Pfeiffer AddChild(fpStatusView); 9513afa642SPhil Greenway 9613afa642SPhil Greenway rect = Bounds(); 9713afa642SPhil Greenway rect.top = viewFrame.top; 9813afa642SPhil Greenway rect.left = viewFrame.right + 1; 9913afa642SPhil Greenway rect.bottom = viewFrame.bottom; 100cdb89ebbSMatthew Wilber BScrollBar *pvscroll; 1017eca0987SMichael Pfeiffer pvscroll = new BScrollBar(rect, "vscroll", fpImageView, 0, 150, B_VERTICAL); 102cdb89ebbSMatthew Wilber AddChild(pvscroll); 10313afa642SPhil Greenway 10403839579SMatthew Wilber SetSizeLimits(250, 100000, 100, 100000); 10513afa642SPhil Greenway 10613afa642SPhil Greenway // finish creating window 107cdb89ebbSMatthew Wilber SetRef(pref); 10813afa642SPhil Greenway UpdateTitle(); 10913afa642SPhil Greenway 1107eca0987SMichael Pfeiffer fpImageView->SetImage(pref); 1117eca0987SMichael Pfeiffer 1127eca0987SMichael Pfeiffer SetPulseRate(100000); // every 1/10 second; ShowImageView needs it for marching ants 11303839579SMatthew Wilber 114*d10d5947SMichael Pfeiffer if (InitCheck() == B_OK) { 115*d10d5947SMichael Pfeiffer fpImageView->FlushToLeftTop(); 116*d10d5947SMichael Pfeiffer WindowRedimension(fpImageView->GetBitmap()); 11713afa642SPhil Greenway Show(); 118*d10d5947SMichael Pfeiffer } else { 119*d10d5947SMichael Pfeiffer // exit if file could not be opened 120*d10d5947SMichael Pfeiffer Quit(); 121*d10d5947SMichael Pfeiffer } 12213afa642SPhil Greenway } 12313afa642SPhil Greenway 12413afa642SPhil Greenway ShowImageWindow::~ShowImageWindow() 12513afa642SPhil Greenway { 1267eca0987SMichael Pfeiffer delete fpRef; 12713afa642SPhil Greenway } 12813afa642SPhil Greenway 129cdb89ebbSMatthew Wilber status_t 130cdb89ebbSMatthew Wilber ShowImageWindow::InitCheck() 13113afa642SPhil Greenway { 132*d10d5947SMichael Pfeiffer if (!fpRef || !fpImageView || fpImageView->GetBitmap() == NULL) 13313afa642SPhil Greenway return B_ERROR; 134cdb89ebbSMatthew Wilber else 13513afa642SPhil Greenway return B_OK; 13613afa642SPhil Greenway } 137cdb89ebbSMatthew Wilber 138cdb89ebbSMatthew Wilber void 139cdb89ebbSMatthew Wilber ShowImageWindow::SetRef(const entry_ref *pref) 140cdb89ebbSMatthew Wilber { 1417eca0987SMichael Pfeiffer if (!fpRef) 1427eca0987SMichael Pfeiffer fpRef = new entry_ref(*pref); 143cdb89ebbSMatthew Wilber else 1447eca0987SMichael Pfeiffer *fpRef = *pref; 14513afa642SPhil Greenway } 14613afa642SPhil Greenway 147cdb89ebbSMatthew Wilber void 148cdb89ebbSMatthew Wilber ShowImageWindow::UpdateTitle() 14913afa642SPhil Greenway { 1507eca0987SMichael Pfeiffer BEntry entry(fpRef); 15113afa642SPhil Greenway if (entry.InitCheck() == B_OK) { 15213afa642SPhil Greenway BPath path; 15313afa642SPhil Greenway entry.GetPath(&path); 154cdb89ebbSMatthew Wilber if (path.InitCheck() == B_OK) 15513afa642SPhil Greenway SetTitle(path.Path()); 15613afa642SPhil Greenway } 15713afa642SPhil Greenway } 15813afa642SPhil Greenway 159cdb89ebbSMatthew Wilber void 160*d10d5947SMichael Pfeiffer ShowImageWindow::UpdateRecentDocumentsMenu() 161*d10d5947SMichael Pfeiffer { 162*d10d5947SMichael Pfeiffer BMenuItem *item; 163*d10d5947SMichael Pfeiffer BMessage list, *msg; 164*d10d5947SMichael Pfeiffer entry_ref ref; 165*d10d5947SMichael Pfeiffer char name[B_FILE_NAME_LENGTH]; 166*d10d5947SMichael Pfeiffer 167*d10d5947SMichael Pfeiffer while ((item = fpOpenMenu->RemoveItem((int32)0)) != NULL) { 168*d10d5947SMichael Pfeiffer delete item; 169*d10d5947SMichael Pfeiffer } 170*d10d5947SMichael Pfeiffer 171*d10d5947SMichael Pfeiffer be_roster->GetRecentDocuments(&list, 20, NULL, APP_SIG); 172*d10d5947SMichael Pfeiffer for (int i = 0; list.FindRef("refs", i, &ref) == B_OK; i++) { 173*d10d5947SMichael Pfeiffer BEntry entry(&ref); 174*d10d5947SMichael Pfeiffer entry.GetName(name); 175*d10d5947SMichael Pfeiffer msg = new BMessage(B_REFS_RECEIVED); 176*d10d5947SMichael Pfeiffer msg->AddRef("refs", &ref); 177*d10d5947SMichael Pfeiffer item = new BMenuItem(name, msg, 0, 0); 178*d10d5947SMichael Pfeiffer fpOpenMenu->AddItem(item); 179*d10d5947SMichael Pfeiffer item->SetTarget(be_app, NULL); 180*d10d5947SMichael Pfeiffer } 181*d10d5947SMichael Pfeiffer } 182*d10d5947SMichael Pfeiffer 183*d10d5947SMichael Pfeiffer void 184cdb89ebbSMatthew Wilber ShowImageWindow::LoadMenus(BMenuBar *pbar) 18513afa642SPhil Greenway { 186cdb89ebbSMatthew Wilber BMenu *pmenu = new BMenu("File"); 187*d10d5947SMichael Pfeiffer fpOpenMenu = new BMenu("Open"); 188*d10d5947SMichael Pfeiffer pmenu->AddItem(fpOpenMenu); 189*d10d5947SMichael Pfeiffer fpOpenMenu->Superitem()->SetTrigger('O'); 190*d10d5947SMichael Pfeiffer fpOpenMenu->Superitem()->SetMessage(new BMessage(MSG_FILE_OPEN)); 191*d10d5947SMichael Pfeiffer fpOpenMenu->Superitem()->SetTarget(be_app); 192*d10d5947SMichael Pfeiffer fpOpenMenu->Superitem()->SetShortcut('O', 0); 193cdb89ebbSMatthew Wilber pmenu->AddSeparatorItem(); 194ad13f387SMichael Pfeiffer AddItemMenu(pmenu, "Dia Show", MSG_DIA_SHOW, 0, 0, 'W', true); 195ad13f387SMichael Pfeiffer BMenu* pDelay = new BMenu("Delay"); 196ad13f387SMichael Pfeiffer pDelay->SetRadioMode(true); 197ad13f387SMichael Pfeiffer // Note: ShowImage loades images in window thread so it becomes unresponsive if 198ad13f387SMichael Pfeiffer // dia show delay is too short! (Especially if loading the image takes as long as 199ad13f387SMichael Pfeiffer // or longer than the dia show delay). Should load in background thread! 200ad13f387SMichael Pfeiffer // AddDelayItem(pDelay, "Half a Second", 0.5, false); 201ad13f387SMichael Pfeiffer // AddDelayItem(pDelay, "One Second", 1, false); 202ad13f387SMichael Pfeiffer // AddDelayItem(pDelay, "Two Second", 2, false); 203ad13f387SMichael Pfeiffer AddDelayItem(pDelay, "Three Seconds", 3, true); 204ad13f387SMichael Pfeiffer AddDelayItem(pDelay, "Four Second", 4, false); 205ad13f387SMichael Pfeiffer AddDelayItem(pDelay, "Five Seconds", 5, false); 206ad13f387SMichael Pfeiffer AddDelayItem(pDelay, "Six Seconds", 6, false); 207ad13f387SMichael Pfeiffer AddDelayItem(pDelay, "Seven Seconds", 7, false); 208ad13f387SMichael Pfeiffer AddDelayItem(pDelay, "Eight Seconds", 8, false); 209ad13f387SMichael Pfeiffer AddDelayItem(pDelay, "Nine Seconds", 9, false); 210ad13f387SMichael Pfeiffer AddDelayItem(pDelay, "Ten Seconds", 10, false); 211ad13f387SMichael Pfeiffer AddDelayItem(pDelay, "Tweenty Seconds", 20, false); 212ad13f387SMichael Pfeiffer pmenu->AddItem(pDelay); 213ad13f387SMichael Pfeiffer pmenu->AddSeparatorItem(); 214ad13f387SMichael Pfeiffer AddItemMenu(pmenu, "Next", MSG_FILE_NEXT, B_DOWN_ARROW, 0, 'W', true); 215ad13f387SMichael Pfeiffer AddItemMenu(pmenu, "Previous", MSG_FILE_PREV, B_UP_ARROW, 0, 'W', true); 216ad13f387SMichael Pfeiffer pmenu->AddSeparatorItem(); 217cdb89ebbSMatthew Wilber BMenu *pmenuSaveAs = new BMenu("Save As...", B_ITEMS_IN_COLUMN); 218cdb89ebbSMatthew Wilber BTranslationUtils::AddTranslationItems(pmenuSaveAs, B_TRANSLATOR_BITMAP); 219fc0a275bSMatthew Wilber // Fill Save As submenu with all types that can be converted 220fc0a275bSMatthew Wilber // to from the Be bitmap image format 221cdb89ebbSMatthew Wilber pmenu->AddItem(pmenuSaveAs); 222cdb89ebbSMatthew Wilber AddItemMenu(pmenu, "Close", MSG_CLOSE, 'W', 0, 'W', true); 223cdb89ebbSMatthew Wilber pmenu->AddSeparatorItem(); 224cdb89ebbSMatthew Wilber AddItemMenu(pmenu, "About ShowImage...", B_ABOUT_REQUESTED, 0, 0, 'A', true); 225cdb89ebbSMatthew Wilber pmenu->AddSeparatorItem(); 226cdb89ebbSMatthew Wilber AddItemMenu(pmenu, "Quit", B_QUIT_REQUESTED, 'Q', 0, 'A', true); 227cdb89ebbSMatthew Wilber pbar->AddItem(pmenu); 22813afa642SPhil Greenway 229cdb89ebbSMatthew Wilber pmenu = new BMenu("Edit"); 230cdb89ebbSMatthew Wilber AddItemMenu(pmenu, "Undo", B_UNDO, 'Z', 0, 'W', false); 231cdb89ebbSMatthew Wilber pmenu->AddSeparatorItem(); 232cdb89ebbSMatthew Wilber AddItemMenu(pmenu, "Cut", B_CUT, 'X', 0, 'W', false); 233*d10d5947SMichael Pfeiffer AddItemMenu(pmenu, "Copy", B_COPY, 'C', 0, 'W', true); 234cdb89ebbSMatthew Wilber AddItemMenu(pmenu, "Paste", B_PASTE, 'V', 0, 'W', false); 235*d10d5947SMichael Pfeiffer AddItemMenu(pmenu, "Clear", MSG_CLEAR_SELECT, 0, 0, 'W', true); 236cdb89ebbSMatthew Wilber pmenu->AddSeparatorItem(); 237*d10d5947SMichael Pfeiffer AddItemMenu(pmenu, "Select All", MSG_SELECT_ALL, 'A', 0, 'W', true); 238cdb89ebbSMatthew Wilber pbar->AddItem(pmenu); 23913afa642SPhil Greenway 2407eca0987SMichael Pfeiffer pmenu = fpPageMenu = new BMenu("Page"); 24103839579SMatthew Wilber AddItemMenu(pmenu, "First", MSG_PAGE_FIRST, 'F', 0, 'W', true); 24203839579SMatthew Wilber AddItemMenu(pmenu, "Last", MSG_PAGE_LAST, 'L', 0, 'W', true); 24303839579SMatthew Wilber AddItemMenu(pmenu, "Next", MSG_PAGE_NEXT, 'N', 0, 'W', true); 24403839579SMatthew Wilber AddItemMenu(pmenu, "Previous", MSG_PAGE_PREV, 'P', 0, 'W', true); 24503839579SMatthew Wilber pbar->AddItem(pmenu); 24603839579SMatthew Wilber 247cdb89ebbSMatthew Wilber pmenu = new BMenu("Image"); 248cdb89ebbSMatthew Wilber AddItemMenu(pmenu, "Dither Image", MSG_DITHER_IMAGE, 0, 0, 'W', true); 249ad13f387SMichael Pfeiffer pmenu->AddSeparatorItem(); 250ad13f387SMichael Pfeiffer AddItemMenu(pmenu, "Rotate Clockwise", MSG_ROTATE_CLOCKWISE, B_RIGHT_ARROW, 0, 'W', true); 251ad13f387SMichael Pfeiffer AddItemMenu(pmenu, "Rotate Anticlockwise", MSG_ROTATE_ACLKWISE, B_LEFT_ARROW, 0, 'W', true); 252ad13f387SMichael Pfeiffer pmenu->AddSeparatorItem(); 253ad13f387SMichael Pfeiffer AddItemMenu(pmenu, "Mirror Vertical", MSG_MIRROR_VERTICAL, 0, 0, 'W', true); 254ad13f387SMichael Pfeiffer AddItemMenu(pmenu, "Mirror Horizontal", MSG_MIRROR_HORIZONTAL, 0, 0, 'W', true); 255ad13f387SMichael Pfeiffer pmenu->AddSeparatorItem(); 256ad13f387SMichael Pfeiffer AddItemMenu(pmenu, "Invert", MSG_INVERT, 0, 0, 'W', true); 257ad13f387SMichael Pfeiffer pbar->AddItem(pmenu); 258ad13f387SMichael Pfeiffer 259ad13f387SMichael Pfeiffer pmenu = new BMenu("View"); 2607eca0987SMichael Pfeiffer AddItemMenu(pmenu, "Fit To Window Size", MSG_FIT_TO_WINDOW_SIZE, 0, 0, 'W', true); 261ad13f387SMichael Pfeiffer AddItemMenu(pmenu, "Full Screen", MSG_FULL_SCREEN, B_ENTER, 0, 'W', true); 262cdb89ebbSMatthew Wilber pbar->AddItem(pmenu); 263*d10d5947SMichael Pfeiffer 264*d10d5947SMichael Pfeiffer UpdateRecentDocumentsMenu(); 26513afa642SPhil Greenway } 26613afa642SPhil Greenway 267cdb89ebbSMatthew Wilber BMenuItem * 268cdb89ebbSMatthew Wilber ShowImageWindow::AddItemMenu(BMenu *pmenu, char *caption, long unsigned int msg, 269cdb89ebbSMatthew Wilber char shortcut, uint32 modifier, char target, bool benabled) 270cdb89ebbSMatthew Wilber { 271cdb89ebbSMatthew Wilber BMenuItem* pitem; 272cdb89ebbSMatthew Wilber pitem = new BMenuItem(caption, new BMessage(msg), shortcut); 27313afa642SPhil Greenway 27413afa642SPhil Greenway if (target == 'A') 275cdb89ebbSMatthew Wilber pitem->SetTarget(be_app); 27613afa642SPhil Greenway 277cdb89ebbSMatthew Wilber pitem->SetEnabled(benabled); 278cdb89ebbSMatthew Wilber pmenu->AddItem(pitem); 27913afa642SPhil Greenway 280cdb89ebbSMatthew Wilber return pitem; 28113afa642SPhil Greenway } 28213afa642SPhil Greenway 283ad13f387SMichael Pfeiffer BMenuItem* 284ad13f387SMichael Pfeiffer ShowImageWindow::AddDelayItem(BMenu *pmenu, char *caption, float value, bool marked) 285ad13f387SMichael Pfeiffer { 286ad13f387SMichael Pfeiffer BMenuItem* pitem; 287ad13f387SMichael Pfeiffer BMessage* pmsg; 288ad13f387SMichael Pfeiffer pmsg = new BMessage(MSG_DIA_SHOW_DELAY); 289ad13f387SMichael Pfeiffer pmsg->AddFloat("value", value); 290ad13f387SMichael Pfeiffer 291ad13f387SMichael Pfeiffer pitem = new BMenuItem(caption, pmsg, 0); 292ad13f387SMichael Pfeiffer 293ad13f387SMichael Pfeiffer if (marked) pitem->SetMarked(true); 294ad13f387SMichael Pfeiffer pmenu->AddItem(pitem); 295ad13f387SMichael Pfeiffer 296ad13f387SMichael Pfeiffer return pitem; 297ad13f387SMichael Pfeiffer } 298ad13f387SMichael Pfeiffer 299cdb89ebbSMatthew Wilber void 300cdb89ebbSMatthew Wilber ShowImageWindow::WindowRedimension(BBitmap *pbitmap) 30113afa642SPhil Greenway { 302*d10d5947SMichael Pfeiffer BScreen screen; 303*d10d5947SMichael Pfeiffer BRect r(pbitmap->Bounds()); 304*d10d5947SMichael Pfeiffer float width, height; 305*d10d5947SMichael Pfeiffer float maxWidth, maxHeight; 306*d10d5947SMichael Pfeiffer const float windowBorderWidth = 5; 307*d10d5947SMichael Pfeiffer const float windowBorderHeight = 5; 30813afa642SPhil Greenway 309*d10d5947SMichael Pfeiffer if (screen.Frame().right == 0.0) { 310*d10d5947SMichael Pfeiffer return; // invalid screen object 311*d10d5947SMichael Pfeiffer } 312cdb89ebbSMatthew Wilber 313*d10d5947SMichael Pfeiffer width = r.Width() + B_V_SCROLL_BAR_WIDTH; 314*d10d5947SMichael Pfeiffer height = r.Height() + 1 + fpBar->Frame().Height() + B_H_SCROLL_BAR_HEIGHT; 315cdb89ebbSMatthew Wilber 316*d10d5947SMichael Pfeiffer // dimensions so that window does not reach outside of screen 317*d10d5947SMichael Pfeiffer maxWidth = screen.Frame().Width() + 1 - windowBorderWidth - Frame().left; 318*d10d5947SMichael Pfeiffer maxHeight = screen.Frame().Height() + 1 - windowBorderHeight - Frame().top; 319cdb89ebbSMatthew Wilber 320*d10d5947SMichael Pfeiffer if (width > maxWidth) width = maxWidth; 321*d10d5947SMichael Pfeiffer if (height > maxHeight) height = maxHeight; 322*d10d5947SMichael Pfeiffer 323*d10d5947SMichael Pfeiffer ResizeTo(width, height); 32413afa642SPhil Greenway } 32513afa642SPhil Greenway 326cdb89ebbSMatthew Wilber void 327cdb89ebbSMatthew Wilber ShowImageWindow::FrameResized(float width, float height) 32813afa642SPhil Greenway { 32913afa642SPhil Greenway } 33013afa642SPhil Greenway 3317eca0987SMichael Pfeiffer bool 3327eca0987SMichael Pfeiffer ShowImageWindow::ToggleMenuItem(uint32 what) 3337eca0987SMichael Pfeiffer { 3347eca0987SMichael Pfeiffer BMenuItem *item; 3357eca0987SMichael Pfeiffer bool marked = false; 3367eca0987SMichael Pfeiffer item = fpBar->FindItem(what); 3377eca0987SMichael Pfeiffer if (item != NULL) { 3387eca0987SMichael Pfeiffer marked = !item->IsMarked(); 3397eca0987SMichael Pfeiffer item->SetMarked(marked); 3407eca0987SMichael Pfeiffer } 3417eca0987SMichael Pfeiffer return marked; 3427eca0987SMichael Pfeiffer } 3437eca0987SMichael Pfeiffer 344cdb89ebbSMatthew Wilber void 345cdb89ebbSMatthew Wilber ShowImageWindow::MessageReceived(BMessage *pmsg) 34613afa642SPhil Greenway { 347cdb89ebbSMatthew Wilber switch (pmsg->what) { 348fc0a275bSMatthew Wilber case MSG_OUTPUT_TYPE: 349fc0a275bSMatthew Wilber // User clicked Save As then choose an output format 3507eca0987SMichael Pfeiffer if (!fpSavePanel) 351cdb89ebbSMatthew Wilber // If user doesn't already have a save panel open 352cdb89ebbSMatthew Wilber SaveAs(pmsg); 35313afa642SPhil Greenway break; 354fc0a275bSMatthew Wilber 355fc0a275bSMatthew Wilber case MSG_SAVE_PANEL: 356fc0a275bSMatthew Wilber // User specified where to save the output image 357cdb89ebbSMatthew Wilber SaveToFile(pmsg); 358fc0a275bSMatthew Wilber break; 359fc0a275bSMatthew Wilber 36007caaa8eSMatthew Wilber case MSG_CLOSE: 361cdb89ebbSMatthew Wilber if (CanQuit()) 36207caaa8eSMatthew Wilber Quit(); 36307caaa8eSMatthew Wilber break; 36407caaa8eSMatthew Wilber 365cdb89ebbSMatthew Wilber case B_CANCEL: 3667eca0987SMichael Pfeiffer delete fpSavePanel; 3677eca0987SMichael Pfeiffer fpSavePanel = NULL; 368cdb89ebbSMatthew Wilber break; 369cdb89ebbSMatthew Wilber 37003839579SMatthew Wilber case MSG_UPDATE_STATUS: 37103839579SMatthew Wilber { 3727eca0987SMichael Pfeiffer bool benable = (fpImageView->PageCount() > 1) ? true : false; 3737eca0987SMichael Pfeiffer if (fpPageMenu->IsEnabled() != benable) 3741d592070SMatthew Wilber // Only call this function if the state is changing 3751d592070SMatthew Wilber // to avoid flickering 3767eca0987SMichael Pfeiffer fpPageMenu->SetEnabled(benable); 3771d592070SMatthew Wilber 37803839579SMatthew Wilber BString str; 37903839579SMatthew Wilber if (pmsg->FindString("status", &str) == B_OK) 3807eca0987SMichael Pfeiffer fpStatusView->SetText(str); 3817eca0987SMichael Pfeiffer 3827eca0987SMichael Pfeiffer entry_ref ref; 3837eca0987SMichael Pfeiffer if (pmsg->FindRef("ref", &ref) == B_OK) { 3847eca0987SMichael Pfeiffer SetRef(&ref); 3857eca0987SMichael Pfeiffer UpdateTitle(); 3867eca0987SMichael Pfeiffer } 38703839579SMatthew Wilber break; 38803839579SMatthew Wilber } 38903839579SMatthew Wilber 39013afa642SPhil Greenway case B_UNDO: 39113afa642SPhil Greenway break; 39213afa642SPhil Greenway case B_CUT: 39313afa642SPhil Greenway break; 39413afa642SPhil Greenway case B_COPY: 395*d10d5947SMichael Pfeiffer fpImageView->CopySelectionToClipboard(); 39613afa642SPhil Greenway break; 39713afa642SPhil Greenway case B_PASTE: 39813afa642SPhil Greenway break; 39913afa642SPhil Greenway case MSG_CLEAR_SELECT: 400*d10d5947SMichael Pfeiffer fpImageView->Unselect(); 40113afa642SPhil Greenway break; 40213afa642SPhil Greenway case MSG_SELECT_ALL: 403*d10d5947SMichael Pfeiffer fpImageView->SelectAll(); 40413afa642SPhil Greenway break; 40513afa642SPhil Greenway 40603839579SMatthew Wilber case MSG_PAGE_FIRST: 4077eca0987SMichael Pfeiffer fpImageView->FirstPage(); 40803839579SMatthew Wilber break; 40903839579SMatthew Wilber 41003839579SMatthew Wilber case MSG_PAGE_LAST: 4117eca0987SMichael Pfeiffer fpImageView->LastPage(); 41203839579SMatthew Wilber break; 41303839579SMatthew Wilber 41403839579SMatthew Wilber case MSG_PAGE_NEXT: 4157eca0987SMichael Pfeiffer fpImageView->NextPage(); 41603839579SMatthew Wilber break; 41703839579SMatthew Wilber 41803839579SMatthew Wilber case MSG_PAGE_PREV: 4197eca0987SMichael Pfeiffer fpImageView->PrevPage(); 42003839579SMatthew Wilber break; 42103839579SMatthew Wilber 422cdb89ebbSMatthew Wilber case MSG_DITHER_IMAGE: 4237eca0987SMichael Pfeiffer ToggleMenuItem(pmsg->what); 4247eca0987SMichael Pfeiffer break; 4257eca0987SMichael Pfeiffer 4267eca0987SMichael Pfeiffer case MSG_FIT_TO_WINDOW_SIZE: 4277eca0987SMichael Pfeiffer { 4287eca0987SMichael Pfeiffer bool resize; 4297eca0987SMichael Pfeiffer resize = ToggleMenuItem(pmsg->what); 4307eca0987SMichael Pfeiffer fpImageView->ResizeToViewBounds(resize); 4317eca0987SMichael Pfeiffer } 4327eca0987SMichael Pfeiffer break; 4337eca0987SMichael Pfeiffer 4347eca0987SMichael Pfeiffer case MSG_FILE_PREV: 4357eca0987SMichael Pfeiffer fpImageView->PrevFile(); 4367eca0987SMichael Pfeiffer break; 4377eca0987SMichael Pfeiffer 4387eca0987SMichael Pfeiffer case MSG_FILE_NEXT: 4397eca0987SMichael Pfeiffer fpImageView->NextFile(); 44013afa642SPhil Greenway break; 44113afa642SPhil Greenway 442ad13f387SMichael Pfeiffer case MSG_ROTATE_CLOCKWISE: 443ad13f387SMichael Pfeiffer fpImageView->Rotate(90); 444ad13f387SMichael Pfeiffer break; 445ad13f387SMichael Pfeiffer case MSG_ROTATE_ACLKWISE: 446ad13f387SMichael Pfeiffer fpImageView->Rotate(270); 447ad13f387SMichael Pfeiffer break; 448ad13f387SMichael Pfeiffer case MSG_MIRROR_VERTICAL: 449ad13f387SMichael Pfeiffer fpImageView->Mirror(true); 450ad13f387SMichael Pfeiffer break; 451ad13f387SMichael Pfeiffer case MSG_MIRROR_HORIZONTAL: 452ad13f387SMichael Pfeiffer fpImageView->Mirror(false); 453ad13f387SMichael Pfeiffer break; 454ad13f387SMichael Pfeiffer case MSG_INVERT: 455ad13f387SMichael Pfeiffer fpImageView->Invert(); 456ad13f387SMichael Pfeiffer break; 457ad13f387SMichael Pfeiffer case MSG_DIA_SHOW: 458ad13f387SMichael Pfeiffer if (ToggleMenuItem(pmsg->what)) { 459ad13f387SMichael Pfeiffer fpImageView->StartDiaShow(); 460ad13f387SMichael Pfeiffer } else { 461ad13f387SMichael Pfeiffer fpImageView->StopDiaShow(); 462ad13f387SMichael Pfeiffer } 463ad13f387SMichael Pfeiffer case MSG_DIA_SHOW_DELAY: 464ad13f387SMichael Pfeiffer { 465ad13f387SMichael Pfeiffer float value; 466ad13f387SMichael Pfeiffer if (pmsg->FindFloat("value", &value) == B_OK) { 467ad13f387SMichael Pfeiffer fpImageView->SetDiaShowDelay(value); 468ad13f387SMichael Pfeiffer } 469ad13f387SMichael Pfeiffer } 470ad13f387SMichael Pfeiffer break; 471ad13f387SMichael Pfeiffer 472ad13f387SMichael Pfeiffer case MSG_FULL_SCREEN: 473ad13f387SMichael Pfeiffer ToggleFullScreen(); 474ad13f387SMichael Pfeiffer break; 475ad13f387SMichael Pfeiffer 476*d10d5947SMichael Pfeiffer case MSG_UPDATE_RECENT_DOCUMENTS: 477*d10d5947SMichael Pfeiffer UpdateRecentDocumentsMenu(); 478*d10d5947SMichael Pfeiffer break; 479*d10d5947SMichael Pfeiffer 48013afa642SPhil Greenway default: 481cdb89ebbSMatthew Wilber BWindow::MessageReceived(pmsg); 48213afa642SPhil Greenway break; 48313afa642SPhil Greenway } 48413afa642SPhil Greenway } 485fc0a275bSMatthew Wilber 486fc0a275bSMatthew Wilber void 487fc0a275bSMatthew Wilber ShowImageWindow::SaveAs(BMessage *pmsg) 488fc0a275bSMatthew Wilber { 489cdb89ebbSMatthew Wilber // Read the translator and output type the user chose 490cdb89ebbSMatthew Wilber translator_id outTranslator; 491cdb89ebbSMatthew Wilber uint32 outType; 492cdb89ebbSMatthew Wilber if (pmsg->FindInt32(TRANSLATOR_FLD, 493cdb89ebbSMatthew Wilber reinterpret_cast<int32 *>(&outTranslator)) != B_OK) 494fc0a275bSMatthew Wilber return; 495cdb89ebbSMatthew Wilber if (pmsg->FindInt32(TYPE_FLD, 496cdb89ebbSMatthew Wilber reinterpret_cast<int32 *>(&outType)) != B_OK) 497fc0a275bSMatthew Wilber return; 498fc0a275bSMatthew Wilber 499cdb89ebbSMatthew Wilber // Add the chosen translator and output type to the 500cdb89ebbSMatthew Wilber // message that the save panel will send back 501cdb89ebbSMatthew Wilber BMessage *ppanelMsg = new BMessage(MSG_SAVE_PANEL); 502cdb89ebbSMatthew Wilber ppanelMsg->AddInt32(TRANSLATOR_FLD, outTranslator); 503cdb89ebbSMatthew Wilber ppanelMsg->AddInt32(TYPE_FLD, outType); 504cdb89ebbSMatthew Wilber 505cdb89ebbSMatthew Wilber // Create save panel and show it 5067eca0987SMichael Pfeiffer fpSavePanel = new BFilePanel(B_SAVE_PANEL, new BMessenger(this), NULL, 0, 507cdb89ebbSMatthew Wilber false, ppanelMsg); 5087eca0987SMichael Pfeiffer if (!fpSavePanel) 509fc0a275bSMatthew Wilber return; 5107eca0987SMichael Pfeiffer fpSavePanel->Window()->SetWorkspaces(B_CURRENT_WORKSPACE); 5117eca0987SMichael Pfeiffer fpSavePanel->Show(); 512fc0a275bSMatthew Wilber } 513fc0a275bSMatthew Wilber 514fc0a275bSMatthew Wilber void 515fc0a275bSMatthew Wilber ShowImageWindow::SaveToFile(BMessage *pmsg) 516fc0a275bSMatthew Wilber { 517cdb89ebbSMatthew Wilber // Read in where the file should be saved 518fc0a275bSMatthew Wilber entry_ref dirref; 519fc0a275bSMatthew Wilber if (pmsg->FindRef("directory", &dirref) != B_OK) 520fc0a275bSMatthew Wilber return; 521fc0a275bSMatthew Wilber const char *filename; 522fc0a275bSMatthew Wilber if (pmsg->FindString("name", &filename) != B_OK) 523fc0a275bSMatthew Wilber return; 524fc0a275bSMatthew Wilber 525cdb89ebbSMatthew Wilber // Read in the translator and type to be used 526cdb89ebbSMatthew Wilber // to save the output image 527cdb89ebbSMatthew Wilber translator_id outTranslator; 528cdb89ebbSMatthew Wilber uint32 outType; 529cdb89ebbSMatthew Wilber if (pmsg->FindInt32(TRANSLATOR_FLD, 530cdb89ebbSMatthew Wilber reinterpret_cast<int32 *>(&outTranslator)) != B_OK) 531cdb89ebbSMatthew Wilber return; 532cdb89ebbSMatthew Wilber if (pmsg->FindInt32(TYPE_FLD, 533cdb89ebbSMatthew Wilber reinterpret_cast<int32 *>(&outType)) != B_OK) 534cdb89ebbSMatthew Wilber return; 535cdb89ebbSMatthew Wilber 536cdb89ebbSMatthew Wilber // Create the output file 537fc0a275bSMatthew Wilber BDirectory dir(&dirref); 538fc0a275bSMatthew Wilber BFile file(&dir, filename, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); 539fc0a275bSMatthew Wilber if (file.InitCheck() != B_OK) 540fc0a275bSMatthew Wilber return; 541fc0a275bSMatthew Wilber 542cdb89ebbSMatthew Wilber // Translate the image and write it out to the output file 5437eca0987SMichael Pfeiffer BBitmapStream stream(fpImageView->GetBitmap()); 544fc0a275bSMatthew Wilber BTranslatorRoster *proster = BTranslatorRoster::Default(); 545cdb89ebbSMatthew Wilber if (proster->Translate(outTranslator, &stream, NULL, 546cdb89ebbSMatthew Wilber &file, outType) != B_OK) { 547fc0a275bSMatthew Wilber BAlert *palert = new BAlert(NULL, "Error writing image file.", "Ok"); 548fc0a275bSMatthew Wilber palert->Go(); 549fc0a275bSMatthew Wilber } 550fc0a275bSMatthew Wilber 551fc0a275bSMatthew Wilber BBitmap *pout = NULL; 552fc0a275bSMatthew Wilber stream.DetachBitmap(&pout); 553fc0a275bSMatthew Wilber // bitmap used by stream still belongs to the view, 554fc0a275bSMatthew Wilber // detach so it doesn't get deleted 555fc0a275bSMatthew Wilber } 556fc0a275bSMatthew Wilber 557cdb89ebbSMatthew Wilber bool 558cdb89ebbSMatthew Wilber ShowImageWindow::CanQuit() 559cdb89ebbSMatthew Wilber { 5607eca0987SMichael Pfeiffer if (fpSavePanel) 561cdb89ebbSMatthew Wilber // Don't allow this window to be closed if a save panel is open 562cdb89ebbSMatthew Wilber return false; 563cdb89ebbSMatthew Wilber else 564cdb89ebbSMatthew Wilber return true; 565cdb89ebbSMatthew Wilber } 566cdb89ebbSMatthew Wilber 567ad13f387SMichael Pfeiffer void 568ad13f387SMichael Pfeiffer ShowImageWindow::ToggleFullScreen() 569ad13f387SMichael Pfeiffer { 570ad13f387SMichael Pfeiffer BRect frame; 571ad13f387SMichael Pfeiffer fFullScreen = !fFullScreen; 572ad13f387SMichael Pfeiffer if (fFullScreen) { 573ad13f387SMichael Pfeiffer BScreen screen; 574ad13f387SMichael Pfeiffer fWindowFrame = Frame(); 575ad13f387SMichael Pfeiffer frame = screen.Frame(); 576ad13f387SMichael Pfeiffer frame.top -= fpBar->Bounds().Height()+1; 577ad13f387SMichael Pfeiffer frame.right += B_V_SCROLL_BAR_WIDTH; 578ad13f387SMichael Pfeiffer frame.bottom += B_H_SCROLL_BAR_HEIGHT; 579ad13f387SMichael Pfeiffer frame.InsetBy(-1, -1); // PEN_SIZE in ShowImageView 580ad13f387SMichael Pfeiffer 581ad13f387SMichael Pfeiffer SetFlags(Flags() | B_NOT_RESIZABLE | B_NOT_MOVABLE); 582ad13f387SMichael Pfeiffer } else { 583ad13f387SMichael Pfeiffer frame = fWindowFrame; 584ad13f387SMichael Pfeiffer 585ad13f387SMichael Pfeiffer SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE)); 586ad13f387SMichael Pfeiffer } 587ad13f387SMichael Pfeiffer MoveTo(frame.left, frame.top); 588ad13f387SMichael Pfeiffer ResizeTo(frame.Width(), frame.Height()); 589ad13f387SMichael Pfeiffer } 590ad13f387SMichael Pfeiffer 591cdb89ebbSMatthew Wilber bool 592cdb89ebbSMatthew Wilber ShowImageWindow::QuitRequested() 593cdb89ebbSMatthew Wilber { 594cdb89ebbSMatthew Wilber return CanQuit(); 595cdb89ebbSMatthew Wilber } 596cdb89ebbSMatthew Wilber 59707caaa8eSMatthew Wilber void 59807caaa8eSMatthew Wilber ShowImageWindow::Quit() 59907caaa8eSMatthew Wilber { 60007caaa8eSMatthew Wilber // tell the app to forget about this window 60107caaa8eSMatthew Wilber be_app->PostMessage(MSG_WINDOW_QUIT); 60207caaa8eSMatthew Wilber BWindow::Quit(); 60307caaa8eSMatthew Wilber } 604fc0a275bSMatthew Wilber 605