* added SetUserClipping() and DrawingRegion(), which is used for
handling client defined clipping. The client clipping stays in local coords, which greatly simplyfies things. We ought to find a way to reduce the number of regions needed per Layer. I just added another one... * renamed a few "lay"s to "child". * used the new client added clipping in ServerWindow git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14847 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
41f78f7884
commit
c5522d81d8
@ -50,6 +50,7 @@ Layer::Layer(BRect frame, const char* name, int32 token,
|
|||||||
fVisible2(),
|
fVisible2(),
|
||||||
fFullVisible2(),
|
fFullVisible2(),
|
||||||
fDirtyForRebuild(),
|
fDirtyForRebuild(),
|
||||||
|
fDrawingRegion(),
|
||||||
|
|
||||||
fDriver(driver),
|
fDriver(driver),
|
||||||
fRootLayer(NULL),
|
fRootLayer(NULL),
|
||||||
@ -421,6 +422,16 @@ Layer::SetName(const char* name)
|
|||||||
fName.SetTo(name);
|
fName.SetTo(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetUserClipping
|
||||||
|
void
|
||||||
|
Layer::SetUserClipping(const BRegion& region)
|
||||||
|
{
|
||||||
|
fDrawState->SetClippingRegion(region);
|
||||||
|
|
||||||
|
// rebuild clipping
|
||||||
|
_RebuildDrawingRegion();
|
||||||
|
}
|
||||||
|
|
||||||
// SetFlags
|
// SetFlags
|
||||||
void
|
void
|
||||||
Layer::SetFlags(uint32 flags)
|
Layer::SetFlags(uint32 flags)
|
||||||
@ -521,8 +532,6 @@ Layer::PushState()
|
|||||||
{
|
{
|
||||||
fDrawState = fDrawState->PushState();
|
fDrawState = fDrawState->PushState();
|
||||||
fDrawState->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE);
|
fDrawState->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE);
|
||||||
|
|
||||||
// TODO: rebuild clipping and redraw
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -534,10 +543,15 @@ Layer::PopState()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool rebuildClipping = fDrawState->ClippingRegion() != NULL;
|
||||||
|
|
||||||
fDrawState = fDrawState->PopState();
|
fDrawState = fDrawState->PopState();
|
||||||
fDrawState->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE);
|
fDrawState->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE);
|
||||||
|
|
||||||
// TODO: rebuild clipping and redraw
|
// rebuild clipping
|
||||||
|
// (the clipping from the popped state is not effective anymore)
|
||||||
|
if (rebuildClipping)
|
||||||
|
_RebuildDrawingRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -880,21 +894,21 @@ void
|
|||||||
Layer::PruneTree(void)
|
Layer::PruneTree(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
Layer* lay;
|
Layer* child;
|
||||||
Layer* nextlay;
|
Layer* nextChild;
|
||||||
|
|
||||||
lay = fFirstChild;
|
child = fFirstChild;
|
||||||
fFirstChild = NULL;
|
fFirstChild = NULL;
|
||||||
|
|
||||||
while (lay != NULL) {
|
while (child != NULL) {
|
||||||
if (lay->fFirstChild != NULL)
|
if (child->fFirstChild != NULL)
|
||||||
lay->PruneTree();
|
child->PruneTree();
|
||||||
|
|
||||||
nextlay = lay->fNextSibling;
|
nextChild = child->fNextSibling;
|
||||||
lay->fNextSibling = NULL;
|
child->fNextSibling = NULL;
|
||||||
|
|
||||||
delete lay;
|
delete child;
|
||||||
lay = nextlay;
|
child = nextChild;
|
||||||
}
|
}
|
||||||
// Man, this thing is short. Elegant, ain't it? :P
|
// Man, this thing is short. Elegant, ain't it? :P
|
||||||
}
|
}
|
||||||
@ -1249,8 +1263,8 @@ Layer::_ResizeLayerFrameBy(float x, float y)
|
|||||||
// call hook function
|
// call hook function
|
||||||
ResizedByHook(dx, dy, true); // automatic
|
ResizedByHook(dx, dy, true); // automatic
|
||||||
|
|
||||||
for (Layer *lay = LastChild(); lay; lay = PreviousChild())
|
for (Layer* child = LastChild(); child; child = PreviousChild())
|
||||||
lay->resize_layer_frame_by(dx, dy);
|
child->resize_layer_frame_by(dx, dy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
@ -1281,39 +1295,39 @@ Layer::_RezizeLayerRedrawMore(BRegion ®, float dx, float dy)
|
|||||||
if (dx == 0 && dy == 0)
|
if (dx == 0 && dy == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (Layer *lay = LastChild(); lay; lay = PreviousChild()) {
|
for (Layer* child = LastChild(); child; child = PreviousChild()) {
|
||||||
uint16 rm = lay->fResizeMode & 0x0000FFFF;
|
uint16 rm = child->fResizeMode & 0x0000FFFF;
|
||||||
|
|
||||||
if ((rm & 0x0F0F) == (uint16)B_FOLLOW_LEFT_RIGHT || (rm & 0xF0F0) == (uint16)B_FOLLOW_TOP_BOTTOM) {
|
if ((rm & 0x0F0F) == (uint16)B_FOLLOW_LEFT_RIGHT || (rm & 0xF0F0) == (uint16)B_FOLLOW_TOP_BOTTOM) {
|
||||||
// NOTE: this is not exactly corect, but it works :-)
|
// NOTE: this is not exactly corect, but it works :-)
|
||||||
// Normaly we shoud've used the lay's old, required region - the one returned
|
// Normaly we shoud've used the child's old, required region - the one returned
|
||||||
// from get_user_region() with the old frame, and the current one. lay->Bounds()
|
// from get_user_region() with the old frame, and the current one. child->Bounds()
|
||||||
// works for the moment so we leave it like this.
|
// works for the moment so we leave it like this.
|
||||||
|
|
||||||
// calculate the old bounds.
|
// calculate the old bounds.
|
||||||
BRect oldBounds(lay->Bounds());
|
BRect oldBounds(child->Bounds());
|
||||||
if ((rm & 0x0F0F) == (uint16)B_FOLLOW_LEFT_RIGHT)
|
if ((rm & 0x0F0F) == (uint16)B_FOLLOW_LEFT_RIGHT)
|
||||||
oldBounds.right -=dx;
|
oldBounds.right -=dx;
|
||||||
if ((rm & 0xF0F0) == (uint16)B_FOLLOW_TOP_BOTTOM)
|
if ((rm & 0xF0F0) == (uint16)B_FOLLOW_TOP_BOTTOM)
|
||||||
oldBounds.bottom -=dy;
|
oldBounds.bottom -=dy;
|
||||||
|
|
||||||
// compute the region that became visible because we got bigger OR smaller.
|
// compute the region that became visible because we got bigger OR smaller.
|
||||||
BRegion regZ(lay->Bounds());
|
BRegion regZ(child->Bounds());
|
||||||
regZ.Include(oldBounds);
|
regZ.Include(oldBounds);
|
||||||
regZ.Exclude(oldBounds&lay->Bounds());
|
regZ.Exclude(oldBounds & child->Bounds());
|
||||||
|
|
||||||
lay->ConvertToScreen(®Z);
|
child->ConvertToScreen(®Z);
|
||||||
|
|
||||||
// intersect that with this'(not lay's) fullVisible region
|
// intersect that with this'(not child's) fullVisible region
|
||||||
regZ.IntersectWith(&fFullVisible2);
|
regZ.IntersectWith(&fFullVisible2);
|
||||||
reg.Include(®Z);
|
reg.Include(®Z);
|
||||||
|
|
||||||
lay->_RezizeLayerRedrawMore(reg,
|
child->_RezizeLayerRedrawMore(reg,
|
||||||
(rm & 0x0F0F) == (uint16)B_FOLLOW_LEFT_RIGHT? dx: 0,
|
(rm & 0x0F0F) == (uint16)B_FOLLOW_LEFT_RIGHT? dx: 0,
|
||||||
(rm & 0xF0F0) == (uint16)B_FOLLOW_TOP_BOTTOM? dy: 0);
|
(rm & 0xF0F0) == (uint16)B_FOLLOW_TOP_BOTTOM? dy: 0);
|
||||||
|
|
||||||
// above, OR this:
|
// above, OR this:
|
||||||
// reg.Include(&lay->fFullVisible2);
|
// reg.Include(&child->fFullVisible2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (((rm & 0x0F0F) == (uint16)B_FOLLOW_RIGHT && dx != 0) ||
|
if (((rm & 0x0F0F) == (uint16)B_FOLLOW_RIGHT && dx != 0) ||
|
||||||
@ -1321,7 +1335,7 @@ Layer::_RezizeLayerRedrawMore(BRegion ®, float dx, float dy)
|
|||||||
((rm & 0xF0F0) == (uint16)B_FOLLOW_BOTTOM && dy != 0)||
|
((rm & 0xF0F0) == (uint16)B_FOLLOW_BOTTOM && dy != 0)||
|
||||||
((rm & 0xF0F0) == (uint16)B_FOLLOW_V_CENTER && dy != 0))
|
((rm & 0xF0F0) == (uint16)B_FOLLOW_V_CENTER && dy != 0))
|
||||||
{
|
{
|
||||||
reg.Include(&lay->fFullVisible2);
|
reg.Include(&child->fFullVisible2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1332,14 +1346,14 @@ Layer::_ResizeLayerFullUpdateOnResize(BRegion ®, float dx, float dy)
|
|||||||
if (dx == 0 && dy == 0)
|
if (dx == 0 && dy == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (Layer *lay = LastChild(); lay; lay = PreviousChild()) {
|
for (Layer* child = LastChild(); child; child = PreviousChild()) {
|
||||||
uint16 rm = lay->fResizeMode & 0x0000FFFF;
|
uint16 rm = child->fResizeMode & 0x0000FFFF;
|
||||||
|
|
||||||
if ((rm & 0x0F0F) == (uint16)B_FOLLOW_LEFT_RIGHT || (rm & 0xF0F0) == (uint16)B_FOLLOW_TOP_BOTTOM) {
|
if ((rm & 0x0F0F) == (uint16)B_FOLLOW_LEFT_RIGHT || (rm & 0xF0F0) == (uint16)B_FOLLOW_TOP_BOTTOM) {
|
||||||
if (lay->fFlags & B_FULL_UPDATE_ON_RESIZE && lay->fVisible2.CountRects() > 0)
|
if (child->fFlags & B_FULL_UPDATE_ON_RESIZE && child->fVisible2.CountRects() > 0)
|
||||||
reg.Include(&lay->fVisible2);
|
reg.Include(&child->fVisible2);
|
||||||
|
|
||||||
lay->_ResizeLayerFullUpdateOnResize(reg,
|
child->_ResizeLayerFullUpdateOnResize(reg,
|
||||||
(rm & 0x0F0F) == (uint16)B_FOLLOW_LEFT_RIGHT? dx: 0,
|
(rm & 0x0F0F) == (uint16)B_FOLLOW_LEFT_RIGHT? dx: 0,
|
||||||
(rm & 0xF0F0) == (uint16)B_FOLLOW_TOP_BOTTOM? dy: 0);
|
(rm & 0xF0F0) == (uint16)B_FOLLOW_TOP_BOTTOM? dy: 0);
|
||||||
}
|
}
|
||||||
@ -1409,15 +1423,15 @@ Layer::_RebuildVisibleRegions( const BRegion &invalid,
|
|||||||
// allow this layer to hide some parts from its children
|
// allow this layer to hide some parts from its children
|
||||||
_ReserveRegions(common);
|
_ReserveRegions(common);
|
||||||
|
|
||||||
for (Layer *lay = LastChild(); lay; lay = PreviousChild()) {
|
for (Layer *child = LastChild(); child; child = PreviousChild()) {
|
||||||
if (lay == startFrom)
|
if (child == startFrom)
|
||||||
fullRebuild = true;
|
fullRebuild = true;
|
||||||
|
|
||||||
if (fullRebuild)
|
if (fullRebuild)
|
||||||
lay->_RebuildVisibleRegions(invalid, common, lay->LastChild());
|
child->_RebuildVisibleRegions(invalid, common, child->LastChild());
|
||||||
|
|
||||||
// to let children know much they can take from parent's visible region
|
// to let children know much they can take from parent's visible region
|
||||||
common.Exclude(&lay->fFullVisible2);
|
common.Exclude(&child->fFullVisible2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// include what's left after all children took what they could.
|
// include what's left after all children took what they could.
|
||||||
@ -1450,15 +1464,30 @@ Layer::_RebuildVisibleRegions( const BRegion &invalid,
|
|||||||
// allow this layer to hide some parts from its children
|
// allow this layer to hide some parts from its children
|
||||||
_ReserveRegions(common);
|
_ReserveRegions(common);
|
||||||
|
|
||||||
for (Layer *lay = LastChild(); lay; lay = PreviousChild()) {
|
for (Layer *child = LastChild(); child; child = PreviousChild()) {
|
||||||
lay->_RebuildVisibleRegions(invalid, common, lay->LastChild());
|
child->_RebuildVisibleRegions(invalid, common, child->LastChild());
|
||||||
|
|
||||||
// to let children know much they can take from parent's visible region
|
// to let children know much they can take from parent's visible region
|
||||||
common.Exclude(&lay->fFullVisible2);
|
common.Exclude(&child->fFullVisible2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// include what's left after all children took what they could.
|
// include what's left after all children took what they could.
|
||||||
fVisible2.Include(&common);
|
fVisible2.Include(&common);
|
||||||
|
|
||||||
|
_RebuildDrawingRegion();
|
||||||
|
}
|
||||||
|
|
||||||
|
// _RebuildDrawingRegion
|
||||||
|
void
|
||||||
|
Layer::_RebuildDrawingRegion()
|
||||||
|
{
|
||||||
|
fDrawingRegion = fVisible2;
|
||||||
|
// apply user clipping which is in native coordinate system
|
||||||
|
if (const BRegion* userClipping = fDrawState->ClippingRegion()) {
|
||||||
|
BRegion screenUserClipping(*userClipping);
|
||||||
|
ConvertToScreen(&screenUserClipping);
|
||||||
|
fDrawingRegion.IntersectWith(&screenUserClipping);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1539,13 +1568,13 @@ Layer::_AllRedraw(const BRegion &invalid)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Layer *lay = LastChild(); lay != NULL; lay = PreviousChild()) {
|
for (Layer *child = LastChild(); child != NULL; child = PreviousChild()) {
|
||||||
if (!(lay->IsHidden())) {
|
if (!(child->IsHidden())) {
|
||||||
BRegion common(lay->fFullVisible2);
|
BRegion common(child->fFullVisible2);
|
||||||
common.IntersectWith(&invalid);
|
common.IntersectWith(&invalid);
|
||||||
|
|
||||||
if (common.CountRects() > 0)
|
if (common.CountRects() > 0)
|
||||||
lay->_AllRedraw(invalid);
|
child->_AllRedraw(invalid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,8 +194,12 @@ class Layer {
|
|||||||
void SetFlags(uint32 flags);
|
void SetFlags(uint32 flags);
|
||||||
|
|
||||||
// clipping stuff and redraw
|
// clipping stuff and redraw
|
||||||
|
void SetUserClipping(const BRegion& region);
|
||||||
|
// region is expected in layer coordinates
|
||||||
|
|
||||||
inline const BRegion& VisibleRegion() const { return fVisible2; }
|
inline const BRegion& VisibleRegion() const { return fVisible2; }
|
||||||
inline const BRegion& FullVisible() const { return fFullVisible2; }
|
inline const BRegion& FullVisible() const { return fFullVisible2; }
|
||||||
|
inline const BRegion& DrawingRegion() const { return fDrawingRegion; }
|
||||||
|
|
||||||
virtual void GetWantedRegion(BRegion& reg);
|
virtual void GetWantedRegion(BRegion& reg);
|
||||||
|
|
||||||
@ -224,6 +228,7 @@ class Layer {
|
|||||||
void _RebuildVisibleRegions( const BRegion &invalid,
|
void _RebuildVisibleRegions( const BRegion &invalid,
|
||||||
const BRegion &parentLocalVisible,
|
const BRegion &parentLocalVisible,
|
||||||
const Layer *startFrom);
|
const Layer *startFrom);
|
||||||
|
void _RebuildDrawingRegion();
|
||||||
void _ClearVisibleRegions();
|
void _ClearVisibleRegions();
|
||||||
void _ResizeLayerFrameBy(float x, float y);
|
void _ResizeLayerFrameBy(float x, float y);
|
||||||
void _RezizeLayerRedrawMore(BRegion ®, float dx, float dy);
|
void _RezizeLayerRedrawMore(BRegion ®, float dx, float dy);
|
||||||
@ -245,6 +250,7 @@ class Layer {
|
|||||||
BRegion fVisible2;
|
BRegion fVisible2;
|
||||||
BRegion fFullVisible2;
|
BRegion fFullVisible2;
|
||||||
BRegion fDirtyForRebuild;
|
BRegion fDirtyForRebuild;
|
||||||
|
BRegion fDrawingRegion;
|
||||||
|
|
||||||
DrawingEngine* fDriver;
|
DrawingEngine* fDriver;
|
||||||
RootLayer* fRootLayer;
|
RootLayer* fRootLayer;
|
||||||
|
@ -1079,14 +1079,14 @@ if (myRootLayer)
|
|||||||
fLink.Attach<int32>(0L);
|
fLink.Attach<int32>(0L);
|
||||||
fLink.Flush();
|
fLink.Flush();
|
||||||
} else {
|
} else {
|
||||||
// TODO: Watch out for the coordinate system in AS_LAYER_GET_CLIP_REGION
|
BRegion drawingRegion = fCurrentLayer->DrawingRegion();
|
||||||
int32 rectCount = fCurrentLayer->fVisible2.CountRects();
|
int32 rectCount = drawingRegion.CountRects();
|
||||||
|
|
||||||
fLink.StartMessage(SERVER_TRUE);
|
fLink.StartMessage(SERVER_TRUE);
|
||||||
fLink.Attach<int32>(rectCount);
|
fLink.Attach<int32>(rectCount);
|
||||||
|
|
||||||
for (int32 i = 0; i < rectCount; i++) {
|
for (int32 i = 0; i < rectCount; i++) {
|
||||||
BRect converted(fCurrentLayer->fVisible2.RectAt(i));
|
BRect converted(drawingRegion.RectAt(i));
|
||||||
fCurrentLayer->ConvertFromScreen(&converted);
|
fCurrentLayer->ConvertFromScreen(&converted);
|
||||||
fLink.Attach<BRect>(converted);
|
fLink.Attach<BRect>(converted);
|
||||||
}
|
}
|
||||||
@ -1100,25 +1100,16 @@ if (myRootLayer)
|
|||||||
{
|
{
|
||||||
DTRACE(("ServerWindow %s: Message AS_LAYER_SET_CLIP_REGION: Layer: %s\n", Title(), fCurrentLayer->Name()));
|
DTRACE(("ServerWindow %s: Message AS_LAYER_SET_CLIP_REGION: Layer: %s\n", Title(), fCurrentLayer->Name()));
|
||||||
|
|
||||||
// TODO: Watch out for the coordinate system in AS_LAYER_SET_CLIP_REGION
|
int32 rectCount;
|
||||||
int32 noOfRects;
|
link.Read<int32>(&rectCount);
|
||||||
|
|
||||||
link.Read<int32>(&noOfRects);
|
|
||||||
|
|
||||||
BRegion region;
|
BRegion region;
|
||||||
for (int i = 0; i < noOfRects; i++) {
|
for (int32 i = 0; i < rectCount; i++) {
|
||||||
BRect r;
|
BRect r;
|
||||||
link.Read<BRect>(&r);
|
link.Read<BRect>(&r);
|
||||||
fCurrentLayer->ConvertToScreen(&r);
|
|
||||||
region.Include(r);
|
region.Include(r);
|
||||||
}
|
}
|
||||||
// TODO: Turned off user clipping for now (will probably not harm anything but performance right now)
|
fCurrentLayer->SetUserClipping(region);
|
||||||
// We need to integrate user clipping more, in Layer::PopState, the clipping needs to be
|
|
||||||
// restored too. "AS_LAYER_SET_CLIP_REGION" is irritating, as I think it should be
|
|
||||||
// "AS_LAYER_CONSTRAIN_CLIP_REGION", since it means to "add" to the current clipping, not "set" it.
|
|
||||||
// fCurrentLayer->CurrentState()->SetClippingRegion(region);
|
|
||||||
|
|
||||||
// TODO: rebuild clipping and redraw
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1622,7 +1613,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
|||||||
// NOTE: fCurrentLayer and fCurrentLayer->fLayerData cannot be NULL,
|
// NOTE: fCurrentLayer and fCurrentLayer->fLayerData cannot be NULL,
|
||||||
// _DispatchGraphicsMessage() is called from _DispatchMessage() which
|
// _DispatchGraphicsMessage() is called from _DispatchMessage() which
|
||||||
// checks both these conditions
|
// checks both these conditions
|
||||||
BRegion rreg(fCurrentLayer->VisibleRegion());
|
BRegion rreg(fCurrentLayer->DrawingRegion());
|
||||||
|
|
||||||
if (fWinBorder->InUpdate())
|
if (fWinBorder->InUpdate())
|
||||||
rreg.IntersectWith(&fWinBorder->RegionToBeUpdated());
|
rreg.IntersectWith(&fWinBorder->RegionToBeUpdated());
|
||||||
|
Loading…
Reference in New Issue
Block a user