00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "Container.hh"
00026
00027 #include "FbTk/Button.hh"
00028 #include "FbTk/EventManager.hh"
00029
00030 Container::Container(const FbTk::FbWindow &parent):
00031 FbTk::FbWindow(parent, 0, 0, 1, 1, ExposureMask),
00032 m_align(RELATIVE),
00033 m_max_size_per_client(60),
00034 m_selected(0),
00035 m_update_lock(false) {
00036 FbTk::EventManager::instance()->add(*this, *this);
00037 }
00038
00039 Container::~Container() {
00040
00041 }
00042
00043 void Container::resize(unsigned int width, unsigned int height) {
00044
00045 if (FbTk::FbWindow::width() == width &&
00046 FbTk::FbWindow::height() == height)
00047 return;
00048
00049 FbTk::FbWindow::resize(width, height);
00050 repositionItems();
00051 }
00052
00053 void Container::moveResize(int x, int y,
00054 unsigned int width, unsigned int height) {
00055 FbTk::FbWindow::moveResize(x, y, width, height);
00056 repositionItems();
00057 }
00058
00059 void Container::insertItems(ItemList &item_list, int pos) {
00060
00061
00062 ItemList::iterator it = m_item_list.begin();
00063 ItemList::iterator it_end = m_item_list.end();
00064 for (; it != it_end; ++it) {
00065 if ((*it)->parent() != this)
00066 return;
00067 }
00068
00069 if (pos > size() || pos < 0) {
00070
00071 m_item_list.splice(m_item_list.end(), item_list);
00072 } else if (pos == 0) {
00073
00074 m_item_list.splice(m_item_list.begin(), item_list);
00075 } else {
00076
00077 for (it = m_item_list.begin(); pos != 0; ++it, --pos)
00078 continue;
00079 m_item_list.splice(it, item_list);
00080 }
00081
00082 m_item_list.unique();
00083
00084
00085 repositionItems();
00086 }
00087
00088 void Container::insertItem(Item item, int pos) {
00089 if (find(item) != -1)
00090 return;
00091
00092
00093 if (item->parent() != this)
00094 return;
00095
00096 if (pos >= size() || pos < 0) {
00097 m_item_list.push_back(item);
00098 } else if (pos == 0) {
00099 m_item_list.push_front(item);
00100 } else {
00101 ItemList::iterator it = m_item_list.begin();
00102 for (; pos != 0; ++it, --pos)
00103 continue;
00104
00105 m_item_list.insert(it, item);
00106 }
00107
00108
00109 m_item_list.unique();
00110
00111 repositionItems();
00112 }
00113
00114 void Container::removeItem(int index) {
00115 if (index < 0 || index > size())
00116 return;
00117
00118 ItemList::iterator it = m_item_list.begin();
00119 for (; index != 0; ++it, --index)
00120 continue;
00121
00122 if (*it == selected())
00123 m_selected = 0;
00124
00125 m_item_list.erase(it);
00126
00127 repositionItems();
00128 }
00129
00130 void Container::removeAll() {
00131 m_selected = 0;
00132 m_item_list.clear();
00133 if (!m_update_lock) {
00134 clear();
00135 updateTransparent();
00136 }
00137
00138 }
00139
00140 int Container::find(Item item) {
00141 ItemList::iterator it = m_item_list.begin();
00142 ItemList::iterator it_end = m_item_list.end();
00143 int index = 0;
00144 for (; it != it_end; ++it, ++index) {
00145 if ((*it) == item)
00146 break;
00147 }
00148
00149 if (it == it_end)
00150 return -1;
00151
00152 return index;
00153 }
00154
00155 void Container::setSelected(int pos) {
00156 if (pos < 0 || pos >= size())
00157 m_selected = 0;
00158 else {
00159 ItemList::iterator it = m_item_list.begin();
00160 for (; pos != 0; --pos, ++it)
00161 continue;
00162 m_selected = *it;
00163 if (m_selected) {
00164 m_selected->clear();
00165 m_selected->updateTransparent();
00166 }
00167 }
00168
00169 }
00170
00171 void Container::setMaxSizePerClient(unsigned int size) {
00172 m_max_size_per_client = size;
00173 }
00174
00175 void Container::setAlignment(Container::Alignment a) {
00176 m_align = a;
00177 }
00178
00179 void Container::exposeEvent(XExposeEvent &event) {
00180 if (!m_update_lock) {
00181 clearArea(event.x, event.y, event.width, event.height);
00182 updateTransparent(event.x, event.y, event.width, event.height);
00183 }
00184 }
00185
00186 void Container::repositionItems() {
00187 if (size() == 0 || m_update_lock)
00188 return;
00189
00191
00192 const int max_width_per_client = maxWidthPerClient();
00193
00194 ItemList::iterator it = m_item_list.begin();
00195 const ItemList::iterator it_end = m_item_list.end();
00196 int borderW = m_item_list.front()->borderWidth();
00197
00198 int rounding_error = width() - ((maxWidthPerClient() + borderW)* m_item_list.size() - borderW);
00199
00200 int next_x = -borderW;
00201 int extra = 0;
00202 int direction = 1;
00203 if (alignment() == RIGHT) {
00204 direction = -1;
00205 next_x = width() - max_width_per_client + borderW;
00206 }
00207
00208 for (; it != it_end; ++it, next_x += direction*(max_width_per_client + borderW + extra)) {
00209 if (rounding_error != 0) {
00210 --rounding_error;
00211 extra = 1;
00212 } else {
00213 extra = 0;
00214 }
00215
00216 (*it)->moveResize(next_x,
00217 -borderW,
00218 max_width_per_client + extra,
00219 height());
00220 (*it)->clear();
00221 (*it)->updateTransparent();
00222 }
00223
00224 }
00225
00226
00227 unsigned int Container::maxWidthPerClient() const {
00228 switch (alignment()) {
00229 case RIGHT:
00230 case LEFT:
00231 return m_max_size_per_client;
00232 break;
00233 case RELATIVE:
00234 int count = size();
00235 if (count == 0)
00236 return width();
00237 else {
00238 int borderW = m_item_list.front()->borderWidth();
00239
00240
00241 return (width() - (count - 1) * borderW) / count;
00242 }
00243 break;
00244 }
00245
00246
00247 return 1;
00248 }