fully implemented support for B_DOCUMENT_WINDOW_LOOK windows (resize tab overlapping top_view's area). Added support for live moving and resizing the layers shown, resizing is done by dragging from the lower right corner of a layer or winborder. Fixed a bug with for B_FULL_UPDATE_ON_RESIZE flag. More testing remains to be done because there seems to be a problem with clipping under certain circumstances, but I'm nearly finished. :-)

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12872 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Adi Oanca
2005-05-28 20:09:17 +00:00
parent 7d8462aed5
commit 6e795cfe26
8 changed files with 224 additions and 87 deletions
Binary file not shown.
+54 -47
View File
@@ -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 &reg)
bool Layer::alter_visible_for_children(BRegion &reg)
{
// 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();
}
}
+2 -1
View File
@@ -67,7 +67,7 @@ protected:
rgb_color fColor;
private:
virtual void operate_on_visible(BRegion &region);
virtual bool alter_visible_for_children(BRegion &region);
virtual void set_user_regions(BRegion &reg);
void clear_visible_regions();
@@ -87,6 +87,7 @@ private:
Layer* fLower;
Layer* fTop;
Layer* fParent;
mutable Layer* fCurrent;
uint32 fFlags;
bool fHidden;
+63 -19
View File
@@ -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;
+9 -1
View File
@@ -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;
};
+37 -13
View File
@@ -3,6 +3,8 @@
#include "WinBorder.h"
#include <stdio.h>
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 &region)
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 &region)
{
region.Exclude(&fDecRegion);
return true;
}
void WinBorder::set_user_regions(BRegion &reg)
{
set_decorator_region(Bounds());
ConvertToScreen2(&fDecRegion);
if (fRebuildDecRegion)
{
set_decorator_region(Bounds());
ConvertToScreen2(&fDecRegion);
}
BRect screenFrame(Bounds());
ConvertToScreen2(&screenFrame);
@@ -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 &region);
virtual bool alter_visible_for_children(BRegion &region);
virtual void set_user_regions(BRegion &reg);
BRegion fDecRegion;
bool fRebuildDecRegion;
};
+53 -5
View File
@@ -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()