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