diff options
author | Guillaume Melquiond <guillaume.melquiond@gmail.com> | 2007-10-20 11:29:18 +0000 |
---|---|---|
committer | Guillaume Melquiond <guillaume.melquiond@gmail.com> | 2007-10-20 11:29:18 +0000 |
commit | 59472ef68fdef3f7e8858a81a46e28c127119c58 (patch) | |
tree | 75b5f5e658fa1b05487463f0449440524ed76256 /src/gui/widgets/layout.cpp | |
parent | 41cf359468d6379bc0e033bee9ac148d1b9255dd (diff) | |
download | mana-client-59472ef68fdef3f7e8858a81a46e28c127119c58.tar.gz mana-client-59472ef68fdef3f7e8858a81a46e28c127119c58.tar.bz2 mana-client-59472ef68fdef3f7e8858a81a46e28c127119c58.tar.xz mana-client-59472ef68fdef3f7e8858a81a46e28c127119c58.zip |
Added a layout handler for automatically positioning widgets in a window. Fixed layout of login dialog box when native language is not English.
Diffstat (limited to 'src/gui/widgets/layout.cpp')
-rw-r--r-- | src/gui/widgets/layout.cpp | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/src/gui/widgets/layout.cpp b/src/gui/widgets/layout.cpp new file mode 100644 index 00000000..8a64acc0 --- /dev/null +++ b/src/gui/widgets/layout.cpp @@ -0,0 +1,159 @@ +/* + * The Mana World + * Copyright 2007 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * The Mana World is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#include "layout.h" + +void Layout::resizeGrid(int w, int h) +{ + bool extW = w && w > (int)mColWidths.size(), + extH = h && h > (int)mRowHeights.size(); + if (!extW && !extH) return; + + if (extH) + { + mRowHeights.resize(h, -1); + mCells.resize(h); + if (!extW) w = (int)mColWidths.size(); + } + + mColWidths.resize(w, -1); + for (std::vector< std::vector< Cell > >::iterator + i = mCells.begin(), i_end = mCells.end(); i != i_end; ++i) + { + i->resize(w); + } +} + +void Layout::setColWidth(int n, int w) +{ + resizeGrid(n + 1, 0); + mColWidths[n] = w; +} + +void Layout::setRowHeight(int n, int h) +{ + resizeGrid(0, n + 1); + mRowHeights[n] = h; +} + +Cell &Layout::place(gcn::Widget *widget, int x, int y, int w, int h) +{ + resizeGrid(x + w, y + h); + Cell &cell = mCells[y][x]; + cell.mWidget = widget; + cell.mColExtent = w; + cell.mRowExtent = h; + cell.mPadding = 0; + cell.mHAlign = Cell::FILL; + cell.mVAlign = Cell::FILL; + return cell; +} + +static void align(int &pos, int &cur, int upp, Cell::Alignment a) +{ + cur = std::min(cur, upp); + switch (a) + { + case Cell::LEFT: + return; + case Cell::RIGHT: + pos += upp - cur; + return; + case Cell::CENTER: + pos += (upp - cur) / 2; + return; + case Cell::FILL: + cur = upp; + return; + } +} + +void Layout::reflow() +{ + int gridW = mColWidths.size(), gridH = mRowHeights.size(); + + std::vector< int > widths(gridW, 0); + std::vector< int > heights(gridH, 0); + + for (int gridY = 0; gridY < gridH; ++gridY) + { + for (int gridX = 0; gridX < gridW; ++gridX) + { + Cell &cell = mCells[gridY][gridX]; + if (!cell.mWidget) continue; + + if (cell.mColExtent == 1) + { + int w = cell.mWidget->getWidth() + cell.mPadding * 2; + if (w > widths[gridX]) widths[gridX] = w; + } + + if (cell.mRowExtent == 1) + { + int h = cell.mWidget->getHeight() + cell.mPadding * 2; + if (h > heights[gridY]) heights[gridY] = h; + } + } + } + + for (int gridX = 0; gridX < gridW; ++gridX) + { + int w = mColWidths[gridX]; + if (w != -1) widths[gridX] = w; + } + + for (int gridY = 0; gridY < gridH; ++gridY) + { + int h = mRowHeights[gridY]; + if (h != -1) heights[gridY] = h; + } + + int y = 0; + for (int gridY = 0; gridY < gridH; ++gridY) + { + int h = heights[gridY]; + int x = 0; + for (int gridX = 0; gridX < gridW; ++gridX) + { + int w = widths[gridX]; + Cell &cell = mCells[gridY][gridX]; + if (cell.mWidget) + { + int ew = w - cell.mPadding * 2, + eh = h - cell.mPadding * 2; + for (int i = 1; i < cell.mColExtent; ++i) + ew += widths[gridX + i] + mPadding; + for (int i = 1; i < cell.mRowExtent; ++i) + eh += heights[gridY + i] + mPadding; + int dw = cell.mWidget->getWidth(), + dh = cell.mWidget->getHeight(); + int dx = x + cell.mPadding, dy = y + cell.mPadding; + align(dx, dw, ew, cell.mHAlign); + align(dy, dh, eh, cell.mVAlign); + cell.mWidget->setDimension(gcn::Rectangle(dx, dy, dw, dh)); + } + x += w + mPadding; + } + y += h + mPadding; + } +} |