* Layers are now put into an application wide token space that mirrors the
client's token space. * finding layers by token is now O(1) instead of O(n) (as they are looked up in the token space). * removed Layer::FindView() as it's no longer needed (or should be used). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15113 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+72
-95
@@ -26,6 +26,7 @@
|
|||||||
#include "DrawState.h"
|
#include "DrawState.h"
|
||||||
#include "PortLink.h"
|
#include "PortLink.h"
|
||||||
#include "RootLayer.h"
|
#include "RootLayer.h"
|
||||||
|
#include "ServerApp.h"
|
||||||
#include "ServerProtocol.h"
|
#include "ServerProtocol.h"
|
||||||
#include "ServerWindow.h"
|
#include "ServerWindow.h"
|
||||||
#include "WinBorder.h"
|
#include "WinBorder.h"
|
||||||
@@ -105,6 +106,9 @@ Layer::~Layer()
|
|||||||
{
|
{
|
||||||
delete fDrawState;
|
delete fDrawState;
|
||||||
|
|
||||||
|
if (fWindow != NULL)
|
||||||
|
fWindow->App()->ViewTokens().RemoveToken(ViewToken());
|
||||||
|
|
||||||
Layer* child = fFirstChild;
|
Layer* child = fFirstChild;
|
||||||
while (child != NULL) {
|
while (child != NULL) {
|
||||||
Layer* nextChild = child->fNextSibling;
|
Layer* nextChild = child->fNextSibling;
|
||||||
@@ -124,79 +128,79 @@ Layer::~Layer()
|
|||||||
it spits an error to stdout and returns.
|
it spits an error to stdout and returns.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
Layer::AddChild(Layer* layer, ServerWindow* window)
|
Layer::AddChild(Layer* child, ServerWindow* window)
|
||||||
{
|
{
|
||||||
STRACE(("Layer(%s)::AddChild(%s) START\n", Name(), layer->Name()));
|
STRACE(("Layer(%s)::AddChild(%s)\n", Name(), child->Name()));
|
||||||
|
|
||||||
if (layer->fParent != NULL) {
|
if (child->fParent != NULL) {
|
||||||
printf("ERROR: AddChild(): Layer already has a parent\n");
|
printf("ERROR: AddChild(): Layer already has a parent\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1) attach layer to the tree structure
|
// 1) attach layer to the tree structure
|
||||||
layer->fParent = this;
|
child->fParent = this;
|
||||||
|
|
||||||
// if we have children already, bump the current last child back one and
|
// if we have children already, bump the current last child back one and
|
||||||
// make the new child the last layer
|
// make the new child the last layer
|
||||||
if (fLastChild) {
|
if (fLastChild) {
|
||||||
layer->fPreviousSibling = fLastChild;
|
child->fPreviousSibling = fLastChild;
|
||||||
fLastChild->fNextSibling = layer;
|
fLastChild->fNextSibling = child;
|
||||||
} else {
|
} else {
|
||||||
fFirstChild = layer;
|
fFirstChild = child;
|
||||||
}
|
}
|
||||||
fLastChild = layer;
|
fLastChild = child;
|
||||||
|
|
||||||
// if we have no RootLayer yet, then there is no need to set any parameters --
|
// 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
|
// they will be set when the RootLayer for this tree will be added
|
||||||
// to the main tree structure.
|
// to the main tree structure.
|
||||||
if (!fRootLayer) {
|
if (!fRootLayer) {
|
||||||
STRACE(("Layer(%s)::AddChild(%s) END\n", Name(), layer->Name()));
|
STRACE(("Layer(%s)::AddChild(%s) END\n", Name(), child->Name()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2) Iterate over the newly-added layer and all its children, setting the
|
// 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
|
// root layer and server window and also rebuilding the full-size region
|
||||||
// for every descendant of the newly-added layer
|
// for every descendant of the newly-added layer
|
||||||
|
|
||||||
//c = short for: current
|
Layer* stop = child;
|
||||||
Layer* c = layer;
|
|
||||||
Layer* stop = layer;
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// action block
|
// action block
|
||||||
|
|
||||||
// 2.1) set the RootLayer for this object.
|
// 2.1) set the RootLayer for this object.
|
||||||
c->SetRootLayer(c->fParent->fRootLayer);
|
child->SetRootLayer(child->fParent->fRootLayer);
|
||||||
|
|
||||||
// 2.2) this Layer must know if it has a ServerWindow object attached.
|
// 2.2) this Layer must know if it has a ServerWindow object attached.
|
||||||
c->fWindow = window;
|
child->fWindow = window;
|
||||||
|
|
||||||
|
// insert view into local token space
|
||||||
|
window->App()->ViewTokens().SetToken(child->ViewToken(),
|
||||||
|
B_HANDLER_TOKEN, child);
|
||||||
|
|
||||||
// tree parsing algorithm
|
// tree parsing algorithm
|
||||||
if (c->fFirstChild) {
|
if (child->fFirstChild) {
|
||||||
// go deep
|
// go deep
|
||||||
c = c->fFirstChild;
|
child = child->fFirstChild;
|
||||||
} else {
|
} else {
|
||||||
// go right or up
|
// go right or up
|
||||||
|
|
||||||
if (c == stop) // our trip is over
|
if (child == stop) // our trip is over
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (c->fNextSibling) {
|
if (child->fNextSibling) {
|
||||||
// go right
|
// go right
|
||||||
c = c->fNextSibling;
|
child = child->fNextSibling;
|
||||||
} else {
|
} else {
|
||||||
// go up
|
// go up
|
||||||
while (!c->fParent->fNextSibling && c->fParent != stop)
|
while (child->fParent->fNextSibling == NULL && child->fParent != stop)
|
||||||
c = c->fParent;
|
child = child->fParent;
|
||||||
|
|
||||||
if (c->fParent == stop) // that's enough!
|
if (child->fParent == stop) // that's enough!
|
||||||
break;
|
break;
|
||||||
|
|
||||||
c = c->fParent->fNextSibling;
|
child = child->fParent->fNextSibling;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STRACE(("Layer(%s)::AddChild(%s) END\n", Name(), layer->Name()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -208,16 +212,15 @@ Layer::AddChild(Layer* layer, ServerWindow* window)
|
|||||||
spits out an error to stdout and returns
|
spits out an error to stdout and returns
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
Layer::RemoveChild(Layer *layer)
|
Layer::RemoveChild(Layer *child)
|
||||||
{
|
{
|
||||||
STRACE(("Layer(%s)::RemoveChild(%s) START\n", Name(), layer->Name()));
|
STRACE(("Layer(%s)::RemoveChild(%s)\n", Name(), child->Name()));
|
||||||
|
|
||||||
if (!layer->fParent) {
|
if (!child->fParent) {
|
||||||
printf("ERROR: RemoveChild(): Layer doesn't have a parent\n");
|
printf("ERROR: RemoveChild(): Layer doesn't have a parent\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (child->fParent != this) {
|
||||||
if (layer->fParent != this) {
|
|
||||||
printf("ERROR: RemoveChild(): Layer is not a child of this layer\n");
|
printf("ERROR: RemoveChild(): Layer is not a child of this layer\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -225,65 +228,63 @@ Layer::RemoveChild(Layer *layer)
|
|||||||
// 1) remove this layer from the main tree.
|
// 1) remove this layer from the main tree.
|
||||||
|
|
||||||
// Take care of fParent
|
// Take care of fParent
|
||||||
layer->fParent = NULL;
|
child->fParent = NULL;
|
||||||
|
|
||||||
if (fFirstChild == layer)
|
if (fFirstChild == child)
|
||||||
fFirstChild = layer->fNextSibling;
|
fFirstChild = child->fNextSibling;
|
||||||
|
|
||||||
if (fLastChild == layer)
|
if (fLastChild == child)
|
||||||
fLastChild = layer->fPreviousSibling;
|
fLastChild = child->fPreviousSibling;
|
||||||
|
|
||||||
// Take care of siblings
|
// Take care of siblings
|
||||||
if (layer->fPreviousSibling != NULL)
|
if (child->fPreviousSibling != NULL)
|
||||||
layer->fPreviousSibling->fNextSibling = layer->fNextSibling;
|
child->fPreviousSibling->fNextSibling = child->fNextSibling;
|
||||||
|
|
||||||
if (layer->fNextSibling != NULL)
|
if (child->fNextSibling != NULL)
|
||||||
layer->fNextSibling->fPreviousSibling = layer->fPreviousSibling;
|
child->fNextSibling->fPreviousSibling = child->fPreviousSibling;
|
||||||
|
|
||||||
layer->fPreviousSibling = NULL;
|
child->fPreviousSibling = NULL;
|
||||||
layer->fNextSibling = NULL;
|
child->fNextSibling = NULL;
|
||||||
layer->_ClearVisibleRegions();
|
child->_ClearVisibleRegions();
|
||||||
|
|
||||||
// 2) Iterate over all of the removed-layer's descendants and unset the
|
// 2) Iterate over all of the removed-layer's descendants and unset the
|
||||||
// root layer, server window, and all redraw-related regions
|
// root layer, server window, and all redraw-related regions
|
||||||
|
|
||||||
Layer* c = layer; //c = short for: current
|
Layer* stop = child;
|
||||||
Layer* stop = layer;
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// action block
|
// action block
|
||||||
{
|
|
||||||
// 2.1) set the RootLayer for this object.
|
// 2.1) set the RootLayer for this object.
|
||||||
c->SetRootLayer(NULL);
|
child->SetRootLayer(NULL);
|
||||||
// 2.2) this Layer must know if it has a ServerWindow object attached.
|
// 2.2) this Layer must know if it has a ServerWindow object attached.
|
||||||
c->fWindow = NULL;
|
if (child->Window())
|
||||||
}
|
child->Window()->App()->ViewTokens().RemoveToken(child->ViewToken());
|
||||||
|
child->fWindow = NULL;
|
||||||
|
|
||||||
// tree parsing algorithm
|
// tree parsing algorithm
|
||||||
if (c->fFirstChild) {
|
if (child->fFirstChild) {
|
||||||
// go deep
|
// go deep
|
||||||
c = c->fFirstChild;
|
child = child->fFirstChild;
|
||||||
} else {
|
} else {
|
||||||
// go right or up
|
// go right or up
|
||||||
if (c == stop) // out trip is over
|
if (child == stop) // out trip is over
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (c->fNextSibling) {
|
if (child->fNextSibling) {
|
||||||
// go right
|
// go right
|
||||||
c = c->fNextSibling;
|
child = child->fNextSibling;
|
||||||
} else {
|
} else {
|
||||||
// go up
|
// go up
|
||||||
while(!c->fParent->fNextSibling && c->fParent != stop)
|
while (child->fParent->fNextSibling == NULL && child->fParent != stop)
|
||||||
c = c->fParent;
|
child = child->fParent;
|
||||||
|
|
||||||
if (c->fParent == stop) // that enough!
|
if (child->fParent == stop) // that enough!
|
||||||
break;
|
break;
|
||||||
|
|
||||||
c = c->fParent->fNextSibling;
|
child = child->fParent->fNextSibling;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
STRACE(("Layer(%s)::RemoveChild(%s) END\n", Name(), layer->Name()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -327,30 +328,6 @@ Layer::CountChildren() const
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
\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
|
|
||||||
*/
|
|
||||||
Layer*
|
|
||||||
Layer::FindLayer(const int32 token)
|
|
||||||
{
|
|
||||||
// (recursive) search for a layer based on its view token
|
|
||||||
|
|
||||||
// iterate only over direct child layers first
|
|
||||||
for (Layer* child = FirstChild(); child; child = child->NextLayer()) {
|
|
||||||
if (child->fViewToken == token)
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
|
|
||||||
// try a recursive search
|
|
||||||
for (Layer* child = FirstChild(); child; child = child->NextLayer()) {
|
|
||||||
if (Layer* layer = child->FindLayer(token))
|
|
||||||
return layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Returns the layer at the given point
|
\brief Returns the layer at the given point
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ class Layer {
|
|||||||
{ return fParent; }
|
{ return fParent; }
|
||||||
|
|
||||||
uint32 CountChildren() const;
|
uint32 CountChildren() const;
|
||||||
Layer* FindLayer(const int32 token);
|
|
||||||
Layer* LayerAt(BPoint where);
|
Layer* LayerAt(BPoint where);
|
||||||
|
|
||||||
Layer* FirstChild() const;
|
Layer* FirstChild() const;
|
||||||
|
|||||||
@@ -17,9 +17,11 @@
|
|||||||
#include "SubWindowList.h"
|
#include "SubWindowList.h"
|
||||||
#include "BGet++.h"
|
#include "BGet++.h"
|
||||||
|
|
||||||
#include <ObjectList.h>
|
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
|
||||||
|
#include <ObjectList.h>
|
||||||
|
#include <TokenSpace.h>
|
||||||
|
|
||||||
|
|
||||||
class AreaPool;
|
class AreaPool;
|
||||||
class BMessage;
|
class BMessage;
|
||||||
@@ -74,6 +76,8 @@ class ServerApp : public MessageLooper {
|
|||||||
|
|
||||||
Desktop* GetDesktop() const { return fDesktop; }
|
Desktop* GetDesktop() const { return fDesktop; }
|
||||||
|
|
||||||
|
BPrivate::BTokenSpace& ViewTokens() { return fViewTokens; }
|
||||||
|
|
||||||
// ToDo: public?
|
// ToDo: public?
|
||||||
SubWindowList fAppSubWindowList;
|
SubWindowList fAppSubWindowList;
|
||||||
|
|
||||||
@@ -97,6 +101,7 @@ class ServerApp : public MessageLooper {
|
|||||||
|
|
||||||
BLocker fWindowListLock;
|
BLocker fWindowListLock;
|
||||||
BObjectList<ServerWindow> fWindowList;
|
BObjectList<ServerWindow> fWindowList;
|
||||||
|
BPrivate::BTokenSpace fViewTokens;
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// - Are really Bitmaps and Pictures stored per application and not globally ?
|
// - Are really Bitmaps and Pictures stored per application and not globally ?
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ ServerWindow::ServerWindow(const char *title, ServerApp *app,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//!Tears down all connections the main app_server objects, and deletes some internals.
|
//! Tears down all connections the main app_server objects, and deletes some internals.
|
||||||
ServerWindow::~ServerWindow()
|
ServerWindow::~ServerWindow()
|
||||||
{
|
{
|
||||||
STRACE(("*ServerWindow(%s@%p):~ServerWindow()\n", fTitle, this));
|
STRACE(("*ServerWindow(%s@%p):~ServerWindow()\n", fTitle, this));
|
||||||
@@ -522,9 +522,13 @@ if (fWinBorder->IsOffscreenWindow()) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_parent) {
|
if (_parent) {
|
||||||
Layer *parent = fWinBorder->FindLayer(parentToken);
|
Layer *parent;
|
||||||
if (parent == NULL)
|
if (App()->ViewTokens().GetToken(parentToken, B_HANDLER_TOKEN,
|
||||||
|
(void**)&parent) != B_OK
|
||||||
|
|| parent->Window() != this) {
|
||||||
CRITICAL("View token not found!\n");
|
CRITICAL("View token not found!\n");
|
||||||
|
parent = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
*_parent = parent;
|
*_parent = parent;
|
||||||
}
|
}
|
||||||
@@ -583,7 +587,6 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
|||||||
int32 yOffset = (int32)(dst.top - src.top);
|
int32 yOffset = (int32)(dst.top - src.top);
|
||||||
|
|
||||||
fCurrentLayer->CopyBits(src, dst, xOffset, yOffset);
|
fCurrentLayer->CopyBits(src, dst, xOffset, yOffset);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AS_SET_CURRENT_LAYER:
|
case AS_SET_CURRENT_LAYER:
|
||||||
@@ -592,18 +595,17 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
|||||||
|
|
||||||
link.Read<int32>(&token);
|
link.Read<int32>(&token);
|
||||||
|
|
||||||
Layer *current = fWinBorder->FindLayer(token);
|
Layer *current;
|
||||||
if (current) {
|
if (App()->ViewTokens().GetToken(token, B_HANDLER_TOKEN,
|
||||||
DTRACE(("ServerWindow %s: Message AS_SET_CURRENT_LAYER: %s, token %ld\n", fTitle, current->Name(), token));
|
(void**)¤t) != B_OK
|
||||||
} else {
|
|| current->Window() != this) {
|
||||||
|
// ToDo: if this happens, we probably want to kill the app and clean up
|
||||||
DTRACE(("ServerWindow %s: Message AS_SET_CURRENT_LAYER: layer not found, token %ld\n", fTitle, token));
|
DTRACE(("ServerWindow %s: Message AS_SET_CURRENT_LAYER: layer not found, token %ld\n", fTitle, token));
|
||||||
}
|
current = NULL;
|
||||||
|
} else {
|
||||||
if (current)
|
DTRACE(("ServerWindow %s: Message AS_SET_CURRENT_LAYER: %s, token %ld\n", fTitle, current->Name(), token));
|
||||||
fCurrentLayer = current;
|
fCurrentLayer = current;
|
||||||
else // hope this NEVER happens! :-)
|
}
|
||||||
CRITICAL("Server PANIC: window cannot find Layer with ID\n");
|
|
||||||
// ToDo: if this happens, we probably want to kill the app and clean up
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -831,12 +831,16 @@ WinBorder::RequestClientRedraw(const BRegion &invalid)
|
|||||||
void
|
void
|
||||||
WinBorder::SetTopLayer(Layer* layer)
|
WinBorder::SetTopLayer(Layer* layer)
|
||||||
{
|
{
|
||||||
if (layer) {
|
if (fTopLayer != NULL) {
|
||||||
fTopLayer = layer;
|
RemoveChild(fTopLayer);
|
||||||
fTopLayer->SetAsTopLayer(true);
|
fTopLayer->SetAsTopLayer(false);
|
||||||
|
}
|
||||||
|
|
||||||
// connect decorator and top layer. (?)
|
fTopLayer = layer;
|
||||||
AddChild(fTopLayer, NULL);
|
|
||||||
|
if (layer != NULL) {
|
||||||
|
AddChild(fTopLayer, Window());
|
||||||
|
fTopLayer->SetAsTopLayer(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user