2004-09-21 02:50:02 +04:00
|
|
|
//------------------------------------------------------------------------------
|
2005-06-15 01:28:56 +04:00
|
|
|
// Copyright (c) 2001-2005, Haiku, Inc.
|
2004-09-21 02:50:02 +04:00
|
|
|
//
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
// copy of this software and associated documentation files (the "Software"),
|
|
|
|
// to deal in the Software without restriction, including without limitation
|
|
|
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
// and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
// Software is furnished to do so, subject to the following conditions:
|
|
|
|
//
|
|
|
|
// The above copyright notice and this permission notice shall be included in
|
|
|
|
// all copies or substantial portions of the Software.
|
|
|
|
//
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
// DEALINGS IN THE SOFTWARE.
|
|
|
|
//
|
|
|
|
// File Name: Layer.cpp
|
|
|
|
// Author: DarkWyrm <bpmagic@columbus.rr.com>
|
2005-06-16 22:58:14 +04:00
|
|
|
// Adi Oanca <adioanca@cotty.iren.ro>
|
2005-04-27 21:26:57 +04:00
|
|
|
// Stephan Aßmus <superstippi@gmx.de>
|
2004-09-21 02:50:02 +04:00
|
|
|
// Description: Class used for rendering to the frame buffer. One layer per
|
|
|
|
// view on screen and also for window decorators
|
|
|
|
//
|
|
|
|
//------------------------------------------------------------------------------
|
2003-02-07 15:53:57 +03:00
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
2004-02-24 15:02:47 +03:00
|
|
|
#include <stdlib.h>
|
2005-04-27 21:26:57 +04:00
|
|
|
|
|
|
|
#include <AppDefs.h>
|
|
|
|
#include <Message.h>
|
|
|
|
#include <Region.h>
|
|
|
|
#include <View.h>
|
|
|
|
|
2005-05-26 03:59:23 +04:00
|
|
|
#include "DebugInfoManager.h"
|
2004-02-24 15:02:47 +03:00
|
|
|
#include "DisplayDriver.h"
|
|
|
|
#include "LayerData.h"
|
2005-01-23 02:25:41 +03:00
|
|
|
#include "PortLink.h"
|
2005-04-27 21:26:57 +04:00
|
|
|
#include "RootLayer.h"
|
2005-01-23 02:25:41 +03:00
|
|
|
#include "ServerProtocol.h"
|
2005-04-27 21:26:57 +04:00
|
|
|
#include "ServerWindow.h"
|
|
|
|
#include "WinBorder.h"
|
|
|
|
#include "Layer.h"
|
2005-06-10 20:20:38 +04:00
|
|
|
#include "ServerBitmap.h"
|
2003-02-07 15:53:57 +03:00
|
|
|
|
2004-06-18 15:50:17 +04:00
|
|
|
//#define DEBUG_LAYER
|
2003-09-25 16:25:13 +04:00
|
|
|
#ifdef DEBUG_LAYER
|
|
|
|
# define STRACE(x) printf x
|
|
|
|
#else
|
|
|
|
# define STRACE(x) ;
|
|
|
|
#endif
|
|
|
|
|
2005-03-17 20:41:00 +03:00
|
|
|
//#define DEBUG_LAYER_REBUILD
|
2004-06-03 00:44:46 +04:00
|
|
|
#ifdef DEBUG_LAYER_REBUILD
|
|
|
|
# define RBTRACE(x) printf x
|
|
|
|
#else
|
|
|
|
# define RBTRACE(x) ;
|
|
|
|
#endif
|
|
|
|
|
2005-01-23 00:51:39 +03:00
|
|
|
enum {
|
|
|
|
B_LAYER_ACTION_NONE = 0,
|
|
|
|
B_LAYER_ACTION_MOVE,
|
|
|
|
B_LAYER_ACTION_RESIZE
|
|
|
|
};
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
Layer::Layer(BRect frame, const char* name, int32 token,
|
|
|
|
uint32 resize, uint32 flags, DisplayDriver* driver)
|
2005-06-10 19:28:34 +04:00
|
|
|
:
|
|
|
|
fFrame(frame), // in parent coordinates
|
|
|
|
// fBoundsLeftTop(0.0, 0.0),
|
|
|
|
|
|
|
|
// Layer does not start out as a part of the tree
|
|
|
|
fOwner(NULL),
|
|
|
|
fParent(NULL),
|
|
|
|
fUpperSibling(NULL),
|
|
|
|
fLowerSibling(NULL),
|
|
|
|
fTopChild(NULL),
|
|
|
|
fBottomChild(NULL),
|
|
|
|
fCurrent(NULL),
|
|
|
|
|
|
|
|
// all regions (fVisible, fFullVisible, fFull) start empty
|
2005-06-17 00:43:53 +04:00
|
|
|
#ifndef NEW_CLIPPING
|
2005-06-10 19:28:34 +04:00
|
|
|
fVisible(),
|
|
|
|
fFullVisible(),
|
2005-06-22 00:11:44 +04:00
|
|
|
fFull(),
|
|
|
|
fFrameAction(B_LAYER_ACTION_NONE),
|
2005-06-17 00:43:53 +04:00
|
|
|
#else
|
|
|
|
fVisible2(),
|
|
|
|
fFullVisible2(),
|
|
|
|
#endif
|
2005-06-10 19:28:34 +04:00
|
|
|
|
2005-06-17 00:43:53 +04:00
|
|
|
#ifndef NEW_CLIPPING
|
2005-06-10 19:28:34 +04:00
|
|
|
fClipReg(&fVisible),
|
2005-06-17 00:43:53 +04:00
|
|
|
#else
|
|
|
|
fClipReg(&fVisible2),
|
|
|
|
#endif
|
2005-06-10 19:28:34 +04:00
|
|
|
fServerWin(NULL),
|
|
|
|
fName(new BString(name)),
|
|
|
|
fViewToken(token),
|
|
|
|
|
|
|
|
fFlags(flags),
|
|
|
|
fResizeMode(resize),
|
|
|
|
fEventMask(0UL),
|
|
|
|
fEventOptions(0UL),
|
|
|
|
fHidden(false),
|
|
|
|
fIsTopLayer(false),
|
|
|
|
|
|
|
|
fAdFlags(0),
|
|
|
|
fClassID(AS_LAYER_CLASS),
|
|
|
|
|
|
|
|
fDriver(driver),
|
|
|
|
fLayerData(new LayerData()),
|
|
|
|
|
2005-06-10 20:20:38 +04:00
|
|
|
fRootLayer(NULL),
|
|
|
|
|
|
|
|
fViewColor(255, 255, 255, 255),
|
|
|
|
fBackgroundBitmap(NULL),
|
|
|
|
fOverlayBitmap(NULL)
|
2005-04-27 21:26:57 +04:00
|
|
|
{
|
2005-06-04 15:18:30 +04:00
|
|
|
if (!frame.IsValid()) {
|
|
|
|
char helper[1024];
|
|
|
|
sprintf(helper, "Layer::Layer(BRect(%.1f, %.1f, %.1f, %.1f), name: %s, token: %ld) - frame is invalid\n",
|
|
|
|
frame.left, frame.top, frame.right, frame.bottom, name, token);
|
|
|
|
CRITICAL(helper);
|
|
|
|
fFrame.Set(0, 0, 10, 10);
|
|
|
|
}
|
2005-04-27 21:26:57 +04:00
|
|
|
|
|
|
|
if (!fDriver)
|
2005-05-26 03:59:23 +04:00
|
|
|
CRITICAL("You MUST have a valid driver to init a Layer object\n");
|
2005-04-27 21:26:57 +04:00
|
|
|
|
2004-06-03 00:44:46 +04:00
|
|
|
STRACE(("Layer(%s) successfuly created\n", GetName()));
|
2003-01-24 18:19:27 +03:00
|
|
|
}
|
|
|
|
|
2003-02-07 15:53:57 +03:00
|
|
|
//! Destructor frees all allocated heap space
|
2005-06-04 15:18:30 +04:00
|
|
|
Layer::~Layer()
|
2003-01-24 18:19:27 +03:00
|
|
|
{
|
2005-04-27 21:26:57 +04:00
|
|
|
delete fLayerData;
|
|
|
|
delete fName;
|
2004-06-11 22:21:57 +04:00
|
|
|
|
|
|
|
// TODO: uncomment!
|
2004-02-24 15:02:47 +03:00
|
|
|
//PruneTree();
|
2004-06-11 22:21:57 +04:00
|
|
|
|
|
|
|
// fServerWin->RemoveChild(fDriver);
|
2004-02-24 15:02:47 +03:00
|
|
|
// delete fDriver;
|
2003-01-24 18:19:27 +03:00
|
|
|
}
|
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
/*!
|
|
|
|
\brief Adds a child layer to the current one
|
|
|
|
\param layer a new child layer
|
|
|
|
\param serverWin the serverwindow to which the layer will belong
|
|
|
|
|
|
|
|
Unlike the BView version, if the layer already belongs to another, then
|
|
|
|
it spits an error to stdout and returns.
|
|
|
|
*/
|
2005-04-27 21:26:57 +04:00
|
|
|
void
|
|
|
|
Layer::AddChild(Layer* layer, ServerWindow* serverWin)
|
2003-01-24 18:19:27 +03:00
|
|
|
{
|
2004-06-11 22:21:57 +04:00
|
|
|
STRACE(("Layer(%s)::AddChild(%s) START\n", GetName(), layer->GetName()));
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
if (layer->fParent != NULL) {
|
2004-06-11 22:21:57 +04:00
|
|
|
printf("ERROR: AddChild(): Layer already has a parent\n");
|
2003-01-24 18:19:27 +03:00
|
|
|
return;
|
|
|
|
}
|
2004-06-11 22:21:57 +04:00
|
|
|
|
2004-06-16 10:40:26 +04:00
|
|
|
// 1) attach layer to the tree structure
|
2004-06-11 22:21:57 +04:00
|
|
|
layer->fParent = this;
|
2004-09-09 04:54:21 +04:00
|
|
|
|
|
|
|
// if we have children already, bump the current front child back one and
|
|
|
|
// make the new child the frontmost layer
|
2005-04-27 21:26:57 +04:00
|
|
|
if (fBottomChild) {
|
2004-06-11 22:21:57 +04:00
|
|
|
layer->fUpperSibling = fBottomChild;
|
|
|
|
fBottomChild->fLowerSibling = layer;
|
2005-04-27 21:26:57 +04:00
|
|
|
} else {
|
2004-06-11 22:21:57 +04:00
|
|
|
fTopChild = layer;
|
2003-11-14 03:15:29 +03:00
|
|
|
}
|
2004-06-11 22:21:57 +04:00
|
|
|
fBottomChild = layer;
|
2003-11-14 03:15:29 +03:00
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
// if we have no RootLayer yet, then there is no need to set any parameters --
|
|
|
|
// they will be set when the RootLayer for this tree will be added
|
2004-06-16 10:40:26 +04:00
|
|
|
// to the main tree structure.
|
2005-04-27 21:26:57 +04:00
|
|
|
if (!fRootLayer) {
|
2004-06-17 18:39:21 +04:00
|
|
|
STRACE(("Layer(%s)::AddChild(%s) END\n", GetName(), layer->GetName()));
|
2004-06-16 10:40:26 +04:00
|
|
|
return;
|
2004-06-17 18:39:21 +04:00
|
|
|
}
|
2003-11-14 03:15:29 +03:00
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
// 2) Iterate over the newly-added layer and all its children, setting the
|
|
|
|
// root layer and server window and also rebuilding the full-size region
|
|
|
|
// for every descendant of the newly-added layer
|
|
|
|
|
|
|
|
//c = short for: current
|
2005-04-27 21:26:57 +04:00
|
|
|
Layer* c = layer;
|
|
|
|
Layer* stop = layer;
|
|
|
|
while (true) {
|
2004-06-16 10:40:26 +04:00
|
|
|
// action block
|
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
// 2.1) set the RootLayer for this object.
|
|
|
|
c->SetRootLayer(c->fParent->fRootLayer);
|
|
|
|
|
|
|
|
// 2.2) this Layer must know if it has a ServerWindow object attached.
|
2005-02-28 23:23:51 +03:00
|
|
|
c->fServerWin=serverWin;
|
2004-09-09 04:54:21 +04:00
|
|
|
|
|
|
|
// 2.3) we are attached to the main tree so build our full region.
|
2005-06-16 22:58:14 +04:00
|
|
|
#ifndef NEW_CLIPPING
|
2004-09-09 04:54:21 +04:00
|
|
|
c->RebuildFullRegion();
|
2005-06-16 22:58:14 +04:00
|
|
|
#endif
|
2004-06-16 10:40:26 +04:00
|
|
|
// tree parsing algorithm
|
2005-04-27 21:26:57 +04:00
|
|
|
if (c->fTopChild) {
|
2004-09-09 04:54:21 +04:00
|
|
|
// go deep
|
2004-06-16 10:40:26 +04:00
|
|
|
c = c->fTopChild;
|
2005-04-27 21:26:57 +04:00
|
|
|
} else {
|
2004-09-09 04:54:21 +04:00
|
|
|
// go right or up
|
|
|
|
|
2004-06-16 10:40:26 +04:00
|
|
|
if (c == stop) // out trip is over
|
|
|
|
break;
|
2004-09-09 04:54:21 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
if (c->fLowerSibling) {
|
2004-09-09 04:54:21 +04:00
|
|
|
// go right
|
2004-06-16 10:40:26 +04:00
|
|
|
c = c->fLowerSibling;
|
2005-04-27 21:26:57 +04:00
|
|
|
} else {
|
2004-09-09 04:54:21 +04:00
|
|
|
// go up
|
2005-04-27 21:26:57 +04:00
|
|
|
while (!c->fParent->fLowerSibling && c->fParent != stop)
|
2004-06-16 10:40:26 +04:00
|
|
|
c = c->fParent;
|
2004-09-09 04:54:21 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
if (c->fParent == stop) // that's enough!
|
2004-06-16 10:40:26 +04:00
|
|
|
break;
|
2004-09-09 04:54:21 +04:00
|
|
|
|
2004-06-16 10:40:26 +04:00
|
|
|
c = c->fParent->fLowerSibling;
|
2004-06-11 22:21:57 +04:00
|
|
|
}
|
2003-11-14 03:15:29 +03:00
|
|
|
}
|
|
|
|
}
|
2004-06-16 10:40:26 +04:00
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
STRACE(("Layer(%s)::AddChild(%s) END\n", GetName(), layer->GetName()));
|
2003-01-24 18:19:27 +03:00
|
|
|
}
|
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
/*!
|
|
|
|
\brief Removes a child layer from the current one
|
|
|
|
\param layer the layer to remove
|
|
|
|
|
|
|
|
If the layer does not belong to the the current layer, then this function
|
|
|
|
spits out an error to stdout and returns
|
|
|
|
*/
|
2005-04-27 21:26:57 +04:00
|
|
|
void
|
|
|
|
Layer::RemoveChild(Layer *layer)
|
2003-01-24 18:19:27 +03:00
|
|
|
{
|
2004-06-11 22:21:57 +04:00
|
|
|
STRACE(("Layer(%s)::RemoveChild(%s) START\n", GetName(), layer->GetName()));
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
if (!layer->fParent) {
|
2004-06-11 22:21:57 +04:00
|
|
|
printf("ERROR: RemoveChild(): Layer doesn't have a fParent\n");
|
2003-01-24 18:19:27 +03:00
|
|
|
return;
|
|
|
|
}
|
2004-06-11 22:21:57 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
if (layer->fParent != this) {
|
2004-01-13 03:56:36 +03:00
|
|
|
printf("ERROR: RemoveChild(): Layer is not a child of this layer\n");
|
2003-01-24 18:19:27 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
// 1) remove this layer from the main tree.
|
|
|
|
|
2004-06-11 22:21:57 +04:00
|
|
|
// Take care of fParent
|
2004-09-09 04:54:21 +04:00
|
|
|
layer->fParent = NULL;
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
if (fTopChild == layer)
|
2004-09-09 04:54:21 +04:00
|
|
|
fTopChild = layer->fLowerSibling;
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
if (fBottomChild == layer)
|
2004-09-09 04:54:21 +04:00
|
|
|
fBottomChild = layer->fUpperSibling;
|
|
|
|
|
2003-01-24 18:19:27 +03:00
|
|
|
// Take care of siblings
|
2005-04-27 21:26:57 +04:00
|
|
|
if (layer->fUpperSibling != NULL)
|
2004-06-11 22:21:57 +04:00
|
|
|
layer->fUpperSibling->fLowerSibling = layer->fLowerSibling;
|
2004-09-09 04:54:21 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
if (layer->fLowerSibling != NULL)
|
2004-06-11 22:21:57 +04:00
|
|
|
layer->fLowerSibling->fUpperSibling = layer->fUpperSibling;
|
2004-09-09 04:54:21 +04:00
|
|
|
|
|
|
|
layer->fUpperSibling = NULL;
|
|
|
|
layer->fLowerSibling = NULL;
|
2004-06-16 10:40:26 +04:00
|
|
|
|
2005-06-16 00:36:43 +04:00
|
|
|
#ifdef NEW_CLIPPING
|
|
|
|
layer->clear_visible_regions();
|
|
|
|
#endif
|
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
// 2) Iterate over all of the removed-layer's descendants and unset the
|
|
|
|
// root layer, server window, and all redraw-related regions
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
Layer* c = layer; //c = short for: current
|
|
|
|
Layer* stop = layer;
|
2004-09-09 04:54:21 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
while (true) {
|
2004-06-16 10:40:26 +04:00
|
|
|
// action block
|
2004-06-11 22:21:57 +04:00
|
|
|
{
|
2004-06-16 10:40:26 +04:00
|
|
|
// 2.1) set the RootLayer for this object.
|
|
|
|
c->SetRootLayer(NULL);
|
|
|
|
// 2.2) this Layer must know if it has a ServerWindow object attached.
|
2005-04-27 21:26:57 +04:00
|
|
|
c->fServerWin = NULL;
|
2004-06-16 10:40:26 +04:00
|
|
|
// 2.3) we were removed from the main tree so clear our full region.
|
2005-06-16 23:44:55 +04:00
|
|
|
#ifndef NEW_CLIPPING
|
2004-06-16 10:40:26 +04:00
|
|
|
c->fFull.MakeEmpty();
|
|
|
|
// 2.4) clear fullVisible region.
|
|
|
|
c->fFullVisible.MakeEmpty();
|
|
|
|
// 2.5) we don't have a visible region anymore.
|
|
|
|
c->fVisible.MakeEmpty();
|
2005-06-17 00:43:53 +04:00
|
|
|
#endif
|
2004-06-16 10:40:26 +04:00
|
|
|
}
|
2003-11-14 03:15:29 +03:00
|
|
|
|
2004-06-16 10:40:26 +04:00
|
|
|
// tree parsing algorithm
|
2005-04-27 21:26:57 +04:00
|
|
|
if (c->fTopChild) {
|
2004-09-09 04:54:21 +04:00
|
|
|
// go deep
|
2004-06-16 10:40:26 +04:00
|
|
|
c = c->fTopChild;
|
2005-04-27 21:26:57 +04:00
|
|
|
} else {
|
2004-09-09 04:54:21 +04:00
|
|
|
// go right or up
|
2004-06-16 10:40:26 +04:00
|
|
|
if (c == stop) // out trip is over
|
|
|
|
break;
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
if (c->fLowerSibling) {
|
2004-09-09 04:54:21 +04:00
|
|
|
// go right
|
2004-06-16 10:40:26 +04:00
|
|
|
c = c->fLowerSibling;
|
2005-04-27 21:26:57 +04:00
|
|
|
} else {
|
2004-09-09 04:54:21 +04:00
|
|
|
// go up
|
2005-04-27 21:26:57 +04:00
|
|
|
while(!c->fParent->fLowerSibling && c->fParent != stop)
|
2004-06-16 10:40:26 +04:00
|
|
|
c = c->fParent;
|
2004-09-09 04:54:21 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
if (c->fParent == stop) // that enough!
|
2004-06-16 10:40:26 +04:00
|
|
|
break;
|
2004-09-09 04:54:21 +04:00
|
|
|
|
2004-06-16 10:40:26 +04:00
|
|
|
c = c->fParent->fLowerSibling;
|
2004-06-11 22:21:57 +04:00
|
|
|
}
|
2003-11-14 03:15:29 +03:00
|
|
|
}
|
2004-06-11 22:21:57 +04:00
|
|
|
}
|
2004-09-09 04:54:21 +04:00
|
|
|
STRACE(("Layer(%s)::RemoveChild(%s) END\n", GetName(), layer->GetName()));
|
2003-01-24 18:19:27 +03:00
|
|
|
}
|
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
//! Removes the calling layer from the tree
|
2005-04-27 21:26:57 +04:00
|
|
|
void
|
|
|
|
Layer::RemoveSelf()
|
2003-01-24 18:19:27 +03:00
|
|
|
{
|
2003-02-07 15:53:57 +03:00
|
|
|
// A Layer removes itself from the tree (duh)
|
2005-04-27 21:26:57 +04:00
|
|
|
if (fParent == NULL) {
|
2004-06-11 22:21:57 +04:00
|
|
|
printf("ERROR: RemoveSelf(): Layer doesn't have a fParent\n");
|
2003-01-24 18:19:27 +03:00
|
|
|
return;
|
|
|
|
}
|
2004-06-11 22:21:57 +04:00
|
|
|
fParent->RemoveChild(this);
|
2003-01-24 18:19:27 +03:00
|
|
|
}
|
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
/*!
|
|
|
|
\brief Determins if the calling layer has the passed layer as a child
|
|
|
|
\return true if the child is owned by the caller, false if not
|
|
|
|
*/
|
2005-04-27 21:26:57 +04:00
|
|
|
bool
|
|
|
|
Layer::HasChild(Layer* layer)
|
2004-06-11 22:21:57 +04:00
|
|
|
{
|
2005-06-15 23:01:43 +04:00
|
|
|
for (Layer *lay = TopChild(); lay; lay = LowerSibling()) {
|
2005-04-27 21:26:57 +04:00
|
|
|
if (lay == layer)
|
2004-01-13 03:56:36 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2004-01-12 01:12:55 +03:00
|
|
|
}
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
//! Returns the number of children
|
|
|
|
uint32
|
|
|
|
Layer::CountChildren(void) const
|
2003-01-24 18:19:27 +03:00
|
|
|
{
|
2005-04-27 21:26:57 +04:00
|
|
|
uint32 count = 0;
|
2005-06-15 23:01:43 +04:00
|
|
|
Layer *lay = TopChild();
|
2005-04-27 21:26:57 +04:00
|
|
|
while (lay != NULL) {
|
2005-06-15 23:01:43 +04:00
|
|
|
lay = LowerSibling();
|
2005-04-27 21:26:57 +04:00
|
|
|
count++;
|
2003-01-24 18:19:27 +03:00
|
|
|
}
|
2005-04-27 21:26:57 +04:00
|
|
|
return count;
|
2003-01-24 18:19:27 +03:00
|
|
|
}
|
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
/*!
|
|
|
|
\brief Finds a child of the caller based on its token ID
|
|
|
|
\param token ID of the layer to find
|
|
|
|
\return Pointer to the layer or NULL if not found
|
|
|
|
*/
|
2005-04-27 21:26:57 +04:00
|
|
|
Layer*
|
|
|
|
Layer::FindLayer(const int32 token)
|
2003-01-24 18:19:27 +03:00
|
|
|
{
|
2003-02-07 15:53:57 +03:00
|
|
|
// recursive search for a layer based on its view token
|
2005-04-27 21:26:57 +04:00
|
|
|
Layer* lay;
|
|
|
|
Layer* trylay;
|
2004-06-11 22:21:57 +04:00
|
|
|
|
2003-01-24 18:19:27 +03:00
|
|
|
// Search child layers first
|
2005-06-15 23:01:43 +04:00
|
|
|
for (lay = TopChild(); lay; lay = LowerSibling()) {
|
2005-04-27 21:26:57 +04:00
|
|
|
if (lay->fViewToken == token)
|
2003-01-24 18:19:27 +03:00
|
|
|
return lay;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Hmmm... not in this layer's children. Try lower descendants
|
2005-06-15 23:01:43 +04:00
|
|
|
for (lay = TopChild(); lay != NULL; lay = LowerSibling()) {
|
2004-06-11 22:21:57 +04:00
|
|
|
trylay = lay->FindLayer(token);
|
2005-04-27 21:26:57 +04:00
|
|
|
if (trylay)
|
2003-01-24 18:19:27 +03:00
|
|
|
return trylay;
|
|
|
|
}
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
// Well, we got this far in the function,
|
|
|
|
// so apparently there is no match to be found
|
2003-02-07 15:53:57 +03:00
|
|
|
return NULL;
|
2003-01-24 18:19:27 +03:00
|
|
|
}
|
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
/*!
|
2005-04-27 21:26:57 +04:00
|
|
|
\brief Returns the layer at the given point
|
|
|
|
\param pt The point to look the layer at
|
|
|
|
\return The layer containing the point or NULL if no layer found
|
2004-09-09 04:54:21 +04:00
|
|
|
*/
|
2005-04-27 21:26:57 +04:00
|
|
|
Layer*
|
|
|
|
Layer::LayerAt(const BPoint &pt)
|
2004-06-11 22:21:57 +04:00
|
|
|
{
|
2005-06-17 00:43:53 +04:00
|
|
|
#ifndef NEW_CLIPPING
|
2005-04-27 21:26:57 +04:00
|
|
|
if (fVisible.Contains(pt))
|
|
|
|
return this;
|
|
|
|
|
|
|
|
if (fFullVisible.Contains(pt)) {
|
|
|
|
Layer *lay = NULL;
|
2005-06-15 23:01:43 +04:00
|
|
|
for (Layer* child = BottomChild(); child; child = UpperSibling()) {
|
2005-04-27 21:26:57 +04:00
|
|
|
lay = child->LayerAt(pt);
|
|
|
|
if (lay)
|
|
|
|
return lay;
|
|
|
|
}
|
|
|
|
}
|
2005-06-22 00:11:44 +04:00
|
|
|
#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;
|
|
|
|
}
|
|
|
|
}
|
2005-06-17 00:43:53 +04:00
|
|
|
#endif
|
2005-04-27 21:26:57 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2005-06-15 23:01:43 +04:00
|
|
|
// TopChild
|
2005-04-27 21:26:57 +04:00
|
|
|
Layer*
|
2005-06-15 23:01:43 +04:00
|
|
|
Layer::TopChild() const
|
2005-04-27 21:26:57 +04:00
|
|
|
{
|
|
|
|
fCurrent = fTopChild;
|
|
|
|
return fCurrent;
|
2003-09-17 23:28:31 +04:00
|
|
|
}
|
|
|
|
|
2005-06-15 23:01:43 +04:00
|
|
|
// LowerSibling
|
2005-04-27 21:26:57 +04:00
|
|
|
Layer*
|
2005-06-15 23:01:43 +04:00
|
|
|
Layer::LowerSibling() const
|
2004-02-24 15:02:47 +03:00
|
|
|
{
|
2005-04-27 21:26:57 +04:00
|
|
|
fCurrent = fCurrent->fLowerSibling;
|
|
|
|
return fCurrent;
|
2004-02-24 15:02:47 +03:00
|
|
|
}
|
2003-11-14 03:15:29 +03:00
|
|
|
|
2005-06-15 23:01:43 +04:00
|
|
|
// UpperSibling
|
2005-04-27 21:26:57 +04:00
|
|
|
Layer*
|
2005-06-15 23:01:43 +04:00
|
|
|
Layer::UpperSibling() const
|
2004-02-24 15:02:47 +03:00
|
|
|
{
|
2005-04-27 21:26:57 +04:00
|
|
|
fCurrent = fCurrent->fUpperSibling;
|
|
|
|
return fCurrent;
|
|
|
|
}
|
2003-11-14 03:15:29 +03:00
|
|
|
|
2005-06-15 23:01:43 +04:00
|
|
|
// BottomChild
|
2005-04-27 21:26:57 +04:00
|
|
|
Layer*
|
2005-06-15 23:01:43 +04:00
|
|
|
Layer::BottomChild() const
|
2005-04-27 21:26:57 +04:00
|
|
|
{
|
|
|
|
fCurrent = fBottomChild;
|
|
|
|
return fCurrent;
|
2004-02-24 15:02:47 +03:00
|
|
|
}
|
2003-11-14 03:15:29 +03:00
|
|
|
|
2005-06-16 22:58:14 +04:00
|
|
|
#ifndef NEW_CLIPPING
|
2005-04-27 21:26:57 +04:00
|
|
|
|
|
|
|
//! Rebuilds the layer's "completely visible" region
|
|
|
|
void
|
|
|
|
Layer::RebuildFullRegion(void)
|
2004-02-24 15:02:47 +03:00
|
|
|
{
|
2005-04-27 21:26:57 +04:00
|
|
|
STRACE(("Layer(%s)::RebuildFullRegion()\n", GetName()));
|
2004-06-11 22:21:57 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
if (fParent)
|
|
|
|
fFull.Set(fParent->ConvertToTop(fFrame ));
|
|
|
|
else
|
|
|
|
fFull.Set(fFrame);
|
|
|
|
|
|
|
|
// TODO: restrict to screen coordinates
|
2004-06-11 22:21:57 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
// TODO: Convert to screen coordinates
|
|
|
|
|
|
|
|
LayerData *ld;
|
|
|
|
ld = fLayerData;
|
|
|
|
do {
|
|
|
|
// clip to user region
|
|
|
|
if (const BRegion* userClipping = ld->ClippingRegion())
|
|
|
|
fFull.IntersectWith(userClipping);
|
|
|
|
|
|
|
|
} while ((ld = ld->prevState));
|
2003-11-14 03:15:29 +03:00
|
|
|
}
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
// StartRebuildRegions
|
|
|
|
void
|
|
|
|
Layer::StartRebuildRegions( const BRegion& reg, Layer *target, uint32 action, BPoint& pt)
|
2003-01-24 18:19:27 +03:00
|
|
|
{
|
2005-04-27 21:26:57 +04:00
|
|
|
STRACE(("Layer(%s)::StartRebuildRegions() START\n", GetName()));
|
|
|
|
RBTRACE(("\n\nLayer(%s)::StartRebuildRegions() START\n", GetName()));
|
2005-05-04 01:43:51 +04:00
|
|
|
if (!fParent)
|
2005-04-27 21:26:57 +04:00
|
|
|
fFullVisible = fFull;
|
|
|
|
|
|
|
|
BRegion oldVisible = fVisible;
|
|
|
|
|
|
|
|
fVisible = fFullVisible;
|
2004-06-16 10:40:26 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
// Rebuild regions for children...
|
2005-06-15 23:01:43 +04:00
|
|
|
for (Layer *lay = BottomChild(); lay; lay = UpperSibling()) {
|
2005-04-27 21:26:57 +04:00
|
|
|
if (lay == target)
|
|
|
|
lay->RebuildRegions(reg, action, pt, BPoint(0.0f, 0.0f));
|
|
|
|
else
|
|
|
|
lay->RebuildRegions(reg, B_LAYER_NONE, pt, BPoint(0.0f, 0.0f));
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef DEBUG_LAYER_REBUILD
|
|
|
|
printf("\nSRR: Layer(%s) ALMOST done regions:\n", GetName());
|
|
|
|
printf("\tVisible Region:\n");
|
|
|
|
fVisible.PrintToStream();
|
|
|
|
printf("\tFull Visible Region:\n");
|
|
|
|
fFullVisible.PrintToStream();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
BRegion redrawReg(fVisible);
|
|
|
|
|
|
|
|
// if this is the first time
|
|
|
|
if (oldVisible.CountRects() > 0)
|
|
|
|
redrawReg.Exclude(&oldVisible);
|
2004-02-24 15:02:47 +03:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
if (redrawReg.CountRects() > 0)
|
|
|
|
fRootLayer->fRedrawReg.Include(&redrawReg);
|
2004-06-11 22:21:57 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
#ifdef DEBUG_LAYER_REBUILD
|
|
|
|
printf("\nLayer(%s)::StartRebuildRegions() DONE. Results:\n", GetName());
|
|
|
|
printf("\tRedraw Region:\n");
|
|
|
|
fRootLayer->fRedrawReg.PrintToStream();
|
|
|
|
printf("\tCopy Region:\n");
|
|
|
|
for (int32 k=0; k<fRootLayer->fCopyRegList.CountItems(); k++) {
|
|
|
|
((BRegion*)(fRootLayer->fCopyRegList.ItemAt(k)))->PrintToStream();
|
|
|
|
((BPoint*)(fRootLayer->fCopyList.ItemAt(k)))->PrintToStream();
|
|
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
STRACE(("Layer(%s)::StartRebuildRegions() END\n", GetName()));
|
|
|
|
RBTRACE(("Layer(%s)::StartRebuildRegions() END\n", GetName()));
|
2003-01-24 18:19:27 +03:00
|
|
|
}
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
// RebuildRegions
|
|
|
|
void
|
|
|
|
Layer::RebuildRegions( const BRegion& reg, uint32 action, BPoint pt, BPoint ptOffset)
|
2004-06-11 22:21:57 +04:00
|
|
|
{
|
2005-04-27 21:26:57 +04:00
|
|
|
STRACE(("Layer(%s)::RebuildRegions() START\n", GetName()));
|
2003-11-14 03:15:29 +03:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
// TODO:/NOTE: this method must be executed as quickly as possible.
|
|
|
|
|
|
|
|
// Currently SendView[Moved/Resized]Msg() simply constructs a message and calls
|
|
|
|
// ServerWindow::SendMessageToClient(). This involves the alternative use of
|
|
|
|
// kernel and this code in the CPU, so there are a lot of context switches.
|
|
|
|
// This is NOT good at all!
|
|
|
|
|
|
|
|
// One alternative would be the use of a BMessageQueue per ServerWindows OR only
|
|
|
|
// one for app_server which will be emptied as soon as this critical operation ended.
|
|
|
|
// Talk to DW, Gabe.
|
|
|
|
|
|
|
|
BRegion oldRegion;
|
|
|
|
uint32 newAction = action;
|
|
|
|
BPoint newPt = pt;
|
|
|
|
BPoint newOffset = ptOffset; // used for resizing only
|
|
|
|
|
|
|
|
BPoint dummyNewLocation;
|
2004-02-24 15:02:47 +03:00
|
|
|
|
|
|
|
RRLabel1:
|
2005-04-27 21:26:57 +04:00
|
|
|
switch(action) {
|
|
|
|
case B_LAYER_NONE: {
|
2005-03-14 23:59:00 +03:00
|
|
|
RBTRACE(("1) Layer(%s): Action B_LAYER_NONE\n", GetName()));
|
2005-04-29 03:56:40 +04:00
|
|
|
STRACE(("1) Layer(%s): Action B_LAYER_NONE\n", GetName()));
|
2004-06-11 22:21:57 +04:00
|
|
|
oldRegion = fVisible;
|
2004-02-24 15:02:47 +03:00
|
|
|
break;
|
|
|
|
}
|
2005-04-27 21:26:57 +04:00
|
|
|
case B_LAYER_MOVE: {
|
2005-03-14 23:59:00 +03:00
|
|
|
RBTRACE(("1) Layer(%s): Action B_LAYER_MOVE\n", GetName()));
|
2005-04-29 03:56:40 +04:00
|
|
|
STRACE(("1) Layer(%s): Action B_LAYER_MOVE\n", GetName()));
|
2004-06-11 22:21:57 +04:00
|
|
|
oldRegion = fFullVisible;
|
|
|
|
fFrame.OffsetBy(pt.x, pt.y);
|
|
|
|
fFull.OffsetBy(pt.x, pt.y);
|
|
|
|
|
2005-05-16 19:39:58 +04:00
|
|
|
// TODO: investigate combining frame event messages for efficiency
|
2004-02-24 15:02:47 +03:00
|
|
|
//SendViewMovedMsg();
|
2005-05-16 19:39:58 +04:00
|
|
|
AddToViewsWithInvalidCoords();
|
2004-02-24 15:02:47 +03:00
|
|
|
|
|
|
|
newAction = B_LAYER_SIMPLE_MOVE;
|
|
|
|
break;
|
|
|
|
}
|
2005-04-27 21:26:57 +04:00
|
|
|
case B_LAYER_SIMPLE_MOVE: {
|
2005-03-14 23:59:00 +03:00
|
|
|
RBTRACE(("1) Layer(%s): Action B_LAYER_SIMPLE_MOVE\n", GetName()));
|
2005-04-29 03:56:40 +04:00
|
|
|
STRACE(("1) Layer(%s): Action B_LAYER_SIMPLE_MOVE\n", GetName()));
|
2004-06-11 22:21:57 +04:00
|
|
|
fFull.OffsetBy(pt.x, pt.y);
|
|
|
|
|
2004-02-24 15:02:47 +03:00
|
|
|
break;
|
|
|
|
}
|
2005-04-27 21:26:57 +04:00
|
|
|
case B_LAYER_RESIZE: {
|
2005-03-14 23:59:00 +03:00
|
|
|
RBTRACE(("1) Layer(%s): Action B_LAYER_RESIZE\n", GetName()));
|
2005-04-29 03:56:40 +04:00
|
|
|
STRACE(("1) Layer(%s): Action B_LAYER_RESIZE\n", GetName()));
|
2004-06-11 22:21:57 +04:00
|
|
|
oldRegion = fVisible;
|
|
|
|
|
|
|
|
fFrame.right += pt.x;
|
|
|
|
fFrame.bottom += pt.y;
|
2004-02-24 15:02:47 +03:00
|
|
|
RebuildFullRegion();
|
2004-06-11 22:21:57 +04:00
|
|
|
|
2005-05-16 19:39:58 +04:00
|
|
|
// TODO: investigate combining frame event messages for efficiency
|
2004-02-24 15:02:47 +03:00
|
|
|
//SendViewResizedMsg();
|
2005-05-16 19:39:58 +04:00
|
|
|
AddToViewsWithInvalidCoords();
|
2004-06-11 22:21:57 +04:00
|
|
|
|
|
|
|
newAction = B_LAYER_MASK_RESIZE;
|
2004-02-24 15:02:47 +03:00
|
|
|
break;
|
|
|
|
}
|
2005-04-27 21:26:57 +04:00
|
|
|
case B_LAYER_MASK_RESIZE: {
|
2005-03-14 23:59:00 +03:00
|
|
|
RBTRACE(("1) Layer(%s): Action B_LAYER_MASK_RESIZE\n", GetName()));
|
2005-04-29 03:56:40 +04:00
|
|
|
STRACE(("1) Layer(%s): Action B_LAYER_MASK_RESIZE\n", GetName()));
|
2004-06-11 22:21:57 +04:00
|
|
|
oldRegion = fVisible;
|
|
|
|
|
|
|
|
BPoint offset, rSize;
|
|
|
|
BPoint coords[2];
|
|
|
|
|
2004-02-24 15:02:47 +03:00
|
|
|
ResizeOthers(pt.x, pt.y, coords, NULL);
|
2004-06-11 22:21:57 +04:00
|
|
|
offset = coords[0];
|
|
|
|
rSize = coords[1];
|
|
|
|
newOffset = offset + ptOffset;
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
if (!(rSize.x == 0.0f && rSize.y == 0.0f)) {
|
2004-06-11 22:21:57 +04:00
|
|
|
fFrame.OffsetBy(offset);
|
|
|
|
fFrame.right += rSize.x;
|
|
|
|
fFrame.bottom += rSize.y;
|
2004-02-24 15:02:47 +03:00
|
|
|
RebuildFullRegion();
|
2004-06-11 22:21:57 +04:00
|
|
|
|
2005-05-16 19:39:58 +04:00
|
|
|
// TODO: investigate combining frame event messages for efficiency
|
2004-02-24 15:02:47 +03:00
|
|
|
//SendViewResizedMsg();
|
2005-05-16 19:39:58 +04:00
|
|
|
AddToViewsWithInvalidCoords();
|
2004-02-24 15:02:47 +03:00
|
|
|
|
2004-06-11 22:21:57 +04:00
|
|
|
newAction = B_LAYER_MASK_RESIZE;
|
|
|
|
newPt = rSize;
|
2004-02-24 15:02:47 +03:00
|
|
|
dummyNewLocation = newOffset;
|
2005-04-27 21:26:57 +04:00
|
|
|
} else {
|
|
|
|
if (!(offset.x == 0.0f && offset.y == 0.0f)) {
|
2004-06-11 22:21:57 +04:00
|
|
|
pt = newOffset;
|
|
|
|
action = B_LAYER_MOVE;
|
|
|
|
newPt = pt;
|
|
|
|
goto RRLabel1;
|
2005-04-27 21:26:57 +04:00
|
|
|
} else {
|
2004-06-11 22:21:57 +04:00
|
|
|
pt = ptOffset;
|
|
|
|
action = B_LAYER_MOVE;
|
|
|
|
newPt = pt;
|
|
|
|
goto RRLabel1;
|
|
|
|
}
|
2003-11-14 03:15:29 +03:00
|
|
|
}
|
2004-02-24 15:02:47 +03:00
|
|
|
break;
|
2003-11-14 03:15:29 +03:00
|
|
|
}
|
|
|
|
}
|
2004-02-24 15:02:47 +03:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
if (!IsHidden()) {
|
2004-09-09 04:54:21 +04:00
|
|
|
#ifdef DEBUG_LAYER_REBUILD
|
2005-03-14 23:59:00 +03:00
|
|
|
printf("Layer(%s) real action START\n", GetName());
|
2004-09-09 04:54:21 +04:00
|
|
|
fFull.PrintToStream();
|
|
|
|
#endif
|
2005-03-17 20:41:00 +03:00
|
|
|
fFullVisible.MakeEmpty();
|
|
|
|
fVisible = fFull;
|
2004-09-09 04:54:21 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
if (fParent && fVisible.CountRects() > 0) {
|
2004-06-16 10:40:26 +04:00
|
|
|
// not the usual case, but support fot this is needed.
|
2005-04-27 21:26:57 +04:00
|
|
|
if (fParent->fAdFlags & B_LAYER_CHILDREN_DEPENDANT) {
|
2004-09-09 04:54:21 +04:00
|
|
|
#ifdef DEBUG_LAYER_REBUILD
|
2005-03-14 23:59:00 +03:00
|
|
|
printf(" B_LAYER_CHILDREN_DEPENDANT Parent\n");
|
2004-09-09 04:54:21 +04:00
|
|
|
#endif
|
|
|
|
|
2004-06-16 10:40:26 +04:00
|
|
|
// because we're skipping one level, we need to do out
|
|
|
|
// parent business as well.
|
2004-09-09 04:54:21 +04:00
|
|
|
|
2004-06-16 10:40:26 +04:00
|
|
|
// our visible area is relative to our parent's parent.
|
|
|
|
if (fParent->fParent)
|
|
|
|
fVisible.IntersectWith(&(fParent->fParent->fVisible));
|
2004-09-09 04:54:21 +04:00
|
|
|
|
2004-06-16 10:40:26 +04:00
|
|
|
// exclude parent's visible area which could be composed by
|
|
|
|
// prior siblings' visible areas.
|
|
|
|
if (fVisible.CountRects() > 0)
|
|
|
|
fVisible.Exclude(&(fParent->fVisible));
|
2004-09-09 04:54:21 +04:00
|
|
|
|
2004-06-16 10:40:26 +04:00
|
|
|
// we have a final visible area. Include it to our parent's one,
|
|
|
|
// exclude from parent's parent.
|
2005-04-27 21:26:57 +04:00
|
|
|
if (fVisible.CountRects() > 0) {
|
2004-06-16 10:40:26 +04:00
|
|
|
fParent->fFullVisible.Include(&fVisible);
|
2004-09-09 04:54:21 +04:00
|
|
|
|
2004-06-16 10:40:26 +04:00
|
|
|
if (fParent->fParent)
|
|
|
|
fParent->fParent->fVisible.Exclude(&fVisible);
|
|
|
|
}
|
2005-04-27 21:26:57 +04:00
|
|
|
} else {
|
2004-09-09 04:54:21 +04:00
|
|
|
// for 95+% of cases
|
|
|
|
|
|
|
|
#ifdef DEBUG_LAYER_REBUILD
|
2005-03-14 23:59:00 +03:00
|
|
|
printf(" (!)B_LAYER_CHILDREN_DEPENDANT Parent\n");
|
2004-09-09 04:54:21 +04:00
|
|
|
#endif
|
|
|
|
|
2004-06-16 10:40:26 +04:00
|
|
|
// the visible area is the one common with parent's one.
|
|
|
|
fVisible.IntersectWith(&(fParent->fVisible));
|
2004-09-09 04:54:21 +04:00
|
|
|
|
2004-06-16 10:40:26 +04:00
|
|
|
// exclude from parent's visible area. we're the owners now.
|
|
|
|
if (fVisible.CountRects() > 0)
|
|
|
|
fParent->fVisible.Exclude(&fVisible);
|
|
|
|
}
|
2003-11-14 03:15:29 +03:00
|
|
|
}
|
2004-06-11 22:21:57 +04:00
|
|
|
fFullVisible = fVisible;
|
2003-11-14 03:15:29 +03:00
|
|
|
}
|
2004-06-11 22:21:57 +04:00
|
|
|
|
|
|
|
// Rebuild regions for children...
|
2005-06-15 23:01:43 +04:00
|
|
|
for(Layer *lay = BottomChild(); lay != NULL; lay = UpperSibling())
|
2004-06-11 22:21:57 +04:00
|
|
|
lay->RebuildRegions(reg, newAction, newPt, newOffset);
|
2005-03-14 23:59:00 +03:00
|
|
|
|
|
|
|
#ifdef DEBUG_LAYER_REBUILD
|
|
|
|
printf("\nLayer(%s) ALMOST done regions:\n", GetName());
|
|
|
|
printf("\tVisible Region:\n");
|
|
|
|
fVisible.PrintToStream();
|
|
|
|
printf("\tFull Visible Region:\n");
|
|
|
|
fFullVisible.PrintToStream();
|
|
|
|
#endif
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
if(!IsHidden()) {
|
|
|
|
switch(action) {
|
|
|
|
case B_LAYER_NONE: {
|
2005-03-14 23:59:00 +03:00
|
|
|
RBTRACE(("2) Layer(%s): Action B_LAYER_NONE\n", GetName()));
|
2004-06-11 22:21:57 +04:00
|
|
|
BRegion r(fVisible);
|
|
|
|
if (oldRegion.CountRects() > 0)
|
|
|
|
r.Exclude(&oldRegion);
|
|
|
|
|
|
|
|
if(r.CountRects() > 0)
|
2005-01-24 20:18:19 +03:00
|
|
|
fRootLayer->fRedrawReg.Include(&r);
|
2004-06-11 22:21:57 +04:00
|
|
|
break;
|
2003-11-14 03:15:29 +03:00
|
|
|
}
|
2005-04-27 21:26:57 +04:00
|
|
|
case B_LAYER_MOVE: {
|
2005-03-14 23:59:00 +03:00
|
|
|
RBTRACE(("2) Layer(%s): Action B_LAYER_MOVE\n", GetName()));
|
2004-06-11 22:21:57 +04:00
|
|
|
BRegion redrawReg;
|
|
|
|
BRegion *copyReg = new BRegion();
|
|
|
|
BRegion screenReg(fRootLayer->Bounds());
|
|
|
|
|
|
|
|
oldRegion.OffsetBy(pt.x, pt.y);
|
|
|
|
oldRegion.IntersectWith(&fFullVisible);
|
|
|
|
|
|
|
|
*copyReg = oldRegion;
|
|
|
|
copyReg->IntersectWith(&screenReg);
|
2005-04-27 21:26:57 +04:00
|
|
|
if (copyReg->CountRects() > 0 && !(pt.x == 0.0f && pt.y == 0.0f)) {
|
2004-06-11 22:21:57 +04:00
|
|
|
copyReg->OffsetBy(-pt.x, -pt.y);
|
|
|
|
BPoint *point = new BPoint(pt);
|
2005-01-24 20:18:19 +03:00
|
|
|
fRootLayer->fCopyRegList.AddItem(copyReg);
|
|
|
|
fRootLayer->fCopyList.AddItem(point);
|
2005-04-27 21:26:57 +04:00
|
|
|
} else {
|
2004-06-11 22:21:57 +04:00
|
|
|
delete copyReg;
|
|
|
|
}
|
|
|
|
|
|
|
|
redrawReg = fFullVisible;
|
|
|
|
redrawReg.Exclude(&oldRegion);
|
2005-04-27 21:26:57 +04:00
|
|
|
if (redrawReg.CountRects() > 0 && !(pt.x == 0.0f && pt.y == 0.0f)) {
|
2005-01-24 20:18:19 +03:00
|
|
|
fRootLayer->fRedrawReg.Include(&redrawReg);
|
2004-06-11 22:21:57 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
2003-07-05 20:03:54 +04:00
|
|
|
}
|
2005-04-27 21:26:57 +04:00
|
|
|
case B_LAYER_RESIZE: {
|
2005-03-14 23:59:00 +03:00
|
|
|
RBTRACE(("2) Layer(%s): Action B_LAYER_RESIZE\n", GetName()));
|
2004-06-11 22:21:57 +04:00
|
|
|
BRegion redrawReg;
|
|
|
|
|
|
|
|
redrawReg = fVisible;
|
|
|
|
redrawReg.Exclude(&oldRegion);
|
|
|
|
if(redrawReg.CountRects() > 0)
|
2005-01-24 20:18:19 +03:00
|
|
|
fRootLayer->fRedrawReg.Include(&redrawReg);
|
2004-06-11 22:21:57 +04:00
|
|
|
|
|
|
|
break;
|
2004-02-24 15:02:47 +03:00
|
|
|
}
|
2005-04-27 21:26:57 +04:00
|
|
|
case B_LAYER_MASK_RESIZE: {
|
2005-03-14 23:59:00 +03:00
|
|
|
RBTRACE(("2) Layer(%s): Action B_LAYER_MASK_RESIZE\n", GetName()));
|
2004-06-11 22:21:57 +04:00
|
|
|
BRegion redrawReg;
|
|
|
|
BRegion *copyReg = new BRegion();
|
|
|
|
|
|
|
|
oldRegion.OffsetBy(dummyNewLocation.x, dummyNewLocation.y);
|
|
|
|
|
|
|
|
redrawReg = fVisible;
|
|
|
|
redrawReg.Exclude(&oldRegion);
|
2005-04-27 21:26:57 +04:00
|
|
|
if (redrawReg.CountRects() > 0)
|
2005-01-24 20:18:19 +03:00
|
|
|
fRootLayer->fRedrawReg.Include(&redrawReg);
|
2004-06-11 22:21:57 +04:00
|
|
|
|
|
|
|
*copyReg = fVisible;
|
|
|
|
copyReg->IntersectWith(&oldRegion);
|
|
|
|
copyReg->OffsetBy(-dummyNewLocation.x, -dummyNewLocation.y);
|
2005-04-27 21:26:57 +04:00
|
|
|
if (copyReg->CountRects() > 0
|
|
|
|
&& !(dummyNewLocation.x == 0.0f && dummyNewLocation.y == 0.0f)) {
|
2005-01-24 20:18:19 +03:00
|
|
|
fRootLayer->fCopyRegList.AddItem(copyReg);
|
|
|
|
fRootLayer->fCopyList.AddItem(new BPoint(dummyNewLocation));
|
2004-06-11 22:21:57 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
2003-11-14 03:15:29 +03:00
|
|
|
}
|
2004-06-11 22:21:57 +04:00
|
|
|
default:
|
2005-03-14 23:59:00 +03:00
|
|
|
RBTRACE(("2) Layer(%s): Action default\n", GetName()));
|
2004-06-11 22:21:57 +04:00
|
|
|
break;
|
2004-02-24 15:02:47 +03:00
|
|
|
}
|
|
|
|
}
|
2005-04-27 21:26:57 +04:00
|
|
|
/* if (IsHidden()) {
|
2004-06-11 22:21:57 +04:00
|
|
|
fFullVisible.MakeEmpty();
|
|
|
|
fVisible.MakeEmpty();
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
STRACE(("Layer(%s)::RebuildRegions() END\n", GetName()));
|
2003-01-24 18:19:27 +03:00
|
|
|
}
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
// ResizeOthers
|
|
|
|
uint32
|
|
|
|
Layer::ResizeOthers(float x, float y, BPoint coords[], BPoint *ptOffset)
|
2003-01-24 18:19:27 +03:00
|
|
|
{
|
2005-04-27 21:26:57 +04:00
|
|
|
STRACE(("Layer(%s)::ResizeOthers() START\n", GetName()));
|
|
|
|
uint32 rmask = fResizeMode;
|
2004-06-11 22:21:57 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
// offset
|
|
|
|
coords[0].x = 0.0f;
|
|
|
|
coords[0].y = 0.0f;
|
2004-06-11 22:21:57 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
// resize by width/height
|
|
|
|
coords[1].x = 0.0f;
|
|
|
|
coords[1].y = 0.0f;
|
2005-02-28 23:23:51 +03:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
if ((rmask & 0x00000f00UL)>>8 == _VIEW_LEFT_ &&
|
|
|
|
(rmask & 0x0000000fUL)>>0 == _VIEW_RIGHT_) {
|
|
|
|
coords[1].x = x;
|
|
|
|
} else if ((rmask & 0x00000f00UL)>>8 == _VIEW_LEFT_) {
|
|
|
|
} else if ((rmask & 0x0000000fUL)>>0 == _VIEW_RIGHT_) {
|
|
|
|
coords[0].x = x;
|
|
|
|
} else if ((rmask & 0x00000f00UL)>>8 == _VIEW_CENTER_) {
|
|
|
|
coords[0].x = x/2;
|
|
|
|
} else {
|
|
|
|
// illegal flag. Do nothing.
|
2004-02-24 15:02:47 +03:00
|
|
|
}
|
2004-06-16 10:40:26 +04:00
|
|
|
|
2004-02-24 15:02:47 +03:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
if ((rmask & 0x0000f000UL)>>12 == _VIEW_TOP_ &&
|
|
|
|
(rmask & 0x000000f0UL)>>4 == _VIEW_BOTTOM_) {
|
|
|
|
coords[1].y = y;
|
|
|
|
} else if ((rmask & 0x0000f000UL)>>12 == _VIEW_TOP_) {
|
|
|
|
} else if ((rmask & 0x000000f0UL)>>4 == _VIEW_BOTTOM_) {
|
|
|
|
coords[0].y = y;
|
|
|
|
} else if ((rmask & 0x0000f000UL)>>12 == _VIEW_CENTER_) {
|
|
|
|
coords[0].y = y/2;
|
|
|
|
} else {
|
|
|
|
// illegal flag. Do nothing.
|
|
|
|
}
|
|
|
|
|
|
|
|
STRACE(("Layer(%s)::ResizeOthers() END\n", GetName()));
|
|
|
|
return 0UL;
|
2003-11-14 03:15:29 +03:00
|
|
|
}
|
|
|
|
|
2005-06-16 22:58:14 +04:00
|
|
|
#endif
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
// Redraw
|
|
|
|
void
|
|
|
|
Layer::Redraw(const BRegion& reg, Layer *startFrom)
|
2004-02-24 15:02:47 +03:00
|
|
|
{
|
2005-04-27 21:26:57 +04:00
|
|
|
STRACE(("Layer(%s)::Redraw();\n", GetName()));
|
|
|
|
if (IsHidden())
|
|
|
|
// this layer has nothing visible on screen, so bail out.
|
2003-11-14 03:15:29 +03:00
|
|
|
return;
|
2005-01-23 00:51:39 +03:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
BRegion *pReg = const_cast<BRegion*>(®);
|
2005-01-23 02:25:41 +03:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
if (pReg->CountRects() > 0)
|
|
|
|
RequestDraw(reg, startFrom);
|
|
|
|
|
|
|
|
STRACE(("Layer(%s)::Redraw() ENDED\n", GetName()));
|
2005-01-23 02:25:41 +03:00
|
|
|
}
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
// Draw
|
|
|
|
void
|
2005-06-10 19:28:34 +04:00
|
|
|
Layer::Draw(const BRect &rect)
|
2005-01-23 02:25:41 +03:00
|
|
|
{
|
2005-04-27 21:26:57 +04:00
|
|
|
#ifdef DEBUG_LAYER
|
|
|
|
printf("Layer(%s)::Draw: ", GetName());
|
2005-06-10 19:28:34 +04:00
|
|
|
rect.PrintToStream();
|
2005-04-27 21:26:57 +04:00
|
|
|
#endif
|
2005-01-23 00:51:39 +03:00
|
|
|
|
2005-06-10 20:20:38 +04:00
|
|
|
if (!ViewColor().IsTransparentMagic())
|
|
|
|
fDriver->FillRect(rect, ViewColor());
|
2003-11-14 03:15:29 +03:00
|
|
|
}
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
// EmptyGlobals
|
|
|
|
void
|
|
|
|
Layer::EmptyGlobals()
|
2004-06-11 22:21:57 +04:00
|
|
|
{
|
2005-01-24 20:18:19 +03:00
|
|
|
fRootLayer->fRedrawReg.MakeEmpty();
|
2005-04-27 21:26:57 +04:00
|
|
|
|
|
|
|
int32 count = fRootLayer->fCopyRegList.CountItems();
|
|
|
|
for (int32 i = 0; i < count; i++)
|
|
|
|
delete (BRegion*)fRootLayer->fCopyRegList.ItemAt(i);
|
|
|
|
fRootLayer->fCopyRegList.MakeEmpty();
|
2004-06-11 22:21:57 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
count = fRootLayer->fCopyList.CountItems();
|
|
|
|
for (int32 i = 0; i < count; i++)
|
|
|
|
delete (BPoint*)fRootLayer->fCopyList.ItemAt(i);
|
|
|
|
fRootLayer->fCopyList.MakeEmpty();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\brief Shows the layer
|
|
|
|
\param invalidate Invalidate the region when showing the layer. defaults to true
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
Layer::Show(bool invalidate)
|
|
|
|
{
|
|
|
|
STRACE(("Layer(%s)::Show()\n", GetName()));
|
2005-06-04 15:18:30 +04:00
|
|
|
if(!IsHidden())
|
2005-04-27 21:26:57 +04:00
|
|
|
return;
|
|
|
|
|
|
|
|
fHidden = false;
|
2005-06-04 15:18:30 +04:00
|
|
|
|
|
|
|
// NOTE: I added this here and it solves the invalid region problem
|
|
|
|
// for Windows that have been resized before they were shown. -Stephan
|
2005-06-16 22:58:14 +04:00
|
|
|
#ifndef NEW_CLIPPING
|
2005-06-04 15:18:30 +04:00
|
|
|
RebuildFullRegion();
|
|
|
|
SendViewCoordUpdateMsg();
|
|
|
|
|
|
|
|
if (invalidate)
|
2005-04-27 21:26:57 +04:00
|
|
|
GetRootLayer()->GoInvalidate(this, fFull);
|
2005-06-22 00:11:44 +04:00
|
|
|
#else
|
|
|
|
|
2005-06-16 23:44:55 +04:00
|
|
|
#endif
|
2004-02-24 15:02:47 +03:00
|
|
|
}
|
2003-11-14 03:15:29 +03:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
/*!
|
|
|
|
\brief Shows the layer
|
|
|
|
\param invalidate Invalidate the region when hiding the layer. defaults to true
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
Layer::Hide(bool invalidate)
|
2004-06-11 22:21:57 +04:00
|
|
|
{
|
2005-04-27 21:26:57 +04:00
|
|
|
STRACE(("Layer(%s)::Hide()\n", GetName()));
|
2005-06-04 15:18:30 +04:00
|
|
|
if (IsHidden())
|
2005-04-27 21:26:57 +04:00
|
|
|
return;
|
2004-06-11 22:21:57 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
fHidden = true;
|
2005-06-17 00:43:53 +04:00
|
|
|
#ifndef NEW_CLIPPING
|
2005-06-04 15:18:30 +04:00
|
|
|
if (invalidate)
|
2005-04-27 21:26:57 +04:00
|
|
|
GetRootLayer()->GoInvalidate(this, fFullVisible);
|
2005-06-17 00:43:53 +04:00
|
|
|
#endif
|
2005-04-27 21:26:57 +04:00
|
|
|
}
|
2004-02-24 15:02:47 +03:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
//! Returns true if the layer is hidden
|
|
|
|
bool
|
|
|
|
Layer::IsHidden(void) const
|
|
|
|
{
|
|
|
|
if (fHidden)
|
|
|
|
return true;
|
2005-06-16 00:36:43 +04:00
|
|
|
|
|
|
|
if (fParent)
|
2005-04-27 21:26:57 +04:00
|
|
|
return fParent->IsHidden();
|
|
|
|
|
2005-06-16 00:36:43 +04:00
|
|
|
return fHidden;
|
2005-04-27 21:26:57 +04:00
|
|
|
}
|
2003-11-14 03:15:29 +03:00
|
|
|
|
2005-06-10 19:28:34 +04:00
|
|
|
|
|
|
|
void
|
|
|
|
Layer::PushState()
|
|
|
|
{
|
2005-06-16 16:32:42 +04:00
|
|
|
LayerData *data = new LayerData(*fLayerData);
|
2005-06-10 19:28:34 +04:00
|
|
|
data->prevState = fLayerData;
|
|
|
|
fLayerData = data;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
Layer::PopState()
|
|
|
|
{
|
|
|
|
if (fLayerData->prevState == NULL) {
|
|
|
|
fprintf(stderr, "WARNING: User called BView(%s)::PopState(), but there is NO state on stack!\n", fName->String());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
LayerData *data = fLayerData;
|
|
|
|
fLayerData = fLayerData->prevState;
|
|
|
|
data->prevState = NULL;
|
|
|
|
delete data;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
//! Matches the BView call of the same name
|
|
|
|
BRect
|
|
|
|
Layer::Bounds(void) const
|
|
|
|
{
|
|
|
|
BRect r(fFrame);
|
|
|
|
// r.OffsetTo(fBoundsLeftTop);
|
|
|
|
r.OffsetTo(BoundsOrigin());
|
|
|
|
return r;
|
|
|
|
}
|
2004-02-24 15:02:47 +03:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
//! Matches the BView call of the same name
|
|
|
|
BRect
|
|
|
|
Layer::Frame(void) const
|
|
|
|
{
|
|
|
|
return fFrame;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Moves the layer by specified values, complete with redraw
|
|
|
|
void
|
|
|
|
Layer::MoveBy(float x, float y)
|
|
|
|
{
|
|
|
|
STRACE(("Layer(%s)::MoveBy() START\n", GetName()));
|
|
|
|
if (!fParent) {
|
2005-05-26 03:59:23 +04:00
|
|
|
CRITICAL("ERROR: in Layer::MoveBy()! - No parent!\n");
|
2005-04-27 21:26:57 +04:00
|
|
|
return;
|
2004-02-24 15:02:47 +03:00
|
|
|
}
|
|
|
|
|
2005-06-15 01:28:56 +04:00
|
|
|
BPrivate::PortLink msg(-1, -1);
|
2005-04-27 21:26:57 +04:00
|
|
|
msg.StartMessage(AS_ROOTLAYER_LAYER_MOVE);
|
|
|
|
msg.Attach<Layer*>(this);
|
|
|
|
msg.Attach<float>(x);
|
|
|
|
msg.Attach<float>(y);
|
|
|
|
GetRootLayer()->EnqueueMessage(msg);
|
|
|
|
|
|
|
|
STRACE(("Layer(%s)::MoveBy() END\n", GetName()));
|
2003-11-14 03:15:29 +03:00
|
|
|
}
|
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
//! Resize the layer by the specified amount, complete with redraw
|
2005-04-27 21:26:57 +04:00
|
|
|
void
|
|
|
|
Layer::ResizeBy(float x, float y)
|
2004-02-24 15:02:47 +03:00
|
|
|
{
|
2004-06-11 22:21:57 +04:00
|
|
|
STRACE(("Layer(%s)::ResizeBy() START\n", GetName()));
|
|
|
|
|
2005-06-06 02:02:25 +04:00
|
|
|
if (!fParent) {
|
2005-04-28 13:44:29 +04:00
|
|
|
printf("ERROR: in Layer::ResizeBy()! - No parent!\n");
|
2004-02-24 15:02:47 +03:00
|
|
|
return;
|
2004-01-13 03:56:36 +03:00
|
|
|
}
|
2005-01-23 00:51:39 +03:00
|
|
|
|
2005-06-15 01:28:56 +04:00
|
|
|
BPrivate::PortLink msg(-1, -1);
|
2005-01-23 02:25:41 +03:00
|
|
|
msg.StartMessage(AS_ROOTLAYER_LAYER_RESIZE);
|
|
|
|
msg.Attach<Layer*>(this);
|
|
|
|
msg.Attach<float>(x);
|
|
|
|
msg.Attach<float>(y);
|
|
|
|
GetRootLayer()->EnqueueMessage(msg);
|
|
|
|
|
|
|
|
STRACE(("Layer(%s)::ResizeBy() END\n", GetName()));
|
|
|
|
}
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
// BoundsOrigin
|
|
|
|
BPoint
|
|
|
|
Layer::BoundsOrigin() const
|
2005-01-23 02:25:41 +03:00
|
|
|
{
|
2005-06-15 22:47:41 +04:00
|
|
|
BPoint origin(0,0);
|
|
|
|
float scale = Scale();
|
|
|
|
|
|
|
|
LayerData *ld = fLayerData;
|
|
|
|
do {
|
|
|
|
origin += ld->Origin();
|
|
|
|
} while ((ld = ld->prevState));
|
|
|
|
|
|
|
|
origin.x *= scale;
|
|
|
|
origin.y *= scale;
|
|
|
|
|
|
|
|
return origin;
|
|
|
|
}
|
|
|
|
|
|
|
|
float
|
|
|
|
Layer::Scale() const
|
|
|
|
{
|
|
|
|
float scale = 1.0f;
|
|
|
|
|
|
|
|
LayerData *ld = fLayerData;
|
|
|
|
do {
|
2005-06-16 16:32:42 +04:00
|
|
|
scale *= ld->Scale();
|
2005-06-15 22:47:41 +04:00
|
|
|
} while ((ld = ld->prevState));
|
|
|
|
|
|
|
|
return scale;
|
2005-04-27 21:26:57 +04:00
|
|
|
}
|
2005-01-23 00:51:39 +03:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
//! Converts the passed point to parent coordinates
|
|
|
|
BPoint
|
|
|
|
Layer::ConvertToParent(BPoint pt)
|
|
|
|
{
|
|
|
|
pt -= BoundsOrigin();
|
|
|
|
pt += fFrame.LeftTop();
|
|
|
|
return pt;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Converts the passed rectangle to parent coordinates
|
|
|
|
BRect
|
|
|
|
Layer::ConvertToParent(BRect rect)
|
|
|
|
{
|
|
|
|
// rect.OffsetBy(fFrame.LeftTop());
|
|
|
|
// return rect;
|
|
|
|
rect.OffsetBy(-BoundsOrigin().x, -BoundsOrigin().y);
|
|
|
|
rect.OffsetBy(fFrame.LeftTop());
|
|
|
|
return rect;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Converts the passed region to parent coordinates
|
|
|
|
BRegion
|
|
|
|
Layer::ConvertToParent(BRegion* reg)
|
|
|
|
{
|
|
|
|
// TODO: wouldn't it be more efficient to use the copy
|
|
|
|
// constructor for BRegion and then call OffsetBy()?
|
|
|
|
BRegion newreg;
|
|
|
|
for (int32 i = 0; i < reg->CountRects(); i++)
|
|
|
|
newreg.Include(ConvertToParent(reg->RectAt(i)));
|
|
|
|
return newreg;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Converts the passed point from parent coordinates
|
|
|
|
BPoint
|
|
|
|
Layer::ConvertFromParent(BPoint pt)
|
|
|
|
{
|
|
|
|
// return pt - fFrame.LeftTop();
|
|
|
|
pt -= fFrame.LeftTop();
|
|
|
|
pt += BoundsOrigin();
|
|
|
|
return pt;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Converts the passed rectangle from parent coordinates
|
|
|
|
BRect
|
|
|
|
Layer::ConvertFromParent(BRect rect)
|
|
|
|
{
|
|
|
|
// rect.OffsetBy(-fFrame.left, -fFrame.top);
|
|
|
|
// return rect;
|
|
|
|
rect.OffsetBy(-fFrame.left, -fFrame.top);
|
|
|
|
rect.OffsetBy(BoundsOrigin());
|
|
|
|
return rect;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Converts the passed region from parent coordinates
|
|
|
|
BRegion
|
|
|
|
Layer::ConvertFromParent(BRegion *reg)
|
|
|
|
{
|
|
|
|
BRegion newreg;
|
|
|
|
for(int32 i=0; i<reg->CountRects();i++)
|
|
|
|
newreg.Include(ConvertFromParent(reg->RectAt(i)));
|
|
|
|
return newreg;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ConvertToTop
|
|
|
|
BPoint
|
|
|
|
Layer::ConvertToTop(BPoint pt)
|
|
|
|
{
|
|
|
|
if (fParent) {
|
|
|
|
// return (fParent->ConvertToTop(pt + fFrame.LeftTop()));
|
|
|
|
pt = ConvertToParent(pt);
|
|
|
|
return fParent->ConvertToTop(pt);
|
|
|
|
} else
|
|
|
|
return pt;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Converts the passed rectangle to screen coordinates
|
|
|
|
BRect
|
|
|
|
Layer::ConvertToTop(BRect rect)
|
|
|
|
{
|
|
|
|
if (fParent) {
|
|
|
|
// return fParent->ConvertToTop(rect.OffsetByCopy(fFrame.LeftTop()));
|
|
|
|
rect = ConvertToParent(rect);
|
|
|
|
return fParent->ConvertToTop(rect);
|
|
|
|
} else
|
|
|
|
return rect;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Converts the passed region to screen coordinates
|
|
|
|
BRegion
|
|
|
|
Layer::ConvertToTop(BRegion *reg)
|
|
|
|
{
|
|
|
|
BRegion newreg;
|
|
|
|
for (int32 i = 0; i < reg->CountRects();i++)
|
|
|
|
newreg.Include(ConvertToTop(reg->RectAt(i)));
|
|
|
|
return newreg;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ConvertFromTop
|
|
|
|
BPoint
|
|
|
|
Layer::ConvertFromTop(BPoint pt)
|
|
|
|
{
|
|
|
|
if (fParent) {
|
|
|
|
// return fParent->ConvertFromTop(pt-fFrame.LeftTop());
|
|
|
|
pt = ConvertFromParent(pt);
|
|
|
|
return fParent->ConvertFromTop(pt);
|
|
|
|
} else
|
|
|
|
return pt;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Converts the passed rectangle from screen coordinates
|
|
|
|
BRect
|
|
|
|
Layer::ConvertFromTop(BRect rect)
|
|
|
|
{
|
|
|
|
if (fParent) {
|
|
|
|
// return fParent->ConvertFromTop(rect.OffsetByCopy(-fFrame.LeftTop().x,
|
|
|
|
// -fFrame.LeftTop().y));
|
|
|
|
rect = ConvertFromParent(rect);
|
|
|
|
return fParent->ConvertFromTop(rect);
|
|
|
|
} else
|
|
|
|
return rect;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Converts the passed region from screen coordinates
|
|
|
|
BRegion
|
|
|
|
Layer::ConvertFromTop(BRegion *reg)
|
|
|
|
{
|
|
|
|
BRegion newreg;
|
2004-06-11 22:21:57 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
for (int32 i = 0; i < reg->CountRects(); i++)
|
|
|
|
newreg.Include(ConvertFromTop(reg->RectAt(i)));
|
2004-06-11 22:21:57 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
return newreg;
|
|
|
|
}
|
2005-01-23 00:51:39 +03:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
//! Recursively deletes all children of the calling layer
|
|
|
|
void
|
|
|
|
Layer::PruneTree(void)
|
|
|
|
{
|
|
|
|
Layer* lay;
|
|
|
|
Layer* nextlay;
|
|
|
|
|
|
|
|
lay = fTopChild;
|
|
|
|
fTopChild = NULL;
|
|
|
|
|
|
|
|
while (lay != NULL) {
|
|
|
|
if (lay->fTopChild != NULL)
|
|
|
|
lay->PruneTree();
|
|
|
|
|
|
|
|
nextlay = lay->fLowerSibling;
|
|
|
|
lay->fLowerSibling = NULL;
|
|
|
|
|
|
|
|
delete lay;
|
|
|
|
lay = nextlay;
|
|
|
|
}
|
|
|
|
// Man, this thing is short. Elegant, ain't it? :P
|
2003-01-24 18:19:27 +03:00
|
|
|
}
|
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
//! Prints information about the layer's current state
|
2005-04-27 21:26:57 +04:00
|
|
|
void
|
|
|
|
Layer::PrintToStream()
|
2003-01-24 18:19:27 +03:00
|
|
|
{
|
2004-06-11 22:21:57 +04:00
|
|
|
printf("\n----------- Layer %s -----------\n",fName->String());
|
|
|
|
printf("\t Parent: %s\n", fParent? fParent->GetName():"NULL");
|
2004-04-03 19:08:09 +04:00
|
|
|
printf("\t us: %s\t ls: %s\n",
|
2004-06-11 22:21:57 +04:00
|
|
|
fUpperSibling? fUpperSibling->GetName():"NULL",
|
|
|
|
fLowerSibling? fLowerSibling->GetName():"NULL");
|
2004-04-03 19:08:09 +04:00
|
|
|
printf("\t topChild: %s\t bottomChild: %s\n",
|
2004-06-11 22:21:57 +04:00
|
|
|
fTopChild? fTopChild->GetName():"NULL",
|
|
|
|
fBottomChild? fBottomChild->GetName():"NULL");
|
|
|
|
|
|
|
|
printf("Frame: (%f, %f, %f, %f)", fFrame.left, fFrame.top, fFrame.right, fFrame.bottom);
|
|
|
|
printf("Token: %ld\n",fViewToken);
|
2004-07-30 19:16:59 +04:00
|
|
|
printf("Hidden - direct: %s\n", fHidden?"true":"false");
|
2004-02-24 15:02:47 +03:00
|
|
|
printf("Hidden - indirect: %s\n", IsHidden()?"true":"false");
|
2004-06-11 22:21:57 +04:00
|
|
|
printf("ResizingMode: %lx\n", fResizeMode);
|
|
|
|
printf("Flags: %lx\n", fFlags);
|
|
|
|
|
|
|
|
if (fLayerData)
|
|
|
|
fLayerData->PrintToStream();
|
2004-04-03 19:08:09 +04:00
|
|
|
else
|
|
|
|
printf(" NO LayerData valid pointer\n");
|
2003-01-24 18:19:27 +03:00
|
|
|
}
|
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
//! Prints pointer info kept by the current layer
|
2005-04-27 21:26:57 +04:00
|
|
|
void
|
|
|
|
Layer::PrintNode()
|
2003-01-24 18:19:27 +03:00
|
|
|
{
|
2004-06-11 22:21:57 +04:00
|
|
|
printf("-----------\nLayer %s\n",fName->String());
|
|
|
|
if(fParent)
|
|
|
|
printf("Parent: %s (%p)\n",fParent->GetName(), fParent);
|
2003-01-24 18:19:27 +03:00
|
|
|
else
|
|
|
|
printf("Parent: NULL\n");
|
2004-06-11 22:21:57 +04:00
|
|
|
if(fUpperSibling)
|
|
|
|
printf("Upper sibling: %s (%p)\n",fUpperSibling->GetName(), fUpperSibling);
|
2003-01-24 18:19:27 +03:00
|
|
|
else
|
|
|
|
printf("Upper sibling: NULL\n");
|
2004-06-11 22:21:57 +04:00
|
|
|
if(fLowerSibling)
|
|
|
|
printf("Lower sibling: %s (%p)\n",fLowerSibling->GetName(), fLowerSibling);
|
2003-01-24 18:19:27 +03:00
|
|
|
else
|
|
|
|
printf("Lower sibling: NULL\n");
|
2004-06-11 22:21:57 +04:00
|
|
|
if(fTopChild)
|
|
|
|
printf("Top child: %s (%p)\n",fTopChild->GetName(), fTopChild);
|
2003-01-24 18:19:27 +03:00
|
|
|
else
|
|
|
|
printf("Top child: NULL\n");
|
2004-06-11 22:21:57 +04:00
|
|
|
if(fBottomChild)
|
|
|
|
printf("Bottom child: %s (%p)\n",fBottomChild->GetName(), fBottomChild);
|
2003-01-24 18:19:27 +03:00
|
|
|
else
|
|
|
|
printf("Bottom child: NULL\n");
|
2005-06-17 00:43:53 +04:00
|
|
|
#ifndef NEW_CLIPPING
|
2004-06-11 22:21:57 +04:00
|
|
|
printf("Visible Areas: "); fVisible.PrintToStream();
|
2005-06-17 00:43:53 +04:00
|
|
|
#endif
|
2003-01-24 18:19:27 +03:00
|
|
|
}
|
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
//! Prints the tree hierarchy from the current layer down
|
2005-04-27 21:26:57 +04:00
|
|
|
void
|
|
|
|
Layer::PrintTree()
|
2004-06-11 22:21:57 +04:00
|
|
|
{
|
2004-02-24 15:02:47 +03:00
|
|
|
printf("\n Tree structure:\n");
|
|
|
|
printf("\t%s\t%s\n", GetName(), IsHidden()? "Hidden": "NOT hidden");
|
2005-06-15 23:01:43 +04:00
|
|
|
for(Layer *lay = BottomChild(); lay != NULL; lay = UpperSibling())
|
2004-02-24 15:02:47 +03:00
|
|
|
printf("\t%s\t%s\n", lay->GetName(), lay->IsHidden()? "Hidden": "NOT hidden");
|
2003-09-15 23:11:52 +04:00
|
|
|
}
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
// UpdateStart
|
|
|
|
void
|
|
|
|
Layer::UpdateStart()
|
2003-01-24 18:19:27 +03:00
|
|
|
{
|
2005-04-27 21:26:57 +04:00
|
|
|
// During updates we only want to draw what's in the update region
|
|
|
|
if (fClassID == AS_WINBORDER_CLASS) {
|
|
|
|
// NOTE: don't worry, RooLayer is locked here.
|
|
|
|
WinBorder *wb = (WinBorder*)this;
|
2003-01-24 18:19:27 +03:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
wb->fInUpdate = true;
|
|
|
|
wb->fRequestSent = false;
|
|
|
|
wb->yUpdateReg = wb->fUpdateReg;
|
|
|
|
wb->fUpdateReg.MakeEmpty();
|
|
|
|
wb->cnt--;
|
|
|
|
if (wb->cnt != 0)
|
2005-05-26 03:59:23 +04:00
|
|
|
CRITICAL("Layer::UpdateStart(): wb->cnt != 0 -> Not Allowed!");
|
2005-04-27 21:26:57 +04:00
|
|
|
}
|
2003-01-24 18:19:27 +03:00
|
|
|
}
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
// UpdateEnd
|
|
|
|
void
|
|
|
|
Layer::UpdateEnd()
|
2005-04-06 00:03:07 +04:00
|
|
|
{
|
2005-04-27 21:26:57 +04:00
|
|
|
// The usual case. Drawing is permitted in the whole visible area.
|
|
|
|
if (fClassID == AS_WINBORDER_CLASS) {
|
|
|
|
WinBorder *wb = (WinBorder*)this;
|
2005-04-06 00:03:07 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
wb->yUpdateReg.MakeEmpty();
|
|
|
|
|
|
|
|
wb->fInUpdate = false;
|
|
|
|
|
|
|
|
if (wb->zUpdateReg.CountRects() > 0) {
|
|
|
|
BRegion reg(wb->zUpdateReg);
|
|
|
|
wb->RequestDraw(reg, NULL);
|
|
|
|
}
|
|
|
|
}
|
2003-01-24 18:19:27 +03:00
|
|
|
}
|
|
|
|
|
2005-06-22 00:11:44 +04:00
|
|
|
|
|
|
|
#ifndef NEW_CLIPPING
|
|
|
|
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
// move_layer
|
|
|
|
void
|
|
|
|
Layer::move_layer(float x, float y)
|
2003-01-24 18:19:27 +03:00
|
|
|
{
|
2005-04-29 03:56:40 +04:00
|
|
|
/* if (fClassID == AS_WINBORDER_CLASS) {
|
2005-04-27 21:26:57 +04:00
|
|
|
WinBorder *wb = (WinBorder*)this;
|
|
|
|
wb->zUpdateReg.OffsetBy(x, y);
|
|
|
|
wb->yUpdateReg.OffsetBy(x, y);
|
|
|
|
wb->fUpdateReg.OffsetBy(x, y);
|
2005-04-29 03:56:40 +04:00
|
|
|
}*/
|
2004-06-11 22:21:57 +04:00
|
|
|
|
2005-06-16 23:44:55 +04:00
|
|
|
fFrameAction = B_LAYER_ACTION_MOVE;
|
|
|
|
|
2005-04-29 03:56:40 +04:00
|
|
|
BPoint pt(x, y);
|
|
|
|
BRect rect(fFull.Frame().OffsetByCopy(pt));
|
|
|
|
|
2005-05-05 03:48:19 +04:00
|
|
|
if (!fParent) {
|
|
|
|
printf("no parent in Layer::move_layer() (%s)\n", GetName());
|
|
|
|
fFrameAction = B_LAYER_ACTION_NONE;
|
|
|
|
return;
|
|
|
|
}
|
2005-06-22 00:11:44 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
fParent->StartRebuildRegions(BRegion(rect), this, B_LAYER_MOVE, pt);
|
2005-04-29 03:56:40 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
fDriver->CopyRegionList(&fRootLayer->fCopyRegList,
|
|
|
|
&fRootLayer->fCopyList,
|
|
|
|
fRootLayer->fCopyRegList.CountItems(),
|
|
|
|
&fFullVisible);
|
2005-04-29 03:56:40 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
fParent->Redraw(fRootLayer->fRedrawReg, this);
|
2005-05-16 19:39:58 +04:00
|
|
|
|
|
|
|
SendViewCoordUpdateMsg();
|
2004-06-11 22:21:57 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
EmptyGlobals();
|
2003-01-24 18:19:27 +03:00
|
|
|
|
2005-05-05 03:48:19 +04:00
|
|
|
fFrameAction = B_LAYER_ACTION_NONE;
|
2004-09-14 04:51:51 +04:00
|
|
|
}
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
// resize_layer
|
|
|
|
void
|
|
|
|
Layer::resize_layer(float x, float y)
|
2003-01-24 18:19:27 +03:00
|
|
|
{
|
2005-04-27 21:26:57 +04:00
|
|
|
fFrameAction = B_LAYER_ACTION_RESIZE;
|
2003-01-24 18:19:27 +03:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
BPoint pt(x,y);
|
2005-06-16 22:58:14 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
BRect rect(fFull.Frame());
|
|
|
|
rect.right += x;
|
|
|
|
rect.bottom += y;
|
2005-05-04 01:43:51 +04:00
|
|
|
|
2005-05-05 03:48:19 +04:00
|
|
|
if (!fParent) {
|
|
|
|
printf("no parent in Layer::resize_layer() (%s)\n", GetName());
|
|
|
|
fFrameAction = B_LAYER_ACTION_NONE;
|
|
|
|
return;
|
|
|
|
}
|
2005-06-22 00:11:44 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
fParent->StartRebuildRegions(BRegion(rect), this, B_LAYER_RESIZE, pt);
|
2005-06-16 22:58:14 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
fDriver->CopyRegionList(&fRootLayer->fCopyRegList, &fRootLayer->fCopyList, fRootLayer->fCopyRegList.CountItems(), &fFullVisible);
|
2005-06-22 00:11:44 +04:00
|
|
|
|
2005-06-17 00:43:53 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
fParent->Redraw(fRootLayer->fRedrawReg, this);
|
2005-05-16 19:39:58 +04:00
|
|
|
|
|
|
|
SendViewCoordUpdateMsg();
|
2005-04-27 21:26:57 +04:00
|
|
|
|
|
|
|
EmptyGlobals();
|
|
|
|
|
|
|
|
fFrameAction = B_LAYER_ACTION_NONE;
|
2003-01-24 18:19:27 +03:00
|
|
|
}
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
// FullInvalidate
|
|
|
|
void
|
|
|
|
Layer::FullInvalidate(const BRect &rect)
|
2004-09-14 04:51:51 +04:00
|
|
|
{
|
2005-04-27 21:26:57 +04:00
|
|
|
FullInvalidate(BRegion(rect));
|
2004-09-14 04:51:51 +04:00
|
|
|
}
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
// FullInvalidate
|
|
|
|
void
|
|
|
|
Layer::FullInvalidate(const BRegion& region)
|
2003-01-24 18:19:27 +03:00
|
|
|
{
|
2005-04-27 21:26:57 +04:00
|
|
|
STRACE(("Layer(%s)::FullInvalidate():\n", GetName()));
|
2004-06-11 22:21:57 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
#ifdef DEBUG_LAYER
|
|
|
|
region.PrintToStream();
|
|
|
|
printf("\n");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
BPoint pt(0,0);
|
|
|
|
StartRebuildRegions(region, NULL,/* B_LAYER_INVALIDATE, pt); */B_LAYER_NONE, pt);
|
2005-06-16 22:58:14 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
Redraw(fRootLayer->fRedrawReg);
|
|
|
|
|
|
|
|
EmptyGlobals();
|
2003-01-24 18:19:27 +03:00
|
|
|
}
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
// Invalidate
|
|
|
|
void
|
|
|
|
Layer::Invalidate(const BRegion& region)
|
2003-01-24 18:19:27 +03:00
|
|
|
{
|
2005-04-27 21:26:57 +04:00
|
|
|
STRACE(("Layer(%s)::Invalidate():\n", GetName()));
|
|
|
|
#ifdef DEBUG_LAYER
|
|
|
|
region.PrintToStream();
|
|
|
|
printf("\n");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
fRootLayer->fRedrawReg = region;
|
|
|
|
|
|
|
|
Redraw(fRootLayer->fRedrawReg);
|
|
|
|
|
|
|
|
EmptyGlobals();
|
2003-01-24 18:19:27 +03:00
|
|
|
}
|
2003-04-05 05:51:35 +04:00
|
|
|
|
2005-06-22 00:11:44 +04:00
|
|
|
#endif // 5 methods
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
// RequestDraw
|
|
|
|
void
|
|
|
|
Layer::RequestDraw(const BRegion ®, Layer *startFrom)
|
2004-06-11 22:21:57 +04:00
|
|
|
{
|
2005-04-27 21:26:57 +04:00
|
|
|
STRACE(("Layer(%s)::RequestDraw()\n", GetName()));
|
2005-06-22 00:11:44 +04:00
|
|
|
printf("Layer(%s)::RequestDraw()\n", GetName());
|
|
|
|
//if (fClassID == AS_ROOTLAYER_CLASS)
|
|
|
|
// debugger("z");
|
2005-04-27 21:26:57 +04:00
|
|
|
// do not redraw any child until you must
|
|
|
|
int redraw = false;
|
|
|
|
if (!startFrom)
|
|
|
|
redraw = true;
|
|
|
|
|
|
|
|
if (HasClient() && IsTopLayer()) {
|
|
|
|
// calculate the minimum region/rectangle to be updated with
|
|
|
|
// a single message to the client.
|
2005-06-17 00:43:53 +04:00
|
|
|
#ifndef NEW_CLIPPING
|
2005-06-22 00:11:44 +04:00
|
|
|
BRegion updateReg(fFullVisible);
|
|
|
|
#else
|
|
|
|
BRegion updateReg(fFullVisible2);
|
2005-06-17 00:43:53 +04:00
|
|
|
#endif
|
2005-06-22 00:11:44 +04:00
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
if (fFlags & B_FULL_UPDATE_ON_RESIZE
|
2005-06-16 23:44:55 +04:00
|
|
|
#ifndef NEW_CLIPPING
|
|
|
|
&& fFrameAction == B_LAYER_ACTION_RESIZE
|
|
|
|
#endif
|
|
|
|
)
|
|
|
|
{
|
2005-04-27 21:26:57 +04:00
|
|
|
// do nothing
|
|
|
|
} else {
|
|
|
|
updateReg.IntersectWith(®);
|
|
|
|
}
|
|
|
|
if (updateReg.CountRects() > 0) {
|
|
|
|
fOwner->zUpdateReg.Include(&updateReg);
|
|
|
|
if (!fOwner->fInUpdate && !fOwner->fRequestSent) {
|
|
|
|
fOwner->fUpdateReg = fOwner->zUpdateReg;
|
|
|
|
fOwner->cnt++;
|
|
|
|
if (fOwner->cnt != 1)
|
2005-05-26 03:59:23 +04:00
|
|
|
CRITICAL("Layer::RequestDraw(): fOwner->cnt != 1 -> Not Allowed!");
|
2005-04-27 21:26:57 +04:00
|
|
|
fOwner->zUpdateReg.MakeEmpty();
|
|
|
|
SendUpdateMsg(fOwner->fUpdateReg);
|
|
|
|
fOwner->fRequestSent = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-06-17 00:43:53 +04:00
|
|
|
#ifndef NEW_CLIPPING
|
2005-04-27 21:26:57 +04:00
|
|
|
if (fVisible.CountRects() > 0) {
|
|
|
|
BRegion updateReg(fVisible);
|
|
|
|
// calculate the update region
|
2005-06-22 00:11:44 +04:00
|
|
|
if (fFlags & B_FULL_UPDATE_ON_RESIZE && fFrameAction == B_LAYER_ACTION_RESIZE) {
|
2005-04-27 21:26:57 +04:00
|
|
|
// do nothing
|
|
|
|
} else {
|
|
|
|
updateReg.IntersectWith(®);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (updateReg.CountRects() > 0) {
|
|
|
|
fDriver->ConstrainClippingRegion(&updateReg);
|
|
|
|
Draw(updateReg.Frame());
|
|
|
|
fDriver->ConstrainClippingRegion(NULL);
|
|
|
|
}
|
|
|
|
}
|
2005-06-22 00:11:44 +04:00
|
|
|
|
2005-06-15 23:01:43 +04:00
|
|
|
for (Layer *lay = BottomChild(); lay != NULL; lay = UpperSibling()) {
|
2005-04-27 21:26:57 +04:00
|
|
|
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->fFullVisible);
|
|
|
|
common.IntersectWith(®);
|
|
|
|
|
|
|
|
if (common.CountRects() > 0)
|
|
|
|
lay->RequestDraw(reg, NULL);
|
|
|
|
}
|
2004-02-24 15:02:47 +03:00
|
|
|
}
|
2005-06-22 00:11:44 +04:00
|
|
|
#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(®);
|
|
|
|
}
|
|
|
|
|
|
|
|
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(®);
|
|
|
|
|
|
|
|
if (common.CountRects() > 0)
|
|
|
|
lay->RequestDraw(reg, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2004-02-24 15:02:47 +03:00
|
|
|
}
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
/*!
|
|
|
|
\brief Returns the layer's ServerWindow
|
|
|
|
|
|
|
|
If the layer's ServerWindow has not been assigned, it attempts to find
|
|
|
|
the owning ServerWindow in the tree.
|
|
|
|
*/
|
|
|
|
ServerWindow*
|
|
|
|
Layer::SearchForServerWindow()
|
2004-06-11 22:21:57 +04:00
|
|
|
{
|
2005-04-27 21:26:57 +04:00
|
|
|
if (!fServerWin)
|
|
|
|
fServerWin=fParent->SearchForServerWindow();
|
|
|
|
|
|
|
|
return fServerWin;
|
2004-02-24 15:02:47 +03:00
|
|
|
}
|
|
|
|
|
2004-09-09 04:54:21 +04:00
|
|
|
//! Sends an _UPDATE_ message to the client BWindow
|
2005-04-27 21:26:57 +04:00
|
|
|
void
|
|
|
|
Layer::SendUpdateMsg(BRegion& reg)
|
2004-07-05 19:23:29 +04:00
|
|
|
{
|
2005-03-31 20:48:51 +04:00
|
|
|
BMessage msg;
|
|
|
|
msg.what = _UPDATE_;
|
2005-04-06 00:03:07 +04:00
|
|
|
msg.AddRect("_rect", ConvertFromTop(reg.Frame()) );
|
|
|
|
msg.AddRect("debug_rect", reg.Frame() );
|
|
|
|
// msg.AddInt32("_token",fViewToken);
|
2004-07-05 19:23:29 +04:00
|
|
|
|
2005-03-31 20:48:51 +04:00
|
|
|
fOwner->Window()->SendMessageToClient(&msg);
|
2004-07-05 19:23:29 +04:00
|
|
|
}
|
|
|
|
|
2005-05-16 19:39:58 +04:00
|
|
|
// AddToViewsWithInvalidCoords
|
|
|
|
void
|
|
|
|
Layer::AddToViewsWithInvalidCoords() const
|
|
|
|
{
|
|
|
|
if (fServerWin) {
|
2005-06-10 19:50:24 +04:00
|
|
|
fServerWin->ClientViewsWithInvalidCoords().AddInt32("_token", fViewToken);
|
|
|
|
fServerWin->ClientViewsWithInvalidCoords().AddPoint("where", fFrame.LeftTop());
|
|
|
|
fServerWin->ClientViewsWithInvalidCoords().AddFloat("width", fFrame.Width());
|
|
|
|
fServerWin->ClientViewsWithInvalidCoords().AddFloat("height", fFrame.Height());
|
2005-05-16 19:39:58 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// SendViewCoordUpdateMsg
|
|
|
|
void
|
|
|
|
Layer::SendViewCoordUpdateMsg() const
|
|
|
|
{
|
2005-06-10 19:50:24 +04:00
|
|
|
if (fServerWin && !fServerWin->ClientViewsWithInvalidCoords().IsEmpty()) {
|
|
|
|
fServerWin->SendMessageToClient(&fServerWin->ClientViewsWithInvalidCoords());
|
|
|
|
fServerWin->ClientViewsWithInvalidCoords().MakeEmpty();
|
2005-05-16 19:39:58 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-06-10 20:20:38 +04:00
|
|
|
// SetViewColor
|
|
|
|
void
|
|
|
|
Layer::SetViewColor(const RGBColor& color)
|
|
|
|
{
|
|
|
|
fViewColor = color;
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetBackgroundBitmap
|
|
|
|
void
|
|
|
|
Layer::SetBackgroundBitmap(const ServerBitmap* bitmap)
|
|
|
|
{
|
|
|
|
// TODO: What about reference counting?
|
|
|
|
// "Release" old fBackgroundBitmap and "Aquire" new one?
|
|
|
|
fBackgroundBitmap = bitmap;
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetOverlayBitmap
|
|
|
|
void
|
|
|
|
Layer::SetOverlayBitmap(const ServerBitmap* bitmap)
|
|
|
|
{
|
|
|
|
// TODO: What about reference counting?
|
|
|
|
// "Release" old fOverlayBitmap and "Aquire" new one?
|
|
|
|
fOverlayBitmap = bitmap;
|
|
|
|
}
|
|
|
|
|
2005-06-15 23:01:43 +04:00
|
|
|
#ifdef NEW_CLIPPING
|
2005-04-27 21:26:57 +04:00
|
|
|
void
|
2005-06-15 23:01:43 +04:00
|
|
|
Layer::ConvertToScreen2(BRect* rect) const
|
|
|
|
{
|
|
|
|
if (GetRootLayer())
|
|
|
|
if (fParent) {
|
2005-06-16 00:36:43 +04:00
|
|
|
BPoint origin = BoundsOrigin();
|
|
|
|
rect->OffsetBy(-origin.x, -origin.y);
|
2005-06-15 23:01:43 +04:00
|
|
|
rect->OffsetBy(fFrame.left, fFrame.top);
|
|
|
|
|
|
|
|
fParent->ConvertToScreen2(rect);
|
|
|
|
}
|
2003-04-05 05:51:35 +04:00
|
|
|
}
|
|
|
|
|
2005-04-27 21:26:57 +04:00
|
|
|
void
|
2005-06-15 23:01:43 +04:00
|
|
|
Layer::ConvertToScreen2(BRegion* reg) const
|
|
|
|
{
|
|
|
|
if (GetRootLayer())
|
|
|
|
if (fParent) {
|
2005-06-16 00:36:43 +04:00
|
|
|
BPoint origin = BoundsOrigin();
|
|
|
|
reg->OffsetBy(-origin.x, -origin.y);
|
2005-06-15 23:01:43 +04:00
|
|
|
reg->OffsetBy(fFrame.left, fFrame.top);
|
|
|
|
|
|
|
|
fParent->ConvertToScreen2(reg);
|
|
|
|
}
|
2003-04-05 05:51:35 +04:00
|
|
|
}
|
2005-06-16 00:36:43 +04:00
|
|
|
|
|
|
|
void
|
|
|
|
Layer::do_Hide()
|
|
|
|
{
|
|
|
|
fHidden = true;
|
|
|
|
|
|
|
|
if (fParent && !fParent->IsHidden() && GetRootLayer()) {
|
|
|
|
// save fullVisible so we know what to invalidate
|
2005-06-17 00:43:53 +04:00
|
|
|
BRegion invalid(fFullVisible2);
|
2005-06-16 00:36:43 +04:00
|
|
|
|
|
|
|
clear_visible_regions();
|
|
|
|
|
|
|
|
if (invalid.Frame().IsValid())
|
|
|
|
fParent->do_Invalidate(invalid, this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Layer::do_Show()
|
|
|
|
{
|
|
|
|
fHidden = false;
|
|
|
|
|
|
|
|
if (fParent && !fParent->IsHidden() && GetRootLayer()) {
|
|
|
|
BRegion invalid;
|
|
|
|
|
|
|
|
get_user_regions(invalid);
|
|
|
|
|
|
|
|
if (invalid.CountRects() > 0)
|
|
|
|
fParent->do_Invalidate(invalid, this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Layer::do_Invalidate(const BRegion &invalid, const Layer *startFrom)
|
|
|
|
{
|
2005-06-17 00:43:53 +04:00
|
|
|
BRegion localVisible(fFullVisible2);
|
2005-06-16 00:36:43 +04:00
|
|
|
localVisible.IntersectWith(&invalid);
|
|
|
|
rebuild_visible_regions(invalid, localVisible,
|
|
|
|
startFrom? startFrom: BottomChild());
|
|
|
|
|
|
|
|
// 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)?
|
2005-06-22 00:11:44 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
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)?
|
2005-06-16 00:36:43 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
Layer::resize_layer_frame_by(float x, float y)
|
|
|
|
{
|
|
|
|
uint16 rm = fResizeMode & 0x0000FFFF;
|
|
|
|
BRect newFrame = fFrame;
|
|
|
|
|
|
|
|
if ((rm & 0x0F00U) == _VIEW_LEFT_ << 8)
|
|
|
|
newFrame.left += 0.0f;
|
|
|
|
else if ((rm & 0x0F00U) == _VIEW_RIGHT_ << 8)
|
|
|
|
newFrame.left += x;
|
|
|
|
else if ((rm & 0x0F00U) == _VIEW_CENTER_ << 8)
|
|
|
|
newFrame.left += x/2;
|
|
|
|
|
|
|
|
if ((rm & 0x000FU) == _VIEW_LEFT_)
|
|
|
|
newFrame.right += 0.0f;
|
|
|
|
else if ((rm & 0x000FU) == _VIEW_RIGHT_)
|
|
|
|
newFrame.right += x;
|
|
|
|
else if ((rm & 0x000FU) == _VIEW_CENTER_)
|
|
|
|
newFrame.right += x/2;
|
|
|
|
|
|
|
|
if ((rm & 0xF000U) == _VIEW_TOP_ << 12)
|
|
|
|
newFrame.top += 0.0f;
|
|
|
|
else if ((rm & 0xF000U) == _VIEW_BOTTOM_ << 12)
|
|
|
|
newFrame.top += y;
|
|
|
|
else if ((rm & 0xF000U) == _VIEW_CENTER_ << 12)
|
|
|
|
newFrame.top += y/2;
|
|
|
|
|
|
|
|
if ((rm & 0x00F0U) == _VIEW_TOP_ << 4)
|
|
|
|
newFrame.bottom += 0.0f;
|
|
|
|
else if ((rm & 0x00F0U) == _VIEW_BOTTOM_ << 4)
|
|
|
|
newFrame.bottom += y;
|
|
|
|
else if ((rm & 0x00F0U) == _VIEW_CENTER_ << 4)
|
|
|
|
newFrame.bottom += y/2;
|
|
|
|
|
|
|
|
if (newFrame != fFrame) {
|
|
|
|
float dx, dy;
|
|
|
|
|
|
|
|
dx = newFrame.Width() - fFrame.Width();
|
|
|
|
dy = newFrame.Height() - fFrame.Height();
|
|
|
|
|
|
|
|
fFrame = newFrame;
|
|
|
|
|
|
|
|
if (dx != 0.0f || dy != 0.0f) {
|
|
|
|
// call hook function
|
|
|
|
ResizedByHook(dx, dy, true); // automatic
|
|
|
|
|
|
|
|
for (Layer *lay = BottomChild(); lay; lay = UpperSibling())
|
|
|
|
lay->resize_layer_frame_by(dx, dy);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
MovedByHook(dx, dy);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
Layer::rezize_layer_redraw_more(BRegion ®, float dx, float dy)
|
|
|
|
{
|
|
|
|
if (dx == 0 && dy == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (Layer *lay = BottomChild(); lay; lay = UpperSibling()) {
|
|
|
|
uint16 rm = lay->fResizeMode & 0x0000FFFF;
|
|
|
|
|
|
|
|
if ((rm & 0x0F0F) == (uint16)B_FOLLOW_LEFT_RIGHT || (rm & 0xF0F0) == (uint16)B_FOLLOW_TOP_BOTTOM) {
|
|
|
|
// NOTE: this is not exactly corect, but it works :-)
|
|
|
|
// Normaly we shoud've used the lay's old, required region - the one returned
|
|
|
|
// from get_user_region() with the old frame, and the current one. lay->Bounds()
|
|
|
|
// works for the moment so we leave it like this.
|
|
|
|
|
|
|
|
// calculate the old bounds.
|
|
|
|
BRect oldBounds(lay->Bounds());
|
|
|
|
if ((rm & 0x0F0F) == (uint16)B_FOLLOW_LEFT_RIGHT)
|
|
|
|
oldBounds.right -=dx;
|
|
|
|
if ((rm & 0xF0F0) == (uint16)B_FOLLOW_TOP_BOTTOM)
|
|
|
|
oldBounds.bottom -=dy;
|
|
|
|
|
|
|
|
// compute the region that became visible because we got bigger OR smaller.
|
|
|
|
BRegion regZ(lay->Bounds());
|
|
|
|
regZ.Include(oldBounds);
|
|
|
|
regZ.Exclude(oldBounds&lay->Bounds());
|
|
|
|
|
|
|
|
lay->ConvertToScreen2(®Z);
|
|
|
|
|
|
|
|
// intersect that with this'(not lay's) fullVisible region
|
2005-06-17 00:43:53 +04:00
|
|
|
regZ.IntersectWith(&fFullVisible2);
|
2005-06-16 00:36:43 +04:00
|
|
|
reg.Include(®Z);
|
|
|
|
|
|
|
|
lay->rezize_layer_redraw_more(reg,
|
|
|
|
(rm & 0x0F0F) == (uint16)B_FOLLOW_LEFT_RIGHT? dx: 0,
|
|
|
|
(rm & 0xF0F0) == (uint16)B_FOLLOW_TOP_BOTTOM? dy: 0);
|
|
|
|
|
|
|
|
// above, OR this:
|
2005-06-17 00:43:53 +04:00
|
|
|
// reg.Include(&lay->fFullVisible2);
|
2005-06-16 00:36:43 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
if (((rm & 0x0F0F) == (uint16)B_FOLLOW_RIGHT && dx != 0) ||
|
|
|
|
((rm & 0x0F0F) == (uint16)B_FOLLOW_H_CENTER && dx != 0) ||
|
|
|
|
((rm & 0xF0F0) == (uint16)B_FOLLOW_BOTTOM && dy != 0)||
|
|
|
|
((rm & 0xF0F0) == (uint16)B_FOLLOW_V_CENTER && dy != 0))
|
|
|
|
{
|
2005-06-17 00:43:53 +04:00
|
|
|
reg.Include(&lay->fFullVisible2);
|
2005-06-16 00:36:43 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
Layer::resize_layer_full_update_on_resize(BRegion ®, float dx, float dy)
|
|
|
|
{
|
|
|
|
if (dx == 0 && dy == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (Layer *lay = BottomChild(); lay; lay = UpperSibling()) {
|
|
|
|
uint16 rm = lay->fResizeMode & 0x0000FFFF;
|
|
|
|
|
|
|
|
if ((rm & 0x0F0F) == (uint16)B_FOLLOW_LEFT_RIGHT || (rm & 0xF0F0) == (uint16)B_FOLLOW_TOP_BOTTOM) {
|
2005-06-17 00:43:53 +04:00
|
|
|
if (lay->fFlags & B_FULL_UPDATE_ON_RESIZE && lay->fVisible2.CountRects() > 0)
|
|
|
|
reg.Include(&lay->fVisible2);
|
2005-06-16 00:36:43 +04:00
|
|
|
|
|
|
|
lay->resize_layer_full_update_on_resize(reg,
|
|
|
|
(rm & 0x0F0F) == (uint16)B_FOLLOW_LEFT_RIGHT? dx: 0,
|
|
|
|
(rm & 0xF0F0) == (uint16)B_FOLLOW_TOP_BOTTOM? dy: 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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 *lay = BottomChild(); lay; lay = UpperSibling())
|
|
|
|
lay->resize_layer_frame_by(dx, dy);
|
|
|
|
|
|
|
|
// call hook function
|
|
|
|
if (dx != 0.0f || dy != 0.0f)
|
|
|
|
ResizedByHook(dx, dy, false); // manual
|
|
|
|
|
|
|
|
if (!IsHidden() && GetRootLayer()) {
|
2005-06-17 00:43:53 +04:00
|
|
|
BRegion oldFullVisible(fFullVisible2);
|
2005-06-16 00:36:43 +04:00
|
|
|
// this is required to invalidate the old border
|
2005-06-17 00:43:53 +04:00
|
|
|
BRegion oldVisible(fVisible2);
|
2005-06-16 00:36:43 +04:00
|
|
|
|
|
|
|
// in case they moved, bottom, right and center aligned layers must be redrawn
|
|
|
|
BRegion redrawMore;
|
|
|
|
rezize_layer_redraw_more(redrawMore, dx, dy);
|
|
|
|
|
|
|
|
// we'll invalidate the old area and the new, maxmial one.
|
|
|
|
BRegion invalid;
|
|
|
|
get_user_regions(invalid);
|
2005-06-17 00:43:53 +04:00
|
|
|
invalid.Include(&fFullVisible2);
|
2005-06-16 00:36:43 +04:00
|
|
|
|
|
|
|
clear_visible_regions();
|
|
|
|
|
|
|
|
fParent->do_RebuildVisibleRegions(invalid, this);
|
|
|
|
|
|
|
|
// 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.
|
2005-06-17 00:43:53 +04:00
|
|
|
BRegion redrawReg(fFullVisible2);
|
2005-06-16 00:36:43 +04:00
|
|
|
redrawReg.Exclude(&oldFullVisible);
|
|
|
|
// 2) in case we shrink
|
|
|
|
BRegion redrawReg2(oldFullVisible);
|
2005-06-17 00:43:53 +04:00
|
|
|
redrawReg2.Exclude(&fFullVisible2);
|
2005-06-16 00:36:43 +04:00
|
|
|
// 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.
|
|
|
|
rezize_layer_redraw_more(redrawReg, dx, dy);
|
|
|
|
|
|
|
|
// 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
|
2005-06-17 00:43:53 +04:00
|
|
|
if (fFlags & B_FULL_UPDATE_ON_RESIZE && fVisible2.Frame().IsValid()) {
|
2005-06-16 00:36:43 +04:00
|
|
|
resize_layer_full_update_on_resize(GetRootLayer()->fRedrawReg, dx, dy);
|
|
|
|
|
2005-06-17 00:43:53 +04:00
|
|
|
GetRootLayer()->fRedrawReg.Include(&fVisible2);
|
2005-06-16 00:36:43 +04:00
|
|
|
GetRootLayer()->fRedrawReg.Include(&oldVisible);
|
|
|
|
}
|
|
|
|
// clear canvas and set invalid regions for affected WinBorders
|
|
|
|
// TODO: ---
|
|
|
|
GetRootLayer()->RequestDraw(GetRootLayer()->fRedrawReg, BottomChild());
|
|
|
|
// GetRootLayer()->RequestRedraw(); // TODO: what if we pass (fParent, startFromTHIS, &redrawReg)?
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Layer::do_MoveBy(float dx, float dy)
|
|
|
|
{
|
|
|
|
if (dx == 0.0f && dy == 0.0f)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// fFrame.Set(fFrame.left+dx, fFrame.top+dy, fFrame.right+dx, fFrame.bottom+dy);
|
|
|
|
fFrame.OffsetBy(dx, dy);
|
|
|
|
|
|
|
|
// call hook function
|
|
|
|
MovedByHook(dx, dy);
|
|
|
|
|
|
|
|
if (!IsHidden() && GetRootLayer()) {
|
2005-06-17 00:43:53 +04:00
|
|
|
BRegion oldFullVisible(fFullVisible2);
|
2005-06-16 00:36:43 +04:00
|
|
|
|
|
|
|
// we'll invalidate the old position and the new, maxmial one.
|
|
|
|
BRegion invalid;
|
|
|
|
get_user_regions(invalid);
|
2005-06-17 00:43:53 +04:00
|
|
|
invalid.Include(&fFullVisible2);
|
2005-06-16 00:36:43 +04:00
|
|
|
|
|
|
|
clear_visible_regions();
|
|
|
|
|
|
|
|
fParent->do_RebuildVisibleRegions(invalid, this);
|
|
|
|
|
|
|
|
// 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.
|
2005-06-17 00:43:53 +04:00
|
|
|
BRegion redrawReg(fFullVisible2);
|
2005-06-16 00:36:43 +04:00
|
|
|
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.
|
2005-06-17 00:43:53 +04:00
|
|
|
oldFullVisible.IntersectWith(&fFullVisible2);
|
2005-06-16 00:36:43 +04:00
|
|
|
|
|
|
|
// offset back and instruct the HW to do the actual copying.
|
|
|
|
oldFullVisible.OffsetBy(-dx, -dy);
|
|
|
|
// TODO: uncomment!!!
|
|
|
|
// GetRootLayer()->CopyRegion(&oldFullVisible, dx, dy);
|
|
|
|
|
|
|
|
// add redrawReg to our RootLayer's redraw region.
|
|
|
|
GetRootLayer()->fRedrawReg.Include(&redrawReg);
|
|
|
|
// TODO: ---
|
|
|
|
GetRootLayer()->RequestDraw(GetRootLayer()->fRedrawReg, BottomChild());
|
|
|
|
// GetRootLayer()->RequestRedraw(); // TODO: what if we pass (fParent, startFromTHIS, &redrawReg)?
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Layer::do_ScrollBy(float dx, float dy)
|
|
|
|
{
|
|
|
|
fLayerData->OffsetOrigin(BPoint(dx, dy));
|
|
|
|
// fOrigin.Set(fOrigin.x + dx, fOrigin.y + dy);
|
|
|
|
|
|
|
|
if (!IsHidden() && GetRootLayer()) {
|
|
|
|
// set the region to be invalidated.
|
2005-06-17 00:43:53 +04:00
|
|
|
BRegion invalid(fFullVisible2);
|
2005-06-16 00:36:43 +04:00
|
|
|
|
|
|
|
clear_visible_regions();
|
|
|
|
|
|
|
|
rebuild_visible_regions(invalid, invalid, BottomChild());
|
|
|
|
|
|
|
|
// for the moment we say that the whole surface needs to be redraw.
|
2005-06-17 00:43:53 +04:00
|
|
|
BRegion redrawReg(fFullVisible2);
|
2005-06-16 00:36:43 +04:00
|
|
|
|
|
|
|
// 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.
|
2005-06-17 00:43:53 +04:00
|
|
|
invalid.IntersectWith(&fFullVisible2);
|
2005-06-16 00:36:43 +04:00
|
|
|
// TODO: uncomment!!!
|
|
|
|
// GetRootLayer()->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);
|
|
|
|
redrawReg.Exclude(&invalid);
|
|
|
|
|
|
|
|
GetRootLayer()->fRedrawReg.Include(&redrawReg);
|
|
|
|
// TODO: ---
|
|
|
|
GetRootLayer()->RequestDraw(GetRootLayer()->fRedrawReg, BottomChild());
|
|
|
|
// GetRootLayer()->RequestRedraw(); // TODO: what if we pass (fParent, startFromTHIS, &redrawReg)?
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dx != 0.0f || dy != 0.0f)
|
|
|
|
ScrolledByHook(dx, dy);
|
|
|
|
}
|
|
|
|
void
|
|
|
|
Layer::get_user_regions(BRegion ®)
|
|
|
|
{
|
|
|
|
// 1) set to frame in screen coords
|
|
|
|
BRect screenFrame(Bounds());
|
|
|
|
ConvertToScreen2(&screenFrame);
|
|
|
|
reg.Set(screenFrame);
|
|
|
|
|
|
|
|
// 2) intersect with screen region
|
|
|
|
BRegion screenReg(GetRootLayer()->Bounds());
|
|
|
|
reg.IntersectWith(&screenReg);
|
|
|
|
|
|
|
|
// TODO: you MUST at some point uncomment this block!
|
|
|
|
/*
|
|
|
|
// 3) impose user constrained regions
|
|
|
|
LayerData *stackData = fLayerData;
|
|
|
|
while (stackData)
|
|
|
|
{
|
|
|
|
// transform in screen coords
|
|
|
|
BRegion screenReg(stackData->ClippingRegion());
|
|
|
|
ConvertToScreen2(&screenReg);
|
|
|
|
reg.IntersectWith(&screenReg);
|
|
|
|
stackData = stackData->prevState;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Layer::do_RebuildVisibleRegions(const BRegion &invalid, const Layer *startFrom)
|
|
|
|
{
|
2005-06-17 00:43:53 +04:00
|
|
|
BRegion localVisible(fFullVisible2);
|
2005-06-16 00:36:43 +04:00
|
|
|
localVisible.IntersectWith(&invalid);
|
|
|
|
rebuild_visible_regions(invalid, localVisible, startFrom);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Layer::rebuild_visible_regions(const BRegion &invalid,
|
|
|
|
const BRegion &parentLocalVisible,
|
|
|
|
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.
|
2005-06-17 00:43:53 +04:00
|
|
|
if (!parentLocalVisible.Frame().IsValid() && !(fFullVisible2.CountRects() > 0))
|
2005-06-16 00:36:43 +04:00
|
|
|
return;
|
|
|
|
|
|
|
|
bool fullRebuild = false;
|
|
|
|
|
|
|
|
// intersect maximum wanted region with the invalid region
|
|
|
|
BRegion common;
|
|
|
|
get_user_regions(common);
|
|
|
|
common.IntersectWith(&invalid);
|
|
|
|
|
|
|
|
// if the resulted region is not valid, this layer is not in the catchment area
|
|
|
|
// of the region being invalidated
|
|
|
|
if (!common.CountRects() > 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// now intersect with parent's visible part of the region that was/is invalidated
|
|
|
|
common.IntersectWith(&parentLocalVisible);
|
|
|
|
|
|
|
|
// exclude the invalid region
|
2005-06-17 00:43:53 +04:00
|
|
|
fFullVisible2.Exclude(&invalid);
|
|
|
|
fVisible2.Exclude(&invalid);
|
2005-06-16 00:36:43 +04:00
|
|
|
|
|
|
|
// put in what's really visible
|
2005-06-17 00:43:53 +04:00
|
|
|
fFullVisible2.Include(&common);
|
2005-06-16 00:36:43 +04:00
|
|
|
|
|
|
|
// 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 = BottomChild(); lay; lay = UpperSibling()) {
|
|
|
|
if (lay == startFrom)
|
|
|
|
fullRebuild = true;
|
|
|
|
|
|
|
|
if (fullRebuild)
|
|
|
|
lay->rebuild_visible_regions(invalid, common, lay->BottomChild());
|
|
|
|
|
|
|
|
// to let children know much they can take from parent's visible region
|
2005-06-17 00:43:53 +04:00
|
|
|
common.Exclude(&lay->fFullVisible2);
|
2005-06-16 00:36:43 +04:00
|
|
|
// we've hidden some parts of our visible region from our children,
|
|
|
|
// and we must be in sysnc with this region too...
|
|
|
|
if (altered)
|
2005-06-17 00:43:53 +04:00
|
|
|
unalteredVisible.Exclude(&lay->fFullVisible2);
|
2005-06-16 00:36:43 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// the visible region of this layer is what left after all its children took
|
|
|
|
// what they could.
|
|
|
|
if (altered)
|
2005-06-17 00:43:53 +04:00
|
|
|
fVisible2.Include(&unalteredVisible);
|
2005-06-16 00:36:43 +04:00
|
|
|
else
|
2005-06-17 00:43:53 +04:00
|
|
|
fVisible2.Include(&common);
|
2005-06-16 00:36:43 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Layer::alter_visible_for_children(BRegion ®)
|
|
|
|
{
|
|
|
|
// Empty Hook function
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Layer::clear_visible_regions()
|
|
|
|
{
|
|
|
|
// OPT: maybe we should uncomment these lines for performance
|
2005-06-17 00:43:53 +04:00
|
|
|
//if (fFullVisible2.CountRects() <= 0)
|
2005-06-16 00:36:43 +04:00
|
|
|
// return;
|
|
|
|
|
2005-06-17 00:43:53 +04:00
|
|
|
fVisible2.MakeEmpty();
|
|
|
|
fFullVisible2.MakeEmpty();
|
2005-06-16 00:36:43 +04:00
|
|
|
for (Layer *child = BottomChild(); child; child = UpperSibling())
|
|
|
|
child->clear_visible_regions();
|
|
|
|
}
|
|
|
|
|
2005-06-15 23:01:43 +04:00
|
|
|
#endif
|
2004-01-13 03:56:36 +03:00
|
|
|
|