1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef THEME_LAYOUT_H 24 #define THEME_LAYOUT_H 25 26 #include "common/array.h" 27 #include "common/rect.h" 28 #include "graphics/font.h" 29 30 #ifdef LAYOUT_DEBUG_DIALOG 31 namespace Graphics { 32 struct Surface; 33 } 34 #endif 35 36 namespace GUI { 37 38 class ThemeLayout { 39 friend class ThemeLayoutMain; 40 friend class ThemeLayoutStacked; 41 friend class ThemeLayoutSpacing; 42 friend class ThemeLayoutWidget; 43 public: 44 enum LayoutType { 45 kLayoutMain, 46 kLayoutVertical, 47 kLayoutHorizontal, 48 kLayoutWidget, 49 kLayoutTabWidget 50 }; 51 ThemeLayout(ThemeLayout * p)52 ThemeLayout(ThemeLayout *p) : 53 _parent(p), _x(0), _y(0), _w(-1), _h(-1), 54 _centered(false), _defaultW(-1), _defaultH(-1), 55 _textHAlign(Graphics::kTextAlignInvalid) {} 56 ~ThemeLayout()57 virtual ~ThemeLayout() { 58 for (uint i = 0; i < _children.size(); ++i) 59 delete _children[i]; 60 } 61 62 virtual void reflowLayout() = 0; 63 resetLayout()64 virtual void resetLayout() { _x = 0; _y = 0; _w = _defaultW; _h = _defaultH; } 65 addChild(ThemeLayout * child)66 void addChild(ThemeLayout *child) { _children.push_back(child); } 67 setPadding(int8 left,int8 right,int8 top,int8 bottom)68 void setPadding(int8 left, int8 right, int8 top, int8 bottom) { 69 _padding.left = left; 70 _padding.right = right; 71 _padding.top = top; 72 _padding.bottom = bottom; 73 } 74 75 protected: getWidth()76 int16 getWidth() { return _w; } getHeight()77 int16 getHeight() { return _h; } 78 offsetX(int newX)79 void offsetX(int newX) { 80 _x += newX; 81 for (uint i = 0; i < _children.size(); ++i) 82 _children[i]->offsetX(newX); 83 } 84 offsetY(int newY)85 void offsetY(int newY) { 86 _y += newY; 87 for (uint i = 0; i < _children.size(); ++i) 88 _children[i]->offsetY(newY); 89 } 90 setWidth(int16 width)91 void setWidth(int16 width) { _w = width; } setHeight(int16 height)92 void setHeight(int16 height) { _h = height; } setTextHAlign(Graphics::TextAlign align)93 void setTextHAlign(Graphics::TextAlign align) { _textHAlign = align; } 94 95 virtual LayoutType getLayoutType() = 0; 96 97 virtual ThemeLayout *makeClone(ThemeLayout *newParent) = 0; 98 99 public: 100 virtual bool getWidgetData(const Common::String &name, int16 &x, int16 &y, uint16 &w, uint16 &h); 101 102 virtual Graphics::TextAlign getWidgetTextHAlign(const Common::String &name); 103 104 void importLayout(ThemeLayout *layout); 105 getTextHAlign()106 Graphics::TextAlign getTextHAlign() { return _textHAlign; } 107 108 #ifdef LAYOUT_DEBUG_DIALOG 109 void debugDraw(Graphics::Surface *screen, const Graphics::Font *font); 110 111 virtual const char *getName() const = 0; 112 #endif 113 114 protected: 115 ThemeLayout *_parent; 116 int16 _x, _y, _w, _h; 117 Common::Rect _padding; 118 Common::Array<ThemeLayout *> _children; 119 bool _centered; 120 int16 _defaultW, _defaultH; 121 Graphics::TextAlign _textHAlign; 122 }; 123 124 class ThemeLayoutMain : public ThemeLayout { 125 public: ThemeLayoutMain(int16 x,int16 y,int16 w,int16 h)126 ThemeLayoutMain(int16 x, int16 y, int16 w, int16 h) : ThemeLayout(0) { 127 _w = _defaultW = w; 128 _h = _defaultH = h; 129 _x = _defaultX = x; 130 _y = _defaultY = y; 131 } 132 void reflowLayout(); 133 resetLayout()134 void resetLayout() { 135 ThemeLayout::resetLayout(); 136 _x = _defaultX; 137 _y = _defaultY; 138 } 139 140 #ifdef LAYOUT_DEBUG_DIALOG getName()141 const char *getName() const { return "Global Layout"; } 142 #endif 143 144 protected: getLayoutType()145 LayoutType getLayoutType() { return kLayoutMain; } makeClone(ThemeLayout * newParent)146 ThemeLayout *makeClone(ThemeLayout *newParent) { assert(!"Do not copy Main Layouts!"); return 0; } 147 148 int16 _defaultX; 149 int16 _defaultY; 150 }; 151 152 class ThemeLayoutStacked : public ThemeLayout { 153 public: ThemeLayoutStacked(ThemeLayout * p,LayoutType type,int spacing,bool center)154 ThemeLayoutStacked(ThemeLayout *p, LayoutType type, int spacing, bool center) : 155 ThemeLayout(p), _type(type) { 156 assert((type == kLayoutVertical) || (type == kLayoutHorizontal)); 157 _spacing = spacing; 158 _centered = center; 159 } 160 reflowLayout()161 void reflowLayout() { 162 if (_type == kLayoutVertical) 163 reflowLayoutVertical(); 164 else 165 reflowLayoutHorizontal(); 166 } 167 void reflowLayoutHorizontal(); 168 void reflowLayoutVertical(); 169 170 #ifdef LAYOUT_DEBUG_DIALOG getName()171 const char *getName() const { 172 return (_type == kLayoutVertical) 173 ? "Vertical Layout" : "Horizontal Layout"; 174 } 175 #endif 176 177 protected: 178 int16 getParentWidth(); 179 int16 getParentHeight(); 180 getLayoutType()181 LayoutType getLayoutType() { return _type; } 182 makeClone(ThemeLayout * newParent)183 ThemeLayout *makeClone(ThemeLayout *newParent) { 184 ThemeLayoutStacked *n = new ThemeLayoutStacked(*this); 185 n->_parent = newParent; 186 187 for (uint i = 0; i < n->_children.size(); ++i) 188 n->_children[i] = n->_children[i]->makeClone(n); 189 190 return n; 191 } 192 193 const LayoutType _type; 194 int8 _spacing; 195 }; 196 197 class ThemeLayoutWidget : public ThemeLayout { 198 public: ThemeLayoutWidget(ThemeLayout * p,const Common::String & name,int16 w,int16 h,Graphics::TextAlign align)199 ThemeLayoutWidget(ThemeLayout *p, const Common::String &name, int16 w, int16 h, Graphics::TextAlign align) : ThemeLayout(p), _name(name) { 200 _w = _defaultW = w; 201 _h = _defaultH = h; 202 203 setTextHAlign(align); 204 } 205 206 bool getWidgetData(const Common::String &name, int16 &x, int16 &y, uint16 &w, uint16 &h); 207 Graphics::TextAlign getWidgetTextHAlign(const Common::String &name); 208 reflowLayout()209 void reflowLayout() {} 210 211 #ifdef LAYOUT_DEBUG_DIALOG getName()212 virtual const char *getName() const { return _name.c_str(); } 213 #endif 214 215 protected: getLayoutType()216 LayoutType getLayoutType() { return kLayoutWidget; } 217 makeClone(ThemeLayout * newParent)218 ThemeLayout *makeClone(ThemeLayout *newParent) { 219 ThemeLayout *n = new ThemeLayoutWidget(*this); 220 n->_parent = newParent; 221 return n; 222 } 223 224 Common::String _name; 225 }; 226 227 class ThemeLayoutTabWidget : public ThemeLayoutWidget { 228 int _tabHeight; 229 230 public: ThemeLayoutTabWidget(ThemeLayout * p,const Common::String & name,int16 w,int16 h,Graphics::TextAlign align,int tabHeight)231 ThemeLayoutTabWidget(ThemeLayout *p, const Common::String &name, int16 w, int16 h, Graphics::TextAlign align, int tabHeight): 232 ThemeLayoutWidget(p, name, w, h, align) { 233 _tabHeight = tabHeight; 234 } 235 reflowLayout()236 void reflowLayout() { 237 for (uint i = 0; i < _children.size(); ++i) { 238 _children[i]->resetLayout(); 239 _children[i]->reflowLayout(); 240 } 241 } 242 getWidgetData(const Common::String & name,int16 & x,int16 & y,uint16 & w,uint16 & h)243 virtual bool getWidgetData(const Common::String &name, int16 &x, int16 &y, uint16 &w, uint16 &h) { 244 if (ThemeLayoutWidget::getWidgetData(name, x, y, w, h)) { 245 h -= _tabHeight; 246 return true; 247 } 248 249 return false; 250 } 251 252 protected: getLayoutType()253 LayoutType getLayoutType() { return kLayoutTabWidget; } 254 makeClone(ThemeLayout * newParent)255 ThemeLayout *makeClone(ThemeLayout *newParent) { 256 ThemeLayoutTabWidget *n = new ThemeLayoutTabWidget(*this); 257 n->_parent = newParent; 258 return n; 259 } 260 }; 261 262 class ThemeLayoutSpacing : public ThemeLayout { 263 public: ThemeLayoutSpacing(ThemeLayout * p,int size)264 ThemeLayoutSpacing(ThemeLayout *p, int size) : ThemeLayout(p) { 265 if (p->getLayoutType() == kLayoutHorizontal) { 266 _w = _defaultW = size; 267 _h = _defaultH = 1; 268 } else if (p->getLayoutType() == kLayoutVertical) { 269 _w = _defaultW = 1; 270 _h = _defaultH = size; 271 } 272 } 273 getWidgetData(const Common::String & name,int16 & x,int16 & y,uint16 & w,uint16 & h)274 bool getWidgetData(const Common::String &name, int16 &x, int16 &y, uint16 &w, uint16 &h) { return false; } reflowLayout()275 void reflowLayout() {} 276 #ifdef LAYOUT_DEBUG_DIALOG getName()277 const char *getName() const { return "SPACE"; } 278 #endif 279 280 protected: getLayoutType()281 LayoutType getLayoutType() { return kLayoutWidget; } 282 makeClone(ThemeLayout * newParent)283 ThemeLayout *makeClone(ThemeLayout *newParent) { 284 ThemeLayout *n = new ThemeLayoutSpacing(*this); 285 n->_parent = newParent; 286 return n; 287 } 288 }; 289 290 } 291 292 #endif 293