From 6046b973b67a81738cbefe3c4328a9c870742eb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sat, 23 Oct 2010 19:49:20 +0000 Subject: [PATCH] * Implemented zooming to the current mouse position. Thanks to stippi for the invalidate trick to prevent the app_server to scroll. * Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39079 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/showimage/ShowImageView.cpp | 78 +++++++++++++++++--------- src/apps/showimage/ShowImageView.h | 8 +-- src/apps/showimage/ShowImageWindow.cpp | 11 ++-- 3 files changed, 63 insertions(+), 34 deletions(-) diff --git a/src/apps/showimage/ShowImageView.cpp b/src/apps/showimage/ShowImageView.cpp index a60c2252e2..3d86108a47 100644 --- a/src/apps/showimage/ShowImageView.cpp +++ b/src/apps/showimage/ShowImageView.cpp @@ -202,9 +202,9 @@ ShowImageView::ShowImageView(BRect rect, const char *name, uint32 resizingMode, fBitmapLocationInView(0.0, 0.0), - fShrinkToBounds(false), - fZoomToBounds(false), - fShrinkOrZoomToBounds(false), + fShrinkToBounds(true), + fZoomToBounds(true), + fShrinkOrZoomToBounds(true), fFullScreen(false), fScrollingBitmap(false), fCreatingSelection(false), @@ -755,9 +755,9 @@ ShowImageView::_AlignBitmap() if (width == 0 || height == 0) return rect; - fShrinkOrZoomToBounds = (fShrinkToBounds && - (bitmapWidth >= width || bitmapHeight >= height)) || - (fZoomToBounds && (bitmapWidth < width && bitmapHeight < height)); + fShrinkOrZoomToBounds = (fShrinkToBounds + && (bitmapWidth >= width || bitmapHeight >= height)) + || (fZoomToBounds && (bitmapWidth < width && bitmapHeight < height)); if (fShrinkOrZoomToBounds) { float s = width / bitmapWidth; @@ -1688,15 +1688,20 @@ ShowImageView::_MouseWheelChanged(BMessage *msg) if (msg->FindFloat("be:wheel_delta_y", &dy) == B_OK) y = dy * kscrollBy; - if (modifiers() & B_SHIFT_KEY) + if ((modifiers() & B_SHIFT_KEY) != 0) _ScrollRestrictedBy(x, y); - else if (modifiers() & B_COMMAND_KEY) + else if ((modifiers() & B_COMMAND_KEY) != 0) _ScrollRestrictedBy(y, x); else { + // Zoom in spot + BPoint where; + uint32 buttons; + GetMouse(&where, &buttons); + if (dy < 0) - ZoomIn(); + ZoomIn(where); else if (dy > 0) - ZoomOut(); + ZoomOut(where); } } @@ -1839,14 +1844,17 @@ ShowImageView::FixupScrollBar(orientation o, float bitmapLength, float viewLengt void ShowImageView::FixupScrollBars() { - BRect rctview = Bounds(), rctbitmap(0, 0, 0, 0); - if (fBitmap) { - rctbitmap = _AlignBitmap(); - rctbitmap.OffsetTo(0, 0); + BRect viewRect = Bounds(); + BRect bitmapRect; + if (fBitmap != NULL) { + bitmapRect = _AlignBitmap(); + bitmapRect.OffsetTo(0, 0); } - FixupScrollBar(B_HORIZONTAL, rctbitmap.Width() + 2 * PEN_SIZE, rctview.Width()); - FixupScrollBar(B_VERTICAL, rctbitmap.Height() + 2 * PEN_SIZE, rctview.Height()); + FixupScrollBar(B_HORIZONTAL, bitmapRect.Width() + 2 * PEN_SIZE, + viewRect.Width()); + FixupScrollBar(B_VERTICAL, bitmapRect.Height() + 2 * PEN_SIZE, + viewRect.Height()); } @@ -2288,30 +2296,47 @@ ShowImageView::_FirstFile() void -ShowImageView::SetZoom(float zoom) +ShowImageView::SetZoom(BPoint where, float zoom) { - if ((fScaleBilinear || fDither) && fZoom != zoom) { + if ((fScaleBilinear || fDither) && fZoom != zoom) _DeleteScaler(); - } - fZoom = zoom; - FixupScrollBars(); + + // Invalidate before scrolling, as that prevents the app_server + // to do the scrolling server side Invalidate(); + + // zoom to center if not otherwise specified + if (where.x == -1) + where.Set(Bounds().Width() / 2, Bounds().Height() / 2); + + BPoint offset = where - Bounds().LeftTop(); + + float oldZoom = fZoom; + fZoom = zoom; + + FixupScrollBars(); + + if (fBitmap != NULL) { + offset.x = (int)(where.x * fZoom / oldZoom + 0.5) - offset.x; + offset.y = (int)(where.y * fZoom / oldZoom + 0.5) - offset.y; + ScrollTo(offset); + } } void -ShowImageView::ZoomIn() +ShowImageView::ZoomIn(BPoint where) { if (fZoom < 16) - SetZoom(fZoom + 0.25); + SetZoom(where, fZoom + 0.25); } void -ShowImageView::ZoomOut() +ShowImageView::ZoomOut(BPoint where) { if (fZoom > 0.25) - SetZoom(fZoom - 0.25); + SetZoom(where, fZoom - 0.25); } @@ -2340,7 +2365,8 @@ ShowImageView::SetSlideShowDelay(float seconds) void ShowImageView::StartSlideShow() { - fSlideShow = true; fSlideShowCountDown = fSlideShowDelay; + fSlideShow = true; + fSlideShowCountDown = fSlideShowDelay; } diff --git a/src/apps/showimage/ShowImageView.h b/src/apps/showimage/ShowImageView.h index da80187ceb..aa3dbb2cbf 100644 --- a/src/apps/showimage/ShowImageView.h +++ b/src/apps/showimage/ShowImageView.h @@ -123,9 +123,9 @@ public: bool SlideShowStarted() const { return fSlideShow; } void StartSlideShow(); void StopSlideShow(); - void SetZoom(float zoom); - void ZoomIn(); - void ZoomOut(); + void SetZoom(BPoint where, float zoom); + void ZoomIn(BPoint where = BPoint(-1, -1)); + void ZoomOut(BPoint where = BPoint(-1, -1)); // Image manipulation void Rotate(int degree); // 90 and 270 only @@ -280,7 +280,7 @@ private: // in pulse rate units int fSlideShowCountDown; // shows next image if it reaches zero - + bool fShowCaption; BString fCaption; diff --git a/src/apps/showimage/ShowImageWindow.cpp b/src/apps/showimage/ShowImageWindow.cpp index a4f58845c1..37f92737a8 100644 --- a/src/apps/showimage/ShowImageWindow.cpp +++ b/src/apps/showimage/ShowImageWindow.cpp @@ -258,6 +258,7 @@ ShowImageWindow::BuildContextMenu(BMenu* menu) #undef B_TRANSLATE_CONTEXT #define B_TRANSLATE_CONTEXT "Menus" + void ShowImageWindow::_BuildViewMenu(BMenu* menu, bool popupMenu) { @@ -292,10 +293,12 @@ ShowImageWindow::_BuildViewMenu(BMenu* menu, bool popupMenu) menu->AddSeparatorItem(); - _AddItemMenu(menu, B_TRANSLATE("High-quality zooming"), - MSG_SCALE_BILINEAR, 0, 0, this); + if (!popupMenu) { + _AddItemMenu(menu, B_TRANSLATE("High-quality zooming"), + MSG_SCALE_BILINEAR, 0, 0, this); - menu->AddSeparatorItem(); + menu->AddSeparatorItem(); + } _AddItemMenu(menu, B_TRANSLATE("Shrink to window"), MSG_SHRINK_TO_WINDOW, 0, 0, this); @@ -886,7 +889,7 @@ ShowImageWindow::MessageReceived(BMessage* message) break; case MSG_ORIGINAL_SIZE: - fImageView->SetZoom(1.0); + fImageView->SetZoom(BPoint(-1, -1), 1.0); break; case MSG_SCALE_BILINEAR: