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