From 4bdd131ac5327f6bf4dc83ceb8bc0b62f847adf7 Mon Sep 17 00:00:00 2001 From: Adi Oanca Date: Mon, 16 May 2005 18:31:01 +0000 Subject: [PATCH] my test app for new clipping code git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12691 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../servers/app/newClipping/Clipping.proj | Bin 0 -> 12013 bytes src/tests/servers/app/newClipping/Layer.cpp | 258 ++++++++++++++++++ src/tests/servers/app/newClipping/Layer.h | 63 +++++ src/tests/servers/app/newClipping/MyView.cpp | 70 +++++ src/tests/servers/app/newClipping/MyView.h | 19 ++ src/tests/servers/app/newClipping/main.cpp | 142 ++++++++++ 6 files changed, 552 insertions(+) create mode 100644 src/tests/servers/app/newClipping/Clipping.proj create mode 100644 src/tests/servers/app/newClipping/Layer.cpp create mode 100644 src/tests/servers/app/newClipping/Layer.h create mode 100644 src/tests/servers/app/newClipping/MyView.cpp create mode 100644 src/tests/servers/app/newClipping/MyView.h create mode 100644 src/tests/servers/app/newClipping/main.cpp diff --git a/src/tests/servers/app/newClipping/Clipping.proj b/src/tests/servers/app/newClipping/Clipping.proj new file mode 100644 index 0000000000000000000000000000000000000000..761e84f00e1a0f52d2ee74701d8c81214ff75d23 GIT binary patch literal 12013 zcmeHNO>ERg6dscWHX(rk30WWzqe!8EHVdMvs5n5vLO>+JV)<#MR>A9?BnIz#Ya0kc zmE0czMNm+x)&>@d+r*3&BGc;2xOa>ILj z1g~pyAs2MnXnGINI}jRif>rYY(9yk#1?XWF^MP&|7yF8{I# ztFIc7oT^`=Z8?(5w0H72xBB@IHx7Gx+Irf9_&>I#U3cQTV+@){o@NLznZXzZ9F%}d zP?_Y_<3nCz^&~q}H?n2T8lm8Yutmc0Lf9f>nHR&Bz?kQ53ua2jp4yxhlMRy*PKPacS(uhIEw*@BYdVaXvMp7N>CzC)-Kjm>rs@!Ev0oHhB1~~yXL@d=X~4ym zz&!8&s7t)NFa5KN=Q`n5qG!KG@9nXUe12=j^lV3Sc)u&+C3>yDb?esS8ni14ez*kP zA}xktAhe1^;La91n>Q`)?8;Lh<1z}6;{AEkP~*GSqh3iB1S$xW7XosbSeCJdmx*q? zbd6pl$_tW;w-p2`2$UiqLy)Gf-d)|`NA~73y2mwaTZtG#Heb#jHE4(T3^iasOT;Hb z8(tAI;QMT$!o$`T!5@6iTIBT*@^B;ZxSm?bn^0 znHvzoV|SQjr-b2q7bIt`)(ZOWq5Ahjux)F8L4;nsN0##gg`Y(SB4`6Y?mdPK>z z*V&9H+2F1l?&EPM#2V}X4)>%klT5T}h_2#7*OI@w zO^#YGLs@tHQKfsKbZydfb=T!te2q@#WohEFjd;s9Ru@ivT~pYMdh<_hh2Q^D z3+kP=0=Y~y+Ys|9|CVIzdYxJf<>#RN()Trmu`&k^1-y&ULwaYNjuw*OkxfJ&cx#cb z&Q*(lZ>lbA2A}j$NxG;cnQIHwqToaBqtBy(eW?F@B0Ai5>+CF{E0iTWs19}P+CsJ1 zWVQ&J_|ZnSNC&*gCXyjrgxxb1`*XoRzO+&JEO?{N9CQfi+%C3){a~Lpqk>Ihj%8oPqQ75?G11ceF6GdEW#y6 zo2M2#PeuzN9z<)Ph0XM5AsN4_1$Hy$F9=9M&j)?_e6;Y=HVCOR8R09M>lr%-9p9mi zPPh^O66j-R0-9E>YoO0{H5M+=4fy2};rI4>wU|Wy7HtuzypQtZ6M@Ww)~b8KYKOCP zkRe&JkNBjc8T8#J$o{aS>K@7Nfh^?@n}U9!-YcMCyR!DHMxVy~T zGU_q#>*2%Y-T<3g)UUp`#0S*uJn|0Y2ITGFqhPp46iiFy4bXqQS?9AKWB#7kdpl^3 zkxVzThD^STdw+M6Pc-qVzg#-P#qpQyQ7Z%X^&rYES)^#aQTqB^Psik&Z0hs4lkIct z!6?3olGn~-QR(zFixN+;6jZLTy<=S=iyPS8Jv%`?OhU(P+lp1@q5&Lg+XMoIyI>XYJl^!!o zvDr%G*3mwUd&;OMwatR)3hGS|5U?obBiCWuk52Wac{@I*%5mxI<*4LKYI5VYQty&+ zY2BD7$8~T*nMU4bTI;~R!dT5(l=Mi%DIeO3WUTW8`=lJX3FJcYeSawK+J_y3#|=Bf zne=cOnnjWx)`6(b>SnH;4*8}W0YkHpfIU*E7Id^*KgON*!B8epG$JDu^&H!0@}m%v z#=ZmP7lpFGJ!x$2;lzwxF1vCe2P0Wy%F^0?oJx4k_ LQA;GYPsZ&Z5#F%` literal 0 HcmV?d00001 diff --git a/src/tests/servers/app/newClipping/Layer.cpp b/src/tests/servers/app/newClipping/Layer.cpp new file mode 100644 index 0000000000..38f11e9f9d --- /dev/null +++ b/src/tests/servers/app/newClipping/Layer.cpp @@ -0,0 +1,258 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Layer.h" + +extern BWindow* wind; + +Layer::Layer(BRect frame, const char* name, uint32 rm, rgb_color c) +{ + fFrame = frame; + fRM = rm; + fColor = c; + + fBottom = NULL; + fUpper = NULL; + fLower = NULL; + fTop = NULL; + fParent = NULL; + fView = NULL; + + strcpy(fName, name); +} + +Layer::~Layer() +{ + Layer *c = fBottom; + Layer *toast; + while (c) + { + toast = c; + c = c->fUpper; + delete toast; + } +} + +void Layer::ConvertToScreen2(BRect* rect) +{ + BView *view = GetRootLayer(); + if (view) + if (fParent) + { + rect->Set( rect->left + fFrame.left, + rect->top + fFrame. top, + rect->right + fFrame.left, + rect->bottom + fFrame.top); + + fParent->ConvertToScreen2(rect); + } +} + +BView* Layer::GetRootLayer() const +{ + if (fView) + return fView; + else + if (fParent) + return fParent->GetRootLayer(); + else + return NULL; +} + +Layer* Layer::VirtualBottomChild() const +{ + return fBottom; +} + +Layer* Layer::VirtualTopChild() const +{ + return fTop; +} + +Layer* Layer::VirtualUpperSibling() const +{ + return fUpper; +} + +Layer* Layer::VirtualLowerSibling() const +{ + return fLower; +} + +void Layer::AddLayer(Layer* layer) +{ + if( layer->fParent != NULL ) + { + printf("ERROR: Layer already has a parent\n"); + return; + } + + layer->fParent = this; + + if (!fBottom) + { + fBottom = layer; + fTop = layer; + return; + } + fBottom->fLower = layer; + layer->fUpper = fBottom; + fBottom = layer; +} + +bool Layer::RemLayer(Layer* layer) +{ + if(!layer->fParent || layer->fParent != this) + { + printf("ERROR: Rem: Layer doesn't have a fParent or !=this\n"); + return false; + } + + layer->fParent = NULL; + + if(fTop == layer) + fTop = layer->fLower; + + if(fBottom == layer ) + fBottom = layer->fUpper; + + if(layer->fUpper != NULL) + layer->fUpper->fLower = layer->fLower; + + if(layer->fLower != NULL) + layer->fLower->fUpper = layer->fUpper; + + layer->fUpper = NULL; + layer->fLower = NULL; + + layer->clear_visible_regions(); + + return true; +} + +void Layer::set_user_regions(BRegion ®) +{ +// OPT: maybe we should have all these cached in a 'fFull' member + + // 1) set to frame in screen coords +// BRect screenFrame(fFrame); + BRect screenFrame(Bounds()); + ConvertToScreen2(&screenFrame); + reg.Set(screenFrame); + + // 2) intersect with screen region +// TODO: remove locking when for real +wind->Lock(); +printf("Adi: RL: %p\n", wind); +printf("Adi: RL: %s\n", wind->Name()); + BRegion screenReg(GetRootLayer()->Bounds()); +wind->Unlock(); + reg.IntersectWith(&screenReg); + +// TODO: you MUST at some point uncomment this block! +/* + // 3) impose user constrained regions + LayerData *stackData = fLayerData; + while (stackData) + { + // transform in screen coords + BRegion screenReg(stackData->ClippingRegion()); + ConvertToScreen2(&screenReg); + reg.IntersectWith(&screenReg); + stackData = stackData->prevState; + } +*/ +} + +void Layer::RebuildVisibleRegions(const BRegion &invalid, const Layer *startFrom) +{ + BRegion localVisible(fFullVisible); + localVisible.IntersectWith(&invalid); + rebuild_visible_regions(invalid, localVisible, startFrom); +} + +void Layer::rebuild_visible_regions(const BRegion &invalid, + const BRegion &parentLocalVisible, + const Layer *startFrom) +{ + bool fullRebuild = false; + // intersect maximum wanted region with the invalid region + BRegion common; + set_user_regions(common); + common.IntersectWith(&invalid); + // if the resulted region is not valid, this layer is not in the catchment area + // of the region being invalidated + if (!common.Frame().IsValid()) + return; + + // now intersect with parent's visible part of the region that was/is invalidated + common.IntersectWith(&parentLocalVisible); +//printf("\t%s: For this layer we invalidate:\n", fName); +//common.PrintToStream(); + if (common.Frame().IsValid()) + { + // we have something to include to our fullVisible. It may already be in + // there, but we'll never know. + fFullVisible.Include(&common); + } + else + { + // this layer is in the catchment area of the region being invalidated, + // yet it will have no new visible area attached to it. It means + // this layer was overshaddowed by those above it and any visible area + // that it may have common with the region being invalidated, must be + // excluded from it's fFullVisible and fVisible regions. + fFullVisible.Exclude(&invalid); + fVisible.Exclude(&invalid); + // we don't return here becase we want the same thing to happen to all + // our children. + + // Don't worry about the last line from this method, it will do nothing - + // common is invalid. Same goes for the last one in the 'for' statement below. + } + + for (Layer *lay = VirtualBottomChild(); lay ; lay = VirtualUpperSibling()) + { + if (lay == startFrom) + fullRebuild = true; + + if (fullRebuild) + lay->rebuild_visible_regions(invalid, common, lay->VirtualBottomChild()); + + common.Exclude(&lay->fFullVisible); +fVisible.Exclude(&lay->fFullVisible); + } + + // the visible region of this layer is what left after all its children took + // what they could. + fVisible.Include(&common); +} + +void Layer::clear_visible_regions() +{ + fVisible.MakeEmpty(); + fFullVisible.MakeEmpty(); + Layer *child = fBottom; + while (child) + { + child->clear_visible_regions(); + child = child->fUpper; + } +} + +void Layer::PrintToStream() const +{ + printf("-> %s\n", fName); + Layer *child = VirtualBottomChild(); + while(child) + { + child->PrintToStream(); + child = child->VirtualUpperSibling(); + } +} diff --git a/src/tests/servers/app/newClipping/Layer.h b/src/tests/servers/app/newClipping/Layer.h new file mode 100644 index 0000000000..22bb446964 --- /dev/null +++ b/src/tests/servers/app/newClipping/Layer.h @@ -0,0 +1,63 @@ +#include +#include +#include +#include + +class BView; + +class Layer +{ +public: + Layer(BRect frame, const char* name, uint32 rm, rgb_color c); + virtual ~Layer(); + + void AddLayer(Layer* layer); + bool RemLayer(Layer* layer); + + Layer* VirtualBottomChild() const; + Layer* VirtualTopChild() const; + Layer* VirtualUpperSibling() const; + Layer* VirtualLowerSibling() const; + + void RebuildVisibleRegions( const BRegion &invalid, + const Layer *startFrom); + void ConvertToScreen2(BRect* rect); + BView* GetRootLayer() const; + void SetRootLayer(BView* view) { fView = view; } + + BRegion* Visible() { return &fVisible; } + BRegion* FullVisible() { return &fFullVisible; } + + BRect Frame() const { return fFrame; } + BRect Bounds() const { BRect r(fFrame); + r.OffsetTo(0,0); + return r; } + const char* Name() const { return fName; } + Layer* Parent() const { return fParent; } + void PrintToStream() const; + + rgb_color HighColor() const { return fColor; } + + void rebuild_visible_regions(const BRegion &invalid, + const BRegion &parentLocalVisible, + const Layer *startFrom); +private: + void set_user_regions(BRegion ®); + void clear_visible_regions(); + + char fName[50]; + BRegion fVisible; + BRegion fFullVisible; + + BRect fFrame; + uint32 fRM; + rgb_color fColor; + + Layer* fBottom; + Layer* fUpper; + Layer* fLower; + Layer* fTop; + Layer* fParent; + + BView* fView; +}; diff --git a/src/tests/servers/app/newClipping/MyView.cpp b/src/tests/servers/app/newClipping/MyView.cpp new file mode 100644 index 0000000000..bb9088f105 --- /dev/null +++ b/src/tests/servers/app/newClipping/MyView.cpp @@ -0,0 +1,70 @@ +#include +#include + +#include + +#include "MyView.h" +#include "Layer.h" + +MyView::MyView(BRect frame, const char *name, uint32 resizingMode, uint32 flags) + : BView(frame, name, resizingMode, flags) +{ + SetViewColor(B_TRANSPARENT_COLOR); + rgb_color col; + col.red = 49; + col.green = 101; + col.blue = 156; + topLayer = new Layer(Bounds(), "topLayer", B_FOLLOW_ALL, col); + topLayer->SetRootLayer(this); + +// topLayer->RebuildVisibleRegions(BRegion(Bounds()), NULL); + topLayer->rebuild_visible_regions(BRegion(Bounds()), BRegion(Bounds()), NULL); +} + +MyView::~MyView() +{ + delete topLayer; +} + +Layer* MyView::FindLayer(Layer *lay, const char *bytes) const +{ + if (strcmp(lay->Name(), bytes) == 0) + return lay; + else + { + Layer *ret = NULL; + Layer *cursor = lay->VirtualBottomChild(); + while(cursor) + { + ret = FindLayer(cursor, bytes); + if (ret) + return ret; + cursor = cursor->VirtualUpperSibling(); + } + } + return NULL; +} + +void MyView::Draw(BRect area) +{ + DrawSubTree(topLayer); +} + +void MyView::DrawSubTree(Layer* lay) +{ +printf("======== %s =======\n", lay->Name()); + lay->Visible()->PrintToStream(); + lay->FullVisible()->PrintToStream(); + Layer *child = lay->VirtualBottomChild(); + while(child) + { + DrawSubTree(child); + child = child->VirtualUpperSibling(); + } + ConstrainClippingRegion(lay->Visible()); + SetHighColor(lay->HighColor()); + BRect temp = lay->Bounds(); + lay->ConvertToScreen2(&temp); + FillRect(temp); + ConstrainClippingRegion(NULL); +} \ No newline at end of file diff --git a/src/tests/servers/app/newClipping/MyView.h b/src/tests/servers/app/newClipping/MyView.h new file mode 100644 index 0000000000..df8f31a7a0 --- /dev/null +++ b/src/tests/servers/app/newClipping/MyView.h @@ -0,0 +1,19 @@ +#include +#include + +class Layer; + +class MyView: public BView +{ +public: + MyView(BRect frame, const char *name, uint32 resizingMode, uint32 flags); + virtual ~MyView(); + + virtual void Draw(BRect area); + + Layer* FindLayer(Layer *lay, const char *bytes) const; + + Layer *topLayer; +private: + void DrawSubTree(Layer* lay); +}; \ No newline at end of file diff --git a/src/tests/servers/app/newClipping/main.cpp b/src/tests/servers/app/newClipping/main.cpp new file mode 100644 index 0000000000..26ab882602 --- /dev/null +++ b/src/tests/servers/app/newClipping/main.cpp @@ -0,0 +1,142 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "MyView.h" +#include "Layer.h" + +#define ApplicationSignature "application/x-vnd.generic-SkeletonApplication" + +BWindow *wind = NULL; + +class clsApp +: + public BApplication +{ +public: + clsApp(); + ~clsApp(); + virtual void ReadyToRun(); +}; + +class clsMainWindow +: + public BWindow +{ +public: + clsMainWindow(const char *uWindowTitle); + ~clsMainWindow(); + + virtual bool QuitRequested(); + void test1(); +private: + MyView *fView; +}; + +clsApp::clsApp() : BApplication(ApplicationSignature) +{ + srand(real_time_clock_usecs()); +} + +clsApp::~clsApp() +{ +} + +void clsApp::ReadyToRun() +{ +} + + +clsMainWindow::clsMainWindow(const char *uWindowTitle) +: + BWindow( + BRect(50, 50, 500, 450), + uWindowTitle, + B_TITLED_WINDOW_LOOK, + B_NORMAL_WINDOW_FEEL, + 0 ) +{ + wind = this; + fView = new MyView(Bounds(), "emu", B_FOLLOW_ALL, B_WILL_DRAW); + AddChild(fView); +} + +clsMainWindow::~clsMainWindow() +{ +} + +bool clsMainWindow::QuitRequested() +{ + be_app->PostMessage(B_QUIT_REQUESTED); + return BWindow::QuitRequested(); +} + +void clsMainWindow::test1() +{ + Layer *topLayer = fView->topLayer; + Layer *parent; + + rgb_color c; + BRect temp; + + c.red = rand()/256; + c.green = rand()/256; + c.blue = rand()/256; + Layer *lay1 = new Layer(BRect(20,20,300,220), "lay1", B_FOLLOW_NONE, c); + topLayer->AddLayer(lay1); + + c.red = rand()/256; + c.green = rand()/256; + c.blue = rand()/256; + Layer *lay2 = new Layer(BRect(20,20,150,150), "lay2", B_FOLLOW_NONE, c); + lay1->AddLayer(lay2); + + c.red = rand()/256; + c.green = rand()/256; + c.blue = rand()/256; + Layer *lay3 = new Layer(BRect(20,20,100,100), "lay3", B_FOLLOW_NONE, c); + lay2->AddLayer(lay3); + + temp = lay1->Bounds(); + lay1->ConvertToScreen2(&temp); + topLayer->RebuildVisibleRegions(BRegion(temp), lay1); + + wind->Lock(); + fView->Invalidate(); + wind->Unlock(); + + snooze(2000000); + + temp = lay2->Bounds(); + lay2->ConvertToScreen2(&temp); + parent = lay2->Parent(); + if (parent) + { + parent->RemLayer(lay2); + parent->RebuildVisibleRegions(BRegion(temp), lay2); + } + + wind->Lock(); + fView->Invalidate(); + wind->Unlock(); + +} + +int main() +{ + new clsApp(); + clsMainWindow *win = new clsMainWindow("clipping"); + win->Show(); + + win->test1(); + + be_app->Run(); + delete be_app; + return 0; +}