* 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
This commit is contained in:
Axel Dörfler 2010-10-23 19:49:20 +00:00
parent fb5adc1f7b
commit 6046b973b6
3 changed files with 63 additions and 34 deletions

View File

@ -202,9 +202,9 @@ ShowImageView::ShowImageView(BRect rect, const char *name, uint32 resizingMode,
fBitmapLocationInView(0.0, 0.0), fBitmapLocationInView(0.0, 0.0),
fShrinkToBounds(false), fShrinkToBounds(true),
fZoomToBounds(false), fZoomToBounds(true),
fShrinkOrZoomToBounds(false), fShrinkOrZoomToBounds(true),
fFullScreen(false), fFullScreen(false),
fScrollingBitmap(false), fScrollingBitmap(false),
fCreatingSelection(false), fCreatingSelection(false),
@ -755,9 +755,9 @@ ShowImageView::_AlignBitmap()
if (width == 0 || height == 0) if (width == 0 || height == 0)
return rect; return rect;
fShrinkOrZoomToBounds = (fShrinkToBounds && fShrinkOrZoomToBounds = (fShrinkToBounds
(bitmapWidth >= width || bitmapHeight >= height)) || && (bitmapWidth >= width || bitmapHeight >= height))
(fZoomToBounds && (bitmapWidth < width && bitmapHeight < height)); || (fZoomToBounds && (bitmapWidth < width && bitmapHeight < height));
if (fShrinkOrZoomToBounds) { if (fShrinkOrZoomToBounds) {
float s = width / bitmapWidth; float s = width / bitmapWidth;
@ -1688,15 +1688,20 @@ ShowImageView::_MouseWheelChanged(BMessage *msg)
if (msg->FindFloat("be:wheel_delta_y", &dy) == B_OK) if (msg->FindFloat("be:wheel_delta_y", &dy) == B_OK)
y = dy * kscrollBy; y = dy * kscrollBy;
if (modifiers() & B_SHIFT_KEY) if ((modifiers() & B_SHIFT_KEY) != 0)
_ScrollRestrictedBy(x, y); _ScrollRestrictedBy(x, y);
else if (modifiers() & B_COMMAND_KEY) else if ((modifiers() & B_COMMAND_KEY) != 0)
_ScrollRestrictedBy(y, x); _ScrollRestrictedBy(y, x);
else { else {
// Zoom in spot
BPoint where;
uint32 buttons;
GetMouse(&where, &buttons);
if (dy < 0) if (dy < 0)
ZoomIn(); ZoomIn(where);
else if (dy > 0) else if (dy > 0)
ZoomOut(); ZoomOut(where);
} }
} }
@ -1839,14 +1844,17 @@ ShowImageView::FixupScrollBar(orientation o, float bitmapLength, float viewLengt
void void
ShowImageView::FixupScrollBars() ShowImageView::FixupScrollBars()
{ {
BRect rctview = Bounds(), rctbitmap(0, 0, 0, 0); BRect viewRect = Bounds();
if (fBitmap) { BRect bitmapRect;
rctbitmap = _AlignBitmap(); if (fBitmap != NULL) {
rctbitmap.OffsetTo(0, 0); bitmapRect = _AlignBitmap();
bitmapRect.OffsetTo(0, 0);
} }
FixupScrollBar(B_HORIZONTAL, rctbitmap.Width() + 2 * PEN_SIZE, rctview.Width()); FixupScrollBar(B_HORIZONTAL, bitmapRect.Width() + 2 * PEN_SIZE,
FixupScrollBar(B_VERTICAL, rctbitmap.Height() + 2 * PEN_SIZE, rctview.Height()); viewRect.Width());
FixupScrollBar(B_VERTICAL, bitmapRect.Height() + 2 * PEN_SIZE,
viewRect.Height());
} }
@ -2288,30 +2296,47 @@ ShowImageView::_FirstFile()
void void
ShowImageView::SetZoom(float zoom) ShowImageView::SetZoom(BPoint where, float zoom)
{ {
if ((fScaleBilinear || fDither) && fZoom != zoom) { if ((fScaleBilinear || fDither) && fZoom != zoom)
_DeleteScaler(); _DeleteScaler();
}
fZoom = zoom; // Invalidate before scrolling, as that prevents the app_server
FixupScrollBars(); // to do the scrolling server side
Invalidate(); 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 void
ShowImageView::ZoomIn() ShowImageView::ZoomIn(BPoint where)
{ {
if (fZoom < 16) if (fZoom < 16)
SetZoom(fZoom + 0.25); SetZoom(where, fZoom + 0.25);
} }
void void
ShowImageView::ZoomOut() ShowImageView::ZoomOut(BPoint where)
{ {
if (fZoom > 0.25) if (fZoom > 0.25)
SetZoom(fZoom - 0.25); SetZoom(where, fZoom - 0.25);
} }
@ -2340,7 +2365,8 @@ ShowImageView::SetSlideShowDelay(float seconds)
void void
ShowImageView::StartSlideShow() ShowImageView::StartSlideShow()
{ {
fSlideShow = true; fSlideShowCountDown = fSlideShowDelay; fSlideShow = true;
fSlideShowCountDown = fSlideShowDelay;
} }

View File

@ -123,9 +123,9 @@ public:
bool SlideShowStarted() const { return fSlideShow; } bool SlideShowStarted() const { return fSlideShow; }
void StartSlideShow(); void StartSlideShow();
void StopSlideShow(); void StopSlideShow();
void SetZoom(float zoom); void SetZoom(BPoint where, float zoom);
void ZoomIn(); void ZoomIn(BPoint where = BPoint(-1, -1));
void ZoomOut(); void ZoomOut(BPoint where = BPoint(-1, -1));
// Image manipulation // Image manipulation
void Rotate(int degree); // 90 and 270 only void Rotate(int degree); // 90 and 270 only
@ -280,7 +280,7 @@ private:
// in pulse rate units // in pulse rate units
int fSlideShowCountDown; int fSlideShowCountDown;
// shows next image if it reaches zero // shows next image if it reaches zero
bool fShowCaption; bool fShowCaption;
BString fCaption; BString fCaption;

View File

@ -258,6 +258,7 @@ ShowImageWindow::BuildContextMenu(BMenu* menu)
#undef B_TRANSLATE_CONTEXT #undef B_TRANSLATE_CONTEXT
#define B_TRANSLATE_CONTEXT "Menus" #define B_TRANSLATE_CONTEXT "Menus"
void void
ShowImageWindow::_BuildViewMenu(BMenu* menu, bool popupMenu) ShowImageWindow::_BuildViewMenu(BMenu* menu, bool popupMenu)
{ {
@ -292,10 +293,12 @@ ShowImageWindow::_BuildViewMenu(BMenu* menu, bool popupMenu)
menu->AddSeparatorItem(); menu->AddSeparatorItem();
_AddItemMenu(menu, B_TRANSLATE("High-quality zooming"), if (!popupMenu) {
MSG_SCALE_BILINEAR, 0, 0, this); _AddItemMenu(menu, B_TRANSLATE("High-quality zooming"),
MSG_SCALE_BILINEAR, 0, 0, this);
menu->AddSeparatorItem(); menu->AddSeparatorItem();
}
_AddItemMenu(menu, B_TRANSLATE("Shrink to window"), _AddItemMenu(menu, B_TRANSLATE("Shrink to window"),
MSG_SHRINK_TO_WINDOW, 0, 0, this); MSG_SHRINK_TO_WINDOW, 0, 0, this);
@ -886,7 +889,7 @@ ShowImageWindow::MessageReceived(BMessage* message)
break; break;
case MSG_ORIGINAL_SIZE: case MSG_ORIGINAL_SIZE:
fImageView->SetZoom(1.0); fImageView->SetZoom(BPoint(-1, -1), 1.0);
break; break;
case MSG_SCALE_BILINEAR: case MSG_SCALE_BILINEAR: