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(®ion);
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(®ion);
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