xref: /haiku/src/kits/interface/Layout.cpp (revision 9ecf9d1c1d4888d341a6eac72112c72d1ae3a4cb)
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 	int32 index = IndexOfView(child);
94 	if (index >= 0) {
95 		if (BLayoutItem* item = RemoveItem(index)) {
96 			delete item;
97 			return true;
98 		}
99 	}
100 
101 	return false;
102 }
103 
104 // RemoveItem
105 bool
106 BLayout::RemoveItem(BLayoutItem* item)
107 {
108 	int32 index = IndexOfItem(item);
109 	return (index >= 0 ? RemoveItem(index) : false);
110 }
111 
112 // RemoveItem
113 BLayoutItem*
114 BLayout::RemoveItem(int32 index)
115 {
116 	if (index < 0 || index >= fItems.CountItems())
117 		return NULL;
118 
119 	BLayoutItem* item = (BLayoutItem*)fItems.RemoveItem(index);
120 
121 	// if the item refers to a BView, we make sure, it is removed from the
122 	// parent view
123 	BView* view = item->View();
124 	if (view && view->fParent == fView)
125 		view->_RemoveSelf();
126 
127 	item->SetLayout(NULL);
128 	ItemRemoved(item);
129 	InvalidateLayout();
130 
131 	return item;
132 }
133 
134 // ItemAt
135 BLayoutItem*
136 BLayout::ItemAt(int32 index) const
137 {
138 	return (BLayoutItem*)fItems.ItemAt(index);
139 }
140 
141 // CountItems
142 int32
143 BLayout::CountItems() const
144 {
145 	return fItems.CountItems();
146 }
147 
148 // IndexOfItem
149 int32
150 BLayout::IndexOfItem(BLayoutItem* item) const
151 {
152 	return fItems.IndexOf(item);
153 }
154 
155 // IndexOfView
156 int32
157 BLayout::IndexOfView(BView* child) const
158 {
159 	int itemCount = fItems.CountItems();
160 	for (int32 i = 0; i < itemCount; i++) {
161 		BLayoutItem* item = (BLayoutItem*)fItems.ItemAt(i);
162 		if (dynamic_cast<BViewLayoutItem*>(item) && item->View() == child)
163 			return i;
164 	}
165 
166 	return -1;
167 }
168 
169 // InvalidateLayout
170 void
171 BLayout::InvalidateLayout()
172 {
173 	if (fView)
174 		fView->InvalidateLayout();
175 }
176 
177 // ItemAdded
178 void
179 BLayout::ItemAdded(BLayoutItem* item)
180 {
181 }
182 
183 // ItemRemoved
184 void
185 BLayout::ItemRemoved(BLayoutItem* item)
186 {
187 }
188 
189 // SetView
190 void
191 BLayout::SetView(BView* view)
192 {
193 	if (view != fView) {
194 		fView = NULL;
195 
196 		// remove and delete all items
197 		for (int32 i = CountItems() - 1; i >= 0; i--)
198 			delete RemoveItem(i);
199 
200 		fView = view;
201 
202 		InvalidateLayout();
203 	}
204 }
205