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
This commit is contained in:
Adi Oanca 2005-11-09 20:14:52 +00:00
parent 90dfa70739
commit 76d68e8ad8
4 changed files with 229 additions and 244 deletions

View File

@ -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 &reg, 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 &reg)
{
@ -1364,12 +1363,6 @@ Layer::GetWantedRegion(BRegion &reg)
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();

View File

@ -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);

View File

@ -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;

View File

@ -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;