* ViewLayer::ViewAt() must not use the screen clipping to find the view

in question as it used to find the view that is under the mouse (found
  during a short phone session with stippi :-)). This fixes bug #1714.
* The local view clipping is still not correctly maintained by the 
  app_server, but that only affects the drawing now. I've added some
  commented out code that give you some visual feedback on this problem
  (ViewLayer::MarkAt()).
* Minor cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23663 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-01-20 16:49:58 +00:00
parent 6d986c16fe
commit 89ba97ea24
3 changed files with 96 additions and 56 deletions
+63 -30
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2007, Haiku, Inc.
* Copyright (c) 2001-2008, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
@@ -171,8 +171,10 @@ ViewLayer::AttachedToWindow(WindowLayer* window)
fIsDesktopBackground = true;
// insert view into local token space
if (fWindow != NULL)
fWindow->ServerWindow()->App()->ViewTokens().SetToken(fToken, B_HANDLER_TOKEN, this);
if (fWindow != NULL) {
fWindow->ServerWindow()->App()->ViewTokens().SetToken(fToken,
B_HANDLER_TOKEN, this);
}
// attach child views as well
for (ViewLayer* child = FirstChild(); child; child = child->NextSibling())
@@ -244,7 +246,8 @@ bool
ViewLayer::RemoveChild(ViewLayer* layer)
{
if (layer->fParent != this) {
printf("ViewLayer::RemoveChild(%p - %s) - ViewLayer is not child of this (%p) layer!\n", layer, layer ? layer->Name() : NULL, this);
printf("ViewLayer::RemoveChild(%p - %s) - ViewLayer is not child of "
"this (%p) layer!\n", layer, layer ? layer->Name() : NULL, this);
return false;
}
@@ -334,34 +337,65 @@ ViewLayer::CollectTokensForChildren(BList* tokenMap) const
}
#if 0
bool
ViewLayer::MarkAt(DrawingEngine* engine, const BPoint& where, int32 level)
{
BRect rect(fFrame.left, fFrame.top, fFrame.right, fFrame.bottom);
if (Parent() != NULL) {
Parent()->ConvertToScreen(&rect);
if (!rect.Contains(where))
return false;
engine->StrokeRect(rect, (rgb_color){level * 30, level * 30, level * 30});
}
bool found = false;
for (ViewLayer* child = FirstChild(); child; child = child->NextSibling()) {
found |= child->MarkAt(engine, where, level + 1);
}
if (!found) {
rgb_color color = {0};
switch (level % 2) {
case 0: color.green = rand() % 256; break;
case 1: color.blue = rand() % 256; break;
}
rect.InsetBy(1, 1);
//engine->FillRegion(fLocalClipping, (rgb_color){255, 255, 0, 10});
engine->StrokeRect(rect, color);
rect.InsetBy(1, 1);
engine->StrokeRect(rect, color);
}
return true;
}
#endif
ViewLayer*
ViewLayer::ViewAt(const BPoint& where, BRegion* windowContentClipping)
ViewLayer::ViewAt(const BPoint& where)
{
if (!fVisible)
return NULL;
// NOTE: if this view can draw on children, it's screen clipping
// excludes these children, so we need to ask those first if they
// contain "where", otherwise we check the screen clipping before
// recursing into the children
IntRect frame = Frame();
if (Parent() != NULL)
Parent()->ConvertToScreen(&frame);
if (!(fFlags & B_DRAW_ON_CHILDREN)) {
if (ScreenClipping(windowContentClipping).Contains(where))
return this;
}
if (!frame.Contains(where))
return NULL;
for (ViewLayer* child = FirstChild(); child; child = child->NextSibling()) {
ViewLayer* layer = child->ViewAt(where, windowContentClipping);
if (layer)
ViewLayer* layer = child->ViewAt(where);
if (layer != NULL)
return layer;
}
if (fFlags & B_DRAW_ON_CHILDREN) {
if (ScreenClipping(windowContentClipping).Contains(where))
return this;
}
return NULL;
}
@@ -1418,8 +1452,7 @@ ViewLayer::MarkBackgroundDirty()
void
ViewLayer::AddTokensForLayersInRegion(BMessage* message,
BRegion& region,
ViewLayer::AddTokensForLayersInRegion(BMessage* message, BRegion& region,
BRegion* windowContentClipping)
{
if (!fVisible)
@@ -1428,15 +1461,15 @@ ViewLayer::AddTokensForLayersInRegion(BMessage* message,
if (region.Intersects(ScreenClipping(windowContentClipping).Frame()))
message->AddInt32("_token", fToken);
for (ViewLayer* child = FirstChild(); child; child = child->NextSibling())
for (ViewLayer* child = FirstChild(); child; child = child->NextSibling()) {
child->AddTokensForLayersInRegion(message, region,
windowContentClipping);
}
}
void
ViewLayer::AddTokensForLayersInRegion(BPrivate::PortLink& link,
BRegion& region,
ViewLayer::AddTokensForLayersInRegion(BPrivate::PortLink& link, BRegion& region,
BRegion* windowContentClipping)
{
if (!fVisible)
@@ -1450,9 +1483,9 @@ ViewLayer::AddTokensForLayersInRegion(BPrivate::PortLink& link,
if (region.Intersects(ScreenClipping(windowContentClipping).Frame()))
link.Attach<int32>(fToken);
for (ViewLayer* child = FirstChild(); child; child = child->NextSibling())
child->AddTokensForLayersInRegion(link, region,
windowContentClipping);
for (ViewLayer* child = FirstChild(); child; child = child->NextSibling()) {
child->AddTokensForLayersInRegion(link, region, windowContentClipping);
}
}
@@ -1541,8 +1574,8 @@ ViewLayer::ScreenClipping(BRegion* windowContentClipping, bool force) const
// the parent, the local clipping does not account for this
IntRect clippedBounds = Bounds();
ConvertToVisibleInTopView(&clippedBounds);
if (clippedBounds.Width() < fScreenClipping.Frame().Width() ||
clippedBounds.Height() < fScreenClipping.Frame().Height()) {
if (clippedBounds.Width() < fScreenClipping.Frame().Width()
|| clippedBounds.Height() < fScreenClipping.Frame().Height()) {
BRegion* temp = fWindow->GetRegion();
if (temp) {
temp->Set((clipping_rect)clippedBounds);
+6 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2007, Haiku, Inc.
* Copyright (c) 2001-2008, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
@@ -101,8 +101,7 @@ class ViewLayer {
uint32 CountChildren(bool deep = false) const;
void CollectTokensForChildren(BList* tokenMap) const;
ViewLayer* ViewAt(const BPoint& where,
BRegion* windowContentClipping);
ViewLayer* ViewAt(const BPoint& where);
// coordinate conversion
void ConvertToParent(BPoint* point) const;
@@ -232,6 +231,10 @@ class ViewLayer {
// debugging
void PrintToStream() const;
#if 0
bool MarkAt(DrawingEngine* engine, const BPoint& where,
int32 level = 0);
#endif
protected:
void _MoveScreenClipping(int32 x, int32 y,
+13 -9
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2007, Haiku, Inc.
* Copyright (c) 2001-2008, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
@@ -508,14 +508,7 @@ WindowLayer::SetTopLayer(ViewLayer* topLayer)
ViewLayer*
WindowLayer::ViewAt(const BPoint& where)
{
ViewLayer* view = NULL;
if (!fContentRegionValid)
_UpdateContentRegion();
view = fTopLayer->ViewAt(where, &fContentRegion);
return view;
return fTopLayer->ViewAt(where);
}
@@ -930,6 +923,17 @@ void
WindowLayer::MouseMoved(BMessage *message, BPoint where, int32* _viewToken,
bool isLatestMouseMoved)
{
#if 0
if (fDecorator != NULL && fTopLayer != NULL) {
DrawingEngine* engine = fDecorator->GetDrawingEngine();
engine->LockParallelAccess();
engine->ConstrainClippingRegion(&VisibleRegion());
fTopLayer->MarkAt(engine, where);
engine->UnlockParallelAccess();
}
#endif
ViewLayer* view = ViewAt(where);
if (view != NULL)
*_viewToken = view->Token();