* 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
This commit is contained in:
Stephan Aßmus
2011-04-08 15:08:33 +00:00
parent e1ae00a962
commit 94fd94986a
4 changed files with 142 additions and 51 deletions
+19 -3
View File
@@ -234,9 +234,15 @@ ShowImageView::Pulse()
} }
if (fHideCursor && !fHasSelection && !fShowingPopUpMenu && fIsActiveWin) { if (fHideCursor && !fHasSelection && !fShowingPopUpMenu && fIsActiveWin) {
if (fHideCursorCountDown <= 0) if (fHideCursorCountDown <= 0) {
be_app->ObscureCursor(); BPoint mousePos;
else uint32 buttons;
GetMouse(&mousePos, &buttons, false);
if (Bounds().Contains(mousePos)) {
be_app->ObscureCursor();
_ShowToolBarIfEnabled(false);
}
} else
fHideCursorCountDown--; fHideCursorCountDown--;
} }
} }
@@ -1147,6 +1153,7 @@ void
ShowImageView::MouseMoved(BPoint point, uint32 state, const BMessage* message) ShowImageView::MouseMoved(BPoint point, uint32 state, const BMessage* message)
{ {
fHideCursorCountDown = HIDE_CURSOR_DELAY_TIME; fHideCursorCountDown = HIDE_CURSOR_DELAY_TIME;
_ShowToolBarIfEnabled(true);
if (fCreatingSelection) if (fCreatingSelection)
_UpdateSelectionRect(point, false); _UpdateSelectionRect(point, false);
else if (fScrollingBitmap) 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 void
ShowImageView::WindowActivated(bool active) ShowImageView::WindowActivated(bool active)
{ {
+1
View File
@@ -178,6 +178,7 @@ private:
void _ToggleSlideShow(); void _ToggleSlideShow();
void _StopSlideShow(); void _StopSlideShow();
void _ExitFullScreen(); void _ExitFullScreen();
void _ShowToolBarIfEnabled(bool show);
private: private:
ShowImageUndo fUndo; ShowImageUndo fUndo;
+119 -47
View File
@@ -97,7 +97,9 @@ enum {
kMsgOriginalSize = 'mOSZ', kMsgOriginalSize = 'mOSZ',
kMsgStretchToWindow = 'mStW', kMsgStretchToWindow = 'mStW',
kMsgNextSlide = 'mNxS', 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, ShowImageWindow::ShowImageWindow(BRect frame, const entry_ref& ref,
const BMessenger& trackerMessenger) const BMessenger& trackerMessenger)
: :
BWindow(frame, "", B_DOCUMENT_WINDOW, 0), BWindow(frame, "", B_DOCUMENT_WINDOW, B_AUTO_UPDATE_SIZE_LIMITS),
fNavigator(ref, trackerMessenger), fNavigator(ref, trackerMessenger),
fSavePanel(NULL), fSavePanel(NULL),
fBar(NULL), fBar(NULL),
@@ -148,15 +150,25 @@ ShowImageWindow::ShowImageWindow(BRect frame, const entry_ref& ref,
{ {
_ApplySettings(); _ApplySettings();
SetLayout(new BGroupLayout(B_VERTICAL, 0));
// create menu bar // create menu bar
fBar = new BMenuBar(BRect(0, 0, Bounds().right, 1), "menu_bar"); fBar = new BMenuBar("menu_bar");
_AddMenus(fBar); _AddMenus(fBar);
float menuBarMinWidth = fBar->MinSize().width;
AddChild(fBar); AddChild(fBar);
BRect viewFrame = Bounds(); // Add a content view so the tool bar can be moved outside of the
viewFrame.top = fBar->Bounds().Height() + 1; // visible portion without colliding with the menu bar.
viewFrame.bottom = viewFrame.top + 30;
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); fToolBarView = new ToolBarView(viewFrame);
// Add the tool icons. // Add the tool icons.
@@ -184,21 +196,21 @@ ShowImageWindow::ShowImageWindow(BRect frame, const entry_ref& ref,
B_TRANSLATE("Zoom in")); B_TRANSLATE("Zoom in"));
fToolBarView->AddAction(MSG_ZOOM_OUT, this, tool_bar_icon(kIconZoomOut), fToolBarView->AddAction(MSG_ZOOM_OUT, this, tool_bar_icon(kIconZoomOut),
B_TRANSLATE("Zoom out")); B_TRANSLATE("Zoom out"));
// fToolBarView->AddSeparator(); fToolBarView->AddGlue();
// fToolBarView->AddAction(MSG_FULL_SCREEN, this, fToolBarView->AddAction(MSG_FULL_SCREEN, this,
// tool_bar_icon(kIconViewFullScreen), B_TRANSLATE("Full screen")); tool_bar_icon(kIconViewWindowed), B_TRANSLATE("Leave full screen"));
fToolBarView->SetActionVisible(MSG_FULL_SCREEN, false);
fToolBarView->ResizeTo(viewFrame.Width(), fToolBarView->MinSize().height); fToolBarView->ResizeTo(viewFrame.Width(), fToolBarView->MinSize().height);
AddChild(fToolBarView); contentView->AddChild(fToolBarView);
if (fShowToolBar) if (fShowToolBar)
viewFrame.top = fToolBarView->Frame().bottom + 1; viewFrame.top = fToolBarView->Frame().bottom + 1;
else else
fToolBarView->Hide(); fToolBarView->Hide();
viewFrame.bottom = Bounds().bottom; viewFrame.bottom = contentView->Bounds().bottom;
viewFrame.right -= B_V_SCROLL_BAR_WIDTH;
viewFrame.bottom -= B_H_SCROLL_BAR_HEIGHT; viewFrame.bottom -= B_H_SCROLL_BAR_HEIGHT;
// create the image view // create the image view
@@ -208,40 +220,38 @@ ShowImageWindow::ShowImageWindow(BRect frame, const entry_ref& ref,
// wrap a scroll view around the view // wrap a scroll view around the view
fScrollView = new BScrollView("image_scroller", fImageView, fScrollView = new BScrollView("image_scroller", fImageView,
B_FOLLOW_ALL, 0, false, false, B_PLAIN_BORDER); B_FOLLOW_ALL, 0, false, false, B_PLAIN_BORDER);
AddChild(fScrollView); contentView->AddChild(fScrollView);
const int32 kstatusWidth = 190; const int32 kstatusWidth = 190;
BRect rect; BRect rect;
rect = Bounds(); rect = contentView->Bounds();
rect.top = viewFrame.bottom + 1; rect.top = viewFrame.bottom + 1;
rect.left = viewFrame.left + kstatusWidth; rect.left = viewFrame.left + kstatusWidth;
rect.right = viewFrame.right + 1; rect.right = viewFrame.right + 1;
rect.bottom += 1; rect.bottom += 1;
BScrollBar* horizontalScrollBar = new BScrollBar(rect, "hscroll", BScrollBar* horizontalScrollBar = new BScrollBar(rect, "hscroll",
fImageView, 0, 150, B_HORIZONTAL); fImageView, 0, 150, B_HORIZONTAL);
AddChild(horizontalScrollBar); contentView->AddChild(horizontalScrollBar);
rect.left = 0; rect.left = 0;
rect.right = kstatusWidth - 1; rect.right = kstatusWidth - 1;
rect.bottom -= 1; rect.bottom -= 1;
fStatusView = new ShowImageStatusView(rect, "status_view", B_FOLLOW_BOTTOM, fStatusView = new ShowImageStatusView(rect, "status_view", B_FOLLOW_BOTTOM,
B_WILL_DRAW); B_WILL_DRAW);
AddChild(fStatusView); contentView->AddChild(fStatusView);
rect = Bounds(); rect = contentView->Bounds();
rect.top = viewFrame.top - 1; rect.top = viewFrame.top - 1;
rect.left = viewFrame.right + 1; rect.left = viewFrame.right + 1;
rect.bottom = viewFrame.bottom + 1; rect.bottom = viewFrame.bottom + 1;
rect.right += 1; rect.right += 1;
fVerticalScrollBar = new BScrollBar(rect, "vscroll", fImageView, fVerticalScrollBar = new BScrollBar(rect, "vscroll", fImageView,
0, 150, B_VERTICAL); 0, 150, B_VERTICAL);
AddChild(fVerticalScrollBar); contentView->AddChild(fVerticalScrollBar);
// Update minimum window size // Update minimum window size
float menuBarMinWidth; float toolBarMinWidth = fToolBarView->MinSize().width;
fBar->GetPreferredSize(&menuBarMinWidth, NULL); printf("menu min size: %.1f, tool bar: %.1f\n", menuBarMinWidth, toolBarMinWidth);
float toolBarMinWidth;
fToolBarView->GetPreferredSize(&toolBarMinWidth, NULL);
SetSizeLimits(std::max(menuBarMinWidth, toolBarMinWidth), 100000, 100, SetSizeLimits(std::max(menuBarMinWidth, toolBarMinWidth), 100000, 100,
100000); 100000);
@@ -345,8 +355,8 @@ ShowImageWindow::_BuildViewMenu(BMenu* menu, bool popupMenu)
_MarkMenuItem(menu, kMsgStretchToWindow, fImageView->StretchesToBounds()); _MarkMenuItem(menu, kMsgStretchToWindow, fImageView->StretchesToBounds());
if (!popupMenu) { if (!popupMenu) {
_AddItemMenu(menu, B_TRANSLATE("Show tool bar"), kMsgToggleToolBar, 0, _AddItemMenu(menu, B_TRANSLATE("Show tool bar"), kMsgToggleToolBar,
0, this); 'T', 0, this);
_MarkMenuItem(menu, kMsgToggleToolBar, _MarkMenuItem(menu, kMsgToggleToolBar,
!fToolBarView->IsHidden(fToolBarView)); !fToolBarView->IsHidden(fToolBarView));
} }
@@ -882,15 +892,8 @@ ShowImageWindow::MessageReceived(BMessage* message)
case MSG_SLIDE_SHOW: case MSG_SLIDE_SHOW:
{ {
// TODO: Maybe two distinct messages? Also once the tool bar bool fullScreen = false;
// automatically shows in full screen mode, the icon should message->FindBool("full screen", &fullScreen);
// 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();
}
BMenuItem* item = fBar->FindItem(message->what); BMenuItem* item = fBar->FindItem(message->what);
if (item == NULL) if (item == NULL)
@@ -899,9 +902,13 @@ ShowImageWindow::MessageReceived(BMessage* message)
if (item->IsMarked()) { if (item->IsMarked()) {
item->SetMarked(false); item->SetMarked(false);
_StopSlideShow(); _StopSlideShow();
fToolBarView->SetActionPressed(MSG_SLIDE_SHOW, false);
} else if (_ClosePrompt()) { } else if (_ClosePrompt()) {
item->SetMarked(true); item->SetMarked(true);
if (!fFullScreen && fullScreen)
_ToggleFullScreen();
_StartSlideShow(); _StartSlideShow();
fToolBarView->SetActionPressed(MSG_SLIDE_SHOW, true);
} }
break; break;
} }
@@ -913,6 +920,7 @@ ShowImageWindow::MessageReceived(BMessage* message)
item->SetMarked(false); item->SetMarked(false);
_StopSlideShow(); _StopSlideShow();
fToolBarView->SetActionPressed(MSG_SLIDE_SHOW, false);
break; break;
} }
@@ -1004,7 +1012,7 @@ ShowImageWindow::MessageReceived(BMessage* message)
case kMsgToggleToolBar: case kMsgToggleToolBar:
{ {
fShowToolBar = _ToggleMenuItem(message->what); fShowToolBar = _ToggleMenuItem(message->what);
_SetToolBarVisible(fShowToolBar); _SetToolBarVisible(fShowToolBar, true);
ShowImageSettings* settings = my_app->Settings(); ShowImageSettings* settings = my_app->Settings();
@@ -1014,6 +1022,54 @@ ShowImageWindow::MessageReceived(BMessage* message)
} }
break; 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: default:
BWindow::MessageReceived(message); BWindow::MessageReceived(message);
@@ -1231,7 +1287,7 @@ ShowImageWindow::_ToggleFullScreen()
SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE)); SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE));
} }
fToolBarView->SetActionPressed(MSG_FULL_SCREEN, fFullScreen); fToolBarView->SetActionVisible(MSG_FULL_SCREEN, fFullScreen);
_SetToolBarVisible(!fFullScreen && fShowToolBar); _SetToolBarVisible(!fFullScreen && fShowToolBar);
MoveTo(frame.left, frame.top); MoveTo(frame.left, frame.top);
@@ -1453,24 +1509,40 @@ ShowImageWindow::_UpdateRatingMenu()
void void
ShowImageWindow::_SetToolBarVisible(bool visible) ShowImageWindow::_SetToolBarVisible(bool visible, bool animate)
{ {
if (visible == !fToolBarView->IsHidden()) if (visible == !fToolBarView->IsHidden())
return; return;
float diff = fToolBarView->Bounds().Height() + 1; float diff = fToolBarView->Bounds().Height() + 2;
if (!visible) { if (!visible)
diff = -diff; diff = -diff;
fToolBarView->Hide(); else
}
fScrollView->ResizeBy(0, -diff);
fScrollView->MoveBy(0, diff);
fVerticalScrollBar->ResizeBy(0, -diff);
fVerticalScrollBar->MoveBy(0, diff);
if (visible)
fToolBarView->Show(); 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();
}
} }
+3 -1
View File
@@ -42,6 +42,7 @@ enum {
MSG_SLIDE_SHOW = 'mSSW', MSG_SLIDE_SHOW = 'mSSW',
kMsgStopSlideShow = 'msss', kMsgStopSlideShow = 'msss',
MSG_FULL_SCREEN = 'mFSC', MSG_FULL_SCREEN = 'mFSC',
kShowToolBarIfEnabled = 'mSTE',
MSG_EXIT_FULL_SCREEN = 'mEFS', MSG_EXIT_FULL_SCREEN = 'mEFS',
MSG_WINDOW_HAS_QUIT = 'wndq' MSG_WINDOW_HAS_QUIT = 'wndq'
}; };
@@ -102,7 +103,8 @@ private:
void _UpdateRatingMenu(); void _UpdateRatingMenu();
void _SetToolBarVisible(bool visible); void _SetToolBarVisible(bool visible,
bool animate = false);
private: private:
ImageFileNavigator fNavigator; ImageFileNavigator fNavigator;