managed to show/hide empty windows with the new clipping code

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13221 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Adi Oanca 2005-06-21 20:11:44 +00:00
parent 718c4fe0c4
commit 3df649ecb3
6 changed files with 185 additions and 112 deletions

View File

@ -86,13 +86,12 @@ Layer::Layer(BRect frame, const char* name, int32 token,
#ifndef NEW_CLIPPING
fVisible(),
fFullVisible(),
fFull(),
fFrameAction(B_LAYER_ACTION_NONE),
#else
fVisible2(),
fFullVisible2(),
#endif
#ifndef NEW_CLIPPING
fFull(),
#endif
#ifndef NEW_CLIPPING
fClipReg(&fVisible),
@ -113,10 +112,6 @@ Layer::Layer(BRect frame, const char* name, int32 token,
fAdFlags(0),
fClassID(AS_LAYER_CLASS),
#ifndef NEW_CLIPPING
fFrameAction(B_LAYER_ACTION_NONE),
#endif
fDriver(driver),
fLayerData(new LayerData()),
@ -427,6 +422,18 @@ Layer::LayerAt(const BPoint &pt)
return lay;
}
}
#else
if (fVisible2.Contains(pt))
return this;
if (fFullVisible2.Contains(pt)) {
Layer *lay = NULL;
for (Layer* child = BottomChild(); child; child = UpperSibling()) {
lay = child->LayerAt(pt);
if (lay)
return lay;
}
}
#endif
return NULL;
}
@ -919,12 +926,12 @@ Layer::Show(bool invalidate)
// for Windows that have been resized before they were shown. -Stephan
#ifndef NEW_CLIPPING
RebuildFullRegion();
#endif
SendViewCoordUpdateMsg();
#ifndef NEW_CLIPPING
if (invalidate)
GetRootLayer()->GoInvalidate(this, fFull);
#else
#endif
}
@ -1334,6 +1341,10 @@ Layer::UpdateEnd()
}
}
#ifndef NEW_CLIPPING
// move_layer
void
Layer::move_layer(float x, float y)
@ -1345,28 +1356,23 @@ Layer::move_layer(float x, float y)
wb->fUpdateReg.OffsetBy(x, y);
}*/
#ifndef NEW_CLIPPING
fFrameAction = B_LAYER_ACTION_MOVE;
BPoint pt(x, y);
BRect rect(fFull.Frame().OffsetByCopy(pt));
#endif
if (!fParent) {
printf("no parent in Layer::move_layer() (%s)\n", GetName());
#ifndef NEW_CLIPPING
fFrameAction = B_LAYER_ACTION_NONE;
#endif
return;
}
#ifndef NEW_CLIPPING
fParent->StartRebuildRegions(BRegion(rect), this, B_LAYER_MOVE, pt);
fDriver->CopyRegionList(&fRootLayer->fCopyRegList,
&fRootLayer->fCopyList,
fRootLayer->fCopyRegList.CountItems(),
&fFullVisible);
#endif
fParent->Redraw(fRootLayer->fRedrawReg, this);
@ -1374,41 +1380,31 @@ return;
EmptyGlobals();
#ifndef NEW_CLIPPING
fFrameAction = B_LAYER_ACTION_NONE;
#endif
}
// resize_layer
void
Layer::resize_layer(float x, float y)
{
#ifndef NEW_CLIPPING
fFrameAction = B_LAYER_ACTION_RESIZE;
BPoint pt(x,y);
#endif
#ifndef NEW_CLIPPING
BRect rect(fFull.Frame());
#else
BRect rect(Frame());
#endif
rect.right += x;
rect.bottom += y;
if (!fParent) {
printf("no parent in Layer::resize_layer() (%s)\n", GetName());
#ifndef NEW_CLIPPING
fFrameAction = B_LAYER_ACTION_NONE;
#endif
return;
}
#ifndef NEW_CLIPPING
fParent->StartRebuildRegions(BRegion(rect), this, B_LAYER_RESIZE, pt);
fDriver->CopyRegionList(&fRootLayer->fCopyRegList, &fRootLayer->fCopyList, fRootLayer->fCopyRegList.CountItems(), &fFullVisible);
#endif
fParent->Redraw(fRootLayer->fRedrawReg, this);
@ -1416,9 +1412,7 @@ return;
EmptyGlobals();
#ifndef NEW_CLIPPING
fFrameAction = B_LAYER_ACTION_NONE;
#endif
}
// FullInvalidate
@ -1439,10 +1433,8 @@ Layer::FullInvalidate(const BRegion& region)
printf("\n");
#endif
#ifndef NEW_CLIPPING
BPoint pt(0,0);
StartRebuildRegions(region, NULL,/* B_LAYER_INVALIDATE, pt); */B_LAYER_NONE, pt);
#endif
Redraw(fRootLayer->fRedrawReg);
@ -1466,12 +1458,16 @@ Layer::Invalidate(const BRegion& region)
EmptyGlobals();
}
#endif // 5 methods
// RequestDraw
void
Layer::RequestDraw(const BRegion &reg, Layer *startFrom)
{
STRACE(("Layer(%s)::RequestDraw()\n", GetName()));
printf("Layer(%s)::RequestDraw()\n", GetName());
//if (fClassID == AS_ROOTLAYER_CLASS)
// debugger("z");
// do not redraw any child until you must
int redraw = false;
if (!startFrom)
@ -1480,11 +1476,12 @@ Layer::RequestDraw(const BRegion &reg, Layer *startFrom)
if (HasClient() && IsTopLayer()) {
// calculate the minimum region/rectangle to be updated with
// a single message to the client.
BRegion updateReg
#ifndef NEW_CLIPPING
(fFullVisible)
BRegion updateReg(fFullVisible);
#else
BRegion updateReg(fFullVisible2);
#endif
;
if (fFlags & B_FULL_UPDATE_ON_RESIZE
#ifndef NEW_CLIPPING
&& fFrameAction == B_LAYER_ACTION_RESIZE
@ -1513,12 +1510,7 @@ if (fOwner->cnt != 1)
if (fVisible.CountRects() > 0) {
BRegion updateReg(fVisible);
// calculate the update region
if (fFlags & B_FULL_UPDATE_ON_RESIZE
#ifndef NEW_CLIPPING
&& fFrameAction == B_LAYER_ACTION_RESIZE
#endif
)
{
if (fFlags & B_FULL_UPDATE_ON_RESIZE && fFrameAction == B_LAYER_ACTION_RESIZE) {
// do nothing
} else {
updateReg.IntersectWith(&reg);
@ -1530,7 +1522,7 @@ if (fOwner->cnt != 1)
fDriver->ConstrainClippingRegion(NULL);
}
}
#endif
for (Layer *lay = BottomChild(); lay != NULL; lay = UpperSibling()) {
if (lay == startFrom)
redraw = true;
@ -1538,15 +1530,48 @@ if (fOwner->cnt != 1)
if (redraw && !(lay->IsHidden())) {
// no need to go deeper if not even the FullVisible region intersects
// Update one.
#ifndef NEW_CLIPPING
BRegion common(lay->fFullVisible);
common.IntersectWith(&reg);
if (common.CountRects() > 0)
lay->RequestDraw(reg, NULL);
#endif
}
}
#else
if (fVisible2.CountRects() > 0) {
BRegion updateReg(fVisible2);
// calculate the update region
if (fFlags & B_FULL_UPDATE_ON_RESIZE
// TODO: must be replaced!
// && fFrameAction == B_LAYER_ACTION_RESIZE
) {
// do nothing
} else {
updateReg.IntersectWith(&reg);
}
if (updateReg.CountRects() > 0) {
fDriver->ConstrainClippingRegion(&updateReg);
Draw(updateReg.Frame());
fDriver->ConstrainClippingRegion(NULL);
}
}
for (Layer *lay = BottomChild(); lay != NULL; lay = UpperSibling()) {
if (lay == startFrom)
redraw = true;
if (redraw && !(lay->IsHidden())) {
// no need to go deeper if not even the FullVisible region intersects
// Update one.
BRegion common(lay->fFullVisible2);
common.IntersectWith(&reg);
if (common.CountRects() > 0)
lay->RequestDraw(reg, NULL);
}
}
#endif
}
/*!
@ -1697,6 +1722,19 @@ Layer::do_Invalidate(const BRegion &invalid, const Layer *startFrom)
// GetRootLayer()->RequestRedraw(); // TODO: what if we pass (fParent, startFromTHIS, &redrawReg)?
}
void
Layer::do_Redraw(const BRegion &invalid, const Layer *startFrom)
{
BRegion localVisible(fFullVisible2);
localVisible.IntersectWith(&invalid);
// add localVisible to our RootLayer's redraw region.
GetRootLayer()->fRedrawReg.Include(&localVisible);
// TODO: ---
GetRootLayer()->RequestDraw(GetRootLayer()->fRedrawReg, BottomChild());
// GetRootLayer()->RequestRedraw(); // TODO: what if we pass (fParent, startFromTHIS, &redrawReg)?
}
inline void
Layer::resize_layer_frame_by(float x, float y)
{

View File

@ -209,6 +209,9 @@ class Layer {
inline const ServerBitmap* OverlayBitmap() const
{ return fOverlayBitmap; }
#ifdef NEW_CLIPPING
inline const BRegion& VisibleRegion() const { return fVisible2; }
inline const BRegion& FullVisible() const { return fFullVisible2; }
virtual void MovedByHook(float dx, float dy) { }
virtual void ResizedByHook(float dx, float dy, bool automatic) { }
virtual void ScrolledByHook(float dx, float dy) { }
@ -228,6 +231,9 @@ class Layer {
void do_Invalidate( const BRegion &invalid,
const Layer *startFrom = NULL);
void do_Redraw( const BRegion &invalid,
const Layer *startFrom = NULL);
void rebuild_visible_regions(const BRegion &invalid,
const BRegion &parentLocalVisible,
const Layer *startFrom);
@ -247,12 +253,14 @@ class Layer {
friend class WinBorder;
friend class ServerWindow;
#ifndef NEW_CLIPPING
void move_layer(float x, float y);
void resize_layer(float x, float y);
void FullInvalidate(const BRect& rect);
void FullInvalidate(const BRegion& region);
void Invalidate(const BRegion& region);
#endif
BRect fFrame;
// TODO: should be removed or reused in a similar fashion
@ -272,14 +280,13 @@ class Layer {
#ifndef NEW_CLIPPING
BRegion fVisible;
BRegion fFullVisible;
BRegion fFull;
int8 fFrameAction;
#else
private:
BRegion fVisible2;
BRegion fFullVisible2;
protected:
#endif
#ifndef NEW_CLIPPING
BRegion fFull;
#endif
BRegion* fClipReg;
@ -294,9 +301,6 @@ class Layer {
bool fIsTopLayer;
uint16 fAdFlags;
int8 fClassID;
#ifndef NEW_CLIPPING
int8 fFrameAction;
#endif
DisplayDriver* fDriver;
LayerData* fLayerData;

View File

@ -227,8 +227,16 @@ RootLayer::WorkingThread(void *data)
oneRootLayer->Lock();
#ifndef NEW_CLIPPING
oneRootLayer->RebuildFullRegion();
#endif
oneRootLayer->invalidate_layer(oneRootLayer, oneRootLayer->Bounds());
#else
oneRootLayer->rebuild_visible_regions(
BRegion(oneRootLayer->Bounds()),
BRegion(oneRootLayer->Bounds()),
oneRootLayer->BottomChild());
oneRootLayer->fRedrawReg.Include(oneRootLayer->Bounds());
oneRootLayer->RequestDraw(oneRootLayer->fRedrawReg, oneRootLayer->BottomChild());
#endif
oneRootLayer->Unlock();
STRACE(("info: RootLayer(%s)::WorkingThread listening on port %ld.\n", oneRootLayer->GetName(), oneRootLayer->fListenPort));
@ -280,11 +288,16 @@ RootLayer::WorkingThread(void *data)
}
case AS_ROOTLAYER_DO_INVALIDATE:
{
printf("Adi: new message\n");
BRegion invalidRegion;
Layer *layer = NULL;
messageQueue.Read<Layer*>(&layer);
messageQueue.ReadRegion(&invalidRegion);
#ifndef NEW_CLIPPING
oneRootLayer->invalidate_layer(layer, invalidRegion);
#else
layer->do_Invalidate(invalidRegion);
#endif
break;
}
case AS_ROOTLAYER_DO_REDRAW:
@ -293,7 +306,11 @@ RootLayer::WorkingThread(void *data)
Layer *layer = NULL;
messageQueue.Read<Layer*>(&layer);
messageQueue.ReadRegion(&redrawRegion);
#ifndef NEW_CLIPPING
oneRootLayer->redraw_layer(layer, redrawRegion);
#else
layer->do_Redraw(redrawRegion);
#endif
break;
}
case AS_ROOTLAYER_LAYER_MOVE:
@ -303,7 +320,11 @@ RootLayer::WorkingThread(void *data)
messageQueue.Read<Layer*>(&layer);
messageQueue.Read<float>(&x);
messageQueue.Read<float>(&y);
#ifndef NEW_CLIPPING
layer->move_layer(x, y);
#else
layer->do_MoveBy(x, y);
#endif
break;
}
case AS_ROOTLAYER_LAYER_RESIZE:
@ -313,7 +334,11 @@ RootLayer::WorkingThread(void *data)
messageQueue.Read<Layer*>(&layer);
messageQueue.Read<float>(&x);
messageQueue.Read<float>(&y);
#ifndef NEW_CLIPPING
layer->resize_layer(x, y);
#else
layer->do_ResizeBy(x, y);
#endif
break;
}
case AS_ROOTLAYER_ADD_TO_SUBSET:
@ -375,11 +400,13 @@ RootLayer::GoInvalidate(const Layer *layer, const BRegion &region)
{
BPrivate::PortLink msg(fListenPort, -1);
msg.StartMessage(AS_ROOTLAYER_DO_INVALIDATE);
//debugger("y");
msg.Attach<const Layer*>(layer);
msg.AttachRegion(region);
msg.Flush();
}
#ifndef NEW_CLIPPING
void RootLayer::invalidate_layer(Layer *layer, const BRegion &region)
{
// NOTE: our thread (WorkingThread) is locked here.
@ -390,7 +417,7 @@ void RootLayer::invalidate_layer(Layer *layer, const BRegion &region)
layer->FullInvalidate(region);
}
#endif
status_t
RootLayer::EnqueueMessage(BPrivate::PortLink &message)
@ -411,7 +438,7 @@ RootLayer::GoRedraw(const Layer *layer, const BRegion &region)
msg.Flush();
}
#ifndef NEW_CLIPPING
void
RootLayer::redraw_layer(Layer *layer, const BRegion &region)
{
@ -419,7 +446,7 @@ RootLayer::redraw_layer(Layer *layer, const BRegion &region)
layer->Invalidate(region);
}
#endif
void
RootLayer::GoChangeWinBorderFeel(const WinBorder *winBorder, int32 newFeel)
@ -1921,9 +1948,10 @@ RootLayer::show_winBorder(WinBorder *winBorder)
if (fActiveWksIndex == i)
invalidate = invalid;
}
printf("Adi 1\n");
if (invalidate)
show_final_scene(exFocus, exActive);
printf("Adi 2\n");
}
void RootLayer::hide_winBorder(WinBorder *winBorder)
@ -2029,7 +2057,11 @@ bool RootLayer::get_workspace_windows()
present = true;
if (!present)
#ifndef NEW_CLIPPING
empty_visible_regions(fWinBorderList2[i]);
#else
fWinBorderList2[i]->clear_visible_regions();
#endif
}
}
@ -2067,6 +2099,7 @@ RootLayer::draw_window_tab(WinBorder *exFocus)
}
}
#ifndef NEW_CLIPPING
inline void
RootLayer::empty_visible_regions(Layer *layer)
{
@ -2074,16 +2107,16 @@ RootLayer::empty_visible_regions(Layer *layer)
// NOTE: first 'layer' must be a WinBorder
Layer *child;
#ifndef NEW_CLIPPING
layer->fFullVisible.MakeEmpty();
layer->fVisible.MakeEmpty();
#endif
child = layer->BottomChild();
while(child) {
empty_visible_regions(child);
child = layer->UpperSibling();
}
}
#endif
inline void
RootLayer::winborder_activation(WinBorder* exActive)
@ -2109,13 +2142,12 @@ RootLayer::show_final_scene(WinBorder *exFocus, WinBorder *exActive)
fHaveWinBorderList = false;
// TODO: should it be improved by calling with region of hidden windows
// plus the full regions of new windows???
invalidate_layer(this,
#ifndef NEW_CLIPPING
fFull
invalidate_layer(this, fFull);
#else
Frame()
// TODO: hmm. Bounds()? Yes, this its OK, for the moment!!! think!
do_Invalidate(Bounds());
#endif
);
}
draw_window_tab(exFocus);

View File

@ -160,11 +160,11 @@ friend class Desktop;
bool get_workspace_windows();
void draw_window_tab(WinBorder *exFocus);
#ifndef NEW_CLIPPING
void empty_visible_regions(Layer *layer);
void invalidate_layer(Layer *layer, const BRegion &region);
void redraw_layer(Layer *layer, const BRegion &region);
#endif
void winborder_activation(WinBorder* exActive);
void show_final_scene(WinBorder *exFocus, WinBorder *exActive);

View File

@ -479,15 +479,14 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
if (parent != NULL)
parent->AddChild(newLayer, this);
if (!newLayer->IsHidden()) {
myRootLayer->GoInvalidate(newLayer,
printf("Adi: create %s\n", fName);
if (!newLayer->IsHidden())
#ifndef NEW_CLIPPING
newLayer->fFull
myRootLayer->GoInvalidate(newLayer, newLayer->fFull);
#else
newLayer->Frame()
myRootLayer->GoInvalidate(newLayer, newLayer->Frame());
#endif
);
}
break;
}
case AS_LAYER_DELETE:
@ -910,13 +909,11 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
fCurrentLayer->RebuildFullRegion();
#endif
if (!(fCurrentLayer->IsHidden()))
myRootLayer->GoInvalidate(fCurrentLayer,
#ifndef NEW_CLIPPING
fCurrentLayer->fFull
myRootLayer->GoInvalidate(fCurrentLayer, fCurrentLayer->fFull);
#else
fCurrentLayer->Frame()
myRootLayer->GoInvalidate(fCurrentLayer, fCurrentLayer->Frame());
#endif
);
break;
}
@ -986,13 +983,11 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
fCurrentLayer->RebuildFullRegion();
#endif
if (!(fCurrentLayer->IsHidden()))
myRootLayer->GoInvalidate(fCurrentLayer,
#ifndef NEW_CLIPPING
fCurrentLayer->fFull
myRootLayer->GoInvalidate(fCurrentLayer, fCurrentLayer->fFull);
#else
fCurrentLayer->Frame()
myRootLayer->GoInvalidate(fCurrentLayer, fCurrentLayer->Frame());
#endif
);
break;
}

View File

@ -176,6 +176,8 @@ y = (float)int32(y);
if (fDecorator)
fDecorator->MoveBy(x,y);
#ifndef NEW_CLIPPING
// NOTE: I moved this here from Layer::move_layer()
// Should this have any bad consequences I'm not aware of?
zUpdateReg.OffsetBy(x, y);
@ -199,9 +201,7 @@ fUpdateReg.OffsetBy(x, y);
// has not been added to fParent apperantly. So now
// you ask why fParent is even valid? Me too.
fFrame.OffsetBy(x, y);
#ifndef NEW_CLIPPING
fFull.OffsetBy(x, y);
#endif
fTopLayer->move_layer(x, y);
// ...and here we get really hacky...
fTopLayer->fFrame.OffsetTo(0.0, 0.0);
@ -209,6 +209,10 @@ fUpdateReg.OffsetBy(x, y);
move_layer(x, y);
}
#else
// implement. maybe...
#endif
if (Window()) {
// dispatch a message to the client informing about the changed size
BMessage msg(B_WINDOW_MOVED);
@ -243,28 +247,34 @@ y = (float)int32(y);
x = wantWidth - fFrame.Width();
y = wantHeight - fFrame.Height();
if (x != 0.0 || y != 0.0) {
if (fDecorator)
fDecorator->ResizeBy(x, y);
if (IsHidden()) {
// TODO: See large comment in MoveBy()
fFrame.right += x;
fFrame.bottom += y;
if (x == 0.0 && y == 0.0)
return;
fTopLayer->resize_layer(x, y);
} else {
resize_layer(x, y);
}
if (fDecorator)
fDecorator->ResizeBy(x, y);
if (Window()) {
// send a message to the client informing about the changed size
BRect frame(fTopLayer->Frame());
BMessage msg(B_WINDOW_RESIZED);
msg.AddInt32("width", frame.Width());
msg.AddInt32("height", frame.Height());
Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false);
}
#ifndef NEW_CLIPPING
if (IsHidden()) {
// TODO: See large comment in MoveBy()
fFrame.right += x;
fFrame.bottom += y;
fTopLayer->resize_layer(x, y);
} else {
resize_layer(x, y);
}
#else
// Do? I don't think so. The new move/resize/scroll hooks should handle these
#endif
if (Window()) {
// send a message to the client informing about the changed size
BRect frame(fTopLayer->Frame());
BMessage msg(B_WINDOW_RESIZED);
msg.AddInt32("width", frame.Width());
msg.AddInt32("height", frame.Height());
Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false);
}
}
@ -654,18 +664,11 @@ 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));
if (fDecorator)
{
fDecRegion.MakeEmpty();
fDecorator->GetFootprint(&fDecRegion);
}
}
bool WinBorder::alter_visible_for_children(BRegion &region)
@ -679,7 +682,8 @@ void WinBorder::get_user_regions(BRegion &reg)
if (fRebuildDecRegion)
{
set_decorator_region(Bounds());
ConvertToScreen2(&fDecRegion);
// TODO? the decorator should be in WinBorder coordinates?? It's easier not to.
//ConvertToScreen2(&fDecRegion);
}
BRect screenFrame(Bounds());