From 89ba97ea2403d19e2293e11e2214877e9e9c62fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 20 Jan 2008 16:49:58 +0000 Subject: [PATCH] * 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 --- src/servers/app/ViewLayer.cpp | 121 ++++++++++++++++++++------------ src/servers/app/ViewLayer.h | 9 ++- src/servers/app/WindowLayer.cpp | 22 +++--- 3 files changed, 96 insertions(+), 56 deletions(-) diff --git a/src/servers/app/ViewLayer.cpp b/src/servers/app/ViewLayer.cpp index 6a35821ce7..e1c85a87b9 100644 --- a/src/servers/app/ViewLayer.cpp +++ b/src/servers/app/ViewLayer.cpp @@ -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: @@ -143,8 +143,8 @@ IntRect ViewLayer::Bounds() const { IntRect bounds(fScrollingOffset.x, fScrollingOffset.y, - fScrollingOffset.x + fFrame.Width(), - fScrollingOffset.y + fFrame.Height()); + fScrollingOffset.x + fFrame.Width(), + fScrollingOffset.y + fFrame.Height()); return bounds; } @@ -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; + return this; } @@ -540,7 +574,7 @@ ViewLayer::ConvertToParent(BRect* rect) const { // remove scrolling offset and convert to parent coordinate space rect->OffsetBy(fFrame.left - fScrollingOffset.x, - fFrame.top - fScrollingOffset.y); + fFrame.top - fScrollingOffset.y); } @@ -549,7 +583,7 @@ ViewLayer::ConvertToParent(IntRect* rect) const { // remove scrolling offset and convert to parent coordinate space rect->OffsetBy(fFrame.left - fScrollingOffset.x, - fFrame.top - fScrollingOffset.y); + fFrame.top - fScrollingOffset.y); } @@ -558,7 +592,7 @@ ViewLayer::ConvertToParent(BRegion* region) const { // remove scrolling offset and convert to parent coordinate space region->OffsetBy(fFrame.left - fScrollingOffset.x, - fFrame.top - fScrollingOffset.y); + fFrame.top - fScrollingOffset.y); } @@ -585,7 +619,7 @@ ViewLayer::ConvertFromParent(BRect* rect) const { // convert from parent coordinate space amd add scrolling offset rect->OffsetBy(fScrollingOffset.x - fFrame.left, - fScrollingOffset.y - fFrame.top); + fScrollingOffset.y - fFrame.top); } @@ -594,7 +628,7 @@ ViewLayer::ConvertFromParent(IntRect* rect) const { // convert from parent coordinate space amd add scrolling offset rect->OffsetBy(fScrollingOffset.x - fFrame.left, - fScrollingOffset.y - fFrame.top); + fScrollingOffset.y - fFrame.top); } @@ -603,7 +637,7 @@ ViewLayer::ConvertFromParent(BRegion* region) const { // convert from parent coordinate space amd add scrolling offset region->OffsetBy(fScrollingOffset.x - fFrame.left, - fScrollingOffset.y - fFrame.top); + fScrollingOffset.y - fFrame.top); } //! converts a point from local to screen coordinate system @@ -964,7 +998,7 @@ ViewLayer::ParentResized(int32 x, int32 y, BRegion* dirtyRegion) int32 heightDiff = (int32)(newFrame.Height() - fFrame.Height()); MoveBy(newFrame.left - fFrame.left, - newFrame.top - fFrame.top, dirtyRegion); + newFrame.top - fFrame.top, dirtyRegion); ResizeBy(widthDiff, heightDiff, dirtyRegion); } else { @@ -1308,7 +1342,7 @@ ViewLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping, if (deep) { for (ViewLayer* child = FirstChild(); child; child = child->NextSibling()) { child->Draw(drawingEngine, effectiveClipping, - windowContentClipping, deep); + windowContentClipping, deep); } } } @@ -1418,9 +1452,8 @@ ViewLayer::MarkBackgroundDirty() void -ViewLayer::AddTokensForLayersInRegion(BMessage* message, - BRegion& region, - BRegion* windowContentClipping) +ViewLayer::AddTokensForLayersInRegion(BMessage* message, BRegion& region, + BRegion* windowContentClipping) { if (!fVisible) return; @@ -1428,16 +1461,16 @@ 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); + windowContentClipping); + } } void -ViewLayer::AddTokensForLayersInRegion(BPrivate::PortLink& link, - BRegion& region, - BRegion* windowContentClipping) +ViewLayer::AddTokensForLayersInRegion(BPrivate::PortLink& link, BRegion& region, + BRegion* windowContentClipping) { if (!fVisible) return; @@ -1450,9 +1483,9 @@ ViewLayer::AddTokensForLayersInRegion(BPrivate::PortLink& link, if (region.Intersects(ScreenClipping(windowContentClipping).Frame())) link.Attach(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); diff --git a/src/servers/app/ViewLayer.h b/src/servers/app/ViewLayer.h index a46507137b..fdf37d2442 100644 --- a/src/servers/app/ViewLayer.h +++ b/src/servers/app/ViewLayer.h @@ -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, diff --git a/src/servers/app/WindowLayer.cpp b/src/servers/app/WindowLayer.cpp index aabb792ddd..8119627108 100644 --- a/src/servers/app/WindowLayer.cpp +++ b/src/servers/app/WindowLayer.cpp @@ -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();