111dbc914SStephan Aßmus
211dbc914SStephan Aßmus#include <stdio.h>
311dbc914SStephan Aßmus
411dbc914SStephan Aßmus#include <Application.h>
511dbc914SStephan Aßmus#include <View.h>
611dbc914SStephan Aßmus#include <Window.h>
711dbc914SStephan Aßmus
811dbc914SStephan Aßmus/*-----------------------------------------------------------------------------
911dbc914SStephan Aßmus
1011dbc914SStephan AßmusOBSERVATION on R5 behaviour:
1111dbc914SStephan Aßmus
1211dbc914SStephan Aßmus* The hook function DrawAfterChildren is not called at all if the
1311dbc914SStephan Aßmus  view flags don't include B_DRAW_ON_CHILDREN.
1411dbc914SStephan Aßmus
1511dbc914SStephan Aßmus* If the view flags include B_DRAW_ON_CHILDREN, then any drawing commands
1611dbc914SStephan Aßmus  executed in Draw() AND DrawAfterChildren() will paint on top of children.
1711dbc914SStephan Aßmus
1811dbc914SStephan Aßmus* The background of a view with the B_DRAW_ON_CHILDREN flag set will not
1911dbc914SStephan Aßmus  be painted by the app_server when child views change position and areas
2011dbc914SStephan Aßmus  in the parent view are "exposed". If the expose events have other reasons,
2111dbc914SStephan Aßmus  the background is painted as usual.
2211dbc914SStephan Aßmus
2311dbc914SStephan Aßmus* The app_server side background painting of child views does not occur
2411dbc914SStephan Aßmus  after the Draw() hook of the parent view with B_DRAW_ON_CHILDREN has been
2511dbc914SStephan Aßmus  called. So while DrawAfterChildren() may be called after the Draw() hooks
2611dbc914SStephan Aßmus  of all children have been called, the background has been painted earlier.
2711dbc914SStephan Aßmus
2811dbc914SStephan Aßmus* It looks like the background painting inside app_server of a view with
2911dbc914SStephan Aßmus  B_DRAW_ON_CHILDREN paints over the background of any children, though
3011dbc914SStephan Aßmus  the background of the children is later painted too. Therefor, if a child
3111dbc914SStephan Aßmus  has B_TRANSPARENT_COLOR background, the background of the parent with
3211dbc914SStephan Aßmus  B_DRAW_ON_CHILDREN stays visible in the area of that child.
3311dbc914SStephan Aßmus
3411dbc914SStephan Aßmus* Both Draw() and DrawAfterChildren() appear to push their own graphics
3511dbc914SStephan Aßmus  states onto the state stack.
3611dbc914SStephan Aßmus
3711dbc914SStephan Aßmus
3811dbc914SStephan AßmusCONCLUSION:
3911dbc914SStephan Aßmus
4011dbc914SStephan AßmusIt looks like the B_DRAW_ON_CHILDREN flag causes two effects:
4111dbc914SStephan Aßmus
4211dbc914SStephan Aßmus* The local view clipping region inside the app_server simply ignores
4311dbc914SStephan Aßmus  any children, this effects any drawing commands, those from Draw()
4411dbc914SStephan Aßmus  and those from DrawAfterChildren()
4511dbc914SStephan Aßmus
4611dbc914SStephan Aßmus* The DrawAfterChildren() hook is called after the children have drawn,
4711dbc914SStephan Aßmus  so that the user may move all drawing functions there which he does not
4811dbc914SStephan Aßmus  wish to have painted over by children.
4911dbc914SStephan Aßmus
5011dbc914SStephan AßmusThat areas exposed by moving child views are not repainted could
5111dbc914SStephan Aßmusbe considered a bug of the R5 implementation.
5211dbc914SStephan Aßmus
5311dbc914SStephan Aßmus-----------------------------------------------------------------------------*/
5411dbc914SStephan Aßmus
5511dbc914SStephan Aßmus
5611dbc914SStephan Aßmus
5711dbc914SStephan Aßmusclass TestView : public BView {
5811dbc914SStephan Aßmuspublic:
5911dbc914SStephan Aßmus	TestView(BRect frame);
6011dbc914SStephan Aßmus	~TestView();
6111dbc914SStephan Aßmus
6211dbc914SStephan Aßmus	virtual	void Draw(BRect updateRect);
6311dbc914SStephan Aßmus	virtual void DrawAfterChildren(BRect updateRect);
6411dbc914SStephan Aßmus};
6511dbc914SStephan Aßmus
6611dbc914SStephan Aßmus
6711dbc914SStephan AßmusTestView::TestView(BRect frame)
6811dbc914SStephan Aßmus	: BView(frame, "TestView", B_FOLLOW_ALL,
7011dbc914SStephan Aßmus{
7111dbc914SStephan Aßmus	SetViewColor(200, 220, 255);
7211dbc914SStephan Aßmus}
7311dbc914SStephan Aßmus
7411dbc914SStephan Aßmus
7511dbc914SStephan AßmusTestView::~TestView()
7611dbc914SStephan Aßmus{
7711dbc914SStephan Aßmus}
7811dbc914SStephan Aßmus
7911dbc914SStephan Aßmus
8011dbc914SStephan Aßmusvoid
8111dbc914SStephan AßmusTestView::Draw(BRect updateRect)
8211dbc914SStephan Aßmus{
8311dbc914SStephan Aßmus	printf("Draw(BRect(%.1f, %.1f, %.1f, %.1f))\n",
8411dbc914SStephan Aßmus		updateRect.left, updateRect.top, updateRect.right, updateRect.bottom);
8511dbc914SStephan Aßmus
8611dbc914SStephan Aßmus	printf("pensize: %.2f\n", PenSize());
8711dbc914SStephan Aßmus
8811dbc914SStephan Aßmus	SetHighColor(0, 0, 255);
8911dbc914SStephan Aßmus	StrokeLine(Bounds().LeftBottom(), Bounds().RightTop());
9011dbc914SStephan Aßmus
9111dbc914SStephan Aßmus	SetPenSize(5);
9211dbc914SStephan Aßmus}
9311dbc914SStephan Aßmus
9411dbc914SStephan Aßmusvoid
9511dbc914SStephan AßmusTestView::DrawAfterChildren(BRect updateRect)
9611dbc914SStephan Aßmus{
9711dbc914SStephan Aßmus	printf("DrawAfterChildren(BRect(%.1f, %.1f, %.1f, %.1f))\n",
9811dbc914SStephan Aßmus		updateRect.left, updateRect.top, updateRect.right, updateRect.bottom);
9911dbc914SStephan Aßmus
10011dbc914SStephan Aßmus	printf("pensize: %.2f\n", PenSize());
10111dbc914SStephan Aßmus
10211dbc914SStephan Aßmus	SetHighColor(255, 0, 0);
10311dbc914SStephan Aßmus	StrokeLine(Bounds().LeftTop(), Bounds().RightBottom());
10411dbc914SStephan Aßmus	Sync();
10511dbc914SStephan Aßmus
10611dbc914SStephan Aßmus	SetPenSize(7);
10711dbc914SStephan Aßmus}
10811dbc914SStephan Aßmus
10911dbc914SStephan Aßmus
11011dbc914SStephan Aßmus//	#pragma mark -
11111dbc914SStephan Aßmus
11211dbc914SStephan Aßmusclass ChildView : public BView {
11311dbc914SStephan Aßmuspublic:
11411dbc914SStephan Aßmus	ChildView(BRect frame, const char* name, rgb_color viewColor);
11511dbc914SStephan Aßmus	~ChildView();
11611dbc914SStephan Aßmus
11711dbc914SStephan Aßmus	virtual	void Draw(BRect updateRect);
11811dbc914SStephan Aßmus};
11911dbc914SStephan Aßmus
12011dbc914SStephan Aßmus
12111dbc914SStephan AßmusChildView::ChildView(BRect frame, const char* name, rgb_color viewColor)
12211dbc914SStephan Aßmus	: BView(frame, name, B_FOLLOW_ALL, 0)
12311dbc914SStephan Aßmus{
12411dbc914SStephan Aßmus	SetLowColor(200, 200, 200);
12511dbc914SStephan Aßmus	SetViewColor(viewColor);
12611dbc914SStephan Aßmus	if (*(int32*)&viewColor == *(int32*)&B_TRANSPARENT_COLOR)
12711dbc914SStephan Aßmus		SetFlags(Flags() | B_WILL_DRAW);
12811dbc914SStephan Aßmus}
12911dbc914SStephan Aßmus
13011dbc914SStephan Aßmus
13111dbc914SStephan AßmusChildView::~ChildView()
13211dbc914SStephan Aßmus{
13311dbc914SStephan Aßmus}
13411dbc914SStephan Aßmus
13511dbc914SStephan Aßmus
13611dbc914SStephan Aßmusvoid
13711dbc914SStephan AßmusChildView::Draw(BRect updateRect)
13811dbc914SStephan Aßmus{
13911dbc914SStephan Aßmus	FillRect(updateRect, B_SOLID_LOW);
14011dbc914SStephan Aßmus}
14111dbc914SStephan Aßmus
14211dbc914SStephan Aßmus
14311dbc914SStephan Aßmus// #pragma mark -
14411dbc914SStephan Aßmus
14511dbc914SStephan Aßmus
14611dbc914SStephan Aßmusint
14711dbc914SStephan Aßmusmain(int argc, char** argv)
14811dbc914SStephan Aßmus{
14911dbc914SStephan Aßmus	BApplication app("application/x-vnd.Haiku-DrawAfterChildren");
15011dbc914SStephan Aßmus
15111dbc914SStephan Aßmus	BRect frame(100, 100, 700, 400);
15211dbc914SStephan Aßmus	BWindow* window = new BWindow(frame, "Window",
15311dbc914SStephan Aßmus		B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE);
15411dbc914SStephan Aßmus
15511dbc914SStephan Aßmus	frame.OffsetTo(B_ORIGIN);
15611dbc914SStephan Aßmus	TestView* view = new TestView(frame);
15711dbc914SStephan Aßmus	window->AddChild(view);
15811dbc914SStephan Aßmus
15911dbc914SStephan Aßmus	frame.InsetBy(20, 20);
16011dbc914SStephan Aßmus	frame.right = frame.left + frame.Width() / 2 - 10;
16111dbc914SStephan Aßmus	BView* child = new ChildView(frame, "child 1",
16211dbc914SStephan Aßmus		(rgb_color){ 200, 200, 200, 255 });
16311dbc914SStephan Aßmus	view->AddChild(child);
16411dbc914SStephan Aßmus
16511dbc914SStephan Aßmus	frame.OffsetBy(frame.Width() + 20, 0);
16611dbc914SStephan Aßmus	child = new ChildView(frame, "child 2", B_TRANSPARENT_COLOR);
16711dbc914SStephan Aßmus	view->AddChild(child);
16811dbc914SStephan Aßmus
16911dbc914SStephan Aßmus	window->Show();
17011dbc914SStephan Aßmus
17111dbc914SStephan Aßmus	app.Run();
17211dbc914SStephan Aßmus	return 0;
17311dbc914SStephan Aßmus}
17411dbc914SStephan Aßmus