xref: /haiku/src/kits/interface/Layout.cpp (revision 16d5c24e533eb14b7b8a99ee9f3ec9ba66335b1e)
1 /*
2  * Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
3  * All rights reserved. Distributed under the terms of the MIT License.
4  */
5 
6 #include <Layout.h>
7 
8 #include <new>
9 
10 #include <View.h>
11 
12 #include "ViewLayoutItem.h"
13 
14 using std::nothrow;
15 
16 
17 // constructor
18 BLayout::BLayout()
19 	: fView(NULL),
20 	  fItems(20)
21 {
22 }
23 
24 // destructor
25 BLayout::~BLayout()
26 {
27 	// this deletes all items
28 	SetView(NULL);
29 }
30 
31 // View
32 BView*
33 BLayout::View() const
34 {
35 	return fView;
36 }
37 
38 // AddView
39 BLayoutItem*
40 BLayout::AddView(BView* child)
41 {
42 	return AddView(-1, child);
43 }
44 
45 // AddView
46 BLayoutItem*
47 BLayout::AddView(int32 index, BView* child)
48 {
49 	if (BViewLayoutItem* item = new(nothrow) BViewLayoutItem(child)) {
50 		if (AddItem(index, item))
51 			return item;
52 		delete item;
53 	}
54 	return NULL;
55 }
56 
57 // AddItem
58 bool
59 BLayout::AddItem(BLayoutItem* item)
60 {
61 	return AddItem(-1, item);
62 }
63 
64 // AddItem
65 bool
66 BLayout::AddItem(int32 index, BLayoutItem* item)
67 {
68 	if (!fView || !item || fItems.HasItem(item))
69 		return false;
70 
71 	// if the item refers to a BView, we make sure, it is added to the parent
72 	// view
73 	BView* view = item->View();
74 	if (view && view->fParent != fView && !fView->_AddChild(view, NULL))
75 		return false;
76 
77 	// validate the index
78 	if (index < 0 || index > fItems.CountItems())
79 		index = fItems.CountItems();
80 
81 	fItems.AddItem(item, index);
82 	ItemAdded(item);
83 	item->SetLayout(this);
84 	InvalidateLayout();
85 
86 	return true;
87 }
88 
89 // RemoveView
90 bool
91 BLayout::RemoveView(BView* child)
92 {
93 	bool removed = false;
94 
95 	// a view can have any number of layout items - we need to remove them all
96 	for (int32 i = fItems.CountItems(); i-- > 0;) {
97 		BLayoutItem* item = ItemAt(i);
98 
99 		if (item->View() != child)
100 			continue;
101 
102 		RemoveItem(i);
103 		removed = true;
104 		delete item;
105 	}
106 
107 	return removed;
108 }
109 
110 // RemoveItem
111 bool
112 BLayout::RemoveItem(BLayoutItem* item)
113 {
114 	int32 index = IndexOfItem(item);
115 	return (index >= 0 ? RemoveItem(index) : false);
116 }
117 
118 // RemoveItem
119 BLayoutItem*
120 BLayout::RemoveItem(int32 index)
121 {
122 	if (index < 0 || index >= fItems.CountItems())
123 		return NULL;
124 
125 	BLayoutItem* item = (BLayoutItem*)fItems.RemoveItem(index);
126 
127 	// if the item refers to a BView, we make sure, it is removed from the
128 	// parent view
129 	BView* view = item->View();
130 	if (view && view->fParent == fView)
131 		view->_RemoveSelf();
132 
133 	item->SetLayout(NULL);
134 	ItemRemoved(item);
135 	InvalidateLayout();
136 
137 	return item;
138 }
139 
140 // ItemAt
141 BLayoutItem*
142 BLayout::ItemAt(int32 index) const
143 {
144 	return (BLayoutItem*)fItems.ItemAt(index);
145 }
146 
147 // CountItems
148 int32
149 BLayout::CountItems() const
150 {
151 	return fItems.CountItems();
152 }
153 
154 // IndexOfItem
155 int32
156 BLayout::IndexOfItem(BLayoutItem* item) const
157 {
158 	return fItems.IndexOf(item);
159 }
160 
161 // IndexOfView
162 int32
163 BLayout::IndexOfView(BView* child) const
164 {
165 	int itemCount = fItems.CountItems();
166 	for (int32 i = 0; i < itemCount; i++) {
167 		BLayoutItem* item = (BLayoutItem*)fItems.ItemAt(i);
168 		if (dynamic_cast<BViewLayoutItem*>(item) && item->View() == child)
169 			return i;
170 	}
171 
172 	return -1;
173 }
174 
175 // InvalidateLayout
176 void
177 BLayout::InvalidateLayout()
178 {
179 	if (fView)
180 		fView->InvalidateLayout();
181 }
182 
183 // ItemAdded
184 void
185 BLayout::ItemAdded(BLayoutItem* item)
186 {
187 }
188 
189 // ItemRemoved
190 void
191 BLayout::ItemRemoved(BLayoutItem* item)
192 {
193 }
194 
195 // SetView
196 void
197 BLayout::SetView(BView* view)
198 {
199 	if (view != fView) {
200 		fView = NULL;
201 
202 		// remove and delete all items
203 		for (int32 i = CountItems() - 1; i >= 0; i--)
204 			delete RemoveItem(i);
205 
206 		fView = view;
207 
208 		InvalidateLayout();
209 	}
210 }
211