From 63034805fd7100ec84ca04b575e9c5da17f9b07b Mon Sep 17 00:00:00 2001 From: DarkWyrm Date: Tue, 3 Dec 2002 00:21:19 +0000 Subject: [PATCH] Removed a bug in Layer::Invalidate() Fixed a bunch of redraw problems git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2131 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/proto7/BeDecorator.cpp | 32 +++++++- src/servers/app/proto7/BeDecorator.h | 4 +- src/servers/app/proto7/Decorator.cpp | 13 +++- src/servers/app/proto7/Decorator.h | 9 ++- src/servers/app/proto7/Layer.cpp | 103 +++++++++++++++++++++---- 5 files changed, 134 insertions(+), 27 deletions(-) diff --git a/src/servers/app/proto7/BeDecorator.cpp b/src/servers/app/proto7/BeDecorator.cpp index 6e3687645f..188185cbe7 100644 --- a/src/servers/app/proto7/BeDecorator.cpp +++ b/src/servers/app/proto7/BeDecorator.cpp @@ -145,6 +145,7 @@ printf("BeDecorator()::_DoLayout()"); rect.PrintToStream(); closerect.top+=(look==WLOOK_FLOATING)?6:4; closerect.right=closerect.left+10; closerect.bottom=closerect.top+10; + closerect.OffsetBy(taboffset,0); borderrect.top+=19; @@ -155,11 +156,13 @@ printf("BeDecorator()::_DoLayout()"); rect.PrintToStream(); if(titlewidth>0) { tabrect.right=closerect.right+textoffset+titlewidth+15; - if(tabrect.right>frame.right) - tabrect.right=frame.right; } else tabrect.right=tabrect.left+tabrect.Width()/2; + tabrect.OffsetBy(taboffset,0); + if(tabrect.right>frame.right) + tabrect.right=frame.right; + if(look==WLOOK_FLOATING) tabrect.top+=4; @@ -201,7 +204,7 @@ void BeDecorator::MoveBy(BPoint pt) zoomrect.OffsetBy(pt); } -BPoint BeDecorator::SlideTab(float dx, float dy=0) +BRect BeDecorator::SlideTab(float dx, float dy=0) { // Check to see if we would slide it out of bounde if( (tabrect.right+dx) > frame.right) @@ -209,10 +212,31 @@ BPoint BeDecorator::SlideTab(float dx, float dy=0) if( (tabrect.left+dx) < frame.left) dx=frame.left-tabrect.left; + taboffset+=int32(dx); + if(taboffset<0) + { + dx-=taboffset; + taboffset=0; + } + + BRect oldrect(tabrect); tabrect.OffsetBy(dx,0); closerect.OffsetBy(dx,0); zoomrect.OffsetBy(dx,0); - return BPoint(dx,0); + + if(dx>0) + { + if(tabrect.leftoldrect.left) + oldrect.left=tabrect.right; + } + + return oldrect; } void BeDecorator::ResizeBy(float x, float y) diff --git a/src/servers/app/proto7/BeDecorator.h b/src/servers/app/proto7/BeDecorator.h index c19836ceb6..601d7dc63a 100644 --- a/src/servers/app/proto7/BeDecorator.h +++ b/src/servers/app/proto7/BeDecorator.h @@ -20,6 +20,7 @@ public: void Draw(void); BRegion *GetFootprint(void); click_type Clicked(BPoint pt, int32 buttons, int32 modifiers); + BRect SlideTab(float dx, float dy=0); protected: void _DrawClose(BRect r); @@ -30,7 +31,7 @@ protected: void _DoLayout(void); void _SetFocus(void); void DrawBlendedRect(BRect r, bool down); - uint32 taboffset; + int32 taboffset; RGBColor tab_highcol, tab_lowcol; RGBColor button_highcol, button_lowcol; @@ -40,7 +41,6 @@ protected: uint64 solidhigh, solidlow; float titlewidth; - bool slidetab; int textoffset, titlechars; }; diff --git a/src/servers/app/proto7/Decorator.cpp b/src/servers/app/proto7/Decorator.cpp index 736484d2ae..2973d5cb3a 100644 --- a/src/servers/app/proto7/Decorator.cpp +++ b/src/servers/app/proto7/Decorator.cpp @@ -1,3 +1,4 @@ +#include #include "Decorator.h" #include "DisplayDriver.h" @@ -160,6 +161,11 @@ void Decorator::MoveBy(BPoint pt) { } +BRect Decorator::SlideTab(float dx, float dy=0) +{ + return BRect(0,0,0,0); +} + void Decorator::ResizeBy(float x, float y) { } @@ -238,11 +244,12 @@ void Decorator::_DrawZoom(BRect r) { } -/* -SRegion Decorator::GetFootprint(void) + +BRegion *Decorator::GetFootprint(void) { + return NULL; } -*/ + click_type Decorator::Clicked(BPoint pt, int32 buttons, int32 modifiers) { return CLICK_NONE; diff --git a/src/servers/app/proto7/Decorator.h b/src/servers/app/proto7/Decorator.h index 59ddfa2fa6..40f0d14825 100644 --- a/src/servers/app/proto7/Decorator.h +++ b/src/servers/app/proto7/Decorator.h @@ -11,7 +11,7 @@ class Layer; class DisplayDriver; typedef enum { CLICK_NONE=0, CLICK_ZOOM, CLICK_CLOSE, CLICK_MINIMIZE, - CLICK_TAB, CLICK_DRAG, CLICK_MOVETOBACK, CLICK_MOVETOFRONT, + CLICK_TAB, CLICK_DRAG, CLICK_MOVETOBACK, CLICK_MOVETOFRONT, CLICK_SLIDETAB, CLICK_RESIZE, CLICK_RESIZE_L, CLICK_RESIZE_T, CLICK_RESIZE_R, CLICK_RESIZE_B, CLICK_RESIZE_LT, CLICK_RESIZE_RT, @@ -36,7 +36,7 @@ typedef enum { CLICK_NONE=0, CLICK_ZOOM, CLICK_CLOSE, CLICK_MINIMIZE, #define WFEEL_FLOATING_SUBSET 4 #define WFEEL_FLOATING_APP 5 #define WFEEL_FLOATING_WINDOW 6 - +/* #define NOT_MOVABLE 0x00000001 #define NOT_CLOSABLE 0x00000020 #define NOT_ZOOMABLE 0x00000040 @@ -52,7 +52,7 @@ typedef enum { CLICK_NONE=0, CLICK_ZOOM, CLICK_CLOSE, CLICK_MINIMIZE, #define NOT_ANCHORED_ON_ACTIVATE 0x00020000 #define ASYNCHRONOUS_CONTROLS 0x00080000 #define QUIT_ON_WINDOW_CLOSE 0x00100000 - +*/ class Decorator { public: @@ -82,6 +82,7 @@ public: virtual void MoveBy(float x, float y); virtual void MoveBy(BPoint pt); + virtual BRect SlideTab(float dx, float dy=0); virtual void ResizeBy(float x, float y); virtual void ResizeBy(BPoint pt); virtual void Draw(BRect r); @@ -92,7 +93,7 @@ public: virtual void DrawTab(void); virtual void DrawTitle(void); virtual void DrawZoom(void); - //virtual SRegion GetFootprint(void); + virtual BRegion *GetFootprint(void); virtual click_type Clicked(BPoint pt, int32 buttons, int32 modifiers); protected: diff --git a/src/servers/app/proto7/Layer.cpp b/src/servers/app/proto7/Layer.cpp index 027ca2e39e..016c82e5ac 100644 --- a/src/servers/app/proto7/Layer.cpp +++ b/src/servers/app/proto7/Layer.cpp @@ -15,6 +15,8 @@ #include //#define DEBUG_LAYERS +//#define DEBUG_REDRAW + int64 solidhigh64=0xFFFFFFFFFFFFFFFFLL; int64 solidlow64=0LL; int64 mixedpat64=0xCCCCCCCCCCCCCCCCLL; @@ -22,6 +24,11 @@ int8 *solidhigh=(int8*)&solidhigh64; int8 *solidlow=(int8*)&solidlow64; int8 *mixedpat=(int8*)&mixedpat64; +bool TestLineIntersect(const BRect&r, float x1, float y1, float x2, float y2,bool vertical=true); +bool TestRectIntersection(const BRect &r,const BRect &r2); +bool TestRegionIntersection(BRegion *r,const BRect &r2); +void IntersectRegionWith(BRegion *r,const BRect &r2); + Layer::Layer(BRect rect, const char *layername, ServerWindow *srvwin, int32 viewflags, int32 token) { @@ -469,20 +476,21 @@ void Layer::Invalidate(BRect rect) { // Make our own section dirty and pass it on to any children, if necessary.... // YES, WE ARE SHARING DIRT! Mudpies anyone? :D -#ifdef DEBUG_LAYERS -printf("Layer %s::Invalidate\n",name->String()); -printf("Frame: ");frame.PrintToStream(); -printf("Invalid rect: ");rect.PrintToStream(); -printf("Visible: ");visible->PrintToStream(); -printf("----------------\n"); +#ifdef DEBUG_REDRAW +printf("Layer %s::Invalidate(%f,%f,%f,%f)\n",name->String(),rect.left,rect.top, + rect.right,rect.bottom); #endif - if(Frame().Intersects(rect)) +// if(Frame().Intersects(rect) || Frame().Contains(rect)) + if(TestRectIntersection(Frame(),rect)) { // Clip the rectangle to the visible region of the layer - if(visible->Intersects(rect)) +// if(visible->Intersects(rect)) + if(TestRegionIntersection(visible,rect)) { - BRegion reg(rect); - reg.IntersectWith(visible); +// BRegion reg(rect); +// reg.IntersectWith(visible); + BRegion reg(*visible); + IntersectRegionWith(®,rect); if(reg.CountRects()>0) { is_dirty=true; @@ -491,6 +499,19 @@ printf("----------------\n"); else invalid=new BRegion(reg); } + else + { +#ifdef DEBUG_REDRAW +printf("\tRegion intersection had no rectangles\n");rect.PrintToStream(); +#endif + } + } + else + { +#ifdef DEBUG_REDRAW +printf("\tRectangle did not intersect frame(%.1f,%.1f,%.1f,%.1f)\n", Frame().left, +Frame().top,Frame().right,Frame().bottom); +#endif } } for(Layer *lay=topchild;lay!=NULL; lay=lay->lowersibling) @@ -913,7 +934,7 @@ void RootLayer::RequestDraw(void) ASSERT(driver!=NULL); -#ifdef DEBUG_LAYERS +#ifdef DEBUG_REDRAW printf("Root::RequestDraw: invalid rects: %ld\n",invalid->CountRects()); #endif @@ -923,8 +944,8 @@ printf("Root::RequestDraw: invalid rects: %ld\n",invalid->CountRects()); { if(invalid->RectAt(i).IsValid()) { -#ifdef DEBUG_LAYERS -printf("Root::RequestDraw:FillRect, color ",layerdata->lowcolor.PrintToStream()); +#ifdef DEBUG_REDRAW +printf("Root::RequestDraw:FillRect, color "); layerdata->lowcolor.PrintToStream(); #endif driver->FillRect(invalid->RectAt(i),layerdata, solidlow); } @@ -949,7 +970,7 @@ void RootLayer::SetColor(RGBColor col) { layerdata->lowcolor=col; #ifdef DEBUG_LAYERS -printf("Root::SetColor - ",col.PrintToStream()); +printf("Root::SetColor - "); col.PrintToStream(); #endif } @@ -957,3 +978,57 @@ RGBColor RootLayer::GetColor(void) const { return layerdata->lowcolor; } + +// Code stolen from the OBOS version of Rect.cpp. BeOS R5 version returns false +// if the rectangles are exactly equal +bool TestRectIntersection(const BRect &r,const BRect &r2) +{ + return TestLineIntersect(r, r2.left, r2.top, r2.left, r2.bottom) || + TestLineIntersect(r, r2.left, r2.top, r2.right, r2.top, false) || + TestLineIntersect(r, r2.right, r2.top, r2.right, r2.bottom) || + TestLineIntersect(r, r2.left, r2.bottom, r2.right, r2.bottom, false) || + r.Contains(r2) || + r2.Contains(r); +} + +bool TestRegionIntersection(BRegion *r,const BRect &r2) +{ + for(int32 i=0; iCountRects(); i++) + if(TestRectIntersection(r->RectAt(i),r2)); + return true; + return false; +} + +void IntersectRegionWith(BRegion *r,const BRect &r2) +{ + // We have three conditions: + // 1) Region frame contains rect. Action: call Include() + // 2) Rect intersects region frame. Action: call IntersectWith + // 3) Region frame does not intersect rectangle. Make the region empty + if(r->Frame().Contains(r2)) + r->Include(r2); + if(r->Frame().Intersects(r2)) + { + BRegion reg(r2); + r->IntersectWith(®); + } + else + r->MakeEmpty(); +} + +bool TestLineIntersect(const BRect& r, float x1, float y1, float x2, float y2, + bool vertical) +{ + if (vertical) + { + return (x1 >= r.left && x1 <= r.right) && + ((y1 >= r.top && y1 <= r.bottom) || + (y2 >= r.top && y2 <= r.bottom)); + } + else + { + return (y1 >= r.top && y1 <= r.bottom) && + ((x1 >= r.left && x1 <= r.right) || + (x2 >= r.left && x2 <= r.right)); + } +} \ No newline at end of file