ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

ThemeLayout.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "common/util.h"
00024 #include "common/system.h"
00025 
00026 #include "gui/ThemeLayout.h"
00027 
00028 #include "graphics/font.h"
00029 
00030 #ifdef LAYOUT_DEBUG_DIALOG
00031 #include "graphics/surface.h"
00032 #endif
00033 
00034 namespace GUI {
00035 
00036 void ThemeLayout::importLayout(ThemeLayout *layout) {
00037     assert(layout->getLayoutType() == kLayoutMain);
00038 
00039     if (layout->_children.size() == 0)
00040         return;
00041 
00042     layout = layout->_children[0];
00043 
00044     if (getLayoutType() == layout->getLayoutType()) {
00045         for (uint i = 0; i < layout->_children.size(); ++i)
00046             _children.push_back(layout->_children[i]->makeClone(this));
00047     } else {
00048         _children.push_back(layout->makeClone(this));
00049     }
00050 }
00051 
00052 bool ThemeLayout::getWidgetData(const Common::String &name, int16 &x, int16 &y, uint16 &w, uint16 &h) {
00053     if (name.empty()) {
00054         assert(getLayoutType() == kLayoutMain);
00055         x = _x; y = _y;
00056         w = _w; h = _h;
00057         return true;
00058     }
00059 
00060     for (uint i = 0; i < _children.size(); ++i) {
00061         if (_children[i]->getWidgetData(name, x, y, w, h))
00062             return true;
00063     }
00064 
00065     return false;
00066 }
00067 
00068 Graphics::TextAlign ThemeLayout::getWidgetTextHAlign(const Common::String &name) {
00069     if (name.empty()) {
00070         assert(getLayoutType() == kLayoutMain);
00071         return _textHAlign;
00072     }
00073 
00074     Graphics::TextAlign res;
00075 
00076     for (uint i = 0; i < _children.size(); ++i) {
00077         if ((res = _children[i]->getWidgetTextHAlign(name)) != Graphics::kTextAlignInvalid)
00078             return res;
00079     }
00080 
00081     return Graphics::kTextAlignInvalid;
00082 }
00083 
00084 int16 ThemeLayoutStacked::getParentWidth() {
00085     ThemeLayout *p = _parent;
00086     int width = 0;
00087 
00088     while (p && p->getLayoutType() != kLayoutMain) {
00089         width += p->_padding.right + p->_padding.left;
00090         if (p->getLayoutType() == kLayoutHorizontal) {
00091             const int spacing = ((ThemeLayoutStacked *)p)->_spacing;
00092             for (uint i = 0; i < p->_children.size(); ++i)
00093                 width += p->_children[i]->getWidth() + spacing;
00094         }
00095         // FIXME: Do we really want to assume that any layout type different
00096         // from kLayoutHorizontal corresponds to width 0 ?
00097         p = p->_parent;
00098     }
00099 
00100     assert(p && p->getLayoutType() == kLayoutMain);
00101     return p->getWidth() - width;
00102 }
00103 
00104 int16 ThemeLayoutStacked::getParentHeight() {
00105     ThemeLayout *p = _parent;
00106     int height = 0;
00107 
00108     while (p && p->getLayoutType() != kLayoutMain) {
00109         height += p->_padding.bottom + p->_padding.top;
00110         if (p->getLayoutType() == kLayoutVertical) {
00111             const int spacing = ((ThemeLayoutStacked *)p)->_spacing;
00112             for (uint i = 0; i < p->_children.size(); ++i)
00113                 height += p->_children[i]->getHeight() + spacing;
00114         }
00115         // FIXME: Do we really want to assume that any layout type different
00116         // from kLayoutVertical corresponds to height 0 ?
00117         p = p->_parent;
00118     }
00119 
00120     assert(p && p->getLayoutType() == kLayoutMain);
00121     return p->getHeight() - height;
00122 }
00123 
00124 #ifdef LAYOUT_DEBUG_DIALOG
00125 void ThemeLayout::debugDraw(Graphics::Surface *screen, const Graphics::Font *font) {
00126     uint32 color = 0xFFFFFFFF;
00127     font->drawString(screen, getName(), _x, _y, _w, color, Graphics::kTextAlignRight, 0, true);
00128     screen->hLine(_x, _y, _x + _w, color);
00129     screen->hLine(_x, _y + _h, _x + _w , color);
00130     screen->vLine(_x, _y, _y + _h, color);
00131     screen->vLine(_x + _w, _y, _y + _h, color);
00132 
00133     for (uint i = 0; i < _children.size(); ++i)
00134         _children[i]->debugDraw(screen, font);
00135 }
00136 #endif
00137 
00138 
00139 bool ThemeLayoutWidget::getWidgetData(const Common::String &name, int16 &x, int16 &y, uint16 &w, uint16 &h) {
00140     if (name == _name) {
00141         x = _x; y = _y;
00142         w = _w; h = _h;
00143         return true;
00144     }
00145 
00146     return false;
00147 }
00148 
00149 Graphics::TextAlign ThemeLayoutWidget::getWidgetTextHAlign(const Common::String &name) {
00150     if (name == _name) {
00151         return _textHAlign;
00152     }
00153 
00154     return Graphics::kTextAlignInvalid;
00155 }
00156 
00157 void ThemeLayoutMain::reflowLayout() {
00158     assert(_children.size() <= 1);
00159 
00160     if (_children.size()) {
00161         _children[0]->resetLayout();
00162         _children[0]->setWidth(_w);
00163         _children[0]->setHeight(_h);
00164         _children[0]->reflowLayout();
00165 
00166         if (_w == -1)
00167             _w = _children[0]->getWidth();
00168 
00169         if (_h == -1)
00170             _h = _children[0]->getHeight();
00171 
00172         if (_y == -1)
00173             _y = (g_system->getOverlayHeight() >> 1) - (_h >> 1);
00174 
00175         if (_x == -1)
00176             _x = (g_system->getOverlayWidth() >> 1) - (_w >> 1);
00177     }
00178 }
00179 
00180 void ThemeLayoutStacked::reflowLayoutVertical() {
00181     int curX, curY;
00182     int resize[8];
00183     int rescount = 0;
00184 
00185     curX = _padding.left;
00186     curY = _padding.top;
00187     _h = _padding.top + _padding.bottom;
00188 
00189     for (uint i = 0; i < _children.size(); ++i) {
00190 
00191         _children[i]->resetLayout();
00192         _children[i]->reflowLayout();
00193 
00194         if (_children[i]->getWidth() == -1)
00195             _children[i]->setWidth((_w == -1 ? getParentWidth() : _w) - _padding.left - _padding.right);
00196 
00197         if (_children[i]->getHeight() == -1) {
00198             assert(rescount < ARRAYSIZE(resize));
00199             resize[rescount++] = i;
00200             _children[i]->setHeight(0);
00201         }
00202 
00203         _children[i]->offsetY(curY);
00204 
00205         // Center child if it this has been requested *and* the space permits it.
00206         if (_centered && _children[i]->getWidth() < _w && _w != -1) {
00207             _children[i]->offsetX((_w >> 1) - (_children[i]->getWidth() >> 1));
00208         } else
00209             _children[i]->offsetX(curX);
00210 
00211         // Advance the vertical offset by the height of the newest item, plus
00212         // the item spacing value.
00213         curY += _children[i]->getHeight() + _spacing;
00214 
00215         // Update width and height of this stack layout
00216         _w = MAX(_w, (int16)(_children[i]->getWidth() + _padding.left + _padding.right));
00217         _h += _children[i]->getHeight() + _spacing;
00218     }
00219 
00220     // If there are any children at all, then we added the spacing value once
00221     // too often. Correct that.
00222     if (!_children.empty())
00223         _h -= _spacing;
00224 
00225     // If there were any items with undetermined height, then compute and set
00226     // their height now. We do so by determining how much space is left, and
00227     // then distributing this equally over all items which need auto-resizing.
00228     if (rescount) {
00229         int newh = (getParentHeight() - _h - _padding.bottom) / rescount;
00230 
00231         for (int i = 0; i < rescount; ++i) {
00232             // Set the height of the item.
00233             _children[resize[i]]->setHeight(newh);
00234             // Increase the height of this ThemeLayoutStacked accordingly, and
00235             // then shift all subsequence children.
00236             _h += newh;
00237             for (uint j = resize[i] + 1; j < _children.size(); ++j)
00238                 _children[j]->offsetY(newh);
00239         }
00240     }
00241 }
00242 
00243 void ThemeLayoutStacked::reflowLayoutHorizontal() {
00244     int curX, curY;
00245     int resize[8];
00246     int rescount = 0;
00247 
00248     curX = _padding.left;
00249     curY = _padding.top;
00250     _w = _padding.left + _padding.right;
00251 
00252     for (uint i = 0; i < _children.size(); ++i) {
00253 
00254         _children[i]->resetLayout();
00255         _children[i]->reflowLayout();
00256 
00257         if (_children[i]->getHeight() == -1)
00258             _children[i]->setHeight((_h == -1 ? getParentHeight() : _h) - _padding.top - _padding.bottom);
00259 
00260         if (_children[i]->getWidth() == -1) {
00261             assert(rescount < ARRAYSIZE(resize));
00262             resize[rescount++] = i;
00263             _children[i]->setWidth(0);
00264         }
00265 
00266         _children[i]->offsetX(curX);
00267 
00268         // Center child if it this has been requested *and* the space permits it.
00269         if (_centered && _children[i]->getHeight() < _h && _h != -1)
00270             _children[i]->offsetY((_h >> 1) - (_children[i]->getHeight() >> 1));
00271         else
00272             _children[i]->offsetY(curY);
00273 
00274         // Advance the horizontal offset by the width of the newest item, plus
00275         // the item spacing value.
00276         curX += (_children[i]->getWidth() + _spacing);
00277 
00278         // Update width and height of this stack layout
00279         _w += _children[i]->getWidth() + _spacing;
00280         _h = MAX(_h, (int16)(_children[i]->getHeight() + _padding.top + _padding.bottom));
00281     }
00282 
00283     // If there are any children at all, then we added the spacing value once
00284     // too often. Correct that.
00285     if (!_children.empty())
00286         _w -= _spacing;
00287 
00288     // If there were any items with undetermined width, then compute and set
00289     // their width now. We do so by determining how much space is left, and
00290     // then distributing this equally over all items which need auto-resizing.
00291     if (rescount) {
00292         int neww = (getParentWidth() - _w - _padding.right) / rescount;
00293 
00294         for (int i = 0; i < rescount; ++i) {
00295             // Set the width of the item.
00296             _children[resize[i]]->setWidth(neww);
00297             // Increase the width of this ThemeLayoutStacked accordingly, and
00298             // then shift all subsequence children.
00299             _w += neww;
00300             for (uint j = resize[i] + 1; j < _children.size(); ++j)
00301                 _children[j]->offsetX(neww);
00302         }
00303     }
00304 }
00305 
00306 } // End of namespace GUI


Generated on Sat May 18 2019 05:01:27 for ResidualVM by doxygen 1.7.1
curved edge   curved edge