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