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
This commit is contained in:
DarkWyrm 2002-12-03 00:21:19 +00:00
parent 57dd5feac4
commit 63034805fd
5 changed files with 134 additions and 27 deletions

View File

@ -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.left<oldrect.right)
oldrect.right=tabrect.left;
}
else
if(dx<0)
{
if(tabrect.right>oldrect.left)
oldrect.left=tabrect.right;
}
return oldrect;
}
void BeDecorator::ResizeBy(float x, float y)

View File

@ -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;
};

View File

@ -1,3 +1,4 @@
#include <Region.h>
#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;

View File

@ -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:

View File

@ -15,6 +15,8 @@
#include <OS.h>
//#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(&reg,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; i<r->CountRects(); 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(&reg);
}
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));
}
}