From 94fd94986adbcfbc84cde243a338aa3f53a16004 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Fri, 8 Apr 2011 15:08:33 +0000 Subject: [PATCH] * The window uses layout management in principle. This was necessary to get the main menu bar to report the correct minimum size. My previous commit with regards to setting the correct minimum window size introduced a regression that the window could not shrink below it's initial size because of some backwards compatibility behavior of BMenuBar (IIRC). * Inserted a content view to hold the tool bar and the show image views. This one does not use layout management, so that everything pretty much works as before. * Showing/Hiding the tool bar is now animated. * When the tool bar is enabled in principle, it will automatically show in full screen mode when the user moves the mouse. When the mouse is not above the tool bar, it is hidden after a delay. * Added a right-aligned "Leave full screen" icon to the tool bar. * Improved the workings of the slide show icon. As before, it automatically triggers full screen mode. It is now pressed when the slide show is running. Clicking it again just stops the slide show without affecting the full screen mode (i.e. also not when the user left full screen mode meanwhile). There are some problems with images not being automatically sized to the full screen size as would be expected. This needs to be fixed, yet. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41202 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/showimage/ShowImageView.cpp | 22 +++- src/apps/showimage/ShowImageView.h | 1 + src/apps/showimage/ShowImageWindow.cpp | 166 ++++++++++++++++++------- src/apps/showimage/ShowImageWindow.h | 4 +- 4 files changed, 142 insertions(+), 51 deletions(-) diff --git a/src/apps/showimage/ShowImageView.cpp b/src/apps/showimage/ShowImageView.cpp index 27f01dc2ed..e73e2dc5b1 100644 --- a/src/apps/showimage/ShowImageView.cpp +++ b/src/apps/showimage/ShowImageView.cpp @@ -234,9 +234,15 @@ ShowImageView::Pulse() } if (fHideCursor && !fHasSelection && !fShowingPopUpMenu && fIsActiveWin) { - if (fHideCursorCountDown <= 0) - be_app->ObscureCursor(); - else + if (fHideCursorCountDown <= 0) { + BPoint mousePos; + uint32 buttons; + GetMouse(&mousePos, &buttons, false); + if (Bounds().Contains(mousePos)) { + be_app->ObscureCursor(); + _ShowToolBarIfEnabled(false); + } + } else fHideCursorCountDown--; } } @@ -1147,6 +1153,7 @@ void ShowImageView::MouseMoved(BPoint point, uint32 state, const BMessage* message) { fHideCursorCountDown = HIDE_CURSOR_DELAY_TIME; + _ShowToolBarIfEnabled(true); if (fCreatingSelection) _UpdateSelectionRect(point, false); else if (fScrollingBitmap) @@ -1824,6 +1831,15 @@ ShowImageView::_ExitFullScreen() } +void +ShowImageView::_ShowToolBarIfEnabled(bool show) +{ + BMessage message(kShowToolBarIfEnabled); + message.AddBool("show", show); + Window()->PostMessage(&message); +} + + void ShowImageView::WindowActivated(bool active) { diff --git a/src/apps/showimage/ShowImageView.h b/src/apps/showimage/ShowImageView.h index ab3a9b1e07..d028e5c3be 100644 --- a/src/apps/showimage/ShowImageView.h +++ b/src/apps/showimage/ShowImageView.h @@ -178,6 +178,7 @@ private: void _ToggleSlideShow(); void _StopSlideShow(); void _ExitFullScreen(); + void _ShowToolBarIfEnabled(bool show); private: ShowImageUndo fUndo; diff --git a/src/apps/showimage/ShowImageWindow.cpp b/src/apps/showimage/ShowImageWindow.cpp index 39da5f093a..aabf2c0225 100644 --- a/src/apps/showimage/ShowImageWindow.cpp +++ b/src/apps/showimage/ShowImageWindow.cpp @@ -97,7 +97,9 @@ enum { kMsgOriginalSize = 'mOSZ', kMsgStretchToWindow = 'mStW', kMsgNextSlide = 'mNxS', - kMsgToggleToolBar = 'mTTB' + kMsgToggleToolBar = 'mTTB', + kMsgSlideToolBar = 'mSTB', + kMsgFinishSlidingToolBar = 'mFST' }; @@ -127,7 +129,7 @@ bs_printf(BString* string, const char* format, ...) ShowImageWindow::ShowImageWindow(BRect frame, const entry_ref& ref, const BMessenger& trackerMessenger) : - BWindow(frame, "", B_DOCUMENT_WINDOW, 0), + BWindow(frame, "", B_DOCUMENT_WINDOW, B_AUTO_UPDATE_SIZE_LIMITS), fNavigator(ref, trackerMessenger), fSavePanel(NULL), fBar(NULL), @@ -148,15 +150,25 @@ ShowImageWindow::ShowImageWindow(BRect frame, const entry_ref& ref, { _ApplySettings(); + SetLayout(new BGroupLayout(B_VERTICAL, 0)); + // create menu bar - fBar = new BMenuBar(BRect(0, 0, Bounds().right, 1), "menu_bar"); + fBar = new BMenuBar("menu_bar"); _AddMenus(fBar); + float menuBarMinWidth = fBar->MinSize().width; AddChild(fBar); - BRect viewFrame = Bounds(); - viewFrame.top = fBar->Bounds().Height() + 1; - viewFrame.bottom = viewFrame.top + 30; + // Add a content view so the tool bar can be moved outside of the + // visible portion without colliding with the menu bar. + BView* contentView = new BView(BRect(), "content", B_FOLLOW_NONE, 0); + contentView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + contentView->SetExplicitMinSize(BSize(250, 100)); + AddChild(contentView); + + // Create the tool bar + BRect viewFrame = contentView->Bounds(); + viewFrame.right -= B_V_SCROLL_BAR_WIDTH; fToolBarView = new ToolBarView(viewFrame); // Add the tool icons. @@ -184,21 +196,21 @@ ShowImageWindow::ShowImageWindow(BRect frame, const entry_ref& ref, B_TRANSLATE("Zoom in")); fToolBarView->AddAction(MSG_ZOOM_OUT, this, tool_bar_icon(kIconZoomOut), B_TRANSLATE("Zoom out")); -// fToolBarView->AddSeparator(); -// fToolBarView->AddAction(MSG_FULL_SCREEN, this, -// tool_bar_icon(kIconViewFullScreen), B_TRANSLATE("Full screen")); + fToolBarView->AddGlue(); + fToolBarView->AddAction(MSG_FULL_SCREEN, this, + tool_bar_icon(kIconViewWindowed), B_TRANSLATE("Leave full screen")); + fToolBarView->SetActionVisible(MSG_FULL_SCREEN, false); fToolBarView->ResizeTo(viewFrame.Width(), fToolBarView->MinSize().height); - AddChild(fToolBarView); + contentView->AddChild(fToolBarView); if (fShowToolBar) viewFrame.top = fToolBarView->Frame().bottom + 1; else fToolBarView->Hide(); - viewFrame.bottom = Bounds().bottom; - viewFrame.right -= B_V_SCROLL_BAR_WIDTH; + viewFrame.bottom = contentView->Bounds().bottom; viewFrame.bottom -= B_H_SCROLL_BAR_HEIGHT; // create the image view @@ -208,40 +220,38 @@ ShowImageWindow::ShowImageWindow(BRect frame, const entry_ref& ref, // wrap a scroll view around the view fScrollView = new BScrollView("image_scroller", fImageView, B_FOLLOW_ALL, 0, false, false, B_PLAIN_BORDER); - AddChild(fScrollView); + contentView->AddChild(fScrollView); const int32 kstatusWidth = 190; BRect rect; - rect = Bounds(); + rect = contentView->Bounds(); rect.top = viewFrame.bottom + 1; rect.left = viewFrame.left + kstatusWidth; rect.right = viewFrame.right + 1; rect.bottom += 1; BScrollBar* horizontalScrollBar = new BScrollBar(rect, "hscroll", fImageView, 0, 150, B_HORIZONTAL); - AddChild(horizontalScrollBar); + contentView->AddChild(horizontalScrollBar); rect.left = 0; rect.right = kstatusWidth - 1; rect.bottom -= 1; fStatusView = new ShowImageStatusView(rect, "status_view", B_FOLLOW_BOTTOM, B_WILL_DRAW); - AddChild(fStatusView); + contentView->AddChild(fStatusView); - rect = Bounds(); + rect = contentView->Bounds(); rect.top = viewFrame.top - 1; rect.left = viewFrame.right + 1; rect.bottom = viewFrame.bottom + 1; rect.right += 1; fVerticalScrollBar = new BScrollBar(rect, "vscroll", fImageView, 0, 150, B_VERTICAL); - AddChild(fVerticalScrollBar); + contentView->AddChild(fVerticalScrollBar); // Update minimum window size - float menuBarMinWidth; - fBar->GetPreferredSize(&menuBarMinWidth, NULL); - float toolBarMinWidth; - fToolBarView->GetPreferredSize(&toolBarMinWidth, NULL); + float toolBarMinWidth = fToolBarView->MinSize().width; + printf("menu min size: %.1f, tool bar: %.1f\n", menuBarMinWidth, toolBarMinWidth); SetSizeLimits(std::max(menuBarMinWidth, toolBarMinWidth), 100000, 100, 100000); @@ -345,8 +355,8 @@ ShowImageWindow::_BuildViewMenu(BMenu* menu, bool popupMenu) _MarkMenuItem(menu, kMsgStretchToWindow, fImageView->StretchesToBounds()); if (!popupMenu) { - _AddItemMenu(menu, B_TRANSLATE("Show tool bar"), kMsgToggleToolBar, 0, - 0, this); + _AddItemMenu(menu, B_TRANSLATE("Show tool bar"), kMsgToggleToolBar, + 'T', 0, this); _MarkMenuItem(menu, kMsgToggleToolBar, !fToolBarView->IsHidden(fToolBarView)); } @@ -882,15 +892,8 @@ ShowImageWindow::MessageReceived(BMessage* message) case MSG_SLIDE_SHOW: { - // TODO: Maybe two distinct messages? Also once the tool bar - // automatically shows in full screen mode, the icon should - // be a pause. There should be a separate icon to leave full - // screen mode as well. - bool fullScreen; - if (message->FindBool("full screen", &fullScreen) == B_OK - && fullScreen) { - _ToggleFullScreen(); - } + bool fullScreen = false; + message->FindBool("full screen", &fullScreen); BMenuItem* item = fBar->FindItem(message->what); if (item == NULL) @@ -899,9 +902,13 @@ ShowImageWindow::MessageReceived(BMessage* message) if (item->IsMarked()) { item->SetMarked(false); _StopSlideShow(); + fToolBarView->SetActionPressed(MSG_SLIDE_SHOW, false); } else if (_ClosePrompt()) { item->SetMarked(true); + if (!fFullScreen && fullScreen) + _ToggleFullScreen(); _StartSlideShow(); + fToolBarView->SetActionPressed(MSG_SLIDE_SHOW, true); } break; } @@ -913,6 +920,7 @@ ShowImageWindow::MessageReceived(BMessage* message) item->SetMarked(false); _StopSlideShow(); + fToolBarView->SetActionPressed(MSG_SLIDE_SHOW, false); break; } @@ -1004,7 +1012,7 @@ ShowImageWindow::MessageReceived(BMessage* message) case kMsgToggleToolBar: { fShowToolBar = _ToggleMenuItem(message->what); - _SetToolBarVisible(fShowToolBar); + _SetToolBarVisible(fShowToolBar, true); ShowImageSettings* settings = my_app->Settings(); @@ -1014,6 +1022,54 @@ ShowImageWindow::MessageReceived(BMessage* message) } break; } + case kShowToolBarIfEnabled: + { + bool show; + if (message->FindBool("show", &show) != B_OK) + break; + _SetToolBarVisible(fShowToolBar && show, true); + break; + } + case kMsgSlideToolBar: + { + float offset; + if (message->FindFloat("offset", &offset) == B_OK) { + fToolBarView->MoveBy(0, offset); + fScrollView->ResizeBy(0, -offset); + fScrollView->MoveBy(0, offset); + fVerticalScrollBar->ResizeBy(0, -offset); + fVerticalScrollBar->MoveBy(0, offset); + UpdateIfNeeded(); + snooze(15000); + } + break; + } + case kMsgFinishSlidingToolBar: + { + float offset; + bool show; + if (message->FindFloat("offset", &offset) == B_OK + && message->FindBool("show", &show) == B_OK) { + // Compensate rounding errors with the final placement + if (show) { + fToolBarView->MoveTo(fToolBarView->Frame().left, 0); + } else { + fToolBarView->MoveTo(fToolBarView->Frame().left, offset); + fToolBarView->Hide(); + } + BRect frame = fToolBarView->Parent()->Bounds(); + frame.top = fToolBarView->Frame().bottom + 1; + fScrollView->MoveTo(0, frame.top); + fScrollView->ResizeTo(fScrollView->Bounds().Width(), + frame.Height() - B_H_SCROLL_BAR_HEIGHT + 1); + fVerticalScrollBar->MoveTo( + frame.right - B_V_SCROLL_BAR_WIDTH + 1, frame.top); + fVerticalScrollBar->ResizeTo( + fVerticalScrollBar->Bounds().Width(), + frame.Height() - B_H_SCROLL_BAR_HEIGHT + 1); + } + break; + } default: BWindow::MessageReceived(message); @@ -1231,7 +1287,7 @@ ShowImageWindow::_ToggleFullScreen() SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE)); } - fToolBarView->SetActionPressed(MSG_FULL_SCREEN, fFullScreen); + fToolBarView->SetActionVisible(MSG_FULL_SCREEN, fFullScreen); _SetToolBarVisible(!fFullScreen && fShowToolBar); MoveTo(frame.left, frame.top); @@ -1453,24 +1509,40 @@ ShowImageWindow::_UpdateRatingMenu() void -ShowImageWindow::_SetToolBarVisible(bool visible) +ShowImageWindow::_SetToolBarVisible(bool visible, bool animate) { if (visible == !fToolBarView->IsHidden()) return; - float diff = fToolBarView->Bounds().Height() + 1; - if (!visible) { + float diff = fToolBarView->Bounds().Height() + 2; + if (!visible) diff = -diff; - fToolBarView->Hide(); - } - - fScrollView->ResizeBy(0, -diff); - fScrollView->MoveBy(0, diff); - fVerticalScrollBar->ResizeBy(0, -diff); - fVerticalScrollBar->MoveBy(0, diff); - - if (visible) + else fToolBarView->Show(); + + if (animate) { + // Slide the controls into view. We do this with messages in order + // not to block the window thread. + const float kAnimationOffsets[] = { 0.05, 0.2, 0.5, 0.2, 0.05 }; + const int32 steps = sizeof(kAnimationOffsets) / sizeof(float); + float originalY = fToolBarView->Frame().top; + for (int32 i = 0; i < steps; i++) { + BMessage message(kMsgSlideToolBar); + message.AddFloat("offset", floorf(diff * kAnimationOffsets[i])); + PostMessage(&message, this); + } + BMessage finalMessage(kMsgFinishSlidingToolBar); + finalMessage.AddFloat("offset", originalY + diff); + finalMessage.AddBool("show", visible); + PostMessage(&finalMessage, this); + } else { + fScrollView->ResizeBy(0, -diff); + fScrollView->MoveBy(0, diff); + fVerticalScrollBar->ResizeBy(0, -diff); + fVerticalScrollBar->MoveBy(0, diff); + if (!visible) + fToolBarView->Hide(); + } } diff --git a/src/apps/showimage/ShowImageWindow.h b/src/apps/showimage/ShowImageWindow.h index 847b6acfc8..f5cf499b41 100644 --- a/src/apps/showimage/ShowImageWindow.h +++ b/src/apps/showimage/ShowImageWindow.h @@ -42,6 +42,7 @@ enum { MSG_SLIDE_SHOW = 'mSSW', kMsgStopSlideShow = 'msss', MSG_FULL_SCREEN = 'mFSC', + kShowToolBarIfEnabled = 'mSTE', MSG_EXIT_FULL_SCREEN = 'mEFS', MSG_WINDOW_HAS_QUIT = 'wndq' }; @@ -102,7 +103,8 @@ private: void _UpdateRatingMenu(); - void _SetToolBarVisible(bool visible); + void _SetToolBarVisible(bool visible, + bool animate = false); private: ImageFileNavigator fNavigator;