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     bool fixedWidth = _w != -1;
00185 
00186     curX = _padding.left;
00187     curY = _padding.top;
00188     _h = _padding.top + _padding.bottom;
00189 
00190     for (uint i = 0; i < _children.size(); ++i) {
00191 
00192         _children[i]->resetLayout();
00193         _children[i]->reflowLayout();
00194 
00195         if (_children[i]->getWidth() == -1)
00196             _children[i]->setWidth((_w == -1 ? getParentWidth() : _w) - _padding.left - _padding.right);
00197 
00198         if (_children[i]->getHeight() == -1) {
00199             assert(rescount < ARRAYSIZE(resize));
00200             resize[rescount++] = i;
00201             _children[i]->setHeight(0);
00202         }
00203 
00204         _children[i]->offsetY(curY);
00205 
00206         // Center child if it this has been requested *and* the space permits it.
00207         if (_centered && _children[i]->getWidth() < (_w - _padding.left - _padding.right) && _w != -1) {
00208             _children[i]->offsetX((_w >> 1) - (_children[i]->getWidth() >> 1));
00209         } else
00210             _children[i]->offsetX(curX);
00211 
00212         // Advance the vertical offset by the height of the newest item, plus
00213         // the item spacing value.
00214         curY += _children[i]->getHeight() + _spacing;
00215 
00216         // Update width and height of this stack layout
00217         if (!fixedWidth) {
00218             _w = MAX(_w, (int16)(_children[i]->getWidth() + _padding.left + _padding.right));
00219         }
00220         _h += _children[i]->getHeight() + _spacing;
00221     }
00222 
00223     // If there are any children at all, then we added the spacing value once
00224     // too often. Correct that.
00225     if (!_children.empty())
00226         _h -= _spacing;
00227 
00228     // If there were any items with undetermined height, then compute and set
00229     // their height now. We do so by determining how much space is left, and
00230     // then distributing this equally over all items which need auto-resizing.
00231     if (rescount) {
00232         int newh = (getParentHeight() - _h - _padding.bottom) / rescount;
00233 
00234         for (int i = 0; i < rescount; ++i) {
00235             // Set the height of the item.
00236             _children[resize[i]]->setHeight(newh);
00237             // Increase the height of this ThemeLayoutStacked accordingly, and
00238             // then shift all subsequence children.
00239             _h += newh;
00240             for (uint j = resize[i] + 1; j < _children.size(); ++j)
00241                 _children[j]->offsetY(newh);
00242         }
00243     }
00244 }
00245 
00246 void ThemeLayoutStacked::reflowLayoutHorizontal() {
00247     int curX, curY;
00248     int resize[8];
00249     int rescount = 0;
00250     bool fixedHeight = _h != -1;
00251 
00252     curX = _padding.left;
00253     curY = _padding.top;
00254     _w = _padding.left + _padding.right;
00255 
00256     for (uint i = 0; i < _children.size(); ++i) {
00257 
00258         _children[i]->resetLayout();
00259         _children[i]->reflowLayout();
00260 
00261         if (_children[i]->getHeight() == -1)
00262             _children[i]->setHeight((_h == -1 ? getParentHeight() : _h) - _padding.top - _padding.bottom);
00263 
00264         if (_children[i]->getWidth() == -1) {
00265             assert(rescount < ARRAYSIZE(resize));
00266             resize[rescount++] = i;
00267             _children[i]->setWidth(0);
00268         }
00269 
00270         _children[i]->offsetX(curX);
00271 
00272         // Center child if it this has been requested *and* the space permits it.
00273         if (_centered && _children[i]->getHeight() < (_h - _padding.top - _padding.bottom) && _h != -1)
00274             _children[i]->offsetY((_h >> 1) - (_children[i]->getHeight() >> 1));
00275         else
00276             _children[i]->offsetY(curY);
00277 
00278         // Advance the horizontal offset by the width of the newest item, plus
00279         // the item spacing value.
00280         curX += (_children[i]->getWidth() + _spacing);
00281 
00282         // Update width and height of this stack layout
00283         _w += _children[i]->getWidth() + _spacing;
00284         if (!fixedHeight) {
00285             _h = MAX(_h, (int16)(_children[i]->getHeight() + _padding.top + _padding.bottom));
00286         }
00287     }
00288 
00289     // If there are any children at all, then we added the spacing value once
00290     // too often. Correct that.
00291     if (!_children.empty())
00292         _w -= _spacing;
00293 
00294     // If there were any items with undetermined width, then compute and set
00295     // their width now. We do so by determining how much space is left, and
00296     // then distributing this equally over all items which need auto-resizing.
00297     if (rescount) {
00298         int neww = (getParentWidth() - _w - _padding.right) / rescount;
00299 
00300         for (int i = 0; i < rescount; ++i) {
00301             // Set the width of the item.
00302             _children[resize[i]]->setWidth(neww);
00303             // Increase the width of this ThemeLayoutStacked accordingly, and
00304             // then shift all subsequence children.
00305             _w += neww;
00306             for (uint j = resize[i] + 1; j < _children.size(); ++j)
00307                 _children[j]->offsetX(neww);
00308         }
00309     }
00310 }
00311 
00312 } // End of namespace GUI


Generated on Sat Dec 14 2019 05:00:51 for ResidualVM by doxygen 1.7.1
curved edge   curved edge