diff options
Diffstat (limited to 'src/Container.cc')
-rw-r--r-- | src/Container.cc | 76 |
1 files changed, 69 insertions, 7 deletions
diff --git a/src/Container.cc b/src/Container.cc index df745d0..9cef92c 100644 --- a/src/Container.cc +++ b/src/Container.cc | |||
@@ -34,6 +34,7 @@ Container::Container(const FbTk::FbWindow &parent): | |||
34 | FbTk::FbWindow(parent, 0, 0, 1, 1, ExposureMask), | 34 | FbTk::FbWindow(parent, 0, 0, 1, 1, ExposureMask), |
35 | m_align(RELATIVE), | 35 | m_align(RELATIVE), |
36 | m_max_size_per_client(60), | 36 | m_max_size_per_client(60), |
37 | m_max_total_size(0), | ||
37 | m_selected(0), | 38 | m_selected(0), |
38 | m_update_lock(false) { | 39 | m_update_lock(false) { |
39 | FbTk::EventManager::instance()->add(*this, *this); | 40 | FbTk::EventManager::instance()->add(*this, *this); |
@@ -59,6 +60,13 @@ void Container::moveResize(int x, int y, | |||
59 | repositionItems(); | 60 | repositionItems(); |
60 | } | 61 | } |
61 | 62 | ||
63 | /* | ||
64 | void Container::move(int x, int y) { | ||
65 | FbTk::FbWindow::move(x, y); | ||
66 | // no need to reposition | ||
67 | } | ||
68 | */ | ||
69 | |||
62 | void Container::insertItems(ItemList &item_list, int pos) { | 70 | void Container::insertItems(ItemList &item_list, int pos) { |
63 | 71 | ||
64 | // make sure all items have parent == this | 72 | // make sure all items have parent == this |
@@ -255,6 +263,33 @@ void Container::setMaxSizePerClient(unsigned int size) { | |||
255 | m_max_size_per_client = size; | 263 | m_max_size_per_client = size; |
256 | } | 264 | } |
257 | 265 | ||
266 | void Container::setMaxTotalSize(unsigned int size) { | ||
267 | m_max_total_size = size; | ||
268 | |||
269 | if (m_max_total_size && width() > m_max_total_size) { | ||
270 | resize(m_max_total_size, height()); | ||
271 | } else { | ||
272 | // this is a bit of duplication from repositionItems | ||
273 | // for when we are allowed to grow ourself | ||
274 | Alignment align = alignment(); | ||
275 | unsigned int num_items = m_item_list.size(); | ||
276 | if (m_max_total_size && (align == RIGHT || align == LEFT) && | ||
277 | num_items) { | ||
278 | unsigned int max_width_per_client = maxWidthPerClient(); | ||
279 | unsigned int borderW = m_item_list.front()->borderWidth(); | ||
280 | |||
281 | unsigned int preferred_width = (max_width_per_client + borderW) * num_items - borderW; | ||
282 | |||
283 | if (preferred_width > m_max_total_size) | ||
284 | preferred_width = m_max_total_size; | ||
285 | |||
286 | if (preferred_width != width()) | ||
287 | repositionItems(); | ||
288 | } | ||
289 | |||
290 | } | ||
291 | } | ||
292 | |||
258 | void Container::setAlignment(Container::Alignment a) { | 293 | void Container::setAlignment(Container::Alignment a) { |
259 | m_align = a; | 294 | m_align = a; |
260 | } | 295 | } |
@@ -325,25 +360,48 @@ void Container::repositionItems() { | |||
325 | 360 | ||
326 | //!! TODO vertical position | 361 | //!! TODO vertical position |
327 | 362 | ||
328 | const int max_width_per_client = maxWidthPerClient(); | 363 | unsigned int max_width_per_client = maxWidthPerClient(); |
364 | unsigned int borderW = m_item_list.front()->borderWidth(); | ||
365 | unsigned int num_items = m_item_list.size(); | ||
366 | |||
367 | unsigned int total_width = width(); | ||
368 | |||
369 | // if we have a max total size, then we must also resize ourself | ||
370 | // within that bound | ||
371 | Alignment align = alignment(); | ||
372 | if (m_max_total_size && (align == RIGHT || align == LEFT)) { | ||
373 | total_width = (max_width_per_client + borderW) * num_items - borderW; | ||
374 | if (total_width > m_max_total_size) { | ||
375 | total_width = m_max_total_size; | ||
376 | if (m_max_total_size > ((num_items - 1)*borderW)) { // don't go negative with unsigned nums | ||
377 | max_width_per_client = ( m_max_total_size - (num_items - 1)*borderW ) / num_items; | ||
378 | total_width = (max_width_per_client + borderW) * num_items - borderW; | ||
379 | } else | ||
380 | max_width_per_client = 1; | ||
381 | } | ||
382 | if (total_width != width()) { | ||
383 | // calling Container::resize here risks infinite loops | ||
384 | FbTk::FbWindow::resize(total_width, height()); | ||
385 | } | ||
386 | } | ||
387 | |||
329 | 388 | ||
330 | ItemList::iterator it = m_item_list.begin(); | 389 | ItemList::iterator it = m_item_list.begin(); |
331 | const ItemList::iterator it_end = m_item_list.end(); | 390 | const ItemList::iterator it_end = m_item_list.end(); |
332 | int borderW = m_item_list.front()->borderWidth(); | ||
333 | 391 | ||
334 | int rounding_error = width() - ((maxWidthPerClient() + borderW)* m_item_list.size() - borderW); | 392 | int rounding_error = total_width - ((max_width_per_client + borderW)* num_items - borderW); |
335 | 393 | ||
336 | int next_x = -borderW; // zero so the border of the first shows | 394 | int next_x = -borderW; // zero so the border of the first shows |
337 | int extra = 0; | 395 | int extra = 0; |
338 | int direction = 1; | 396 | int direction = 1; |
339 | if (alignment() == RIGHT) { | 397 | if (align == RIGHT) { |
340 | direction = -1; | 398 | direction = -1; |
341 | next_x = width() - max_width_per_client + borderW; | 399 | next_x = total_width - max_width_per_client + borderW; |
342 | } | 400 | } |
343 | 401 | ||
344 | for (; it != it_end; ++it, next_x += direction*(max_width_per_client + borderW + extra)) { | 402 | for (; it != it_end; ++it, next_x += direction*(max_width_per_client + borderW + extra)) { |
345 | // we only need to do error stuff with alignment RELATIVE | 403 | // we only need to do error stuff with alignment RELATIVE |
346 | if (rounding_error != 0 && alignment() == RELATIVE) { | 404 | if (rounding_error != 0 && align == RELATIVE) { |
347 | --rounding_error; | 405 | --rounding_error; |
348 | extra = 1; | 406 | extra = 1; |
349 | } else { | 407 | } else { |
@@ -374,7 +432,11 @@ unsigned int Container::maxWidthPerClient() const { | |||
374 | int borderW = m_item_list.front()->borderWidth(); | 432 | int borderW = m_item_list.front()->borderWidth(); |
375 | // there're count-1 borders to fit in with the windows | 433 | // there're count-1 borders to fit in with the windows |
376 | // -> 1 per window plus end | 434 | // -> 1 per window plus end |
377 | return (width() - (count - 1) * borderW) / count; | 435 | unsigned int w = width(); |
436 | if (w < (count-1)*borderW) | ||
437 | return 1; | ||
438 | else | ||
439 | return (w - (count - 1) * borderW) / count; | ||
378 | } | 440 | } |
379 | break; | 441 | break; |
380 | } | 442 | } |