xref: /haiku/src/tests/servers/app/draw_after_children/DrawAfterChildren.cpp (revision 11dbc914f76aad21d89d77d85be1dcd8003248d4)
1*11dbc914SStephan Aßmus 
2*11dbc914SStephan Aßmus #include <stdio.h>
3*11dbc914SStephan Aßmus 
4*11dbc914SStephan Aßmus #include <Application.h>
5*11dbc914SStephan Aßmus #include <View.h>
6*11dbc914SStephan Aßmus #include <Window.h>
7*11dbc914SStephan Aßmus 
8*11dbc914SStephan Aßmus /*-----------------------------------------------------------------------------
9*11dbc914SStephan Aßmus 
10*11dbc914SStephan Aßmus OBSERVATION on R5 behaviour:
11*11dbc914SStephan Aßmus 
12*11dbc914SStephan Aßmus * The hook function DrawAfterChildren is not called at all if the
13*11dbc914SStephan Aßmus   view flags don't include B_DRAW_ON_CHILDREN.
14*11dbc914SStephan Aßmus 
15*11dbc914SStephan Aßmus * If the view flags include B_DRAW_ON_CHILDREN, then any drawing commands
16*11dbc914SStephan Aßmus   executed in Draw() AND DrawAfterChildren() will paint on top of children.
17*11dbc914SStephan Aßmus 
18*11dbc914SStephan Aßmus * The background of a view with the B_DRAW_ON_CHILDREN flag set will not
19*11dbc914SStephan Aßmus   be painted by the app_server when child views change position and areas
20*11dbc914SStephan Aßmus   in the parent view are "exposed". If the expose events have other reasons,
21*11dbc914SStephan Aßmus   the background is painted as usual.
22*11dbc914SStephan Aßmus 
23*11dbc914SStephan Aßmus * The app_server side background painting of child views does not occur
24*11dbc914SStephan Aßmus   after the Draw() hook of the parent view with B_DRAW_ON_CHILDREN has been
25*11dbc914SStephan Aßmus   called. So while DrawAfterChildren() may be called after the Draw() hooks
26*11dbc914SStephan Aßmus   of all children have been called, the background has been painted earlier.
27*11dbc914SStephan Aßmus 
28*11dbc914SStephan Aßmus * It looks like the background painting inside app_server of a view with
29*11dbc914SStephan Aßmus   B_DRAW_ON_CHILDREN paints over the background of any children, though
30*11dbc914SStephan Aßmus   the background of the children is later painted too. Therefor, if a child
31*11dbc914SStephan Aßmus   has B_TRANSPARENT_COLOR background, the background of the parent with
32*11dbc914SStephan Aßmus   B_DRAW_ON_CHILDREN stays visible in the area of that child.
33*11dbc914SStephan Aßmus 
34*11dbc914SStephan Aßmus * Both Draw() and DrawAfterChildren() appear to push their own graphics
35*11dbc914SStephan Aßmus   states onto the state stack.
36*11dbc914SStephan Aßmus 
37*11dbc914SStephan Aßmus 
38*11dbc914SStephan Aßmus CONCLUSION:
39*11dbc914SStephan Aßmus 
40*11dbc914SStephan Aßmus It looks like the B_DRAW_ON_CHILDREN flag causes two effects:
41*11dbc914SStephan Aßmus 
42*11dbc914SStephan Aßmus * The local view clipping region inside the app_server simply ignores
43*11dbc914SStephan Aßmus   any children, this effects any drawing commands, those from Draw()
44*11dbc914SStephan Aßmus   and those from DrawAfterChildren()
45*11dbc914SStephan Aßmus 
46*11dbc914SStephan Aßmus * The DrawAfterChildren() hook is called after the children have drawn,
47*11dbc914SStephan Aßmus   so that the user may move all drawing functions there which he does not
48*11dbc914SStephan Aßmus   wish to have painted over by children.
49*11dbc914SStephan Aßmus 
50*11dbc914SStephan Aßmus That areas exposed by moving child views are not repainted could
51*11dbc914SStephan Aßmus be considered a bug of the R5 implementation.
52*11dbc914SStephan Aßmus 
53*11dbc914SStephan Aßmus -----------------------------------------------------------------------------*/
54*11dbc914SStephan Aßmus 
55*11dbc914SStephan Aßmus 
56*11dbc914SStephan Aßmus 
57*11dbc914SStephan Aßmus class TestView : public BView {
58*11dbc914SStephan Aßmus public:
59*11dbc914SStephan Aßmus 	TestView(BRect frame);
60*11dbc914SStephan Aßmus 	~TestView();
61*11dbc914SStephan Aßmus 
62*11dbc914SStephan Aßmus 	virtual	void Draw(BRect updateRect);
63*11dbc914SStephan Aßmus 	virtual void DrawAfterChildren(BRect updateRect);
64*11dbc914SStephan Aßmus };
65*11dbc914SStephan Aßmus 
66*11dbc914SStephan Aßmus 
TestView(BRect frame)67*11dbc914SStephan Aßmus TestView::TestView(BRect frame)
68*11dbc914SStephan Aßmus 	: BView(frame, "TestView", B_FOLLOW_ALL,
69*11dbc914SStephan Aßmus 		B_WILL_DRAW | B_DRAW_ON_CHILDREN | B_FULL_UPDATE_ON_RESIZE)
70*11dbc914SStephan Aßmus {
71*11dbc914SStephan Aßmus 	SetViewColor(200, 220, 255);
72*11dbc914SStephan Aßmus }
73*11dbc914SStephan Aßmus 
74*11dbc914SStephan Aßmus 
~TestView()75*11dbc914SStephan Aßmus TestView::~TestView()
76*11dbc914SStephan Aßmus {
77*11dbc914SStephan Aßmus }
78*11dbc914SStephan Aßmus 
79*11dbc914SStephan Aßmus 
80*11dbc914SStephan Aßmus void
Draw(BRect updateRect)81*11dbc914SStephan Aßmus TestView::Draw(BRect updateRect)
82*11dbc914SStephan Aßmus {
83*11dbc914SStephan Aßmus 	printf("Draw(BRect(%.1f, %.1f, %.1f, %.1f))\n",
84*11dbc914SStephan Aßmus 		updateRect.left, updateRect.top, updateRect.right, updateRect.bottom);
85*11dbc914SStephan Aßmus 
86*11dbc914SStephan Aßmus 	printf("pensize: %.2f\n", PenSize());
87*11dbc914SStephan Aßmus 
88*11dbc914SStephan Aßmus 	SetHighColor(0, 0, 255);
89*11dbc914SStephan Aßmus 	StrokeLine(Bounds().LeftBottom(), Bounds().RightTop());
90*11dbc914SStephan Aßmus 
91*11dbc914SStephan Aßmus 	SetPenSize(5);
92*11dbc914SStephan Aßmus }
93*11dbc914SStephan Aßmus 
94*11dbc914SStephan Aßmus void
DrawAfterChildren(BRect updateRect)95*11dbc914SStephan Aßmus TestView::DrawAfterChildren(BRect updateRect)
96*11dbc914SStephan Aßmus {
97*11dbc914SStephan Aßmus 	printf("DrawAfterChildren(BRect(%.1f, %.1f, %.1f, %.1f))\n",
98*11dbc914SStephan Aßmus 		updateRect.left, updateRect.top, updateRect.right, updateRect.bottom);
99*11dbc914SStephan Aßmus 
100*11dbc914SStephan Aßmus 	printf("pensize: %.2f\n", PenSize());
101*11dbc914SStephan Aßmus 
102*11dbc914SStephan Aßmus 	SetHighColor(255, 0, 0);
103*11dbc914SStephan Aßmus 	StrokeLine(Bounds().LeftTop(), Bounds().RightBottom());
104*11dbc914SStephan Aßmus 	Sync();
105*11dbc914SStephan Aßmus 
106*11dbc914SStephan Aßmus 	SetPenSize(7);
107*11dbc914SStephan Aßmus }
108*11dbc914SStephan Aßmus 
109*11dbc914SStephan Aßmus 
110*11dbc914SStephan Aßmus //	#pragma mark -
111*11dbc914SStephan Aßmus 
112*11dbc914SStephan Aßmus class ChildView : public BView {
113*11dbc914SStephan Aßmus public:
114*11dbc914SStephan Aßmus 	ChildView(BRect frame, const char* name, rgb_color viewColor);
115*11dbc914SStephan Aßmus 	~ChildView();
116*11dbc914SStephan Aßmus 
117*11dbc914SStephan Aßmus 	virtual	void Draw(BRect updateRect);
118*11dbc914SStephan Aßmus };
119*11dbc914SStephan Aßmus 
120*11dbc914SStephan Aßmus 
ChildView(BRect frame,const char * name,rgb_color viewColor)121*11dbc914SStephan Aßmus ChildView::ChildView(BRect frame, const char* name, rgb_color viewColor)
122*11dbc914SStephan Aßmus 	: BView(frame, name, B_FOLLOW_ALL, 0)
123*11dbc914SStephan Aßmus {
124*11dbc914SStephan Aßmus 	SetLowColor(200, 200, 200);
125*11dbc914SStephan Aßmus 	SetViewColor(viewColor);
126*11dbc914SStephan Aßmus 	if (*(int32*)&viewColor == *(int32*)&B_TRANSPARENT_COLOR)
127*11dbc914SStephan Aßmus 		SetFlags(Flags() | B_WILL_DRAW);
128*11dbc914SStephan Aßmus }
129*11dbc914SStephan Aßmus 
130*11dbc914SStephan Aßmus 
~ChildView()131*11dbc914SStephan Aßmus ChildView::~ChildView()
132*11dbc914SStephan Aßmus {
133*11dbc914SStephan Aßmus }
134*11dbc914SStephan Aßmus 
135*11dbc914SStephan Aßmus 
136*11dbc914SStephan Aßmus void
Draw(BRect updateRect)137*11dbc914SStephan Aßmus ChildView::Draw(BRect updateRect)
138*11dbc914SStephan Aßmus {
139*11dbc914SStephan Aßmus 	FillRect(updateRect, B_SOLID_LOW);
140*11dbc914SStephan Aßmus }
141*11dbc914SStephan Aßmus 
142*11dbc914SStephan Aßmus 
143*11dbc914SStephan Aßmus // #pragma mark -
144*11dbc914SStephan Aßmus 
145*11dbc914SStephan Aßmus 
146*11dbc914SStephan Aßmus int
main(int argc,char ** argv)147*11dbc914SStephan Aßmus main(int argc, char** argv)
148*11dbc914SStephan Aßmus {
149*11dbc914SStephan Aßmus 	BApplication app("application/x-vnd.Haiku-DrawAfterChildren");
150*11dbc914SStephan Aßmus 
151*11dbc914SStephan Aßmus 	BRect frame(100, 100, 700, 400);
152*11dbc914SStephan Aßmus 	BWindow* window = new BWindow(frame, "Window",
153*11dbc914SStephan Aßmus 		B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE);
154*11dbc914SStephan Aßmus 
155*11dbc914SStephan Aßmus 	frame.OffsetTo(B_ORIGIN);
156*11dbc914SStephan Aßmus 	TestView* view = new TestView(frame);
157*11dbc914SStephan Aßmus 	window->AddChild(view);
158*11dbc914SStephan Aßmus 
159*11dbc914SStephan Aßmus 	frame.InsetBy(20, 20);
160*11dbc914SStephan Aßmus 	frame.right = frame.left + frame.Width() / 2 - 10;
161*11dbc914SStephan Aßmus 	BView* child = new ChildView(frame, "child 1",
162*11dbc914SStephan Aßmus 		(rgb_color){ 200, 200, 200, 255 });
163*11dbc914SStephan Aßmus 	view->AddChild(child);
164*11dbc914SStephan Aßmus 
165*11dbc914SStephan Aßmus 	frame.OffsetBy(frame.Width() + 20, 0);
166*11dbc914SStephan Aßmus 	child = new ChildView(frame, "child 2", B_TRANSPARENT_COLOR);
167*11dbc914SStephan Aßmus 	view->AddChild(child);
168*11dbc914SStephan Aßmus 
169*11dbc914SStephan Aßmus 	window->Show();
170*11dbc914SStephan Aßmus 
171*11dbc914SStephan Aßmus 	app.Run();
172*11dbc914SStephan Aßmus 	return 0;
173*11dbc914SStephan Aßmus }
174*11dbc914SStephan Aßmus 
175