xref: /haiku/src/tests/kits/interface/layout/widget_layout_test/View.cpp (revision 4b5501d29dca8c24507a125b2d3b7350e1cb727d)
1a5b50d1fSIngo Weinhold /*
2a5b50d1fSIngo Weinhold  * Copyright 2007, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
3a5b50d1fSIngo Weinhold  * All rights reserved. Distributed under the terms of the MIT License.
4a5b50d1fSIngo Weinhold  */
5a5b50d1fSIngo Weinhold 
6a5b50d1fSIngo Weinhold #include "View.h"
7a5b50d1fSIngo Weinhold 
8a5b50d1fSIngo Weinhold #include <stdio.h>
9a5b50d1fSIngo Weinhold 
10a5b50d1fSIngo Weinhold #include <Region.h>
11a5b50d1fSIngo Weinhold #include <View.h>
12a5b50d1fSIngo Weinhold 
13a5b50d1fSIngo Weinhold 
View()14a5b50d1fSIngo Weinhold View::View()
15a5b50d1fSIngo Weinhold 	: fFrame(0, 0, 0, 0),
16a5b50d1fSIngo Weinhold 	  fContainer(NULL),
17a5b50d1fSIngo Weinhold 	  fParent(NULL),
18a5b50d1fSIngo Weinhold 	  fChildren(),
19a5b50d1fSIngo Weinhold 	  fViewColor(B_TRANSPARENT_32_BIT),
20a5b50d1fSIngo Weinhold 	  fLayoutValid(false)
21a5b50d1fSIngo Weinhold {
22a5b50d1fSIngo Weinhold }
23a5b50d1fSIngo Weinhold 
24a5b50d1fSIngo Weinhold 
View(BRect frame)25a5b50d1fSIngo Weinhold View::View(BRect frame)
26a5b50d1fSIngo Weinhold 	: fFrame(frame),
27a5b50d1fSIngo Weinhold 	  fContainer(NULL),
28a5b50d1fSIngo Weinhold 	  fParent(NULL),
29a5b50d1fSIngo Weinhold 	  fChildren(),
30a5b50d1fSIngo Weinhold 	  fViewColor(B_TRANSPARENT_32_BIT),
31a5b50d1fSIngo Weinhold 	  fLayoutValid(false)
32a5b50d1fSIngo Weinhold {
33a5b50d1fSIngo Weinhold }
34a5b50d1fSIngo Weinhold 
35a5b50d1fSIngo Weinhold 
~View()36a5b50d1fSIngo Weinhold View::~View()
37a5b50d1fSIngo Weinhold {
38a5b50d1fSIngo Weinhold 	// delete children
39a5b50d1fSIngo Weinhold 	for (int32 i = CountChildren() - 1; i >= 0; i--)
40a5b50d1fSIngo Weinhold 		delete RemoveChild(i);
41a5b50d1fSIngo Weinhold }
42a5b50d1fSIngo Weinhold 
43a5b50d1fSIngo Weinhold 
44a5b50d1fSIngo Weinhold void
SetFrame(BRect frame)45a5b50d1fSIngo Weinhold View::SetFrame(BRect frame)
46a5b50d1fSIngo Weinhold {
47a5b50d1fSIngo Weinhold 	if (frame != fFrame && frame.IsValid()) {
48a5b50d1fSIngo Weinhold 		BRect oldFrame(frame);
49a5b50d1fSIngo Weinhold 		Invalidate();
50a5b50d1fSIngo Weinhold 		fFrame = frame;
51a5b50d1fSIngo Weinhold 		Invalidate();
52a5b50d1fSIngo Weinhold 
53a5b50d1fSIngo Weinhold 		FrameChanged(oldFrame, frame);
54a5b50d1fSIngo Weinhold 	}
55a5b50d1fSIngo Weinhold 
56a5b50d1fSIngo Weinhold 	// relayout if necessary
57a5b50d1fSIngo Weinhold 	if (!fLayoutValid) {
58a5b50d1fSIngo Weinhold 		Layout();
59a5b50d1fSIngo Weinhold 		fLayoutValid = true;
60a5b50d1fSIngo Weinhold 	}
61a5b50d1fSIngo Weinhold }
62a5b50d1fSIngo Weinhold 
63a5b50d1fSIngo Weinhold 
64a5b50d1fSIngo Weinhold BRect
Frame() const65a5b50d1fSIngo Weinhold View::Frame() const
66a5b50d1fSIngo Weinhold {
67a5b50d1fSIngo Weinhold 	return fFrame;
68a5b50d1fSIngo Weinhold }
69a5b50d1fSIngo Weinhold 
70a5b50d1fSIngo Weinhold 
71a5b50d1fSIngo Weinhold BRect
Bounds() const72a5b50d1fSIngo Weinhold View::Bounds() const
73a5b50d1fSIngo Weinhold {
74a5b50d1fSIngo Weinhold 	return BRect(fFrame).OffsetToCopy(B_ORIGIN);
75a5b50d1fSIngo Weinhold }
76a5b50d1fSIngo Weinhold 
77a5b50d1fSIngo Weinhold 
78a5b50d1fSIngo Weinhold void
SetLocation(BPoint location)79a5b50d1fSIngo Weinhold View::SetLocation(BPoint location)
80a5b50d1fSIngo Weinhold {
81a5b50d1fSIngo Weinhold 	SetFrame(fFrame.OffsetToCopy(location));
82a5b50d1fSIngo Weinhold }
83a5b50d1fSIngo Weinhold 
84a5b50d1fSIngo Weinhold 
85a5b50d1fSIngo Weinhold BPoint
Location() const86a5b50d1fSIngo Weinhold View::Location() const
87a5b50d1fSIngo Weinhold {
88a5b50d1fSIngo Weinhold 	return fFrame.LeftTop();
89a5b50d1fSIngo Weinhold }
90a5b50d1fSIngo Weinhold 
91a5b50d1fSIngo Weinhold 
92a5b50d1fSIngo Weinhold void
SetSize(BSize size)93a5b50d1fSIngo Weinhold View::SetSize(BSize size)
94a5b50d1fSIngo Weinhold {
95a5b50d1fSIngo Weinhold 	BRect frame(fFrame);
96a5b50d1fSIngo Weinhold 	frame.right = frame.left + size.width;
97a5b50d1fSIngo Weinhold 	frame.bottom = frame.top + size.height;
98a5b50d1fSIngo Weinhold 	SetFrame(frame);
99a5b50d1fSIngo Weinhold }
100a5b50d1fSIngo Weinhold 
101a5b50d1fSIngo Weinhold 
102a5b50d1fSIngo Weinhold BSize
Size() const103a5b50d1fSIngo Weinhold View::Size() const
104a5b50d1fSIngo Weinhold {
105a5b50d1fSIngo Weinhold 	return Frame().Size();
106a5b50d1fSIngo Weinhold }
107a5b50d1fSIngo Weinhold 
108a5b50d1fSIngo Weinhold 
109a5b50d1fSIngo Weinhold BSize
MinSize()110a5b50d1fSIngo Weinhold View::MinSize()
111a5b50d1fSIngo Weinhold {
112a5b50d1fSIngo Weinhold 	return BSize(-1, -1);
113a5b50d1fSIngo Weinhold }
114a5b50d1fSIngo Weinhold 
115a5b50d1fSIngo Weinhold 
116a5b50d1fSIngo Weinhold BSize
MaxSize()117a5b50d1fSIngo Weinhold View::MaxSize()
118a5b50d1fSIngo Weinhold {
119a5b50d1fSIngo Weinhold 	return BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED);
120a5b50d1fSIngo Weinhold }
121a5b50d1fSIngo Weinhold 
122a5b50d1fSIngo Weinhold 
123a5b50d1fSIngo Weinhold BSize
PreferredSize()124a5b50d1fSIngo Weinhold View::PreferredSize()
125a5b50d1fSIngo Weinhold {
126a5b50d1fSIngo Weinhold 	return MinSize();
127a5b50d1fSIngo Weinhold }
128a5b50d1fSIngo Weinhold 
129a5b50d1fSIngo Weinhold 
130a5b50d1fSIngo Weinhold BAlignment
Alignment()131a5b50d1fSIngo Weinhold View::Alignment()
132a5b50d1fSIngo Weinhold {
133a5b50d1fSIngo Weinhold 	return BAlignment(B_ALIGN_HORIZONTAL_CENTER, B_ALIGN_VERTICAL_CENTER);
134a5b50d1fSIngo Weinhold }
135a5b50d1fSIngo Weinhold 
136a5b50d1fSIngo Weinhold 
137a5b50d1fSIngo Weinhold BPoint
LocationInContainer() const138a5b50d1fSIngo Weinhold View::LocationInContainer() const
139a5b50d1fSIngo Weinhold {
140a5b50d1fSIngo Weinhold 	BPoint location = fFrame.LeftTop();
141a5b50d1fSIngo Weinhold 	return (fParent ? fParent->LocationInContainer() + location : location);
142a5b50d1fSIngo Weinhold }
143a5b50d1fSIngo Weinhold 
144a5b50d1fSIngo Weinhold 
145a5b50d1fSIngo Weinhold BRect
FrameInContainer() const146a5b50d1fSIngo Weinhold View::FrameInContainer() const
147a5b50d1fSIngo Weinhold {
148a5b50d1fSIngo Weinhold 	BRect frame(fFrame);
149a5b50d1fSIngo Weinhold 	return frame.OffsetToCopy(LocationInContainer());
150a5b50d1fSIngo Weinhold }
151a5b50d1fSIngo Weinhold 
152a5b50d1fSIngo Weinhold 
153a5b50d1fSIngo Weinhold BPoint
ConvertFromContainer(BPoint point) const154a5b50d1fSIngo Weinhold View::ConvertFromContainer(BPoint point) const
155a5b50d1fSIngo Weinhold {
156a5b50d1fSIngo Weinhold 	return point - LocationInContainer();
157a5b50d1fSIngo Weinhold }
158a5b50d1fSIngo Weinhold 
159a5b50d1fSIngo Weinhold 
160a5b50d1fSIngo Weinhold BRect
ConvertFromContainer(BRect rect) const161a5b50d1fSIngo Weinhold View::ConvertFromContainer(BRect rect) const
162a5b50d1fSIngo Weinhold {
163a5b50d1fSIngo Weinhold 	return rect.OffsetBySelf(-LocationInContainer());
164a5b50d1fSIngo Weinhold }
165a5b50d1fSIngo Weinhold 
166a5b50d1fSIngo Weinhold 
167a5b50d1fSIngo Weinhold BPoint
ConvertToContainer(BPoint point) const168a5b50d1fSIngo Weinhold View::ConvertToContainer(BPoint point) const
169a5b50d1fSIngo Weinhold {
170a5b50d1fSIngo Weinhold 	return point + LocationInContainer();
171a5b50d1fSIngo Weinhold }
172a5b50d1fSIngo Weinhold 
173a5b50d1fSIngo Weinhold 
174a5b50d1fSIngo Weinhold BRect
ConvertToContainer(BRect rect) const175a5b50d1fSIngo Weinhold View::ConvertToContainer(BRect rect) const
176a5b50d1fSIngo Weinhold {
177a5b50d1fSIngo Weinhold 	return rect.OffsetBySelf(LocationInContainer());
178a5b50d1fSIngo Weinhold }
179a5b50d1fSIngo Weinhold 
180a5b50d1fSIngo Weinhold 
181a5b50d1fSIngo Weinhold View*
Parent() const182a5b50d1fSIngo Weinhold View::Parent() const
183a5b50d1fSIngo Weinhold {
184a5b50d1fSIngo Weinhold 	return fParent;
185a5b50d1fSIngo Weinhold }
186a5b50d1fSIngo Weinhold 
187a5b50d1fSIngo Weinhold 
188a5b50d1fSIngo Weinhold BView*
Container() const189a5b50d1fSIngo Weinhold View::Container() const
190a5b50d1fSIngo Weinhold {
191a5b50d1fSIngo Weinhold 	return fContainer;
192a5b50d1fSIngo Weinhold }
193a5b50d1fSIngo Weinhold 
194a5b50d1fSIngo Weinhold 
195a5b50d1fSIngo Weinhold bool
AddChild(View * child)196a5b50d1fSIngo Weinhold View::AddChild(View* child)
197a5b50d1fSIngo Weinhold {
198a5b50d1fSIngo Weinhold 	if (!child)
199a5b50d1fSIngo Weinhold 		return false;
200a5b50d1fSIngo Weinhold 
201a5b50d1fSIngo Weinhold 	if (child->Parent() || child->Container()) {
202a5b50d1fSIngo Weinhold 		fprintf(stderr, "View::AddChild(): view %p already has a parent "
203a5b50d1fSIngo Weinhold 			"or is the container view\n", child);
204a5b50d1fSIngo Weinhold 		return false;
205a5b50d1fSIngo Weinhold 	}
206a5b50d1fSIngo Weinhold 
207a5b50d1fSIngo Weinhold 	if (!fChildren.AddItem(child))
208a5b50d1fSIngo Weinhold 		return false;
209a5b50d1fSIngo Weinhold 
210a5b50d1fSIngo Weinhold 	child->_AddedToParent(this);
211a5b50d1fSIngo Weinhold 
212a5b50d1fSIngo Weinhold 	child->Invalidate();
213a5b50d1fSIngo Weinhold 	InvalidateLayout();
214a5b50d1fSIngo Weinhold 
215a5b50d1fSIngo Weinhold 	return true;
216a5b50d1fSIngo Weinhold }
217a5b50d1fSIngo Weinhold 
218a5b50d1fSIngo Weinhold 
219a5b50d1fSIngo Weinhold bool
RemoveChild(View * child)220a5b50d1fSIngo Weinhold View::RemoveChild(View* child)
221a5b50d1fSIngo Weinhold {
222a5b50d1fSIngo Weinhold 	if (!child)
223a5b50d1fSIngo Weinhold 		return false;
224a5b50d1fSIngo Weinhold 
225a5b50d1fSIngo Weinhold 	return RemoveChild(IndexOfChild(child));
226a5b50d1fSIngo Weinhold }
227a5b50d1fSIngo Weinhold 
228a5b50d1fSIngo Weinhold 
229a5b50d1fSIngo Weinhold View*
RemoveChild(int32 index)230a5b50d1fSIngo Weinhold View::RemoveChild(int32 index)
231a5b50d1fSIngo Weinhold {
232a5b50d1fSIngo Weinhold 	if (index < 0 || index >= fChildren.CountItems())
233a5b50d1fSIngo Weinhold 		return NULL;
234a5b50d1fSIngo Weinhold 
235a5b50d1fSIngo Weinhold 	View* child = ChildAt(index);
236a5b50d1fSIngo Weinhold 	child->Invalidate();
237a5b50d1fSIngo Weinhold 	child->_RemovingFromParent();
238a5b50d1fSIngo Weinhold 	fChildren.RemoveItem(index);
239a5b50d1fSIngo Weinhold 
240a5b50d1fSIngo Weinhold 	InvalidateLayout();
241a5b50d1fSIngo Weinhold 
242a5b50d1fSIngo Weinhold 	return child;
243a5b50d1fSIngo Weinhold }
244a5b50d1fSIngo Weinhold 
245a5b50d1fSIngo Weinhold 
246a5b50d1fSIngo Weinhold int32
CountChildren() const247a5b50d1fSIngo Weinhold View::CountChildren() const
248a5b50d1fSIngo Weinhold {
249a5b50d1fSIngo Weinhold 	return fChildren.CountItems();
250a5b50d1fSIngo Weinhold }
251a5b50d1fSIngo Weinhold 
252a5b50d1fSIngo Weinhold 
253a5b50d1fSIngo Weinhold View*
ChildAt(int32 index) const254a5b50d1fSIngo Weinhold View::ChildAt(int32 index) const
255a5b50d1fSIngo Weinhold {
256a5b50d1fSIngo Weinhold 	return (View*)fChildren.ItemAt(index);
257a5b50d1fSIngo Weinhold }
258a5b50d1fSIngo Weinhold 
259a5b50d1fSIngo Weinhold 
260a5b50d1fSIngo Weinhold View*
ChildAt(BPoint point) const261a5b50d1fSIngo Weinhold View::ChildAt(BPoint point) const
262a5b50d1fSIngo Weinhold {
263a5b50d1fSIngo Weinhold 	for (int32 i = 0; View* child = ChildAt(i); i++) {
264a5b50d1fSIngo Weinhold 		if (child->Frame().Contains(point))
265a5b50d1fSIngo Weinhold 			return child;
266a5b50d1fSIngo Weinhold 	}
267a5b50d1fSIngo Weinhold 
268a5b50d1fSIngo Weinhold 	return NULL;
269a5b50d1fSIngo Weinhold }
270a5b50d1fSIngo Weinhold 
271a5b50d1fSIngo Weinhold 
272a5b50d1fSIngo Weinhold View*
AncestorAt(BPoint point,BPoint * localPoint) const273a5b50d1fSIngo Weinhold View::AncestorAt(BPoint point, BPoint* localPoint) const
274a5b50d1fSIngo Weinhold {
275a5b50d1fSIngo Weinhold 	if (!Bounds().Contains(point))
276a5b50d1fSIngo Weinhold 		return NULL;
277a5b50d1fSIngo Weinhold 
278a5b50d1fSIngo Weinhold 	View* view = const_cast<View*>(this);
279a5b50d1fSIngo Weinhold 
280a5b50d1fSIngo Weinhold 	// Iterate deeper down the hierarchy, until we reach a view that
281a5b50d1fSIngo Weinhold 	// doesn't have a child at the location.
282a5b50d1fSIngo Weinhold 	while (true) {
283a5b50d1fSIngo Weinhold 		View* child = view->ChildAt(point);
284a5b50d1fSIngo Weinhold 		if (!child) {
285a5b50d1fSIngo Weinhold 			if (localPoint)
286a5b50d1fSIngo Weinhold 				*localPoint = point;
287a5b50d1fSIngo Weinhold 			return view;
288a5b50d1fSIngo Weinhold 		}
289a5b50d1fSIngo Weinhold 
290a5b50d1fSIngo Weinhold 		view = child;
291a5b50d1fSIngo Weinhold 		point -= view->Frame().LeftTop();
292a5b50d1fSIngo Weinhold 	}
293a5b50d1fSIngo Weinhold }
294a5b50d1fSIngo Weinhold 
295a5b50d1fSIngo Weinhold 
296a5b50d1fSIngo Weinhold int32
IndexOfChild(View * child) const297a5b50d1fSIngo Weinhold View::IndexOfChild(View* child) const
298a5b50d1fSIngo Weinhold {
299a5b50d1fSIngo Weinhold 	return (child ? fChildren.IndexOf(child) : -1);
300a5b50d1fSIngo Weinhold }
301a5b50d1fSIngo Weinhold 
302a5b50d1fSIngo Weinhold 
303a5b50d1fSIngo Weinhold void
Invalidate(BRect rect)304a5b50d1fSIngo Weinhold View::Invalidate(BRect rect)
305a5b50d1fSIngo Weinhold {
306a5b50d1fSIngo Weinhold 	if (fContainer) {
307a5b50d1fSIngo Weinhold 		rect = rect & Bounds();
308a5b50d1fSIngo Weinhold 		fContainer->Invalidate(rect.OffsetByCopy(LocationInContainer()));
309a5b50d1fSIngo Weinhold 	}
310a5b50d1fSIngo Weinhold }
311a5b50d1fSIngo Weinhold 
312a5b50d1fSIngo Weinhold 
313a5b50d1fSIngo Weinhold void
Invalidate()314a5b50d1fSIngo Weinhold View::Invalidate()
315a5b50d1fSIngo Weinhold {
316a5b50d1fSIngo Weinhold 	Invalidate(Bounds());
317a5b50d1fSIngo Weinhold }
318a5b50d1fSIngo Weinhold 
319a5b50d1fSIngo Weinhold 
320a5b50d1fSIngo Weinhold void
InvalidateLayout()321a5b50d1fSIngo Weinhold View::InvalidateLayout()
322a5b50d1fSIngo Weinhold {
323*4b5501d2SIngo Weinhold //printf("%p->View::InvalidateLayout(): %d\n", this, fLayoutValid);
324a5b50d1fSIngo Weinhold 	if (fLayoutValid) {
325a5b50d1fSIngo Weinhold 		fLayoutValid = false;
326a5b50d1fSIngo Weinhold 		if (fParent)
327a5b50d1fSIngo Weinhold 			fParent->InvalidateLayout();
328a5b50d1fSIngo Weinhold 	}
329a5b50d1fSIngo Weinhold }
330a5b50d1fSIngo Weinhold 
331a5b50d1fSIngo Weinhold 
332a5b50d1fSIngo Weinhold bool
IsLayoutValid() const333a5b50d1fSIngo Weinhold View::IsLayoutValid() const
334a5b50d1fSIngo Weinhold {
335a5b50d1fSIngo Weinhold 	return fLayoutValid;
336a5b50d1fSIngo Weinhold }
337a5b50d1fSIngo Weinhold 
338a5b50d1fSIngo Weinhold 
339a5b50d1fSIngo Weinhold void
SetViewColor(rgb_color color)340a5b50d1fSIngo Weinhold View::SetViewColor(rgb_color color)
341a5b50d1fSIngo Weinhold {
342a5b50d1fSIngo Weinhold 	fViewColor = color;
343a5b50d1fSIngo Weinhold }
344a5b50d1fSIngo Weinhold 
345a5b50d1fSIngo Weinhold 
346a5b50d1fSIngo Weinhold void
Draw(BView * container,BRect updateRect)347a5b50d1fSIngo Weinhold View::Draw(BView* container, BRect updateRect)
348a5b50d1fSIngo Weinhold {
349a5b50d1fSIngo Weinhold }
350a5b50d1fSIngo Weinhold 
351a5b50d1fSIngo Weinhold 
352a5b50d1fSIngo Weinhold void
MouseDown(BPoint where,uint32 buttons,int32 modifiers)353a5b50d1fSIngo Weinhold View::MouseDown(BPoint where, uint32 buttons, int32 modifiers)
354a5b50d1fSIngo Weinhold {
355a5b50d1fSIngo Weinhold }
356a5b50d1fSIngo Weinhold 
357a5b50d1fSIngo Weinhold 
358a5b50d1fSIngo Weinhold void
MouseUp(BPoint where,uint32 buttons,int32 modifiers)359a5b50d1fSIngo Weinhold View::MouseUp(BPoint where, uint32 buttons, int32 modifiers)
360a5b50d1fSIngo Weinhold {
361a5b50d1fSIngo Weinhold }
362a5b50d1fSIngo Weinhold 
363a5b50d1fSIngo Weinhold 
364a5b50d1fSIngo Weinhold void
MouseMoved(BPoint where,uint32 buttons,int32 modifiers)365a5b50d1fSIngo Weinhold View::MouseMoved(BPoint where, uint32 buttons, int32 modifiers)
366a5b50d1fSIngo Weinhold {
367a5b50d1fSIngo Weinhold }
368a5b50d1fSIngo Weinhold 
369a5b50d1fSIngo Weinhold 
370a5b50d1fSIngo Weinhold void
AddedToContainer()371a5b50d1fSIngo Weinhold View::AddedToContainer()
372a5b50d1fSIngo Weinhold {
373a5b50d1fSIngo Weinhold }
374a5b50d1fSIngo Weinhold 
375a5b50d1fSIngo Weinhold 
376a5b50d1fSIngo Weinhold void
RemovingFromContainer()377a5b50d1fSIngo Weinhold View::RemovingFromContainer()
378a5b50d1fSIngo Weinhold {
379a5b50d1fSIngo Weinhold }
380a5b50d1fSIngo Weinhold 
381a5b50d1fSIngo Weinhold 
382a5b50d1fSIngo Weinhold void
FrameChanged(BRect oldFrame,BRect newFrame)383a5b50d1fSIngo Weinhold View::FrameChanged(BRect oldFrame, BRect newFrame)
384a5b50d1fSIngo Weinhold {
385a5b50d1fSIngo Weinhold }
386a5b50d1fSIngo Weinhold 
387a5b50d1fSIngo Weinhold 
388a5b50d1fSIngo Weinhold void
Layout()389a5b50d1fSIngo Weinhold View::Layout()
390a5b50d1fSIngo Weinhold {
391a5b50d1fSIngo Weinhold 	// simply trigger relayouting the children
392a5b50d1fSIngo Weinhold 	for (int32 i = 0; View* child = ChildAt(i); i++)
393a5b50d1fSIngo Weinhold 		child->SetFrame(child->Frame());
394a5b50d1fSIngo Weinhold }
395a5b50d1fSIngo Weinhold 
396a5b50d1fSIngo Weinhold 
397a5b50d1fSIngo Weinhold void
_AddedToParent(View * parent)398a5b50d1fSIngo Weinhold View::_AddedToParent(View* parent)
399a5b50d1fSIngo Weinhold {
400a5b50d1fSIngo Weinhold 	fParent = parent;
401a5b50d1fSIngo Weinhold 
402a5b50d1fSIngo Weinhold 	if (parent->Container()) {
403a5b50d1fSIngo Weinhold 		Invalidate();
404a5b50d1fSIngo Weinhold 		_AddedToContainer(parent->Container());
405a5b50d1fSIngo Weinhold 	}
406a5b50d1fSIngo Weinhold }
407a5b50d1fSIngo Weinhold 
408a5b50d1fSIngo Weinhold 
409a5b50d1fSIngo Weinhold void
_RemovingFromParent()410a5b50d1fSIngo Weinhold View::_RemovingFromParent()
411a5b50d1fSIngo Weinhold {
412a5b50d1fSIngo Weinhold 	if (fContainer)
413a5b50d1fSIngo Weinhold 		_RemovingFromContainer();
414a5b50d1fSIngo Weinhold 
415a5b50d1fSIngo Weinhold 	fParent = NULL;
416a5b50d1fSIngo Weinhold }
417a5b50d1fSIngo Weinhold 
418a5b50d1fSIngo Weinhold 
419a5b50d1fSIngo Weinhold void
_AddedToContainer(BView * container)420a5b50d1fSIngo Weinhold View::_AddedToContainer(BView* container)
421a5b50d1fSIngo Weinhold {
422a5b50d1fSIngo Weinhold 	fContainer = container;
423a5b50d1fSIngo Weinhold 
424a5b50d1fSIngo Weinhold 	AddedToContainer();
425a5b50d1fSIngo Weinhold 
426a5b50d1fSIngo Weinhold 	for (int32 i = 0; View* child = ChildAt(i); i++)
427a5b50d1fSIngo Weinhold 		child->_AddedToContainer(fContainer);
428a5b50d1fSIngo Weinhold }
429a5b50d1fSIngo Weinhold 
430a5b50d1fSIngo Weinhold 
431a5b50d1fSIngo Weinhold void
_RemovingFromContainer()432a5b50d1fSIngo Weinhold View::_RemovingFromContainer()
433a5b50d1fSIngo Weinhold {
434a5b50d1fSIngo Weinhold 	for (int32 i = 0; View* child = ChildAt(i); i++)
435a5b50d1fSIngo Weinhold 		child->_RemovingFromContainer();
436a5b50d1fSIngo Weinhold 
437a5b50d1fSIngo Weinhold 	RemovingFromContainer();
438a5b50d1fSIngo Weinhold 
439a5b50d1fSIngo Weinhold 	fContainer = NULL;
440a5b50d1fSIngo Weinhold }
441a5b50d1fSIngo Weinhold 
442a5b50d1fSIngo Weinhold 
443a5b50d1fSIngo Weinhold void
_Draw(BView * container,BRect updateRect)444a5b50d1fSIngo Weinhold View::_Draw(BView* container, BRect updateRect)
445a5b50d1fSIngo Weinhold {
446a5b50d1fSIngo Weinhold 	// compute the clipping region
447a5b50d1fSIngo Weinhold 	BRegion region(Bounds());
448a5b50d1fSIngo Weinhold 	for (int32 i = 0; View* child = ChildAt(i); i++)
449a5b50d1fSIngo Weinhold 		region.Exclude(child->Frame());
450a5b50d1fSIngo Weinhold 
451a5b50d1fSIngo Weinhold 	if (region.Frame().IsValid()) {
452a5b50d1fSIngo Weinhold 		// set the clipping region
453a5b50d1fSIngo Weinhold 		container->ConstrainClippingRegion(&region);
454a5b50d1fSIngo Weinhold 
455a5b50d1fSIngo Weinhold 		// draw the background, if it isn't transparent
456a5b50d1fSIngo Weinhold 		if (fViewColor.alpha != 0) {
457a5b50d1fSIngo Weinhold 			container->SetLowColor(fViewColor);
458a5b50d1fSIngo Weinhold 			container->FillRect(updateRect, B_SOLID_LOW);
459a5b50d1fSIngo Weinhold 		}
460a5b50d1fSIngo Weinhold 
461a5b50d1fSIngo Weinhold 		// draw this view
462a5b50d1fSIngo Weinhold 		Draw(container, updateRect);
463a5b50d1fSIngo Weinhold 
464a5b50d1fSIngo Weinhold 		// revert the clipping region
465a5b50d1fSIngo Weinhold 		region.Set(Bounds());
466a5b50d1fSIngo Weinhold 		container->ConstrainClippingRegion(&region);
467a5b50d1fSIngo Weinhold 	}
468a5b50d1fSIngo Weinhold 
469a5b50d1fSIngo Weinhold 	// draw the children
470a5b50d1fSIngo Weinhold 	if (CountChildren() > 0) {
471a5b50d1fSIngo Weinhold 		container->PushState();
472a5b50d1fSIngo Weinhold 
473a5b50d1fSIngo Weinhold 		for (int32 i = 0; View* child = ChildAt(i); i++) {
474a5b50d1fSIngo Weinhold 			BRect childFrame = child->Frame();
475a5b50d1fSIngo Weinhold 			BRect childUpdateRect = updateRect & childFrame;
476a5b50d1fSIngo Weinhold 			if (childUpdateRect.IsValid()) {
477a5b50d1fSIngo Weinhold 				// set origin
478a5b50d1fSIngo Weinhold 				childUpdateRect.OffsetBy(-childFrame.LeftTop());
479a5b50d1fSIngo Weinhold 				container->SetOrigin(childFrame.LeftTop());
480a5b50d1fSIngo Weinhold 
481a5b50d1fSIngo Weinhold 				// draw
482a5b50d1fSIngo Weinhold 				child->_Draw(container, childUpdateRect);
483a5b50d1fSIngo Weinhold 			}
484a5b50d1fSIngo Weinhold 		}
485a5b50d1fSIngo Weinhold 
486a5b50d1fSIngo Weinhold 		container->PopState();
487a5b50d1fSIngo Weinhold 	}
488a5b50d1fSIngo Weinhold }
489