better visualization and more comfortable editing of the Bitmap frame

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12740 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2005-05-20 00:04:38 +00:00
parent 4dfc2afb5b
commit 746d7f54e5

View File

@ -46,6 +46,8 @@ class TestView : public BView {
private:
void _ResetRect();
void _InvalidateBitmapRect(BRect r);
void _DrawCross(BPoint where, rgb_color c);
BBitmap* fBitmap;
BRect fBitmapRect;
@ -77,7 +79,7 @@ TestView::MessageReceived(BMessage* message)
if (message->what == MSG_RESET) {
BRect old = fBitmapRect;
_ResetRect();
Invalidate(old | fBitmapRect);
_InvalidateBitmapRect(old | fBitmapRect);
} else
BView::MessageReceived(message);
}
@ -89,18 +91,70 @@ TestView::Draw(BRect updateRect)
SetDrawingMode(B_OP_COPY);
DrawBitmap(fBitmap, fBitmap->Bounds(), fBitmapRect);
// indicate the frame to see any errors in the drawing code
rgb_color red = (rgb_color){ 255, 0, 0, 255 };
_DrawCross(fBitmapRect.LeftTop() + BPoint(-1.0, -1.0), red);
_DrawCross(fBitmapRect.RightTop() + BPoint(1.0, -1.0), red);
_DrawCross(fBitmapRect.LeftBottom() + BPoint(-1.0, 1.0), red);
_DrawCross(fBitmapRect.RightBottom() + BPoint(1.0, 1.0), red);
// text
SetDrawingMode(B_OP_OVER);
SetHighColor(0, 0, 0, 255);
const char* message = "Click and drag to move the bitmap!";
DrawString(message, BPoint(20.0, 30.0));
SetDrawingMode(B_OP_ALPHA);
const char* message = "Click and drag to move and resize the bitmap!";
BPoint textPos(20.0, 30.0);
SetHighColor(255, 255, 255, 180);
DrawString(message, textPos);
SetHighColor(0, 0, 0, 180);
DrawString(message, textPos + BPoint(-1.0, -1.0));
}
bool
hit_test(BPoint where, BPoint p)
{
BRect r(p, p);
r.InsetBy(-7.0, -7.0);
return r.Contains(where);
}
bool
hit_test(BPoint where, BPoint a, BPoint b)
{
BRect r(a, b);
if (a.x == b.x)
r.InsetBy(-7.0, 0.0);
else
r.InsetBy(0.0, -7.0);
return r.Contains(where);
}
// MouseDown
void
TestView::MouseDown(BPoint where)
{
fTracking = TRACKING_ALL;
fTracking = TRACKING_NONE;
// check if we hit a corner
if (hit_test(where, fBitmapRect.LeftTop()))
fTracking = TRACKING_LEFT_TOP;
else if (hit_test(where, fBitmapRect.RightTop()))
fTracking = TRACKING_RIGHT_TOP;
else if (hit_test(where, fBitmapRect.LeftBottom()))
fTracking = TRACKING_LEFT_BOTTOM;
else if (hit_test(where, fBitmapRect.RightBottom()))
fTracking = TRACKING_RIGHT_BOTTOM;
// check if we hit a side
else if (hit_test(where, fBitmapRect.LeftTop(), fBitmapRect.RightTop()))
fTracking = TRACKING_TOP;
else if (hit_test(where, fBitmapRect.LeftTop(), fBitmapRect.LeftBottom()))
fTracking = TRACKING_LEFT;
else if (hit_test(where, fBitmapRect.RightTop(), fBitmapRect.RightBottom()))
fTracking = TRACKING_RIGHT;
else if (hit_test(where, fBitmapRect.LeftBottom(), fBitmapRect.RightBottom()))
fTracking = TRACKING_BOTTOM;
// check if we hit inside the rect
else if (fBitmapRect.Contains(where))
fTracking = TRACKING_ALL;
fLastMousePos = where;
}
@ -117,15 +171,65 @@ TestView::MouseMoved(BPoint where, uint32 transit,
const BMessage* dragMessage)
{
if (fTracking > TRACKING_NONE) {
BRect old = fBitmapRect;
BPoint offset = where - fLastMousePos;
switch (fTracking) {
case TRACKING_LEFT_TOP:
fBitmapRect.Set(fBitmapRect.left + offset.x,
fBitmapRect.top + offset.y,
fBitmapRect.right,
fBitmapRect.bottom);
break;
case TRACKING_RIGHT_BOTTOM:
fBitmapRect.Set(fBitmapRect.left,
fBitmapRect.top,
fBitmapRect.right + offset.x,
fBitmapRect.bottom + offset.y);
break;
case TRACKING_LEFT_BOTTOM:
fBitmapRect.Set(fBitmapRect.left + offset.x,
fBitmapRect.top,
fBitmapRect.right,
fBitmapRect.bottom + offset.y);
break;
case TRACKING_RIGHT_TOP:
fBitmapRect.Set(fBitmapRect.left,
fBitmapRect.top + offset.y,
fBitmapRect.right + offset.x,
fBitmapRect.bottom);
break;
case TRACKING_LEFT:
fBitmapRect.Set(fBitmapRect.left + offset.x,
fBitmapRect.top,
fBitmapRect.right,
fBitmapRect.bottom);
break;
case TRACKING_TOP:
fBitmapRect.Set(fBitmapRect.left,
fBitmapRect.top + offset.y,
fBitmapRect.right,
fBitmapRect.bottom);
break;
case TRACKING_RIGHT:
fBitmapRect.Set(fBitmapRect.left,
fBitmapRect.top,
fBitmapRect.right + offset.x,
fBitmapRect.bottom);
break;
case TRACKING_BOTTOM:
fBitmapRect.Set(fBitmapRect.left,
fBitmapRect.top,
fBitmapRect.right,
fBitmapRect.bottom + offset.y);
break;
case TRACKING_ALL:
default:
BRect old = fBitmapRect;
fBitmapRect.OffsetBy(where - fLastMousePos);
fLastMousePos = where;
Invalidate(old | fBitmapRect);
fBitmapRect.OffsetBy(offset);
break;
}
fLastMousePos = where;
if (old != fBitmapRect)
_InvalidateBitmapRect(old | fBitmapRect);
}
}
@ -138,6 +242,30 @@ TestView::_ResetRect()
floorf((Bounds().Height() - fBitmapRect.Height()) / 2.0 + 0.5));
}
// _InvalidateBitmapRect
void
TestView::_InvalidateBitmapRect(BRect r)
{
r.InsetBy(-4.0, -4.0);
Invalidate(r);
}
// _DrawCross
void
TestView::_DrawCross(BPoint where, rgb_color c)
{
BeginLineArray(4);
AddLine(BPoint(where.x, where.y - 3),
BPoint(where.x, where.y - 1), c);
AddLine(BPoint(where.x, where.y + 1),
BPoint(where.x, where.y + 3), c);
AddLine(BPoint(where.x - 3, where.y),
BPoint(where.x - 1, where.y), c);
AddLine(BPoint(where.x + 1, where.y),
BPoint(where.x + 3, where.y), c);
EndLineArray();
}
// show_window
void
show_window(BRect frame, const char* name)
@ -152,7 +280,8 @@ show_window(BRect frame, const char* name)
window->AddChild(view);
BRect b(0.0, 0.0, 60.0, 15.0);
b.OffsetTo(5.0, view->Bounds().bottom - (b.Height() + 15.0));
BButton* control = new BButton(b, "button", "Reset", new BMessage(MSG_RESET));
BButton* control = new BButton(b, "button", "Reset", new BMessage(MSG_RESET),
B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
view->AddChild(control);
control->SetTarget(view);
@ -165,7 +294,7 @@ main(int argc, char** argv)
{
BApplication* app = new BApplication("application/x.vnd-Haiku.BitmapDrawing");
BRect frame(50.0, 50.0, 300.0, 250.0);
BRect frame(50.0, 50.0, 400.0, 250.0);
show_window(frame, "Bitmap Drawing");
app->Run();