cascadelayout.cpp

Go to the documentation of this file.
00001 /*
00002   libwt - Vassilis Virvilis Toolkit - a widget library
00003   Copyright (C) 2006 Vassilis Virvilis <vasvir2@fastmail.fm>
00004  
00005   This library is free software; you can redistribute it and/or
00006   modify it under the terms of the GNU Lesser General Public
00007   License as published by the Free Software Foundation; either
00008   version 2.1 of the License, or (at your option) any later version.
00009   
00010   This library is distributed in the hope that it will be useful,
00011   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013   Lesser General Public License for more details.
00014   
00015   You should have received a copy of the GNU Lesser General Public
00016   License along with this library; if not, write to the
00017   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018   Boston, MA  02111-1307, SA.
00019 */
00020 
00021 #include <wt/cascadelayout.h>
00022 #include <wt/widget.h>
00023 
00024 namespace Wt {
00025 
00026 void CascadeLayout::init() {
00027     sigc::slot<void> slot = sigc::mem_fun(*this,
00028                                           &CascadeLayout::postLayoutHintEvent);
00029     alignment.changed.connect(slot);
00030     horizontalAdvance.changed.connect(slot);
00031     verticalAdvance.changed.connect(slot);
00032 }
00033 
00034 void CascadeLayout::validate() {
00035     int hint_w = 0, hint_h = 0;
00036     int min_w = 0, min_h = 0;
00037     int count = 0;
00038     const int dx = abs(static_cast<int>(horizontalAdvance));
00039     const int dy = abs(static_cast<int>(verticalAdvance));
00040 
00041     trace("cascadelayout") << this << " CascadeLayout::validate()" << std::endl;
00042 
00043     CascadeLayoutIterator it(*this);
00044     for (it.start(), count = 0; !it.finish(); it++, count++) {
00045         LayoutItem *li = *it;
00046         if (!li->isEmpty()) {
00047             min_w = std::max(min_w, count * dx + li->minimumSize().width());
00048             min_h = std::max(min_h, count * dy + li->minimumSize().height());
00049             hint_w = std::max(hint_w, count * dx + li->sizeHint().width());
00050             hint_h = std::max(hint_h, count * dy + li->sizeHint().height());
00051         }
00052     }
00053 
00054     setSizeHint(Size(hint_w, hint_h));
00055     setMinimumSize(Size(min_w, min_h));
00056 
00057     Layout::validate();
00058 }
00059 
00060 static int preferredWidth(const LayoutItem *li, bool expand) {
00061     return (expand) ? li->sizeHint().width() : li->minimumSize().width();
00062 }
00063 
00064 static int preferredHeight(const LayoutItem *li, bool expand) {
00065     return (expand) ? li->sizeHint().height() : li->minimumSize().height();
00066 }
00067 
00068 void CascadeLayout::setGeometry(const Rect& r) {
00069     CascadeLayoutIterator it(*this);
00070     trace("cascadelayout") << this << " CascadeLayout::setGeometry()" << std::endl;
00071 
00072     // store geometry first
00073     Layout::setGeometry(r);
00074     // if smaller than the minSize it is possible that
00075     // we have to reackuire the size to perform the layout
00076     Rect rect = LayoutItem::geometry() >> margin;
00077 
00078     bool expand_w = (rect.width() >= sizeHint().width());
00079     bool expand_h = (rect.height() >= sizeHint().height());
00080 
00081     rect = Rect::align(rect, Size(preferredWidth(this, expand_w),
00082                                   preferredHeight(this, expand_h)), alignment);
00083 
00084     trace("cascadelayout",
00085           "Expanding horizontally %d vertically %d\n", expand_w, expand_h);
00086     trace("cascadelayout",
00087           "rect.width() = %d sizeHint().width() = %d\n",
00088           rect.width(), sizeHint().width());
00089     trace("cascadelayout",
00090           "rect.height() = %d sizeHint().height() = %d\n",
00091           rect.height(), sizeHint().height());
00092 
00093     const int horizontal_advance = horizontalAdvance;
00094     const int vertical_advance = verticalAdvance;
00095     int covered_x = (horizontal_advance >= 0) ? rect.left() : rect.right() + 1;
00096     int covered_y = (vertical_advance >= 0) ? rect.top() : rect.bottom() + 1;
00097     for (it.start(); !it.finish(); it++) {
00098         LayoutItem *li = *it;
00099 
00100         if (li->isEmpty())
00101             continue;
00102 
00103         int size_w = preferredWidth(li, expand_w);
00104         int offset_x = (horizontal_advance >= 0) ?
00105                        covered_x : covered_x - size_w;
00106         int size_h = preferredHeight(li, expand_h);
00107         int offset_y = (vertical_advance >= 0) ?
00108                        covered_y : covered_y - size_h;
00109 
00110         trace("cascadelayout", "Placing %p at [%d, %d] with [%d x %d]\n",
00111               li, offset_x, offset_y, size_w, size_h);
00112         li->setGeometry(Rect(mainWidget()->mapFromParent(
00113                                  Point(offset_x, offset_y)),
00114                              Size(size_w, size_h)));
00115 
00116         covered_x += horizontal_advance;
00117         covered_y += vertical_advance;
00118     }
00119 }
00120 
00121 } // namespace

Generated Fri Jul 28 19:22:59 2006.
Copyright © 1998-2003 by the respective authors.

This document is licensed under the terms of the GNU Free Documentation License and may be freely distributed under the conditions given by this license.