my test app for new clipping code
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12691 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
fef11f270b
commit
4bdd131ac5
BIN
src/tests/servers/app/newClipping/Clipping.proj
Normal file
BIN
src/tests/servers/app/newClipping/Clipping.proj
Normal file
Binary file not shown.
258
src/tests/servers/app/newClipping/Layer.cpp
Normal file
258
src/tests/servers/app/newClipping/Layer.cpp
Normal file
@ -0,0 +1,258 @@
|
||||
#include <OS.h>
|
||||
#include <View.h>
|
||||
#include <Window.h>
|
||||
#include <Looper.h>
|
||||
#include <Region.h>
|
||||
#include <Rect.h>
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
|
||||
#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();
|
||||
}
|
||||
}
|
63
src/tests/servers/app/newClipping/Layer.h
Normal file
63
src/tests/servers/app/newClipping/Layer.h
Normal file
@ -0,0 +1,63 @@
|
||||
#include <OS.h>
|
||||
#include <Region.h>
|
||||
#include <Rect.h>
|
||||
#include <GraphicsDefs.h>
|
||||
|
||||
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;
|
||||
};
|
70
src/tests/servers/app/newClipping/MyView.cpp
Normal file
70
src/tests/servers/app/newClipping/MyView.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
#include <Message.h>
|
||||
#include <Messenger.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#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);
|
||||
}
|
19
src/tests/servers/app/newClipping/MyView.h
Normal file
19
src/tests/servers/app/newClipping/MyView.h
Normal file
@ -0,0 +1,19 @@
|
||||
#include <OS.h>
|
||||
#include <View.h>
|
||||
|
||||
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);
|
||||
};
|
142
src/tests/servers/app/newClipping/main.cpp
Normal file
142
src/tests/servers/app/newClipping/main.cpp
Normal file
@ -0,0 +1,142 @@
|
||||
#include <OS.h>
|
||||
#include <Application.h>
|
||||
#include <Window.h>
|
||||
#include <View.h>
|
||||
#include <Region.h>
|
||||
#include <Rect.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user