From 76d68e8ad8aa86c83c94423c14623e84a6ac3ded Mon Sep 17 00:00:00 2001 From: Adi Oanca Date: Wed, 9 Nov 2005 20:14:52 +0000 Subject: [PATCH] More cleanup. * moved code from Layer::do_MoveBy/do_ResizeBy/do_ScrollBy into Layer::MoveBy/ResizeBy/ScrollBy() * removed do_Move/Resize/ScrollBy() * removed WinBorder::_ResizeBy() git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14810 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/Layer.cpp | 345 +++++++++++++++++----------------- src/servers/app/Layer.h | 3 - src/servers/app/WinBorder.cpp | 118 ++++++------ src/servers/app/WinBorder.h | 7 +- 4 files changed, 229 insertions(+), 244 deletions(-) diff --git a/src/servers/app/Layer.cpp b/src/servers/app/Layer.cpp index 7d0801e023..3678c78557 100644 --- a/src/servers/app/Layer.cpp +++ b/src/servers/app/Layer.cpp @@ -564,17 +564,58 @@ Layer::Frame(void) const void Layer::MoveBy(float x, float y) { - STRACE(("Layer(%s)::MoveBy() START\n", Name())); - if (!fParent) { - fFrame.OffsetBy(x, y); + STRACE(("Layer(%s)::MoveBy()\n", Name())); + + if (x == 0.0f && y == 0.0f) return; + + // must lock, even if we change frame coordinates + if (fParent && !IsHidden() && GetRootLayer() && GetRootLayer()->Lock()) { + fFrame.OffsetBy(x, y); + + BRegion oldFullVisible(fFullVisible2); + + // we'll invalidate the old position and the new, maxmial one. + BRegion invalid; + GetWantedRegion(invalid); + invalid.Include(&fFullVisible2); + + fParent->MarkForRebuild(invalid); + fParent->TriggerRebuild(); + + // done rebuilding regions, now copy common parts and redraw regions that became visible + + // include the actual and the old fullVisible regions. later, we'll exclude the common parts. + BRegion redrawReg(fFullVisible2); + redrawReg.Include(&oldFullVisible); + + // offset to layer's new location so that we can calculate the common region. + oldFullVisible.OffsetBy(x, y); + + // finally we have the region that needs to be redrawn. + redrawReg.Exclude(&oldFullVisible); + + // by intersecting the old fullVisible offseted to layer's new location, with the current + // fullVisible, we'll have the common region which can be copied using HW acceleration. + oldFullVisible.IntersectWith(&fFullVisible2); + + // offset back and instruct the HW to do the actual copying. + oldFullVisible.OffsetBy(-x, -y); + GetDrawingEngine()->CopyRegion(&oldFullVisible, x, y); + + GetRootLayer()->MarkForRedraw(redrawReg); + GetRootLayer()->TriggerRedraw(); + + GetRootLayer()->Unlock(); + } + else { + // just offset to the new position + fFrame.OffsetBy(x, y); } - GetRootLayer()->Lock(); - do_MoveBy(x, y); - GetRootLayer()->Unlock(); + MovedByHook(x, y); - STRACE(("Layer(%s)::MoveBy() END\n", Name())); + SendViewCoordUpdateMsg(); } @@ -582,20 +623,88 @@ Layer::MoveBy(float x, float y) void Layer::ResizeBy(float x, float y) { - STRACE(("Layer(%s)::ResizeBy() START\n", Name())); + STRACE(("Layer(%s)::ResizeBy()\n", Name())); - if (!fParent) { - // there is no parent yet, so we'll silently adopt the new size - fFrame.right += x; - fFrame.bottom += y; + if (x == 0.0f && y == 0.0f) return; + + // must lock, even if we change frame coordinates + if (fParent && !IsHidden() && GetRootLayer() && GetRootLayer()->Lock()) { + fFrame.Set(fFrame.left, fFrame.top, fFrame.right+x, fFrame.bottom+y); + +// TODO: you should call this hook function AFTER all region rebuilding +// and redrawing stuff + ResizedByHook(x, y, false); + +// TODO: ResizedByHook(x,y,true) is called from inside _ResizeLayerFrameBy +// Should call this AFTER region rebuilding and redrawing. + // resize children using their resize_mask. + for (Layer *child = LastChild(); child != NULL; child = PreviousChild()) + child->_ResizeLayerFrameBy(x, y); + + BRegion oldFullVisible(fFullVisible2); + // this is required to invalidate the old border + BRegion oldVisible(fVisible2); + + // in case they moved, bottom, right and center aligned layers must be redrawn + BRegion redrawMore; + _RezizeLayerRedrawMore(redrawMore, x, y); + + // we'll invalidate the old area and the new, maxmial one. + BRegion invalid; + GetWantedRegion(invalid); + invalid.Include(&fFullVisible2); + + fParent->MarkForRebuild(invalid); + fParent->TriggerRebuild(); + + // done rebuilding regions, now redraw regions that became visible + + // what's invalid, are the differences between to old and the new fullVisible region + // 1) in case we grow. + BRegion redrawReg(fFullVisible2); + redrawReg.Exclude(&oldFullVisible); + // 2) in case we shrink + BRegion redrawReg2(oldFullVisible); + redrawReg2.Exclude(&fFullVisible2); + // 3) combine. + redrawReg.Include(&redrawReg2); + + // for center, right and bottom alligned layers, redraw their old positions + redrawReg.Include(&redrawMore); + + // layers that had their frame modified must be entirely redrawn. + _RezizeLayerRedrawMore(redrawReg, x, y); + + // include layer's visible region in case we want a full update on resize + if (fFlags & B_FULL_UPDATE_ON_RESIZE && fVisible2.Frame().IsValid()) { + _ResizeLayerFullUpdateOnResize(redrawReg, x, y); + + redrawReg.Include(&fVisible2); + redrawReg.Include(&oldVisible); + } + + GetRootLayer()->MarkForRedraw(redrawReg); + GetRootLayer()->TriggerRedraw(); + + GetRootLayer()->Unlock(); + } + // just resize our frame and those of out descendants if their resize mask says so + else { + fFrame.Set(fFrame.left, fFrame.top, fFrame.right+x, fFrame.bottom+y); + +// TODO: you should call this hook function AFTER all region rebuilding +// and redrawing stuff + ResizedByHook(x, y, false); + +// TODO: ResizedByHook(x,y,true) is called from inside _ResizeLayerFrameBy +// Should call this AFTER region rebuilding and redrawing. + // resize children using their resize_mask. + for (Layer *child = LastChild(); child != NULL; child = PreviousChild()) + child->_ResizeLayerFrameBy(x, y); } - GetRootLayer()->Lock(); - do_ResizeBy(x, y); - GetRootLayer()->Unlock(); - - STRACE(("Layer(%s)::ResizeBy() END\n", Name())); + SendViewCoordUpdateMsg(); } @@ -603,13 +712,51 @@ Layer::ResizeBy(float x, float y) void Layer::ScrollBy(float x, float y) { - STRACE(("Layer(%s)::ScrollBy() START\n", Name())); + STRACE(("Layer(%s)::ScrollBy()\n", Name())); - GetRootLayer()->Lock(); - do_ScrollBy(x, y); - GetRootLayer()->Unlock(); + if (x == 0.0f && y == 0.0f) + return; - STRACE(("Layer(%s)::ScrollBy() END\n", Name())); + // must lock, even if we change frame/origin coordinates + if (fParent && !IsHidden() && GetRootLayer() && GetRootLayer()->Lock()) { + fDrawState->OffsetOrigin(BPoint(x, y)); + + // set the region to be invalidated. + BRegion invalid(fFullVisible2); + + MarkForRebuild(invalid); + + TriggerRebuild(); + + // for the moment we say that the whole surface needs to be redraw. + BRegion redrawReg(fFullVisible2); + + // offset old region so that we can start comparing. + invalid.OffsetBy(x, y); + + // compute the common region. we'll use HW acc to copy this to the new location. + invalid.IntersectWith(&fFullVisible2); + GetDrawingEngine()->CopyRegion(&invalid, -x, -y); + + // common region goes back to its original location. then, by excluding + // it from curent fullVisible we'll obtain the region that needs to be redrawn. + invalid.OffsetBy(-x, -y); +// TODO: a quick fix for the scrolling problem!!! FIX THIS! +// redrawReg.Exclude(&invalid); + + GetRootLayer()->MarkForRedraw(redrawReg); + GetRootLayer()->TriggerRedraw(); + + GetRootLayer()->Unlock(); + } + else { + fDrawState->OffsetOrigin(BPoint(x, y)); + } + + ScrolledByHook(x, y); + +// TODO: I think we should update the client-side that bounds rect has modified +// SendViewCoordUpdateMsg(); } void @@ -1199,154 +1346,6 @@ Layer::_ResizeLayerFullUpdateOnResize(BRegion ®, float dx, float dy) } } -void -Layer::do_ResizeBy(float dx, float dy) -{ - fFrame.Set(fFrame.left, fFrame.top, fFrame.right+dx, fFrame.bottom+dy); - - // resize children using their resize_mask. - for (Layer *child = LastChild(); child != NULL; child = PreviousChild()) - child->_ResizeLayerFrameBy(dx, dy); - - // call hook function - if (dx != 0.0f || dy != 0.0f) - ResizedByHook(dx, dy, false); // manual - - if (!IsHidden() && GetRootLayer()) { - BRegion oldFullVisible(fFullVisible2); - // this is required to invalidate the old border - BRegion oldVisible(fVisible2); - - // in case they moved, bottom, right and center aligned layers must be redrawn - BRegion redrawMore; - _RezizeLayerRedrawMore(redrawMore, dx, dy); - - // we'll invalidate the old area and the new, maxmial one. - BRegion invalid; - GetWantedRegion(invalid); - invalid.Include(&fFullVisible2); - - fParent->MarkForRebuild(invalid); - fParent->TriggerRebuild(); - - // done rebuilding regions, now redraw regions that became visible - - // what's invalid, are the differences between to old and the new fullVisible region - // 1) in case we grow. - BRegion redrawReg(fFullVisible2); - redrawReg.Exclude(&oldFullVisible); - // 2) in case we shrink - BRegion redrawReg2(oldFullVisible); - redrawReg2.Exclude(&fFullVisible2); - // 3) combine. - redrawReg.Include(&redrawReg2); - - // for center, right and bottom alligned layers, redraw their old positions - redrawReg.Include(&redrawMore); - - // layers that had their frame modified must be entirely redrawn. - _RezizeLayerRedrawMore(redrawReg, dx, dy); - - // include layer's visible region in case we want a full update on resize - if (fFlags & B_FULL_UPDATE_ON_RESIZE && fVisible2.Frame().IsValid()) { - _ResizeLayerFullUpdateOnResize(redrawReg, dx, dy); - - redrawReg.Include(&fVisible2); - redrawReg.Include(&oldVisible); - } - - GetRootLayer()->MarkForRedraw(redrawReg); - GetRootLayer()->TriggerRedraw(); - } - - SendViewCoordUpdateMsg(); -} - -void Layer::do_MoveBy(float dx, float dy) -{ - if (dx == 0.0f && dy == 0.0f) - return; - - fFrame.OffsetBy(dx, dy); - - // call hook function - MovedByHook(dx, dy); - - if (!IsHidden() && GetRootLayer()) { - BRegion oldFullVisible(fFullVisible2); - - // we'll invalidate the old position and the new, maxmial one. - BRegion invalid; - GetWantedRegion(invalid); - invalid.Include(&fFullVisible2); - - fParent->MarkForRebuild(invalid); - fParent->TriggerRebuild(); - - // done rebuilding regions, now copy common parts and redraw regions that became visible - - // include the actual and the old fullVisible regions. later, we'll exclude the common parts. - BRegion redrawReg(fFullVisible2); - redrawReg.Include(&oldFullVisible); - - // offset to layer's new location so that we can calculate the common region. - oldFullVisible.OffsetBy(dx, dy); - - // finally we have the region that needs to be redrawn. - redrawReg.Exclude(&oldFullVisible); - - // by intersecting the old fullVisible offseted to layer's new location, with the current - // fullVisible, we'll have the common region which can be copied using HW acceleration. - oldFullVisible.IntersectWith(&fFullVisible2); - - // offset back and instruct the HW to do the actual copying. - oldFullVisible.OffsetBy(-dx, -dy); - GetDrawingEngine()->CopyRegion(&oldFullVisible, dx, dy); - - GetRootLayer()->MarkForRedraw(redrawReg); - GetRootLayer()->TriggerRedraw(); - } - - SendViewCoordUpdateMsg(); -} - -void -Layer::do_ScrollBy(float dx, float dy) -{ - fDrawState->OffsetOrigin(BPoint(dx, dy)); - - if (!IsHidden() && GetRootLayer()) { - // set the region to be invalidated. - BRegion invalid(fFullVisible2); - - MarkForRebuild(invalid); - - TriggerRebuild(); - - // for the moment we say that the whole surface needs to be redraw. - BRegion redrawReg(fFullVisible2); - - // offset old region so that we can start comparing. - invalid.OffsetBy(dx, dy); - - // compute the common region. we'll use HW acc to copy this to the new location. - invalid.IntersectWith(&fFullVisible2); - GetDrawingEngine()->CopyRegion(&invalid, -dx, -dy); - - // common region goes back to its original location. then, by excluding - // it from curent fullVisible we'll obtain the region that needs to be redrawn. - invalid.OffsetBy(-dx, -dy); -// TODO: a quick fix for the scrolling problem!!! FIX THIS! -// redrawReg.Exclude(&invalid); - - GetRootLayer()->MarkForRedraw(redrawReg); - GetRootLayer()->TriggerRedraw(); - } - - if (dx != 0.0f || dy != 0.0f) - ScrolledByHook(dx, dy); -} - void Layer::GetWantedRegion(BRegion ®) { @@ -1364,12 +1363,6 @@ Layer::GetWantedRegion(BRegion ®) DrawState *stackData = fDrawState; while (stackData) { if (stackData->ClippingRegion()) { - // transform in screen coords -// NOTE: Already is in screen coords, but I leave this here in -// case we change it -// BRegion screenReg(*stackData->ClippingRegion()); -// ConvertToScreen2(&screenReg); -// reg.IntersectWith(&screenReg); reg.IntersectWith(stackData->ClippingRegion()); } stackData = stackData->PreviousState(); diff --git a/src/servers/app/Layer.h b/src/servers/app/Layer.h index 4a486f5ec8..3a500334ed 100644 --- a/src/servers/app/Layer.h +++ b/src/servers/app/Layer.h @@ -216,9 +216,6 @@ class Layer { void do_Hide(); void do_Show(); - void do_MoveBy(float dx, float dy); - void do_ResizeBy(float dx, float dy); - void do_ScrollBy(float dx, float dy); void do_CopyBits(BRect& src, BRect& dst, int32 xOffset, int32 yOffset); diff --git a/src/servers/app/WinBorder.cpp b/src/servers/app/WinBorder.cpp index 5ee5f0d893..975d3ad38a 100644 --- a/src/servers/app/WinBorder.cpp +++ b/src/servers/app/WinBorder.cpp @@ -130,7 +130,8 @@ WinBorder::WinBorder(const BRect &frame, float frequency; if (window->App()->GetDesktop()->ScreenAt(0)) { window->App()->GetDesktop()->ScreenAt(0)->GetMode(width, height, colorSpace, frequency); - _ResizeBy(width - frame.Width(), height - frame.Height()); +// TODO: MOVE THIS AWAY!!! RemoveBy contains calls to virtual methods! Also, there is not TopLayer()! + WinBorder::ResizeBy(width - frame.Width(), height - frame.Height()); } } @@ -173,9 +174,37 @@ WinBorder::Draw(const BRect &r) void WinBorder::MoveBy(float x, float y) { - if (x == 0 && y == 0) + if (x == 0.0f && y == 0.0f) return; - + + // lock here because we play with some regions + if (GetRootLayer() && GetRootLayer()->Lock()) { + fDecRegion.OffsetBy(x, y); + + fCumulativeRegion.OffsetBy(x, y); + fInUpdateRegion.OffsetBy(x, y); + + if (fDecorator) + fDecorator->MoveBy(x, y); + + Layer::MoveBy(x, y); + + GetRootLayer()->Unlock(); + } + // just offset to the new position + else { + if (fDecorator) + fDecorator->MoveBy(x, y); + + Layer::MoveBy(x, y); + } + + // dispatch a message to the client informing about the changed size + BMessage msg(B_WINDOW_MOVED); + msg.AddInt64("when", system_time()); + msg.AddPoint("where", Frame().LeftTop()); + Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false); + // TODO: MoveBy and ResizeBy() are usually called // from the rootlayer's thread. HandleDirectConnection() could // block the calling thread for ~3 seconds in the worst case, @@ -185,27 +214,13 @@ WinBorder::MoveBy(float x, float y) // Find some way to call DirectConnected() from the ServerWindow's thread, // by sending a message from here or whatever. //Window()->HandleDirectConnection(B_DIRECT_STOP); - Layer::MoveBy(x, y); +// Layer::MoveBy(x, y); //Window()->HandleDirectConnection(B_DIRECT_START|B_BUFFER_MOVED); } void WinBorder::ResizeBy(float x, float y) -{ - STRACE(("WinBorder(%s)::ResizeBy()\n", Name())); - if (x == 0 && y == 0) - return; - - //Window()->HandleDirectConnection(B_DIRECT_STOP); - _ResizeBy(x, y); - //Window()->HandleDirectConnection(B_DIRECT_START|B_BUFFER_RESIZED); -} - - -//! Resizes the winborder with redraw -bool -WinBorder::_ResizeBy(float x, float y) { float wantWidth = fFrame.Width() + x; float wantHeight = fFrame.Height() + y; @@ -225,11 +240,34 @@ WinBorder::_ResizeBy(float x, float y) y = wantHeight - fFrame.Height(); if (x == 0.0 && y == 0.0) - return false; + return; - Layer::ResizeBy(x, y); + // this method can be called from a ServerWindow thread or from a RootLayer one, + // so lock + if (GetRootLayer() && GetRootLayer()->Lock()) { + fRebuildDecRegion = true; - return true; + if (fDecorator) + fDecorator->ResizeBy(x, y); + + Layer::ResizeBy(x, y); + + GetRootLayer()->Unlock(); + } + else { + if (fDecorator) + fDecorator->ResizeBy(x, y); + + Layer::ResizeBy(x, y); + } + + // send a message to the client informing about the changed size + BRect frame(Frame()); + BMessage msg(B_WINDOW_RESIZED); + msg.AddInt64("when", system_time()); + msg.AddInt32("width", frame.IntegerWidth()); + msg.AddInt32("height", frame.IntegerHeight()); + Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false); } // SetName @@ -284,7 +322,6 @@ WinBorder::UpdateEnd() if (fCumulativeRegion.CountRects() > 0) { GetRootLayer()->MarkForRedraw(fCumulativeRegion); GetRootLayer()->TriggerRedraw(); -// RequestDraw(reg, NULL); } } void @@ -293,7 +330,6 @@ WinBorder::EnableUpdateRequests() { if (fCumulativeRegion.CountRects() > 0) { GetRootLayer()->MarkForRedraw(fCumulativeRegion); GetRootLayer()->TriggerRedraw(); -// RequestDraw(reg, NULL); } } @@ -717,42 +753,6 @@ WinBorder::_ActionFor(const BMessage *msg) const return DEC_NONE; } -void WinBorder::MovedByHook(float dx, float dy) -{ - STRACE(("WinBorder(%s)::MovedByHook(%.1f, %.1f) fDecorator: %p\n", Name(), x, y, fDecorator)); - - fDecRegion.OffsetBy(dx, dy); - - if (fDecorator) - fDecorator->MoveBy(dx, dy); - - fCumulativeRegion.OffsetBy(dx, dy); - fInUpdateRegion.OffsetBy(dx, dy); - - // dispatch a message to the client informing about the changed size - BMessage msg(B_WINDOW_MOVED); - msg.AddInt64("when", system_time()); - msg.AddPoint("where", Frame().LeftTop()); - Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false); -} - -void WinBorder::ResizedByHook(float dx, float dy, bool automatic) -{ - STRACE(("WinBorder(%s)::ResizedByHook(%.1f, %.1f, %s) fDecorator: %p\n", Name(), x, y, automatic?"true":"false", fDecorator)); - fRebuildDecRegion = true; - - if (fDecorator) - fDecorator->ResizeBy(dx, dy); - - // send a message to the client informing about the changed size - BRect frame(fTopLayer->Frame()); - BMessage msg(B_WINDOW_RESIZED); - msg.AddInt64("when", system_time()); - msg.AddInt32("width", frame.IntegerWidth()); - msg.AddInt32("height", frame.IntegerHeight()); - Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false); -} - void WinBorder::set_decorator_region(BRect bounds) { fRebuildDecRegion = false; diff --git a/src/servers/app/WinBorder.h b/src/servers/app/WinBorder.h index 96a4ae8b3b..9b13571031 100644 --- a/src/servers/app/WinBorder.h +++ b/src/servers/app/WinBorder.h @@ -50,8 +50,7 @@ class WinBorder : public Layer { virtual void MoveBy(float x, float y); virtual void ResizeBy(float x, float y); virtual void ScrollBy(float x, float y) - { // not allowed - } + { /* not allowed */ } virtual void SetName(const char* name); @@ -117,9 +116,6 @@ class WinBorder : public Layer { SubWindowList fSubWindowList; - virtual void MovedByHook(float dx, float dy); - virtual void ResizedByHook(float dx, float dy, bool automatic); - void RequestClientRedraw(const BRegion &invalid); virtual void SetTopLayer(Layer* layer); @@ -133,7 +129,6 @@ class WinBorder : public Layer { friend class RootLayer; click_type _ActionFor(const BMessage *msg) const; - bool _ResizeBy(float x, float y); Decorator* fDecorator; Layer* fTopLayer;