Browser dialog.

Improved layout expansion in the layout parser.
Fixed serious coordinates initialization bug.

svn-id: r33702
This commit is contained in:
Vicent Marti 2008-08-08 15:06:28 +00:00
parent 1ea3301a8a
commit 3ca6f76f7b
7 changed files with 127 additions and 42 deletions

View file

@ -499,7 +499,17 @@ void ListWidget::reflowLayout() {
_scrollBarWidth = kNormalScrollBarWidth; _scrollBarWidth = kNormalScrollBarWidth;
} }
_entriesPerPage = (_h - _topPadding - _bottomPadding) / kLineHeight; // HACK: Once we take padding into account, there are times where
// integer rounding leaves a big chunk of white space in the bottom
// of the list.
// We do a rough rounding on the decimal places of Entries Per Page,
// to add another entry even if it goes a tad over the padding.
_entriesPerPage = ((_h - _topPadding - _bottomPadding) << 16) / kLineHeight;
if ((uint)(_entriesPerPage & 0xFFFF) >= 0xF000)
_entriesPerPage += (1 << 16);
_entriesPerPage >>= 16;
delete[] _textWidth; delete[] _textWidth;
_textWidth = new int[_entriesPerPage]; _textWidth = new int[_entriesPerPage];

View file

@ -65,6 +65,9 @@ void ThemeLayoutMain::reflowLayout() {
_children[0]->setHeight(_h); _children[0]->setHeight(_h);
_children[0]->reflowLayout(); _children[0]->reflowLayout();
// _children[0]->setX(_x);
// _children[0]->setY(_y);
if (_w == -1) if (_w == -1)
_w = _children[0]->getWidth(); _w = _children[0]->getWidth();
@ -81,25 +84,27 @@ void ThemeLayoutMain::reflowLayout() {
void ThemeLayoutVertical::reflowLayout() { void ThemeLayoutVertical::reflowLayout() {
int curX, curY; int curX, curY;
int autoWidget = -1;
curX = _paddingLeft; curX = _paddingLeft;
curY = _paddingTop; curY = _paddingTop;
_h = _paddingTop + _paddingBottom; _h = _paddingTop + _paddingBottom;
for (uint i = 0; i < _children.size(); ++i) { for (uint i = 0; i < _children.size(); ++i) {
assert(_children[i]->getLayoutType() != kLayoutVertical);
_children[i]->resetLayout(); _children[i]->resetLayout();
_children[i]->reflowLayout(); _children[i]->reflowLayout();
if (i != _children.size() - 1)
assert(_children[i]->getHeight() != -1);
if (_children[i]->getWidth() == -1) if (_children[i]->getWidth() == -1)
_children[i]->setWidth((_w == -1 ? getParentW() : _w) - _paddingLeft - _paddingRight); _children[i]->setWidth((_w == -1 ? getParentW() : _w) - _paddingLeft - _paddingRight);
if (_children[i]->getHeight() == -1) if (_children[i]->getHeight() == -1) {
if (autoWidget != -1)
error("Cannot expand automatically two different widgets.");
autoWidget = i;
_children[i]->setHeight(getParentH() - _h - _spacing); _children[i]->setHeight(getParentH() - _h - _spacing);
}
_children[i]->setY(curY); _children[i]->setY(curY);
@ -116,31 +121,40 @@ void ThemeLayoutVertical::reflowLayout() {
} }
_w = MAX(_w, (int16)(_children[i]->getWidth() + _paddingLeft + _paddingRight)); _w = MAX(_w, (int16)(_children[i]->getWidth() + _paddingLeft + _paddingRight));
if (autoWidget != -1 && autoWidget != (int)i) {
_children[autoWidget]->setHeight(_children[autoWidget]->getHeight() - (_children[i]->getHeight() + _spacing));
for (int j = autoWidget - 1; j >= 0; --j)
_children[j]->setY(-(_children[i]->getHeight() + _spacing));
} else {
_h += _children[i]->getHeight() + _spacing; _h += _children[i]->getHeight() + _spacing;
} }
}
} }
void ThemeLayoutHorizontal::reflowLayout() { void ThemeLayoutHorizontal::reflowLayout() {
int curX, curY; int curX, curY;
int autoWidget = -1;
curX = _paddingLeft; curX = _paddingLeft;
curY = _paddingTop; curY = _paddingTop;
_w = _paddingLeft + _paddingRight; _w = _paddingLeft + _paddingRight;
for (uint i = 0; i < _children.size(); ++i) { for (uint i = 0; i < _children.size(); ++i) {
assert(_children[i]->getLayoutType() != kLayoutHorizontal);
_children[i]->resetLayout(); _children[i]->resetLayout();
_children[i]->reflowLayout(); _children[i]->reflowLayout();
if (i != _children.size() - 1)
assert(_children[i]->getWidth() != -1);
if (_children[i]->getHeight() == -1) if (_children[i]->getHeight() == -1)
_children[i]->setHeight((_h == -1 ? getParentH() : _h) - _paddingTop - _paddingBottom); _children[i]->setHeight((_h == -1 ? getParentH() : _h) - _paddingTop - _paddingBottom);
if (_children[i]->getWidth() == -1) if (_children[i]->getWidth() == -1) {
if (autoWidget != -1)
error("Cannot expand automatically two different widgets.");
autoWidget = i;
_children[i]->setWidth(getParentW() - _w - _spacing); _children[i]->setWidth(getParentW() - _w - _spacing);
}
_children[i]->setX(curX); _children[i]->setX(curX);
@ -156,7 +170,15 @@ void ThemeLayoutHorizontal::reflowLayout() {
curX += (_children[i]->getWidth() + _spacing); curX += (_children[i]->getWidth() + _spacing);
} }
if (autoWidget != -1 && autoWidget != (int)i) {
_children[autoWidget]->setWidth(_children[autoWidget]->getWidth() - (_children[i]->getWidth() + _spacing));
for (int j = autoWidget - 1; j >= 0; --j)
_children[j]->setX(-(_children[i]->getWidth() + _spacing));
} else {
_w += _children[i]->getWidth() + _spacing; _w += _children[i]->getWidth() + _spacing;
}
_h = MAX(_h, (int16)(_children[i]->getHeight() + _paddingTop + _paddingBottom)); _h = MAX(_h, (int16)(_children[i]->getHeight() + _paddingTop + _paddingBottom));
} }
} }
@ -197,19 +219,21 @@ void ThemeEval::addWidget(const Common::String &name, int w, int h, const Common
void ThemeEval::addDialog(const Common::String &name, const Common::String &overlays, bool enabled) { void ThemeEval::addDialog(const Common::String &name, const Common::String &overlays, bool enabled) {
int16 x, y; int16 x, y;
int16 w, h; uint16 w, h;
ThemeLayout *layout = 0;
if (overlays == "screen") { if (overlays == "screen") {
x = y = 0; layout = new ThemeLayoutMain(0, 0, g_system->getOverlayWidth(), g_system->getOverlayHeight());
w = g_system->getOverlayWidth();
h = g_system->getOverlayHeight();
} else if (overlays == "screen_center") { } else if (overlays == "screen_center") {
x = y = w = h = -1; layout = new ThemeLayoutMain(-1, -1, -1, -1);
} else if (!getWidgetData(overlays, x, y, (uint16&)w, (uint16&)h)) { } else if (getWidgetData(overlays, x, y, w, h)) {
error("Error when loading dialog position for '%s'", overlays.c_str()); layout = new ThemeLayoutMain(x, y, w, h);
} }
ThemeLayout *layout = new ThemeLayoutMain(x, y, w, h); if (!layout)
error("Error when loading dialog position for '%s'", overlays.c_str());
_layouts[name] = layout; _layouts[name] = layout;
layout->setPadding( layout->setPadding(

View file

@ -52,7 +52,7 @@ public:
ThemeLayout(ThemeLayout *p, const Common::String &name) : ThemeLayout(ThemeLayout *p, const Common::String &name) :
_parent(p), _name(name), _x(0), _y(0), _w(-1), _h(-1), _reverse(false), _parent(p), _name(name), _x(0), _y(0), _w(-1), _h(-1), _reverse(false),
_paddingLeft(0), _paddingRight(0), _paddingTop(0), _paddingBottom(0), _paddingLeft(0), _paddingRight(0), _paddingTop(0), _paddingBottom(0),
_centered(false) { } _centered(false), _defaultW(-1), _defaultH(-1) { }
virtual ~ThemeLayout() { virtual ~ThemeLayout() {
_children.clear(); _children.clear();
@ -375,7 +375,7 @@ public:
} }
void debugDraw(Graphics::Surface *screen, const Graphics::Font *font) { void debugDraw(Graphics::Surface *screen, const Graphics::Font *font) {
_layouts["Dialog.ScummSaveLoad"]->debugDraw(screen, font); _layouts["Dialog.Browser"]->debugDraw(screen, font);
// _layouts["Dialog.GameOptions_Graphics"]->debugDraw(screen, font); // _layouts["Dialog.GameOptions_Graphics"]->debugDraw(screen, font);
} }

View file

@ -651,15 +651,18 @@ void ThemeRenderer::drawText(const Common::Rect &r, const Common::String &str, W
if (!ready()) if (!ready())
return; return;
Common::Rect dr = r;
dr.left += deltax;
if (inverted) { if (inverted) {
queueDD(kDDTextSelectionBackground, r); queueDD(kDDTextSelectionBackground, r);
queueDDText(kTextDataInverted, r, str, false, useEllipsis, align); queueDDText(kTextDataInverted, dr, str, false, useEllipsis, align);
return; return;
} }
switch (font) { switch (font) {
case kFontStyleNormal: case kFontStyleNormal:
queueDDText(kTextDataNormalFont, r, str, true, useEllipsis, align); queueDDText(kTextDataNormalFont, dr, str, true, useEllipsis, align);
return; return;
default: default:
@ -668,15 +671,15 @@ void ThemeRenderer::drawText(const Common::Rect &r, const Common::String &str, W
switch (state) { switch (state) {
case kStateDisabled: case kStateDisabled:
queueDDText(kTextDataDisabled, r, str, true, useEllipsis, align); queueDDText(kTextDataDisabled, dr, str, true, useEllipsis, align);
return; return;
case kStateHighlight: case kStateHighlight:
queueDDText(kTextDataHover, r, str, true, useEllipsis, align); queueDDText(kTextDataHover, dr, str, true, useEllipsis, align);
return; return;
case kStateEnabled: case kStateEnabled:
queueDDText(kTextDataDefault, r, str, true, useEllipsis, align); queueDDText(kTextDataDefault, dr, str, true, useEllipsis, align);
return; return;
} }
} }
@ -719,9 +722,9 @@ void ThemeRenderer::updateScreen() {
renderDirtyScreen(); renderDirtyScreen();
// _vectorRenderer->fillSurface(); // _vectorRenderer->fillSurface();
// themeEval()->debugDraw(_screen, _font); // themeEval()->debugDraw(_screen, _font);
// _vectorRenderer->copyWholeFrame(_system); // _vectorRenderer->copyWholeFrame(_system);
} }
void ThemeRenderer::renderDirtyScreen() { void ThemeRenderer::renderDirtyScreen() {

View file

@ -133,29 +133,29 @@ int BrowserDialog::runModal() {
*/ */
BrowserDialog::BrowserDialog(const char *title, bool dirBrowser) BrowserDialog::BrowserDialog(const char *title, bool dirBrowser)
: Dialog("browser") { : Dialog("Browser") {
_isDirBrowser = dirBrowser; _isDirBrowser = dirBrowser;
_fileList = NULL; _fileList = NULL;
_currentPath = NULL; _currentPath = NULL;
// Headline - TODO: should be customizable during creation time // Headline - TODO: should be customizable during creation time
new StaticTextWidget(this, "browser_headline", title); new StaticTextWidget(this, "Browser.Headline", title);
// Current path - TODO: handle long paths ? // Current path - TODO: handle long paths ?
_currentPath = new StaticTextWidget(this, "browser_path", "DUMMY"); _currentPath = new StaticTextWidget(this, "Browser.Path", "DUMMY");
// Add file list // Add file list
_fileList = new ListWidget(this, "browser_list"); _fileList = new ListWidget(this, "Browser.List");
_fileList->setNumberingMode(kListNumberingOff); _fileList->setNumberingMode(kListNumberingOff);
_fileList->setEditable(false); _fileList->setEditable(false);
_fileList->setHints(THEME_HINT_PLAIN_COLOR); _fileList->setHints(THEME_HINT_PLAIN_COLOR);
// Buttons // Buttons
new ButtonWidget(this, "browser_up", "Go up", kGoUpCmd, 0); new ButtonWidget(this, "Browser.Up", "Go up", kGoUpCmd, 0);
new ButtonWidget(this, "browser_cancel", "Cancel", kCloseCmd, 0); new ButtonWidget(this, "Browser.Cancel", "Cancel", kCloseCmd, 0);
new ButtonWidget(this, "browser_choose", "Choose", kChooseCmd, 0); new ButtonWidget(this, "Browser.Choose", "Choose", kChooseCmd, 0);
} }
void BrowserDialog::open() { void BrowserDialog::open() {

View file

@ -401,7 +401,7 @@
"<def var = 'Padding.Left' value = '16' /> " "<def var = 'Padding.Left' value = '16' /> "
"<def var = 'Padding.Right' value = '16' /> " "<def var = 'Padding.Right' value = '16' /> "
"<def var = 'Padding.Top' value = '16' /> " "<def var = 'Padding.Top' value = '16' /> "
"<def var = 'ListWidget.hlLeftPadding' value = '8'/> " "<def var = 'ListWidget.hlLeftPadding' value = '0'/> "
"<def var = 'ListWidget.hlRightPadding' value = '16'/> " "<def var = 'ListWidget.hlRightPadding' value = '16'/> "
"<def var = 'PopUpWidget.labelSpacing' value = '10' /> " "<def var = 'PopUpWidget.labelSpacing' value = '10' /> "
"<widget name = 'OptionsLabel' " "<widget name = 'OptionsLabel' "
@ -423,7 +423,7 @@
"size = '-1, Globals.Line.Height' " "size = '-1, Globals.Line.Height' "
"/> " "/> "
"<widget name = 'ListWidget' " "<widget name = 'ListWidget' "
"padding = '7, 5, 3, 3' " "padding = '5, 0, 8, 0' "
"/> " "/> "
"<widget name = 'PopUpWidget' " "<widget name = 'PopUpWidget' "
"padding = '7, 5, 0, 0' " "padding = '7, 5, 0, 0' "
@ -487,6 +487,29 @@
"</layout> " "</layout> "
"</layout> " "</layout> "
"</dialog> " "</dialog> "
"<dialog name = 'Browser' overlays = 'Dialog.Launcher.GameList' shading = 'dim'> "
"<layout type = 'vertical' padding = '8, 8, 8, 8' direction = 'bottom2top'> "
"<layout type = 'horizontal' padding = '0, 0, 16, 0' direction = 'right2left'> "
"<widget name = 'Choose' "
"type = 'Button' "
"/> "
"<widget name = 'Cancel' "
"type = 'Button' "
"/> "
"<space/> "
"<widget name = 'Up' "
"type = 'Button' "
"/> "
"</layout> "
"<widget name = 'List'/> "
"<widget name = 'Path' "
"height = 'Globals.Line.Height' "
"/> "
"<widget name = 'Headline' "
"height = 'Globals.Line.Height' "
"/> "
"</layout> "
"</dialog> "
"<dialog name = 'GlobalOptions' overlays = 'Dialog.Launcher.GameList' shading = 'dim'> " "<dialog name = 'GlobalOptions' overlays = 'Dialog.Launcher.GameList' shading = 'dim'> "
"<layout type = 'vertical' padding = '0, 0, 0, 0' direction = 'bottom2top'> " "<layout type = 'vertical' padding = '0, 0, 0, 0' direction = 'bottom2top'> "
"<layout type = 'horizontal' direction = 'right2left' padding = '16, 16, 16, 16'> " "<layout type = 'horizontal' direction = 'right2left' padding = '16, 16, 16, 16'> "

View file

@ -462,7 +462,7 @@
<def var = 'Padding.Right' value = '16' /> <def var = 'Padding.Right' value = '16' />
<def var = 'Padding.Top' value = '16' /> <def var = 'Padding.Top' value = '16' />
<def var = 'ListWidget.hlLeftPadding' value = '8'/> <def var = 'ListWidget.hlLeftPadding' value = '0'/>
<def var = 'ListWidget.hlRightPadding' value = '16'/> <def var = 'ListWidget.hlRightPadding' value = '16'/>
<def var = 'PopUpWidget.labelSpacing' value = '10' /> <def var = 'PopUpWidget.labelSpacing' value = '10' />
@ -485,7 +485,7 @@
size = '-1, Globals.Line.Height' size = '-1, Globals.Line.Height'
/> />
<widget name = 'ListWidget' <widget name = 'ListWidget'
padding = '7, 5, 3, 3' padding = '5, 0, 8, 0'
/> />
<widget name = 'PopUpWidget' <widget name = 'PopUpWidget'
padding = '7, 5, 0, 0' padding = '7, 5, 0, 0'
@ -552,6 +552,31 @@
</layout> </layout>
</dialog> </dialog>
<dialog name = 'Browser' overlays = 'Dialog.Launcher.GameList' shading = 'dim'>
<layout type = 'vertical' padding = '8, 8, 8, 8' direction = 'bottom2top'>
<layout type = 'horizontal' padding = '0, 0, 16, 0' direction = 'right2left'>
<widget name = 'Choose'
type = 'Button'
/>
<widget name = 'Cancel'
type = 'Button'
/>
<space/>
<widget name = 'Up'
type = 'Button'
/>
</layout>
<widget name = 'List'/>
<widget name = 'Path'
height = 'Globals.Line.Height'
/>
<widget name = 'Headline'
height = 'Globals.Line.Height'
/>
</layout>
</dialog>
<dialog name = 'GlobalOptions' overlays = 'Dialog.Launcher.GameList' shading = 'dim'> <dialog name = 'GlobalOptions' overlays = 'Dialog.Launcher.GameList' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' direction = 'bottom2top'> <layout type = 'vertical' padding = '0, 0, 0, 0' direction = 'bottom2top'>
<layout type = 'horizontal' direction = 'right2left' padding = '16, 16, 16, 16'> <layout type = 'horizontal' direction = 'right2left' padding = '16, 16, 16, 16'>