From e067fed541577ea0af16e0c4d954a660be74190f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Mon, 2 Jan 2006 01:03:31 +0000 Subject: [PATCH] Decorator::ResizeBy tells you the dirty region, DefaultDecorator::Draw() pays attention to the update rect, small clean ups along the way git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15778 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/servers/app/Decorator.h | 6 +- src/servers/app/Decorator.cpp | 35 ++-- src/servers/app/DefaultDecorator.cpp | 218 ++++++++++++++++-------- src/servers/app/DefaultDecorator.h | 4 +- src/servers/app/WindowLayer.cpp | 26 +-- 5 files changed, 171 insertions(+), 118 deletions(-) diff --git a/headers/private/servers/app/Decorator.h b/headers/private/servers/app/Decorator.h index 5d6079b0b8..0f8c0c3ec3 100644 --- a/headers/private/servers/app/Decorator.h +++ b/headers/private/servers/app/Decorator.h @@ -94,10 +94,10 @@ class Decorator { virtual click_type Clicked(BPoint pt, int32 buttons, int32 modifiers); - virtual void MoveBy(float x, float y); + void MoveBy(float x, float y); virtual void MoveBy(BPoint pt); - virtual void ResizeBy(float x, float y); - virtual void ResizeBy(BPoint pt); + void ResizeBy(float x, float y, BRegion* dirty); + virtual void ResizeBy(BPoint pt, BRegion* dirty) = 0; virtual void SetTabLocation(float location) {} virtual float TabLocation() const diff --git a/src/servers/app/Decorator.cpp b/src/servers/app/Decorator.cpp index 6114dae188..d514df6793 100644 --- a/src/servers/app/Decorator.cpp +++ b/src/servers/app/Decorator.cpp @@ -374,14 +374,7 @@ Decorator::Clicked(BPoint pt, int32 buttons, int32 modifiers) void Decorator::MoveBy(float x, float y) { - _zoomrect.OffsetBy(x, y); - _closerect.OffsetBy(x, y); - _minimizerect.OffsetBy(x, y); - _minimizerect.OffsetBy(x, y); - _tabrect.OffsetBy(x, y); - _frame.OffsetBy(x, y); - _resizerect.OffsetBy(x, y); - _borderrect.OffsetBy(x, y); + MoveBy(BPoint(x, y)); } /*! @@ -395,7 +388,14 @@ Decorator::MoveBy(float x, float y) void Decorator::MoveBy(BPoint pt) { - MoveBy(pt.x, pt.y); + _zoomrect.OffsetBy(pt); + _closerect.OffsetBy(pt); + _minimizerect.OffsetBy(pt); + _minimizerect.OffsetBy(pt); + _tabrect.OffsetBy(pt); + _frame.OffsetBy(pt); + _resizerect.OffsetBy(pt); + _borderrect.OffsetBy(pt); } /*! @@ -409,22 +409,9 @@ Decorator::MoveBy(BPoint pt) are not inverted. */ void -Decorator::ResizeBy(float x, float y) -{ -} - -/*! - \brief Resizes the decorator frame - \param pt Point containing the offsets - - This is a required function for subclasses to implement - the default does nothing. - Note that window resize flags should be followed and _frame should be resized - accordingly. It would also be a wise idea to ensure that the window's rectangles - are not inverted. -*/ -void -Decorator::ResizeBy(BPoint pt) +Decorator::ResizeBy(float x, float y, BRegion* dirty) { + ResizeBy(BPoint(x, y), dirty); } /*! diff --git a/src/servers/app/DefaultDecorator.cpp b/src/servers/app/DefaultDecorator.cpp index 87e6fc728a..5b5759db2c 100644 --- a/src/servers/app/DefaultDecorator.cpp +++ b/src/servers/app/DefaultDecorator.cpp @@ -25,8 +25,6 @@ #include -//#define USE_VIEW_FILL_HACK - //#define DEBUG_DECORATOR #ifdef DEBUG_DECORATOR # include @@ -156,13 +154,6 @@ DefaultDecorator::SetFlags(uint32 flags, BRegion* updateRegion) } -void -DefaultDecorator::MoveBy(float x, float y) -{ - MoveBy(BPoint(x, y)); -} - - void DefaultDecorator::MoveBy(BPoint pt) { @@ -181,21 +172,53 @@ DefaultDecorator::MoveBy(BPoint pt) fBottomBorder.OffsetBy(pt); } -void -DefaultDecorator::ResizeBy(float x, float y) -{ - ResizeBy(BPoint(x, y)); -} void -DefaultDecorator::ResizeBy(BPoint pt) +DefaultDecorator::ResizeBy(BPoint pt, BRegion* dirty) { STRACE(("DefaultDecorator: Resize By (%.1f, %.1f)\n", pt.x, pt.y)); // Move all internal rectangles the appropriate amount _frame.right += pt.x; _frame.bottom += pt.y; + // handle invalidation of resize rect + if (dirty && !(fFlags & B_NOT_RESIZABLE)) { + BRect realResizeRect; + switch (fLook) { + case B_DOCUMENT_WINDOW_LOOK: + realResizeRect = _resizerect; + // resize rect at old location + dirty->Include(realResizeRect); + realResizeRect.OffsetBy(pt); + // resize rect at new location + dirty->Include(realResizeRect); + break; + case B_TITLED_WINDOW_LOOK: + case B_FLOATING_WINDOW_LOOK: + case B_MODAL_WINDOW_LOOK: + realResizeRect.Set(fRightBorder.right - 22, fBottomBorder.top, + fRightBorder.right - 22, fBottomBorder.bottom - 1); + // resize rect at old location + dirty->Include(realResizeRect); + realResizeRect.OffsetBy(pt); + // resize rect at new location + dirty->Include(realResizeRect); + + realResizeRect.Set(fRightBorder.left, fBottomBorder.bottom - 22, + fRightBorder.right - 1, fBottomBorder.bottom - 22); + // resize rect at old location + dirty->Include(realResizeRect); + realResizeRect.OffsetBy(pt); + // resize rect at new location + dirty->Include(realResizeRect); + break; + default: + break; + } + } + _resizerect.OffsetBy(pt); + _borderrect.right += pt.x; _borderrect.bottom += pt.y; @@ -208,6 +231,32 @@ DefaultDecorator::ResizeBy(BPoint pt) fBottomBorder.OffsetBy(0.0, pt.y); fBottomBorder.right += pt.x; + if (dirty) { + if (pt.x > 0.0) { + BRect t(fRightBorder.left - pt.x, fTopBorder.top, + fRightBorder.right, fTopBorder.bottom); + dirty->Include(t); + t.Set(fRightBorder.left - pt.x, fBottomBorder.top, + fRightBorder.right, fBottomBorder.bottom); + dirty->Include(t); + dirty->Include(fRightBorder); + } else if (pt.x < 0.0) { + dirty->Include(BRect(fRightBorder.left, fTopBorder.top, + fRightBorder.right, fBottomBorder.bottom)); + } + if (pt.y > 0.0) { + BRect t(fLeftBorder.left, fLeftBorder.bottom - pt.y, + fLeftBorder.right, fLeftBorder.bottom); + dirty->Include(t); + t.Set(fRightBorder.left, fRightBorder.bottom - pt.y, + fRightBorder.right, fRightBorder.bottom); + dirty->Include(t); + dirty->Include(fBottomBorder); + } else if (pt.y < 0.0) { + dirty->Include(fBottomBorder); + } + } + // resize tab and layout tab items if (_tabrect.IsValid()) { float tabWidth = fRightBorder.right - fLeftBorder.left; @@ -218,8 +267,15 @@ DefaultDecorator::ResizeBy(BPoint pt) tabWidth = fMaxTabWidth; if (tabWidth != _tabrect.Width()) { + // NOTE: the tab rect becoming smaller is handled + // by the Desktop anyways, so it is sufficient + // to include it into the dirty region in it's + // final state only once at the end _tabrect.right = _tabrect.left + tabWidth; _LayoutTabItems(_tabrect); + + if (dirty) + dirty->Include(_tabrect); } } } @@ -476,10 +532,8 @@ DefaultDecorator::_DrawFrame(BRect invalid) STRACE(("_DrawFrame(%f,%f,%f,%f)\n", invalid.left, invalid.top, invalid.right, invalid.bottom)); - #ifdef USE_VIEW_FILL_HACK - fDrawState.SetHighColor(RGBColor(192, 192, 192 )); - _driver->FillRect(_frame, fDrawState.HighColor()); - #endif + // NOTE: the DrawingEngine needs to be locked for the entire + // time for the clipping to stay valid for this decorator if (fLook == B_NO_BORDER_WINDOW_LOOK) return; @@ -494,58 +548,73 @@ STRACE(("_DrawFrame(%f,%f,%f,%f)\n", invalid.left, invalid.top, case B_DOCUMENT_WINDOW_LOOK: case B_MODAL_WINDOW_LOOK: { //top - for (int8 i = 0; i < 5; i++) { - _driver->StrokeLine(BPoint(r.left + i, r.top + i), - BPoint(r.right - i, r.top + i), - fFrameColors[i]); + if (invalid.Intersects(fTopBorder)) { + for (int8 i = 0; i < 5; i++) { + _driver->StrokeLine(BPoint(r.left + i, r.top + i), + BPoint(r.right - i, r.top + i), + fFrameColors[i]); + } } //left - for (int8 i = 0; i < 5; i++) { - _driver->StrokeLine(BPoint(r.left + i, r.top + i), - BPoint(r.left + i, r.bottom - i), - fFrameColors[i]); + if (invalid.Intersects(fLeftBorder)) { + for (int8 i = 0; i < 5; i++) { + _driver->StrokeLine(BPoint(r.left + i, r.top + i), + BPoint(r.left + i, r.bottom - i), + fFrameColors[i]); + } } //bottom - for (int8 i = 0; i < 5; i++) { - _driver->StrokeLine(BPoint(r.left + i, r.bottom - i), - BPoint(r.right - i, r.bottom - i), - fFrameColors[(4 - i) == 4 ? 5 : (4 - i)]); + if (invalid.Intersects(fBottomBorder)) { + for (int8 i = 0; i < 5; i++) { + _driver->StrokeLine(BPoint(r.left + i, r.bottom - i), + BPoint(r.right - i, r.bottom - i), + fFrameColors[(4 - i) == 4 ? 5 : (4 - i)]); + } } //right - for (int8 i = 0; i < 5; i++) { - _driver->StrokeLine(BPoint(r.right - i, r.top + i), - BPoint(r.right - i, r.bottom - i), - fFrameColors[(4 - i) == 4 ? 5 : (4 - i)]); + if (invalid.Intersects(fRightBorder)) { + for (int8 i = 0; i < 5; i++) { + _driver->StrokeLine(BPoint(r.right - i, r.top + i), + BPoint(r.right - i, r.bottom - i), + fFrameColors[(4 - i) == 4 ? 5 : (4 - i)]); + } } break; } case B_FLOATING_WINDOW_LOOK: { //top - for (int8 i = 0; i < 3; i++) { - _driver->StrokeLine(BPoint(r.left + i, r.top + i), - BPoint(r.right - i, r.top + i), - fFrameColors[i * 2]); + if (invalid.Intersects(fTopBorder)) { + for (int8 i = 0; i < 3; i++) { + _driver->StrokeLine(BPoint(r.left + i, r.top + i), + BPoint(r.right - i, r.top + i), + fFrameColors[i * 2]); + } } //left - for (int8 i = 0; i < 3; i++) { - _driver->StrokeLine(BPoint(r.left + i, r.top + i), - BPoint(r.left + i, r.bottom - i), - fFrameColors[i * 2]); + if (invalid.Intersects(fLeftBorder)) { + for (int8 i = 0; i < 3; i++) { + _driver->StrokeLine(BPoint(r.left + i, r.top + i), + BPoint(r.left + i, r.bottom - i), + fFrameColors[i * 2]); + } } //bottom - for (int8 i = 0; i < 3; i++) { - _driver->StrokeLine(BPoint(r.left + i, r.bottom - i), - BPoint(r.right - i, r.bottom - i), - fFrameColors[(2 - i) == 2 ? 5 : (2 - i) * 2]); + if (invalid.Intersects(fBottomBorder)) { + for (int8 i = 0; i < 3; i++) { + _driver->StrokeLine(BPoint(r.left + i, r.bottom - i), + BPoint(r.right - i, r.bottom - i), + fFrameColors[(2 - i) == 2 ? 5 : (2 - i) * 2]); + } } //right - for (int8 i = 0; i < 3; i++) { - _driver->StrokeLine(BPoint(r.right - i, r.top + i), - BPoint(r.right - i, r.bottom - i), - fFrameColors[(2 - i) == 2 ? 5 : (2 - i) * 2]); + if (invalid.Intersects(fRightBorder)) { + for (int8 i = 0; i < 3; i++) { + _driver->StrokeLine(BPoint(r.right - i, r.top + i), + BPoint(r.right - i, r.bottom - i), + fFrameColors[(2 - i) == 2 ? 5 : (2 - i) * 2]); + } } break; - break; } case B_BORDERED_WINDOW_LOOK: { _driver->StrokeRect(r, fFrameColors[5]); @@ -563,33 +632,37 @@ STRACE(("_DrawFrame(%f,%f,%f,%f)\n", invalid.left, invalid.top, switch (fLook){ case B_DOCUMENT_WINDOW_LOOK: { - // Explicitly locking the driver is normally unnecessary. However, we - // need to do this because we are rapidly drawing a series of calls - // which would not necessarily draw correctly if we didn't do so. float x = r.right - 3; float y = r.bottom - 3; - _driver->Lock(); - _driver->FillRect(BRect(x-13, y-13, x, y), fFrameColors[2]); - _driver->StrokeLine(BPoint(x-15, y-15), BPoint(x-15, y-2), fFrameColors[0]); - _driver->StrokeLine(BPoint(x-14, y-14), BPoint(x-14, y-1), fFrameColors[1]); - _driver->StrokeLine(BPoint(x-15, y-15), BPoint(x-2, y-15), fFrameColors[0]); - _driver->StrokeLine(BPoint(x-14, y-14), BPoint(x-1, y-14), fFrameColors[1]); + + if (!invalid.Intersects(r)) + break; + + _driver->FillRect(BRect(x - 13, y - 13, x, y), fFrameColors[2]); + _driver->StrokeLine(BPoint(x - 15, y - 15), BPoint(x - 15, y - 2), fFrameColors[0]); + _driver->StrokeLine(BPoint(x - 14, y - 14), BPoint(x - 14, y - 1), fFrameColors[1]); + _driver->StrokeLine(BPoint(x - 15, y - 15), BPoint(x - 2, y - 15), fFrameColors[0]); + _driver->StrokeLine(BPoint(x - 14, y - 14), BPoint(x - 1, y - 14), fFrameColors[1]); for (int8 i = 1; i <= 4; i++) { for (int8 j = 1; j <= i; j++) { - BPoint pt1(x-(3*j)+1, y-(3*(5-i))+1); - BPoint pt2(x-(3*j)+2, y-(3*(5-i))+2); + BPoint pt1(x - (3 * j) + 1, y - (3 * (5 - i)) + 1); + BPoint pt2(x - (3 * j) + 2, y - (3 * (5 - i)) + 2); _driver->StrokePoint(pt1, fFrameColors[0]); _driver->StrokePoint(pt2, fFrameColors[1]); } } - _driver->Unlock(); break; } case B_TITLED_WINDOW_LOOK: case B_FLOATING_WINDOW_LOOK: case B_MODAL_WINDOW_LOOK: { + + if (!invalid.Intersects(BRect(fRightBorder.right - 22, fBottomBorder.bottom - 22, + fRightBorder.right - 1, fBottomBorder.bottom - 1))) + break; + _driver->StrokeLine(BPoint(fRightBorder.left, fBottomBorder.bottom - 22), BPoint(fRightBorder.right - 1, fBottomBorder.bottom - 22), fFrameColors[0]); @@ -609,17 +682,20 @@ STRACE(("_DrawFrame(%f,%f,%f,%f)\n", invalid.left, invalid.top, // _DrawTab void -DefaultDecorator::_DrawTab(BRect r) +DefaultDecorator::_DrawTab(BRect invalid) { - STRACE(("_DrawTab(%f,%f,%f,%f)\n", r.left, r.top, r.right, r.bottom)); + STRACE(("_DrawTab(%.1f,%.1f,%.1f,%.1f)\n", + invalid.left, invalid.top, invalid.right, invalid.bottom)); // If a window has a tab, this will draw it and any buttons which are // in it. - if (!_tabrect.IsValid()) + if (!_tabrect.IsValid() || !invalid.Intersects(_tabrect)) return; // TODO: cache these - RGBColor tabColorLight = RGBColor(tint_color(fTabColor.GetColor32(), (B_LIGHTEN_2_TINT + B_LIGHTEN_MAX_TINT) / 2)); - RGBColor tabColorShadow = RGBColor(tint_color(fTabColor.GetColor32(), B_DARKEN_2_TINT)); + RGBColor tabColorLight = RGBColor(tint_color(fTabColor.GetColor32(), + (B_LIGHTEN_2_TINT + B_LIGHTEN_MAX_TINT) / 2)); + RGBColor tabColorShadow = RGBColor(tint_color(fTabColor.GetColor32(), + B_DARKEN_2_TINT)); // outer frame _driver->StrokeLine(_tabrect.LeftTop(), _tabrect.LeftBottom(), fFrameColors[0]); @@ -650,9 +726,9 @@ DefaultDecorator::_DrawTab(BRect r) _DrawTitle(_tabrect); // Draw the buttons if we're supposed to - if (!(fFlags & B_NOT_CLOSABLE)) + if (!(fFlags & B_NOT_CLOSABLE) && invalid.Intersects(_closerect)) _DrawClose(_closerect); - if (!(fFlags & B_NOT_ZOOMABLE)) + if (!(fFlags & B_NOT_ZOOMABLE) && invalid.Intersects(_zoomrect)) _DrawZoom(_zoomrect); } diff --git a/src/servers/app/DefaultDecorator.h b/src/servers/app/DefaultDecorator.h index 5cad3b014c..46f6c8fbf4 100644 --- a/src/servers/app/DefaultDecorator.h +++ b/src/servers/app/DefaultDecorator.h @@ -27,10 +27,8 @@ public: window_look look, BRegion* updateRegion = NULL); virtual void SetFlags(uint32 flags, BRegion* updateRegion = NULL); - virtual void MoveBy(float x, float y); virtual void MoveBy(BPoint pt); - virtual void ResizeBy(float x, float y); - virtual void ResizeBy(BPoint pt); + virtual void ResizeBy(BPoint pt, BRegion* dirty); virtual void Draw(BRect r); virtual void Draw(); diff --git a/src/servers/app/WindowLayer.cpp b/src/servers/app/WindowLayer.cpp index ff0a8e21f3..acc17fc356 100644 --- a/src/servers/app/WindowLayer.cpp +++ b/src/servers/app/WindowLayer.cpp @@ -375,24 +375,16 @@ WindowLayer::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion) fWindow->HandleDirectConnection(B_DIRECT_START | B_BUFFER_RESIZED); - // put the previous border region into the dirty region as well - // to handle the part that was overlapping a layer - if (dirtyRegion) - dirtyRegion->Include(&fBorderRegion); - fBorderRegionValid = false; fContentRegionValid = false; fEffectiveDrawingRegionValid = false; - if (fDecorator) - fDecorator->ResizeBy(x, y); - - // the border is dirty, put it into - // dirtyRegion for a start - BRegion newBorderRegion; - GetBorderRegion(&newBorderRegion); - if (dirtyRegion) { - dirtyRegion->Include(&newBorderRegion); + if (fDecorator) { + fDecorator->ResizeBy(x, y, dirtyRegion); +//if (dirtyRegion) { +//fDrawingEngine->FillRegion(*dirtyRegion, RGBColor(255, 255, 0, 255)); +//snooze(40000); +//} } if (fTopLayer != NULL) @@ -1603,11 +1595,11 @@ WindowLayer::_DrawBorder() // intersect with the dirty region dirtyBorderRegion.IntersectWith(&fDirtyRegion); - if (dirtyBorderRegion.CountRects() > 0) { -// TODO: decorator drawing with update region... + if (dirtyBorderRegion.CountRects() > 0 && fDrawingEngine->Lock()) { fDrawingEngine->ConstrainClippingRegion(&dirtyBorderRegion); fDecorator->Draw(dirtyBorderRegion.Frame()); - fDrawingEngine->ConstrainClippingRegion(NULL); + + fDrawingEngine->Unlock(); } }