diff --git a/src/tests/servers/app/Jamfile b/src/tests/servers/app/Jamfile index 7121b2cc82..5290b17970 100644 --- a/src/tests/servers/app/Jamfile +++ b/src/tests/servers/app/Jamfile @@ -165,6 +165,7 @@ SubInclude HAIKU_TOP src tests servers app code_to_name ; SubInclude HAIKU_TOP src tests servers app copy_bits ; SubInclude HAIKU_TOP src tests servers app cursor_test ; SubInclude HAIKU_TOP src tests servers app desktop_window ; +SubInclude HAIKU_TOP src tests servers app draw_after_children ; SubInclude HAIKU_TOP src tests servers app event_mask ; SubInclude HAIKU_TOP src tests servers app following ; SubInclude HAIKU_TOP src tests servers app idle_test ; diff --git a/src/tests/servers/app/draw_after_children/DrawAfterChildren.cpp b/src/tests/servers/app/draw_after_children/DrawAfterChildren.cpp new file mode 100644 index 0000000000..decca6633c --- /dev/null +++ b/src/tests/servers/app/draw_after_children/DrawAfterChildren.cpp @@ -0,0 +1,174 @@ + +#include + +#include +#include +#include + +/*----------------------------------------------------------------------------- + +OBSERVATION on R5 behaviour: + +* The hook function DrawAfterChildren is not called at all if the + view flags don't include B_DRAW_ON_CHILDREN. + +* If the view flags include B_DRAW_ON_CHILDREN, then any drawing commands + executed in Draw() AND DrawAfterChildren() will paint on top of children. + +* The background of a view with the B_DRAW_ON_CHILDREN flag set will not + be painted by the app_server when child views change position and areas + in the parent view are "exposed". If the expose events have other reasons, + the background is painted as usual. + +* The app_server side background painting of child views does not occur + after the Draw() hook of the parent view with B_DRAW_ON_CHILDREN has been + called. So while DrawAfterChildren() may be called after the Draw() hooks + of all children have been called, the background has been painted earlier. + +* It looks like the background painting inside app_server of a view with + B_DRAW_ON_CHILDREN paints over the background of any children, though + the background of the children is later painted too. Therefor, if a child + has B_TRANSPARENT_COLOR background, the background of the parent with + B_DRAW_ON_CHILDREN stays visible in the area of that child. + +* Both Draw() and DrawAfterChildren() appear to push their own graphics + states onto the state stack. + + +CONCLUSION: + +It looks like the B_DRAW_ON_CHILDREN flag causes two effects: + +* The local view clipping region inside the app_server simply ignores + any children, this effects any drawing commands, those from Draw() + and those from DrawAfterChildren() + +* The DrawAfterChildren() hook is called after the children have drawn, + so that the user may move all drawing functions there which he does not + wish to have painted over by children. + +That areas exposed by moving child views are not repainted could +be considered a bug of the R5 implementation. + +-----------------------------------------------------------------------------*/ + + + +class TestView : public BView { +public: + TestView(BRect frame); + ~TestView(); + + virtual void Draw(BRect updateRect); + virtual void DrawAfterChildren(BRect updateRect); +}; + + +TestView::TestView(BRect frame) + : BView(frame, "TestView", B_FOLLOW_ALL, + B_WILL_DRAW | B_DRAW_ON_CHILDREN | B_FULL_UPDATE_ON_RESIZE) +{ + SetViewColor(200, 220, 255); +} + + +TestView::~TestView() +{ +} + + +void +TestView::Draw(BRect updateRect) +{ + printf("Draw(BRect(%.1f, %.1f, %.1f, %.1f))\n", + updateRect.left, updateRect.top, updateRect.right, updateRect.bottom); + + printf("pensize: %.2f\n", PenSize()); + + SetHighColor(0, 0, 255); + StrokeLine(Bounds().LeftBottom(), Bounds().RightTop()); + + SetPenSize(5); +} + +void +TestView::DrawAfterChildren(BRect updateRect) +{ + printf("DrawAfterChildren(BRect(%.1f, %.1f, %.1f, %.1f))\n", + updateRect.left, updateRect.top, updateRect.right, updateRect.bottom); + + printf("pensize: %.2f\n", PenSize()); + + SetHighColor(255, 0, 0); + StrokeLine(Bounds().LeftTop(), Bounds().RightBottom()); + Sync(); + + SetPenSize(7); +} + + +// #pragma mark - + +class ChildView : public BView { +public: + ChildView(BRect frame, const char* name, rgb_color viewColor); + ~ChildView(); + + virtual void Draw(BRect updateRect); +}; + + +ChildView::ChildView(BRect frame, const char* name, rgb_color viewColor) + : BView(frame, name, B_FOLLOW_ALL, 0) +{ + SetLowColor(200, 200, 200); + SetViewColor(viewColor); + if (*(int32*)&viewColor == *(int32*)&B_TRANSPARENT_COLOR) + SetFlags(Flags() | B_WILL_DRAW); +} + + +ChildView::~ChildView() +{ +} + + +void +ChildView::Draw(BRect updateRect) +{ + FillRect(updateRect, B_SOLID_LOW); +} + + +// #pragma mark - + + +int +main(int argc, char** argv) +{ + BApplication app("application/x-vnd.Haiku-DrawAfterChildren"); + + BRect frame(100, 100, 700, 400); + BWindow* window = new BWindow(frame, "Window", + B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE); + + frame.OffsetTo(B_ORIGIN); + TestView* view = new TestView(frame); + window->AddChild(view); + + frame.InsetBy(20, 20); + frame.right = frame.left + frame.Width() / 2 - 10; + BView* child = new ChildView(frame, "child 1", + (rgb_color){ 200, 200, 200, 255 }); + view->AddChild(child); + + frame.OffsetBy(frame.Width() + 20, 0); + child = new ChildView(frame, "child 2", B_TRANSPARENT_COLOR); + view->AddChild(child); + + window->Show(); + + app.Run(); + return 0; +} + diff --git a/src/tests/servers/app/draw_after_children/Jamfile b/src/tests/servers/app/draw_after_children/Jamfile new file mode 100644 index 0000000000..9b5309e84c --- /dev/null +++ b/src/tests/servers/app/draw_after_children/Jamfile @@ -0,0 +1,18 @@ +SubDir HAIKU_TOP src tests servers app draw_after_children ; + +SetSubDirSupportedPlatformsBeOSCompatible ; +AddSubDirSupportedPlatforms libbe_test ; + +UseHeaders [ FDirName os app ] ; +UseHeaders [ FDirName os interface ] ; + +Application DrawAfterChildren : + DrawAfterChildren.cpp + : be $(TARGET_LIBSTDC++) +; + +if $(TARGET_PLATFORM) = libbe_test { + HaikuInstall install-test-apps : $(HAIKU_APP_TEST_DIR) : DrawAfterChildren + : tests!apps ; +} + diff --git a/src/tests/servers/app/draw_after_children/run b/src/tests/servers/app/draw_after_children/run new file mode 100755 index 0000000000..a37f644717 --- /dev/null +++ b/src/tests/servers/app/draw_after_children/run @@ -0,0 +1,18 @@ +#!/bin/sh + +../../../../../generated/tests/libbe_test/x86/apps/run_haiku_registrar || exit + +if test -f ../../../../../generated/tests/libbe_test/x86/apps/haiku_app_server; then + ../../../../../generated/tests/libbe_test/x86/apps//haiku_app_server & +else + echo "You need to \"TARGET_PLATFORM=libbe_test jam install-test-apps\" first." +fi + +sleep 1s + +if test -f ../../../../../generated/tests/libbe_test/x86/apps/DrawAfterChildren; then + ../../../../../generated/tests/libbe_test/x86/apps/DrawAfterChildren +else + echo "You need to \"TARGET_PLATFORM=libbe_test jam install-test-apps\" first." +fi +