diff --git a/src/tests/servers/app/newClipping/Clipping.proj b/src/tests/servers/app/newClipping/Clipping.proj index 980b922c99..e9bbc98327 100644 Binary files a/src/tests/servers/app/newClipping/Clipping.proj and b/src/tests/servers/app/newClipping/Clipping.proj differ diff --git a/src/tests/servers/app/newClipping/Layer.cpp b/src/tests/servers/app/newClipping/Layer.cpp index ac7191b8d2..197451c43f 100644 --- a/src/tests/servers/app/newClipping/Layer.cpp +++ b/src/tests/servers/app/newClipping/Layer.cpp @@ -25,6 +25,8 @@ Layer::Layer(BRect frame, const char* name, uint32 rm, uint32 flags, rgb_color c fTop = NULL; fParent = NULL; fView = NULL; + fCurrent = NULL; + fHidden = false; strcpy(fName, name); } @@ -80,22 +82,26 @@ MyView* Layer::GetRootLayer() const Layer* Layer::VirtualBottomChild() const { - return fBottom; + fCurrent = fBottom; + return fCurrent; } Layer* Layer::VirtualTopChild() const { - return fTop; + fCurrent = fTop; + return fCurrent; } Layer* Layer::VirtualUpperSibling() const { - return fUpper; + fCurrent = fCurrent->fUpper; + return fCurrent; } Layer* Layer::VirtualLowerSibling() const { - return fLower; + fCurrent = fCurrent->fLower; + return fCurrent; } void Layer::AddLayer(Layer* layer) @@ -189,16 +195,12 @@ Layer::Show() if (fParent && !fParent->IsVisuallyHidden() && GetRootLayer()) { - BRect r(Bounds()); + BRegion invalid; - if (r.IsValid()) - { - ConvertToScreen2(&r); - - BRegion invalid(r); + set_user_regions(invalid); + if (invalid.CountRects() > 0) fParent->Invalidate(invalid, this); - } } } @@ -296,8 +298,6 @@ Layer::resize_redraw_more_regions(BRegion &redraw) void Layer::ResizeBy(float dx, float dy) { -// TODO: center and right alligned view must be fully redrawn - ISN'T THIS DONE ALREADY? - TEST! - fFrame.Set(fFrame.left, fFrame.top, fFrame.right+dx, fFrame.bottom+dy); // resize children using their resize_mask. @@ -305,15 +305,19 @@ void Layer::ResizeBy(float dx, float dy) lay; lay = VirtualUpperSibling()) lay->resize_layer_frame_by(dx, dy); + // call hook function + if (dx != 0.0f || dy != 0.0f) + ResizedByHook(dx, dy, false); // manual + if (!IsVisuallyHidden() && GetRootLayer()) { BRegion oldFullVisible(fFullVisible); + BRegion oldVisible(fVisible); - // we'll invalidate the old position and the new, maxmial, one (bounds in screen coords). - BRegion invalid(fFullVisible); - BRect r(Bounds()); - ConvertToScreen2(&r); - invalid.Include(r); + // we'll invalidate the old area and the new, maxmial one. + BRegion invalid; + set_user_regions(invalid); + invalid.Include(&fFullVisible); clear_visible_regions(); @@ -336,34 +340,35 @@ void Layer::ResizeBy(float dx, float dy) lay; lay = VirtualUpperSibling()) lay->resize_redraw_more_regions(redrawReg); - // add redrawReg to our RootLayer's redraw region. GetRootLayer()->fRedrawReg.Include(&redrawReg); // include layer's visible region in case we want a full update on resize if (fFlags & B_FULL_UPDATE_ON_RESIZE && fVisible.Frame().IsValid()) + { GetRootLayer()->fRedrawReg.Include(&fVisible); + GetRootLayer()->fRedrawReg.Include(&oldVisible); + } // clear canvas and set invalid regions for affected WinBorders GetRootLayer()->RequestRedraw(); // TODO: what if we pass (fParent, startFromTHIS, &redrawReg)? } - - // call hook function - if (dx != 0.0f || dy != 0.0f) - ResizedByHook(dx, dy, false); // manual } void Layer::MoveBy(float dx, float dy) { fFrame.Set(fFrame.left+dx, fFrame.top+dy, fFrame.right+dx, fFrame.bottom+dy); + // call hook function + if (dx != 0.0f || dy != 0.0f) + MovedByHook(dx, dy); + if (!IsVisuallyHidden() && GetRootLayer()) { BRegion oldFullVisible(fFullVisible); - // we'll invalidate the old position and the new, maxmial, one (bounds in screen coords). - BRegion invalid(fFullVisible); - BRect r(Bounds()); - ConvertToScreen2(&r); - invalid.Include(r); + // we'll invalidate the old position and the new, maxmial one. + BRegion invalid; + set_user_regions(invalid); + invalid.Include(&fFullVisible); clear_visible_regions(); @@ -393,10 +398,6 @@ void Layer::MoveBy(float dx, float dy) GetRootLayer()->fRedrawReg.Include(&redrawReg); GetRootLayer()->RequestRedraw(); // TODO: what if we pass (fParent, startFromTHIS, &redrawReg)? } - - // call hook function - if (dx != 0.0f || dy != 0.0f) - MovedByHook(dx, dy); } void Layer::ScrollBy(float dx, float dy) @@ -528,6 +529,11 @@ void Layer::rebuild_visible_regions(const BRegion &invalid, // common is invalid. Same goes for the last two in the 'for' statement below. } + // this is to allow a layer to hide some parts of itself so children + // won't take them. + BRegion unalteredVisible(common); + bool altered = alter_visible_for_children(common); + for (Layer *lay = VirtualBottomChild(); lay ; lay = VirtualUpperSibling()) { if (lay == startFrom) @@ -536,21 +542,28 @@ void Layer::rebuild_visible_regions(const BRegion &invalid, if (fullRebuild) lay->rebuild_visible_regions(invalid, common, lay->VirtualBottomChild()); + // to let children know much they can take from parent's visible region common.Exclude(&lay->fFullVisible); + // all that a child took must be excluded from our visible region fVisible.Exclude(&lay->fFullVisible); + // we've hidden some parts of our visible region from our children, + // and we must be in sysnc with this region too... + if (altered) + unalteredVisible.Exclude(&lay->fFullVisible); } // the visible region of this layer is what left after all its children took // what they could. - fVisible.Include(&common); - - // we don't need this ATM - //operate_on_visible(fVisible); + if (altered) + fVisible.Include(&unalteredVisible); + else + fVisible.Include(&common); } -void Layer::operate_on_visible(BRegion ®) +bool Layer::alter_visible_for_children(BRegion ®) { // Empty Hook function + return false; } void Layer::clear_visible_regions() @@ -561,21 +574,15 @@ void Layer::clear_visible_regions() fVisible.MakeEmpty(); fFullVisible.MakeEmpty(); - Layer *child = VirtualBottomChild(); - while (child) - { + for (Layer *child = VirtualBottomChild(); child; + child = VirtualUpperSibling()) child->clear_visible_regions(); - child = child->VirtualUpperSibling(); - } } void Layer::PrintToStream() const { printf("-> %s\n", fName); - Layer *child = VirtualBottomChild(); - while(child) - { + for (Layer *child = VirtualBottomChild(); child; + child = VirtualUpperSibling()) child->PrintToStream(); - child = child->VirtualUpperSibling(); - } } diff --git a/src/tests/servers/app/newClipping/Layer.h b/src/tests/servers/app/newClipping/Layer.h index 9fa65b1ab6..a99323c9a2 100644 --- a/src/tests/servers/app/newClipping/Layer.h +++ b/src/tests/servers/app/newClipping/Layer.h @@ -67,7 +67,7 @@ protected: rgb_color fColor; private: - virtual void operate_on_visible(BRegion ®ion); + virtual bool alter_visible_for_children(BRegion ®ion); virtual void set_user_regions(BRegion ®); void clear_visible_regions(); @@ -87,6 +87,7 @@ private: Layer* fLower; Layer* fTop; Layer* fParent; + mutable Layer* fCurrent; uint32 fFlags; bool fHidden; diff --git a/src/tests/servers/app/newClipping/MyView.cpp b/src/tests/servers/app/newClipping/MyView.cpp index ecaf58c43a..621e4da5d6 100644 --- a/src/tests/servers/app/newClipping/MyView.cpp +++ b/src/tests/servers/app/newClipping/MyView.cpp @@ -13,6 +13,10 @@ MyView::MyView(BRect frame, const char *name, uint32 resizingMode, uint32 flags) : BView(frame, name, resizingMode, flags) { SetViewColor(B_TRANSPARENT_COLOR); + fTracking = false; + fIsResize = false; + fMovingLayer = NULL; + rgb_color col; col.red = 49; col.green = 101; @@ -29,23 +33,66 @@ MyView::~MyView() delete topLayer; } -Layer* MyView::FindLayer(Layer *lay, const char *bytes) const +Layer* MyView::FindLayer(Layer *lay, BPoint &where) const { - if (strcmp(lay->Name(), bytes) == 0) + if (lay->Visible()->Contains(where)) return lay; else - { - Layer *ret = NULL; - Layer *cursor = lay->VirtualBottomChild(); - while(cursor) + for (Layer *child = lay->VirtualBottomChild(); child; child = lay->VirtualUpperSibling()) { - ret = FindLayer(cursor, bytes); - if (ret) - return ret; - cursor = cursor->VirtualUpperSibling(); + Layer *found = FindLayer(child, where); + if (found) + return found; + } + return NULL; +} + +void MyView::MouseDown(BPoint where) +{ + fTracking = true; + SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS); + fLastPos = where; + fMovingLayer = FindLayer(topLayer, where); + if (fMovingLayer == topLayer) + fMovingLayer = NULL; + if (fMovingLayer) + { + BRect bounds(fMovingLayer->Bounds()); + fMovingLayer->ConvertToScreen2(&bounds); + BRect resizeRect(bounds.right-10, bounds.bottom-10, bounds.right, bounds.bottom); + if (resizeRect.Contains(where)) + fIsResize = true; + else + fIsResize = false; + } +} + +void MyView::MouseUp(BPoint where) +{ + fTracking = false; + fMovingLayer = NULL; +} + +void MyView::MouseMoved(BPoint where, uint32 code, const BMessage *a_message) +{ + if (fTracking) + { + float dx, dy; + dx = where.x - fLastPos.x; + dy = where.y - fLastPos.y; + fLastPos = where; + + if (dx != 0 || dy != 0) + { + if (fMovingLayer) + { + if (fIsResize) + fMovingLayer->ResizeBy(dx, dy); + else + fMovingLayer->MoveBy(dx, dy); + } } } - return NULL; } void MyView::CopyRegion(BRegion *reg, float dx, float dy) @@ -68,9 +115,9 @@ void MyView::RequestRedraw() void MyView::Draw(BRect area) { ConstrainClippingRegion(&fRedrawReg); -FillRect(Bounds()); -Flush(); -snooze(1000000); +//FillRect(Bounds()); +//Flush(); +//snooze(1000000); PushState(); DrawSubTree(topLayer); PopState(); @@ -83,12 +130,9 @@ void MyView::DrawSubTree(Layer* lay) //printf("======== %s =======\n", lay->Name()); // lay->Visible()->PrintToStream(); // lay->FullVisible()->PrintToStream(); - Layer *child = lay->VirtualBottomChild(); - while(child) - { + for (Layer *child = lay->VirtualBottomChild(); child; child = lay->VirtualUpperSibling()) DrawSubTree(child); - child = child->VirtualUpperSibling(); - } + ConstrainClippingRegion(lay->Visible()); SetHighColor(lay->HighColor()); BRegion reg; diff --git a/src/tests/servers/app/newClipping/MyView.h b/src/tests/servers/app/newClipping/MyView.h index 4a8a5e93b7..637d192200 100644 --- a/src/tests/servers/app/newClipping/MyView.h +++ b/src/tests/servers/app/newClipping/MyView.h @@ -11,14 +11,22 @@ public: virtual ~MyView(); virtual void Draw(BRect area); + virtual void MouseDown(BPoint where); + virtual void MouseUp(BPoint where); + virtual void MouseMoved(BPoint where, uint32 code, const BMessage *a_message); void CopyRegion(BRegion *reg, float dx, float dy); void RequestRedraw(); - Layer* FindLayer(Layer *lay, const char *bytes) const; + Layer* FindLayer(Layer *lay, BPoint &where) const; Layer *topLayer; BRegion fRedrawReg; private: void DrawSubTree(Layer* lay); + + bool fTracking; + BPoint fLastPos; + Layer *fMovingLayer; + bool fIsResize; }; \ No newline at end of file diff --git a/src/tests/servers/app/newClipping/WinBorder.cpp b/src/tests/servers/app/newClipping/WinBorder.cpp index 1d73e402ec..176dde4153 100644 --- a/src/tests/servers/app/newClipping/WinBorder.cpp +++ b/src/tests/servers/app/newClipping/WinBorder.cpp @@ -3,6 +3,8 @@ #include "WinBorder.h" +#include + extern BWindow* wind; WinBorder::WinBorder(BRect frame, const char* name, @@ -12,33 +14,55 @@ WinBorder::WinBorder(BRect frame, const char* name, fColor.red = 255; fColor.green = 203; fColor.blue = 0; + + fRebuildDecRegion = true; } WinBorder::~WinBorder() { } -void WinBorder::set_decorator_region(BRect bounds) +void WinBorder::MovedByHook(float dx, float dy) { - // NOTE: frame is in screen coords - fDecRegion.Include(BRect(bounds.left-3, bounds.top-3, bounds.right+3, bounds.top)); - fDecRegion.Include(BRect(bounds.left-3, bounds.bottom, bounds.right+3, bounds.bottom+3)); - fDecRegion.Include(BRect(bounds.left-3, bounds.top, bounds.left, bounds.bottom)); - fDecRegion.Include(BRect(bounds.right, bounds.top, bounds.right+3, bounds.bottom)); - - fDecRegion.Include(BRect(bounds.left-3, bounds.top-3-10, bounds.left+bounds.Width()/2, bounds.top-3)); - // fDecRegion + fDecRegion.OffsetBy(dx, dy); } -void WinBorder::operate_on_visible(BRegion ®ion) +void WinBorder::ResizedByHook(float dx, float dy, bool automatic) { - + fRebuildDecRegion = true; +} + +void WinBorder::set_decorator_region(BRect bounds) +{ + fRebuildDecRegion = false; + + fDecRegion.MakeEmpty(); + // NOTE: frame is in screen coords + fDecRegion.Include(BRect(bounds.left-4, bounds.top-4, bounds.right+4, bounds.top-1)); + fDecRegion.Include(BRect(bounds.left-4, bounds.bottom+1, bounds.right+4, bounds.bottom+4)); + fDecRegion.Include(BRect(bounds.left-4, bounds.top, bounds.left-1, bounds.bottom)); + fDecRegion.Include(BRect(bounds.right+1, bounds.top, bounds.right+4, bounds.bottom)); + + // tab + fDecRegion.Include(BRect(bounds.left-4, bounds.top-4-10, bounds.left+bounds.Width()/2, bounds.top-4)); + + // resize rect + fDecRegion.Include(BRect(bounds.right-10, bounds.bottom-10, bounds.right, bounds.bottom)); +} + +bool WinBorder::alter_visible_for_children(BRegion ®ion) +{ + region.Exclude(&fDecRegion); + return true; } void WinBorder::set_user_regions(BRegion ®) { - set_decorator_region(Bounds()); - ConvertToScreen2(&fDecRegion); + if (fRebuildDecRegion) + { + set_decorator_region(Bounds()); + ConvertToScreen2(&fDecRegion); + } BRect screenFrame(Bounds()); ConvertToScreen2(&screenFrame); diff --git a/src/tests/servers/app/newClipping/WinBorder.h b/src/tests/servers/app/newClipping/WinBorder.h index 8f43cfeb4d..109548cd49 100644 --- a/src/tests/servers/app/newClipping/WinBorder.h +++ b/src/tests/servers/app/newClipping/WinBorder.h @@ -7,10 +7,15 @@ public: WinBorder(BRect frame, const char* name, uint32 rm, uint32 flags, rgb_color c); ~WinBorder(); + + virtual void MovedByHook(float dx, float dy); + virtual void ResizedByHook(float dx, float dy, bool automatic); + private: void set_decorator_region(BRect frame); - virtual void operate_on_visible(BRegion ®ion); + virtual bool alter_visible_for_children(BRegion ®ion); virtual void set_user_regions(BRegion ®); BRegion fDecRegion; + bool fRebuildDecRegion; }; diff --git a/src/tests/servers/app/newClipping/main.cpp b/src/tests/servers/app/newClipping/main.cpp index 31e7d4a675..1bbfa63372 100644 --- a/src/tests/servers/app/newClipping/main.cpp +++ b/src/tests/servers/app/newClipping/main.cpp @@ -57,7 +57,7 @@ void clsApp::ReadyToRun() clsMainWindow::clsMainWindow(const char *uWindowTitle) : BWindow( - BRect(50, 50, 500, 450), + BRect(50, 50, 800, 650), uWindowTitle, B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, @@ -92,10 +92,10 @@ void clsMainWindow::test1() // = new WinBorder(BRect(20,20,300,220), "lay1", B_FOLLOW_NONE, 0, c); // topLayer->AddLayer(lay1); // ------ - WinBorder *wb1 = new WinBorder(BRect(20,20,300,220), "wb1", B_FOLLOW_NONE, 0, c); + WinBorder *wb1 = new WinBorder(BRect(20,20,300,220), "wb1", B_FOLLOW_NONE, B_FULL_UPDATE_ON_RESIZE, c); topLayer->AddLayer(wb1); - Layer *lay1 - = new Layer(BRect(0,0,280,200), "lay1", B_FOLLOW_NONE, 0, c); + // same size as wb1 + Layer *lay1 = new Layer(BRect(0,0,280,200), "lay1", B_FOLLOW_NONE, 0, c); wb1->AddLayer(lay1); // ------ c.red = rand()/256; @@ -114,14 +114,62 @@ void clsMainWindow::test1() 0, c); lay2->AddLayer(lay3); + c.red = rand()/256; + c.green = rand()/256; + c.blue = rand()/256; + Layer *lay12 = new Layer(BRect(170,20,290,150), "lay21", + B_FOLLOW_NONE, + B_FULL_UPDATE_ON_RESIZE, c); + lay1->AddLayer(lay12); + + c.red = rand()/256; + c.green = rand()/256; + c.blue = rand()/256; + Layer *lay13 = new Layer(BRect(20,20,100,100), "lay31", + B_FOLLOW_LEFT | B_FOLLOW_BOTTOM, + 0, c); + lay12->AddLayer(lay13); + + +//--------- + c.red = rand()/256; + c.green = rand()/256; + c.blue = rand()/256; + WinBorder *wb2 = new WinBorder(BRect(280,120,600,420), "wb2", B_FOLLOW_NONE, B_FULL_UPDATE_ON_RESIZE, c); + topLayer->AddLayer(wb2); + Layer *lay21 = new Layer(wb2->Bounds().OffsetToCopy(0,0), "lay21", B_FOLLOW_NONE, 0, c); + wb2->AddLayer(lay21); + + c.red = rand()/256; + c.green = rand()/256; + c.blue = rand()/256; + Layer *lay22 = new Layer(BRect(20,20,150,150), "lay22", + B_FOLLOW_NONE, + 0, c); + lay21->AddLayer(lay22); + +//--------- + BRegion temp; wb1->GetWantedRegion(temp); topLayer->RebuildVisibleRegions(temp, wb1); + wb2->GetWantedRegion(temp); + topLayer->RebuildVisibleRegions(temp, wb2); + wind->Lock(); fView->Invalidate(); wind->Unlock(); + snooze(2000000); + + wb1->Hide(); + + snooze(2000000); + + wb1->Show(); + +/* snooze(2000000); @@ -151,7 +199,7 @@ void clsMainWindow::test1() snooze(2000000); lay1->Invalidate(BRect(0,0,500,500)); - +*/ } int main()