* 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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user