lots of changes this time...
* further optimized clipping * implemented support for B_FULL_UPDATE_ON_RESIZE flag * added support for hidden layers * implemented Show()/Hide() * implemented Invalidate(region) remains to be done: * fully redraw center and right alligned layers on a resize operation. * additional testing. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12798 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Binary file not shown.
@@ -11,11 +11,12 @@
|
|||||||
|
|
||||||
extern BWindow* wind;
|
extern BWindow* wind;
|
||||||
|
|
||||||
Layer::Layer(BRect frame, const char* name, uint32 rm, rgb_color c)
|
Layer::Layer(BRect frame, const char* name, uint32 rm, uint32 flags, rgb_color c)
|
||||||
{
|
{
|
||||||
fFrame = frame;
|
fFrame = frame;
|
||||||
fOrigin.Set(0.0f, 0.0f);
|
fOrigin.Set(0.0f, 0.0f);
|
||||||
fResizeMode = rm;
|
fResizeMode = rm;
|
||||||
|
fFlags = flags;
|
||||||
fColor = c;
|
fColor = c;
|
||||||
|
|
||||||
fBottom = NULL;
|
fBottom = NULL;
|
||||||
@@ -142,13 +143,74 @@ bool Layer::RemLayer(Layer* layer)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Layer::IsVisuallyHidden() const
|
bool
|
||||||
|
Layer::IsVisuallyHidden() const
|
||||||
{
|
{
|
||||||
// TODO: implement
|
if (fHidden)
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
|
// TODO: remove the following 2 lines when for real.
|
||||||
|
if (fView)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (fParent)
|
||||||
|
return fParent->IsVisuallyHidden();
|
||||||
|
|
||||||
|
return fHidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Layer::resize_layer_frame_by(float x, float y)
|
void
|
||||||
|
Layer::Hide()
|
||||||
|
{
|
||||||
|
fHidden = true;
|
||||||
|
|
||||||
|
if (fParent && !fParent->IsVisuallyHidden() && GetRootLayer())
|
||||||
|
{
|
||||||
|
// save fullVisible so we know what to invalidate
|
||||||
|
BRegion invalid(fFullVisible);
|
||||||
|
|
||||||
|
clear_visible_regions();
|
||||||
|
|
||||||
|
if (invalid.Frame().IsValid())
|
||||||
|
fParent->Invalidate(invalid, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Layer::Show()
|
||||||
|
{
|
||||||
|
fHidden = false;
|
||||||
|
|
||||||
|
if (fParent && !fParent->IsVisuallyHidden() && GetRootLayer())
|
||||||
|
{
|
||||||
|
BRect r(Bounds());
|
||||||
|
|
||||||
|
if (r.IsValid())
|
||||||
|
{
|
||||||
|
ConvertToScreen2(&r);
|
||||||
|
|
||||||
|
BRegion invalid(r);
|
||||||
|
|
||||||
|
fParent->Invalidate(invalid, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Layer::Invalidate(const BRegion &invalid, const Layer *startFrom)
|
||||||
|
{
|
||||||
|
BRegion localVisible(fFullVisible);
|
||||||
|
localVisible.IntersectWith(&invalid);
|
||||||
|
rebuild_visible_regions(invalid, localVisible,
|
||||||
|
startFrom? startFrom: VirtualBottomChild());
|
||||||
|
|
||||||
|
// add localVisible to our RootLayer's redraw region.
|
||||||
|
GetRootLayer()->fRedrawReg.Include(&localVisible);
|
||||||
|
GetRootLayer()->RequestRedraw(); // TODO: what if we pass (fParent, startFromTHIS, &redrawReg)?
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Layer::resize_layer_frame_by(float x, float y)
|
||||||
{
|
{
|
||||||
uint16 rm = fResizeMode & 0x0000FFFF;
|
uint16 rm = fResizeMode & 0x0000FFFF;
|
||||||
BRect newFrame = fFrame;
|
BRect newFrame = fFrame;
|
||||||
@@ -191,6 +253,10 @@ void Layer::resize_layer_frame_by(float x, float y)
|
|||||||
|
|
||||||
fFrame = newFrame;
|
fFrame = newFrame;
|
||||||
|
|
||||||
|
// call hook function
|
||||||
|
if (dx != 0.0f || dy != 0.0f)
|
||||||
|
ResizedByHook(dx, dy, true); // automatic
|
||||||
|
|
||||||
for (Layer *lay = VirtualBottomChild(); lay ; lay = VirtualUpperSibling())
|
for (Layer *lay = VirtualBottomChild(); lay ; lay = VirtualUpperSibling())
|
||||||
{
|
{
|
||||||
lay->resize_layer_frame_by(dx, dy);
|
lay->resize_layer_frame_by(dx, dy);
|
||||||
@@ -199,8 +265,7 @@ void Layer::resize_layer_frame_by(float x, float y)
|
|||||||
|
|
||||||
void Layer::ResizeBy(float dx, float dy)
|
void Layer::ResizeBy(float dx, float dy)
|
||||||
{
|
{
|
||||||
// TODO: add support for B_FULL_UPDATE_ON_RESIZE
|
// TODO: center and right alligned view must be fully redrawn - ISN'T THIS DONE ALREADY? - TEST!
|
||||||
// TODO: center and right alligned view must be full redrawn
|
|
||||||
|
|
||||||
fFrame.Set(fFrame.left, fFrame.top, fFrame.right+dx, fFrame.bottom+dy);
|
fFrame.Set(fFrame.left, fFrame.top, fFrame.right+dx, fFrame.bottom+dy);
|
||||||
|
|
||||||
@@ -237,12 +302,16 @@ void Layer::ResizeBy(float dx, float dy)
|
|||||||
|
|
||||||
// add redrawReg to our RootLayer's redraw region.
|
// add redrawReg to our RootLayer's redraw region.
|
||||||
GetRootLayer()->fRedrawReg.Include(&redrawReg);
|
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);
|
||||||
|
// clear canvas and set invalid regions for affected WinBorders
|
||||||
GetRootLayer()->RequestRedraw(); // TODO: what if we pass (fParent, startFromTHIS, &redrawReg)?
|
GetRootLayer()->RequestRedraw(); // TODO: what if we pass (fParent, startFromTHIS, &redrawReg)?
|
||||||
}
|
}
|
||||||
|
|
||||||
// call hook function
|
// call hook function
|
||||||
if (dx != 0.0f || dy != 0.0f)
|
if (dx != 0.0f || dy != 0.0f)
|
||||||
ResizedByHook(dx, dy);
|
ResizedByHook(dx, dy, false); // manual
|
||||||
}
|
}
|
||||||
|
|
||||||
void Layer::MoveBy(float dx, float dy)
|
void Layer::MoveBy(float dx, float dy)
|
||||||
@@ -371,7 +440,18 @@ void Layer::rebuild_visible_regions(const BRegion &invalid,
|
|||||||
const BRegion &parentLocalVisible,
|
const BRegion &parentLocalVisible,
|
||||||
const Layer *startFrom)
|
const Layer *startFrom)
|
||||||
{
|
{
|
||||||
|
// no point in continuing if this layer is hidden. starting from here, all
|
||||||
|
// descendants have (and will have) invalid visible regions.
|
||||||
|
if (fHidden)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// no need to go deeper if the parent doesn't have a visible region anymore
|
||||||
|
// and our fullVisible region is also empty.
|
||||||
|
if (!parentLocalVisible.Frame().IsValid() && !fFullVisible.Frame().IsValid())
|
||||||
|
return;
|
||||||
|
|
||||||
bool fullRebuild = false;
|
bool fullRebuild = false;
|
||||||
|
|
||||||
// intersect maximum wanted region with the invalid region
|
// intersect maximum wanted region with the invalid region
|
||||||
BRegion common;
|
BRegion common;
|
||||||
set_user_regions(common);
|
set_user_regions(common);
|
||||||
@@ -403,7 +483,7 @@ void Layer::rebuild_visible_regions(const BRegion &invalid,
|
|||||||
// our children.
|
// our children.
|
||||||
|
|
||||||
// Don't worry about the last line from this method, it will do nothing -
|
// 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.
|
// common is invalid. Same goes for the last two in the 'for' statement below.
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Layer *lay = VirtualBottomChild(); lay ; lay = VirtualUpperSibling())
|
for (Layer *lay = VirtualBottomChild(); lay ; lay = VirtualUpperSibling())
|
||||||
@@ -425,6 +505,10 @@ void Layer::rebuild_visible_regions(const BRegion &invalid,
|
|||||||
|
|
||||||
void Layer::clear_visible_regions()
|
void Layer::clear_visible_regions()
|
||||||
{
|
{
|
||||||
|
// OPT: maybe we should uncomment these lines for performance
|
||||||
|
// if (fFullVisible.CountRects() <= 0)
|
||||||
|
// return;
|
||||||
|
|
||||||
fVisible.MakeEmpty();
|
fVisible.MakeEmpty();
|
||||||
fFullVisible.MakeEmpty();
|
fFullVisible.MakeEmpty();
|
||||||
Layer *child = VirtualBottomChild();
|
Layer *child = VirtualBottomChild();
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ class MyView;
|
|||||||
class Layer
|
class Layer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Layer(BRect frame, const char* name, uint32 rm, rgb_color c);
|
Layer(BRect frame, const char* name, uint32 rm, uint32 flags, rgb_color c);
|
||||||
virtual ~Layer();
|
virtual ~Layer();
|
||||||
|
|
||||||
void AddLayer(Layer* layer);
|
void AddLayer(Layer* layer);
|
||||||
@@ -18,8 +18,12 @@ public:
|
|||||||
void ResizeBy(float dx, float dy);
|
void ResizeBy(float dx, float dy);
|
||||||
void ScrollBy(float dx, float dy);
|
void ScrollBy(float dx, float dy);
|
||||||
|
|
||||||
|
bool IsVisuallyHidden() const;
|
||||||
|
void Hide();
|
||||||
|
void Show();
|
||||||
|
|
||||||
virtual void MovedByHook(float dx, float dy) { }
|
virtual void MovedByHook(float dx, float dy) { }
|
||||||
virtual void ResizedByHook(float dx, float dy) { }
|
virtual void ResizedByHook(float dx, float dy, bool automatic) { }
|
||||||
virtual void ScrolledByHook(float dx, float dy) { }
|
virtual void ScrolledByHook(float dx, float dy) { }
|
||||||
|
|
||||||
Layer* VirtualBottomChild() const;
|
Layer* VirtualBottomChild() const;
|
||||||
@@ -27,12 +31,13 @@ public:
|
|||||||
Layer* VirtualUpperSibling() const;
|
Layer* VirtualUpperSibling() const;
|
||||||
Layer* VirtualLowerSibling() const;
|
Layer* VirtualLowerSibling() const;
|
||||||
|
|
||||||
|
void Invalidate( const BRegion &invalid,
|
||||||
|
const Layer *startFrom = NULL);
|
||||||
void RebuildVisibleRegions( const BRegion &invalid,
|
void RebuildVisibleRegions( const BRegion &invalid,
|
||||||
const Layer *startFrom);
|
const Layer *startFrom);
|
||||||
void ConvertToScreen2(BRect* rect);
|
void ConvertToScreen2(BRect* rect);
|
||||||
MyView* GetRootLayer() const;
|
MyView* GetRootLayer() const;
|
||||||
void SetRootLayer(MyView* view) { fView = view; }
|
void SetRootLayer(MyView* view) { fView = view; }
|
||||||
bool IsVisuallyHidden() const;
|
|
||||||
|
|
||||||
BRegion* Visible() { return &fVisible; }
|
BRegion* Visible() { return &fVisible; }
|
||||||
BRegion* FullVisible() { return &fFullVisible; }
|
BRegion* FullVisible() { return &fFullVisible; }
|
||||||
@@ -70,5 +75,8 @@ private:
|
|||||||
Layer* fTop;
|
Layer* fTop;
|
||||||
Layer* fParent;
|
Layer* fParent;
|
||||||
|
|
||||||
|
uint32 fFlags;
|
||||||
|
bool fHidden;
|
||||||
|
|
||||||
MyView* fView;
|
MyView* fView;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ MyView::MyView(BRect frame, const char *name, uint32 resizingMode, uint32 flags)
|
|||||||
col.red = 49;
|
col.red = 49;
|
||||||
col.green = 101;
|
col.green = 101;
|
||||||
col.blue = 156;
|
col.blue = 156;
|
||||||
topLayer = new Layer(Bounds(), "topLayer", B_FOLLOW_ALL, col);
|
topLayer = new Layer(Bounds(), "topLayer", B_FOLLOW_ALL, 0, col);
|
||||||
topLayer->SetRootLayer(this);
|
topLayer->SetRootLayer(this);
|
||||||
|
|
||||||
topLayer->rebuild_visible_regions(BRegion(Bounds()), BRegion(Bounds()), NULL);
|
topLayer->rebuild_visible_regions(BRegion(Bounds()), BRegion(Bounds()), NULL);
|
||||||
@@ -70,6 +70,9 @@ void MyView::RequestRedraw()
|
|||||||
void MyView::Draw(BRect area)
|
void MyView::Draw(BRect area)
|
||||||
{
|
{
|
||||||
ConstrainClippingRegion(&fRedrawReg);
|
ConstrainClippingRegion(&fRedrawReg);
|
||||||
|
FillRect(Bounds());
|
||||||
|
Flush();
|
||||||
|
snooze(1000000);
|
||||||
PushState();
|
PushState();
|
||||||
DrawSubTree(topLayer);
|
DrawSubTree(topLayer);
|
||||||
PopState();
|
PopState();
|
||||||
|
|||||||
@@ -88,19 +88,21 @@ void clsMainWindow::test1()
|
|||||||
c.red = rand()/256;
|
c.red = rand()/256;
|
||||||
c.green = rand()/256;
|
c.green = rand()/256;
|
||||||
c.blue = rand()/256;
|
c.blue = rand()/256;
|
||||||
Layer *lay1 = new Layer(BRect(20,20,300,220), "lay1", B_FOLLOW_NONE, c);
|
Layer *lay1 = new Layer(BRect(20,20,300,220), "lay1", B_FOLLOW_NONE, 0, c);
|
||||||
topLayer->AddLayer(lay1);
|
topLayer->AddLayer(lay1);
|
||||||
|
|
||||||
c.red = rand()/256;
|
c.red = rand()/256;
|
||||||
c.green = rand()/256;
|
c.green = rand()/256;
|
||||||
c.blue = rand()/256;
|
c.blue = rand()/256;
|
||||||
Layer *lay2 = new Layer(BRect(20,20,150,150), "lay2", B_FOLLOW_NONE, c);
|
Layer *lay2 = new Layer(BRect(20,20,150,150), "lay2",
|
||||||
|
B_FOLLOW_NONE,
|
||||||
|
B_FULL_UPDATE_ON_RESIZE, c);
|
||||||
lay1->AddLayer(lay2);
|
lay1->AddLayer(lay2);
|
||||||
|
|
||||||
c.red = rand()/256;
|
c.red = rand()/256;
|
||||||
c.green = rand()/256;
|
c.green = rand()/256;
|
||||||
c.blue = rand()/256;
|
c.blue = rand()/256;
|
||||||
Layer *lay3 = new Layer(BRect(20,20,100,100), "lay3", B_FOLLOW_NONE, c);
|
Layer *lay3 = new Layer(BRect(20,20,100,100), "lay3", B_FOLLOW_NONE, 0, c);
|
||||||
lay2->AddLayer(lay3);
|
lay2->AddLayer(lay3);
|
||||||
|
|
||||||
temp = lay1->Bounds();
|
temp = lay1->Bounds();
|
||||||
@@ -110,22 +112,8 @@ void clsMainWindow::test1()
|
|||||||
wind->Lock();
|
wind->Lock();
|
||||||
fView->Invalidate();
|
fView->Invalidate();
|
||||||
wind->Unlock();
|
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();
|
|
||||||
*/
|
|
||||||
snooze(2000000);
|
snooze(2000000);
|
||||||
|
|
||||||
lay2->MoveBy(25,35);
|
lay2->MoveBy(25,35);
|
||||||
@@ -138,6 +126,18 @@ void clsMainWindow::test1()
|
|||||||
|
|
||||||
lay1->ScrollBy(0,50);
|
lay1->ScrollBy(0,50);
|
||||||
|
|
||||||
|
snooze(2000000);
|
||||||
|
|
||||||
|
lay2->Hide();
|
||||||
|
|
||||||
|
snooze(2000000);
|
||||||
|
|
||||||
|
lay2->Show();
|
||||||
|
|
||||||
|
snooze(2000000);
|
||||||
|
|
||||||
|
lay1->Invalidate(BRect(0,0,500,500));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
|
|||||||
Reference in New Issue
Block a user