* Small cleanups.

* Do not implement backbuffering. Besides being inefficient on Haiku it solves
   the grey area on start up.
 * Reimplement scrolling and layouting the canvas. The mouse cursor is now the
   anchor when scrolling with the mouse wheel.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41180 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2011-04-04 09:37:33 +00:00
parent 59383a8c46
commit aedb8a1c34
2 changed files with 153 additions and 210 deletions
+134 -189
View File
@@ -1,11 +1,9 @@
/* /*
* Copyright 2006-2007, Haiku. * Copyright 2006-2007, 2011, Stephan Aßmus <[email protected]>
* Distributed under the terms of the MIT License. * All rights reserved. Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <[email protected]>
*/ */
#include "CanvasView.h" #include "CanvasView.h"
#include <Bitmap.h> #include <Bitmap.h>
@@ -22,48 +20,47 @@
#include "CommandStack.h" #include "CommandStack.h"
#include "IconRenderer.h" #include "IconRenderer.h"
using std::nothrow; using std::nothrow;
// constructor
CanvasView::CanvasView(BRect frame) CanvasView::CanvasView(BRect frame)
: StateView(frame, "canvas view", B_FOLLOW_ALL, :
B_WILL_DRAW | B_FRAME_EVENTS), StateView(frame, "canvas view", B_FOLLOW_ALL,
fBitmap(new BBitmap(BRect(0, 0, 63, 63), 0, B_RGB32)), B_WILL_DRAW | B_FRAME_EVENTS),
fBackground(new BBitmap(BRect(0, 0, 63, 63), 0, B_RGB32)), fBitmap(new BBitmap(BRect(0, 0, 63, 63), 0, B_RGB32)),
fIcon(NULL), fBackground(new BBitmap(BRect(0, 0, 63, 63), 0, B_RGB32)),
fRenderer(new IconRenderer(fBitmap)), fIcon(NULL),
fDirtyIconArea(fBitmap->Bounds()), fRenderer(new IconRenderer(fBitmap)),
fDirtyIconArea(fBitmap->Bounds()),
fCanvasOrigin(0.0, 0.0), fCanvasOrigin(0.0, 0.0),
fZoomLevel(1.0), fZoomLevel(8.0),
fSpaceHeldDown(false), fSpaceHeldDown(false),
fScrollTracking(false), fInScrollTo(false),
fScrollTrackingStart(0.0, 0.0), fScrollTracking(false),
fScrollTrackingStart(0.0, 0.0),
fMouseFilterMode(SNAPPING_OFF), fMouseFilterMode(SNAPPING_OFF)
fOffsreenBitmap(NULL),
fOffsreenView(NULL)
{ {
_MakeBackground(); _MakeBackground();
fRenderer->SetBackground(fBackground); fRenderer->SetBackground(fBackground);
} }
// destructor
CanvasView::~CanvasView() CanvasView::~CanvasView()
{ {
SetIcon(NULL); SetIcon(NULL);
delete fRenderer; delete fRenderer;
delete fBitmap; delete fBitmap;
delete fBackground; delete fBackground;
_FreeBackBitmap();
} }
// #pragma mark - // #pragma mark -
// AttachedToWindow
void void
CanvasView::AttachedToWindow() CanvasView::AttachedToWindow()
{ {
@@ -73,26 +70,24 @@ CanvasView::AttachedToWindow()
SetLowColor(kStripesHigh); SetLowColor(kStripesHigh);
SetHighColor(kStripesLow); SetHighColor(kStripesLow);
// init data rect for scrolling and center bitmap in the view
BRect dataRect = _LayoutCanvas();
SetDataRect(dataRect);
BRect bounds(Bounds()); BRect bounds(Bounds());
BPoint dataRectCenter((dataRect.left + dataRect.right) / 2,
_AllocBackBitmap(bounds.Width(), bounds.Height()); (dataRect.top + dataRect.bottom) / 2);
BPoint boundsCenter((bounds.left + bounds.right) / 2,
// layout icon in the center (bounds.top + bounds.bottom) / 2);
BRect bitmapBounds(fBitmap->Bounds()); BPoint offset = ScrollOffset();
fCanvasOrigin.x = floorf((bounds.left + bounds.right offset.x = roundf(offset.x + dataRectCenter.x - boundsCenter.x);
- bitmapBounds.right - bitmapBounds.left) / 2.0 + 0.5); offset.y = roundf(offset.y + dataRectCenter.y - boundsCenter.y);
fCanvasOrigin.y = floorf((bounds.top + bounds.bottom SetScrollOffset(offset);
- bitmapBounds.bottom - bitmapBounds.top) / 2.0 + 0.5);
_SetZoom(8.0, false);
} }
// FrameResized
void void
CanvasView::FrameResized(float width, float height) CanvasView::FrameResized(float width, float height)
{ {
_AllocBackBitmap(width, height);
// keep canvas centered // keep canvas centered
BPoint oldCanvasOrigin = fCanvasOrigin; BPoint oldCanvasOrigin = fCanvasOrigin;
SetDataRect(_LayoutCanvas()); SetDataRect(_LayoutCanvas());
@@ -100,58 +95,30 @@ CanvasView::FrameResized(float width, float height)
Invalidate(); Invalidate();
} }
// Draw
void void
CanvasView::Draw(BRect updateRect) CanvasView::Draw(BRect updateRect)
{ {
if (!fOffsreenView) { _DrawInto(this, updateRect);
_DrawInto(this, updateRect);
} else {
BPoint boundsLeftTop = Bounds().LeftTop();
if (fOffsreenBitmap->Lock()) {
fOffsreenView->PushState();
// apply scrolling offset to offscreen view
fOffsreenView->SetOrigin(-boundsLeftTop.x, -boundsLeftTop.y);
// mirror the clipping of this view
// to the offscreen view for performance
BRegion clipping;
GetClippingRegion(&clipping);
fOffsreenView->ConstrainClippingRegion(&clipping);
_DrawInto(fOffsreenView, updateRect);
fOffsreenView->PopState();
fOffsreenView->Sync();
fOffsreenBitmap->Unlock();
}
// compensate scrolling offset in BView
BRect bitmapRect = updateRect;
bitmapRect.OffsetBy(-boundsLeftTop.x, -boundsLeftTop.y);
SetDrawingMode(B_OP_COPY);
DrawBitmap(fOffsreenBitmap, bitmapRect, updateRect);
}
} }
// #pragma mark - // #pragma mark -
// MouseDown
void void
CanvasView::MouseDown(BPoint where) CanvasView::MouseDown(BPoint where)
{ {
if (!IsFocus()) if (!IsFocus())
MakeFocus(true); MakeFocus(true);
uint32 buttons; int32 buttons;
if (Window()->CurrentMessage()->FindInt32("buttons", if (Window()->CurrentMessage()->FindInt32("buttons", &buttons) < B_OK)
(int32*)&buttons) < B_OK)
buttons = 0; buttons = 0;
// handle clicks of the third mouse button ourselves (panning), // handle clicks of the third mouse button ourselves (panning),
// otherwise have StateView handle it (normal clicks) // otherwise have StateView handle it (normal clicks)
if (fSpaceHeldDown || buttons & B_TERTIARY_MOUSE_BUTTON) { if (fSpaceHeldDown || (buttons & B_TERTIARY_MOUSE_BUTTON) != 0) {
// switch into scrolling mode and update cursor // switch into scrolling mode and update cursor
fScrollTracking = true; fScrollTracking = true;
where.x = roundf(where.x); where.x = roundf(where.x);
@@ -160,13 +127,13 @@ CanvasView::MouseDown(BPoint where)
fScrollTrackingStart = where - fScrollOffsetStart; fScrollTrackingStart = where - fScrollOffsetStart;
_UpdateToolCursor(); _UpdateToolCursor();
SetMouseEventMask(B_POINTER_EVENTS, SetMouseEventMask(B_POINTER_EVENTS,
B_LOCK_WINDOW_FOCUS | B_SUSPEND_VIEW_FOCUS); B_LOCK_WINDOW_FOCUS | B_SUSPEND_VIEW_FOCUS);
} else { } else {
StateView::MouseDown(where); StateView::MouseDown(where);
} }
} }
// MouseUp
void void
CanvasView::MouseUp(BPoint where) CanvasView::MouseUp(BPoint where)
{ {
@@ -183,7 +150,7 @@ CanvasView::MouseUp(BPoint where)
} }
} }
// MouseMoved
void void
CanvasView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage) CanvasView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage)
{ {
@@ -206,7 +173,7 @@ CanvasView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage
} }
} }
// FilterMouse
void void
CanvasView::FilterMouse(BPoint* where) const CanvasView::FilterMouse(BPoint* where) const
{ {
@@ -247,7 +214,7 @@ CanvasView::FilterMouse(BPoint* where) const
} }
} }
// MouseWheelChanged
bool bool
CanvasView::MouseWheelChanged(BPoint where, float x, float y) CanvasView::MouseWheelChanged(BPoint where, float x, float y)
{ {
@@ -255,43 +222,66 @@ CanvasView::MouseWheelChanged(BPoint where, float x, float y)
return false; return false;
if (y > 0.0) { if (y > 0.0) {
_SetZoom(_NextZoomOutLevel(fZoomLevel)); _SetZoom(_NextZoomOutLevel(fZoomLevel), true);
return true; return true;
} else if (y < 0.0) { } else if (y < 0.0) {
_SetZoom(_NextZoomInLevel(fZoomLevel)); _SetZoom(_NextZoomInLevel(fZoomLevel), true);
return true; return true;
} }
return false; return false;
} }
// #pragma mark - // #pragma mark -
// ScrollOffsetChanged
void
CanvasView::SetScrollOffset(BPoint newOffset)
{
if (fInScrollTo)
return;
fInScrollTo = true;
newOffset = ValidScrollOffsetFor(newOffset);
if (!fScrollTracking) {
BPoint mouseOffset = newOffset - ScrollOffset();
MouseMoved(fMouseInfo.position + mouseOffset, fMouseInfo.transit,
NULL);
}
Scrollable::SetScrollOffset(newOffset);
fInScrollTo = false;
}
void void
CanvasView::ScrollOffsetChanged(BPoint oldOffset, BPoint newOffset) CanvasView::ScrollOffsetChanged(BPoint oldOffset, BPoint newOffset)
{ {
BPoint offset = newOffset - oldOffset; BPoint offset = newOffset - oldOffset;
if (offset == B_ORIGIN) if (offset == B_ORIGIN) {
// prevent circular code (MouseMoved might call ScrollBy...) // prevent circular code (MouseMoved might call ScrollBy...)
return; return;
}
ScrollBy(offset.x, offset.y); ScrollBy(offset.x, offset.y);
if (!fScrollTracking)
MouseMoved(fMouseInfo.position + offset, fMouseInfo.transit, NULL);
} }
// VisibleSizeChanged
void void
CanvasView::VisibleSizeChanged(float oldWidth, float oldHeight, CanvasView::VisibleSizeChanged(float oldWidth, float oldHeight, float newWidth,
float newWidth, float newHeight) float newHeight)
{ {
BRect dataRect(_LayoutCanvas());
SetDataRect(dataRect);
} }
// #pragma mark - // #pragma mark -
// AreaInvalidated
void void
CanvasView::AreaInvalidated(const BRect& area) CanvasView::AreaInvalidated(const BRect& area)
{ {
@@ -308,7 +298,7 @@ CanvasView::AreaInvalidated(const BRect& area)
// #pragma mark - // #pragma mark -
// SetIcon
void void
CanvasView::SetIcon(Icon* icon) CanvasView::SetIcon(Icon* icon)
{ {
@@ -325,7 +315,7 @@ CanvasView::SetIcon(Icon* icon)
fIcon->AddListener(this); fIcon->AddListener(this);
} }
// SetMouseFilterMode
void void
CanvasView::SetMouseFilterMode(uint32 mode) CanvasView::SetMouseFilterMode(uint32 mode)
{ {
@@ -336,7 +326,7 @@ CanvasView::SetMouseFilterMode(uint32 mode)
Invalidate(_CanvasRect()); Invalidate(_CanvasRect());
} }
// ConvertFromCanvas
void void
CanvasView::ConvertFromCanvas(BPoint* point) const CanvasView::ConvertFromCanvas(BPoint* point) const
{ {
@@ -344,7 +334,7 @@ CanvasView::ConvertFromCanvas(BPoint* point) const
point->y = point->y * fZoomLevel + fCanvasOrigin.y; point->y = point->y * fZoomLevel + fCanvasOrigin.y;
} }
// ConvertToCanvas
void void
CanvasView::ConvertToCanvas(BPoint* point) const CanvasView::ConvertToCanvas(BPoint* point) const
{ {
@@ -352,7 +342,7 @@ CanvasView::ConvertToCanvas(BPoint* point) const
point->y = (point->y - fCanvasOrigin.y) / fZoomLevel; point->y = (point->y - fCanvasOrigin.y) / fZoomLevel;
} }
// ConvertFromCanvas
void void
CanvasView::ConvertFromCanvas(BRect* r) const CanvasView::ConvertFromCanvas(BRect* r) const
{ {
@@ -366,7 +356,7 @@ CanvasView::ConvertFromCanvas(BRect* r) const
r->bottom--; r->bottom--;
} }
// ConvertToCanvas
void void
CanvasView::ConvertToCanvas(BRect* r) const CanvasView::ConvertToCanvas(BRect* r) const
{ {
@@ -376,9 +366,10 @@ CanvasView::ConvertToCanvas(BRect* r) const
r->bottom = (r->bottom - fCanvasOrigin.y) / fZoomLevel; r->bottom = (r->bottom - fCanvasOrigin.y) / fZoomLevel;
} }
// #pragma mark - // #pragma mark -
// _HandleKeyDown
bool bool
CanvasView::_HandleKeyDown(uint32 key, uint32 modifiers) CanvasView::_HandleKeyDown(uint32 key, uint32 modifiers)
{ {
@@ -410,7 +401,7 @@ CanvasView::_HandleKeyDown(uint32 key, uint32 modifiers)
return true; return true;
} }
// _HandleKeyUp
bool bool
CanvasView::_HandleKeyUp(uint32 key, uint32 modifiers) CanvasView::_HandleKeyUp(uint32 key, uint32 modifiers)
{ {
@@ -427,66 +418,19 @@ CanvasView::_HandleKeyUp(uint32 key, uint32 modifiers)
return true; return true;
} }
// _CanvasRect()
BRect BRect
CanvasView::_CanvasRect() const CanvasView::_CanvasRect() const
{ {
BRect r = fBitmap->Bounds(); BRect r;
if (fBitmap == NULL)
return r;
r = fBitmap->Bounds();
ConvertFromCanvas(&r); ConvertFromCanvas(&r);
return r; return r;
} }
// _AllocBackBitmap
void
CanvasView::_AllocBackBitmap(float width, float height)
{
// sanity check
if (width <= 0.0 || height <= 0.0)
return;
if (fOffsreenBitmap) {
// see if the bitmap needs to be expanded
BRect b = fOffsreenBitmap->Bounds();
if (b.Width() >= width && b.Height() >= height)
return;
// it does; clean up:
_FreeBackBitmap();
}
BRect b(0.0, 0.0, width, height);
fOffsreenBitmap = new (nothrow) BBitmap(b, B_RGB32, true);
if (!fOffsreenBitmap) {
fprintf(stderr, "CanvasView::_AllocBackBitmap(): failed to allocate\n");
return;
}
if (fOffsreenBitmap->IsValid()) {
fOffsreenView = new BView(b, 0, B_FOLLOW_NONE, B_WILL_DRAW);
BFont font;
GetFont(&font);
fOffsreenView->SetFont(&font);
fOffsreenView->SetHighColor(HighColor());
fOffsreenView->SetLowColor(LowColor());
fOffsreenView->SetFlags(Flags());
fOffsreenBitmap->AddChild(fOffsreenView);
} else {
_FreeBackBitmap();
fprintf(stderr, "CanvasView::_AllocBackBitmap(): bitmap invalid\n");
}
}
// _FreeBackBitmap
void
CanvasView::_FreeBackBitmap()
{
if (fOffsreenBitmap) {
delete fOffsreenBitmap;
fOffsreenBitmap = NULL;
fOffsreenView = NULL;
}
}
// _DrawInto
void void
CanvasView::_DrawInto(BView* view, BRect updateRect) CanvasView::_DrawInto(BView* view, BRect updateRect)
{ {
@@ -537,7 +481,7 @@ CanvasView::_DrawInto(BView* view, BRect updateRect)
StateView::Draw(view, updateRect); StateView::Draw(view, updateRect);
} }
// _MakeBackground
void void
CanvasView::_MakeBackground() CanvasView::_MakeBackground()
{ {
@@ -585,7 +529,7 @@ CanvasView::_MakeBackground()
} }
} }
// _UpdateToolCursor
void void
CanvasView::_UpdateToolCursor() CanvasView::_UpdateToolCursor()
{ {
@@ -605,9 +549,10 @@ CanvasView::_UpdateToolCursor()
} }
} }
// #pragma mark - // #pragma mark -
// _NextZoomInLevel
double double
CanvasView::_NextZoomInLevel(double zoom) const CanvasView::_NextZoomInLevel(double zoom) const
{ {
@@ -632,7 +577,7 @@ CanvasView::_NextZoomInLevel(double zoom) const
return 64; return 64;
} }
// _NextZoomOutLevel
double double
CanvasView::_NextZoomOutLevel(double zoom) const CanvasView::_NextZoomOutLevel(double zoom) const
{ {
@@ -655,69 +600,69 @@ CanvasView::_NextZoomOutLevel(double zoom) const
return 1; return 1;
} }
// _SetZoom
void void
CanvasView::_SetZoom(double zoomLevel, bool mouseIsAnchor) CanvasView::_SetZoom(double zoomLevel, bool mouseIsAnchor)
{ {
if (fZoomLevel == zoomLevel) if (fZoomLevel == zoomLevel)
return; return;
// TODO: still not working 100% correctly
// zoom into center of view
BRect bounds(Bounds());
BPoint anchor; BPoint anchor;
anchor.x = (bounds.left + bounds.right + 1) / 2.0; if (mouseIsAnchor) {
anchor.y = (bounds.top + bounds.bottom + 1) / 2.0; // zoom into mouse position
anchor = MouseInfo()->position;
} else {
// zoom into center of view
BRect bounds(Bounds());
anchor.x = (bounds.left + bounds.right + 1) / 2.0;
anchor.y = (bounds.top + bounds.bottom + 1) / 2.0;
}
BPoint canvasAnchor = anchor; BPoint canvasAnchor = anchor;
ConvertToCanvas(&canvasAnchor); ConvertToCanvas(&canvasAnchor);
fZoomLevel = zoomLevel; fZoomLevel = zoomLevel;
SetDataRect(_LayoutCanvas()); BRect dataRect = _LayoutCanvas();
ConvertFromCanvas(&canvasAnchor); ConvertFromCanvas(&canvasAnchor);
BPoint offset; BPoint offset = ScrollOffset();
offset.x = roundf(canvasAnchor.x - anchor.x); offset.x = roundf(offset.x + canvasAnchor.x - anchor.x);
offset.y = roundf(canvasAnchor.y - anchor.y); offset.y = roundf(offset.y + canvasAnchor.y - anchor.y);
SetScrollOffset(ScrollOffset() + offset);
Invalidate(); Invalidate();
SetDataRectAndScrollOffset(dataRect, offset);
} }
// _LayoutCanvas
BRect BRect
CanvasView::_LayoutCanvas() CanvasView::_LayoutCanvas()
{ {
if (!fBitmap)
return BRect(0, 0, -1, -1);
// size of zoomed bitmap // size of zoomed bitmap
BRect r(fBitmap->Bounds()); BRect r(_CanvasRect());
r.OffsetTo(0, 0); r.OffsetTo(B_ORIGIN);
r.right = floorf((r.Width() + 1) * fZoomLevel + 0.5) - 1;
r.bottom = floorf((r.Height() + 1) * fZoomLevel + 0.5) - 1;
// TODO: ask manipulators to extend size // ask current view state to extend size
// TODO: Ask StateViewState to extend bounds...
BRect bitmapRect = r; BRect stateBounds = r; //ViewStateBounds();
// resize for empty area around bitmap // resize for empty area around bitmap
// (the size we want, but might still be much smaller than view) // (the size we want, but might still be much smaller than view)
r.right += r.Width() * 0.5; r.InsetBy(-50, -50);
r.bottom += r.Height() * 0.5;
// left top of canvas within empty area // center data rect in bounds
BRect bounds(Bounds()); BRect bounds(Bounds());
bounds.OffsetTo(B_ORIGIN); if (bounds.Width() > r.Width())
bounds = bounds | r; r.InsetBy(-ceilf((bounds.Width() - r.Width()) / 2), 0);
fCanvasOrigin.x = floorf((bounds.left + bounds.right if (bounds.Height() > r.Height())
- bitmapRect.right - bitmapRect.left) / 2.0 + 0.5); r.InsetBy(0, -ceilf((bounds.Height() - r.Height()) / 2));
fCanvasOrigin.y = floorf((bounds.top + bounds.bottom
- bitmapRect.bottom - bitmapRect.top) / 2.0 + 0.5);
return bounds; if (stateBounds.IsValid()) {
stateBounds.InsetBy(-20, -20);
r = r | stateBounds;
}
return r;
} }
+19 -21
View File
@@ -1,9 +1,6 @@
/* /*
* Copyright 2006-2007, Haiku. * Copyright 2006-2007, 2011, Stephan Aßmus <[email protected]>
* Distributed under the terms of the MIT License. * All rights reserved. Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <[email protected]>
*/ */
#ifndef CANVAS_VIEW_H #ifndef CANVAS_VIEW_H
#define CANVAS_VIEW_H #define CANVAS_VIEW_H
@@ -30,10 +27,9 @@ enum {
SNAPPING_16, SNAPPING_16,
}; };
class CanvasView : public StateView,
public Scrollable, class CanvasView : public StateView, public Scrollable, public IconListener {
public IconListener { public:
public:
CanvasView(BRect frame); CanvasView(BRect frame);
virtual ~CanvasView(); virtual ~CanvasView();
@@ -45,22 +41,22 @@ class CanvasView : public StateView,
virtual void MouseDown(BPoint where); virtual void MouseDown(BPoint where);
virtual void MouseUp(BPoint where); virtual void MouseUp(BPoint where);
virtual void MouseMoved(BPoint where, uint32 transit, virtual void MouseMoved(BPoint where, uint32 transit,
const BMessage* dragMessage); const BMessage* dragMessage);
virtual void FilterMouse(BPoint* where) const; virtual void FilterMouse(BPoint* where) const;
virtual bool MouseWheelChanged(BPoint where, virtual bool MouseWheelChanged(BPoint where,
float x, float y); float x, float y);
// Scrollable interface // Scrollable interface
protected: protected:
virtual void SetScrollOffset(BPoint newOffset);
virtual void ScrollOffsetChanged(BPoint oldOffset, virtual void ScrollOffsetChanged(BPoint oldOffset,
BPoint newOffset); BPoint newOffset);
virtual void VisibleSizeChanged(float oldWidth, virtual void VisibleSizeChanged(float oldWidth,
float oldHeight, float oldHeight, float newWidth,
float newWidth, float newHeight);
float newHeight);
// IconListener interface // IconListener interface
public: public:
virtual void AreaInvalidated(const BRect& area); virtual void AreaInvalidated(const BRect& area);
// CanvasView // CanvasView
@@ -79,7 +75,7 @@ class CanvasView : public StateView,
void ConvertFromCanvas(BRect* rect) const; void ConvertFromCanvas(BRect* rect) const;
void ConvertToCanvas(BRect* rect) const; void ConvertToCanvas(BRect* rect) const;
protected: protected:
// StateView interface // StateView interface
virtual bool _HandleKeyDown(uint32 key, uint32 modifiers); virtual bool _HandleKeyDown(uint32 key, uint32 modifiers);
virtual bool _HandleKeyUp(uint32 key, uint32 modifiers); virtual bool _HandleKeyUp(uint32 key, uint32 modifiers);
@@ -91,19 +87,20 @@ class CanvasView : public StateView,
float height); float height);
void _FreeBackBitmap(); void _FreeBackBitmap();
void _DrawInto(BView* view, void _DrawInto(BView* view,
BRect updateRect); BRect updateRect);
void _MakeBackground(); void _MakeBackground();
void _UpdateToolCursor(); void _UpdateToolCursor();
private: private:
double _NextZoomInLevel(double zoom) const; double _NextZoomInLevel(double zoom) const;
double _NextZoomOutLevel(double zoom) const; double _NextZoomOutLevel(double zoom) const;
void _SetZoom(double zoomLevel, void _SetZoom(double zoomLevel,
bool mouseIsAnchor = true); bool mouseIsAnchor = true);
BRect _LayoutCanvas(); BRect _LayoutCanvas();
private:
BBitmap* fBitmap; BBitmap* fBitmap;
BBitmap* fBackground; BBitmap* fBackground;
@@ -115,6 +112,7 @@ class CanvasView : public StateView,
double fZoomLevel; double fZoomLevel;
bool fSpaceHeldDown; bool fSpaceHeldDown;
bool fInScrollTo;
bool fScrollTracking; bool fScrollTracking;
BPoint fScrollTrackingStart; BPoint fScrollTrackingStart;
BPoint fScrollOffsetStart; BPoint fScrollOffsetStart;