Added updated PopUpWidget code from latest ScummVM CVS. This widget

now has the ability to show two columns of items, in cases where
there isn't enough vertical space to show them normally.

Completely finished the GameInfoDialog by adding 'Cartridge.Type'
for both loading and saving.  With these changes, it should now
never be necessary to edit a properties file directly.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@805 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2005-10-01 01:42:36 +00:00
parent 667590c0a8
commit da85d8198a
4 changed files with 208 additions and 54 deletions

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: GameInfoDialog.cxx,v 1.15 2005-09-30 18:17:29 stephena Exp $
// $Id: GameInfoDialog.cxx,v 1.16 2005-10-01 01:42:36 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -112,10 +112,9 @@ GameInfoDialog::GameInfoDialog(
myType = new PopUpWidget(myTab, xpos+lwidth, ypos,
font.getStringWidth("Auto-detect") + 15, lineHeight,
"", 0, 0);
myType->appendEntry("Auto-detect", 1);
myType->appendEntry("2K", 2);
myType->appendEntry("3E", 3);
wid.push_back(myType); // FIXME - add rest of types
for(i = 0; i < 21; ++i)
myType->appendEntry(ourCartridgeList[i].name, i+1);
wid.push_back(myType);
// Add items for tab 0
addToFocusList(wid, tabID);
@ -302,7 +301,14 @@ void GameInfoDialog::loadConfig()
else
mySound->setSelectedTag(0);
// FIXME - add type properties
s = myGameProperties->get("Cartridge.Type", true);
for(i = 0; i < 21; ++i)
{
if(s == ourCartridgeList[i].comparitor)
break;
}
i = (i == 21) ? 0: i + 1;
myType->setSelectedTag(i);
// Console properties
s = myGameProperties->get("Console.LeftDifficulty", true);
@ -406,7 +412,15 @@ void GameInfoDialog::saveConfig()
s = (tag == 1) ? "Mono" : "Stereo";
myGameProperties->set("Cartridge.Sound", s);
// FIXME - type
tag = myType->getSelectedTag();
for(i = 0; i < 21; ++i)
{
if(i == tag-1)
{
myGameProperties->set("Cartridge.Type", ourCartridgeList[i].comparitor);
break;
}
}
// Console properties
tag = myLeftDiff->getSelectedTag();
@ -490,3 +504,28 @@ const PropType GameInfoDialog::ourControllerList[5] = {
{ "Paddles", "PADDLES" },
{ "Joystick", "JOYSTICK" }
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const PropType GameInfoDialog::ourCartridgeList[21] = {
{ "Auto-detect", "AUTO-DETECT" },
{ "Cart2K", "2K" },
{ "Cart3E", "3E" },
{ "Cart3F", "3F" },
{ "Cart4K", "4K" },
{ "CartAR", "AR" },
{ "CartCV", "CV" },
{ "CartDPC", "DPC" },
{ "CartE0", "E0" },
{ "CartE7", "E7" },
{ "CartF4", "F4" },
{ "CartF4SC", "F4SC" },
{ "CartF6", "F6" },
{ "CartF6SC", "F6SC" },
{ "CartF8", "F8" },
{ "CartF8SC", "F8SC" },
{ "CartFASC", "FASC" },
{ "CartFE", "FE" },
{ "CartMB", "MB" },
{ "CartMC", "MC" },
{ "CartUA", "UA" }
};

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: GameInfoDialog.hxx,v 1.11 2005-09-30 00:40:34 stephena Exp $
// $Id: GameInfoDialog.hxx,v 1.12 2005-10-01 01:42:36 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -87,7 +87,7 @@ class GameInfoDialog : public Dialog, public CommandSender
Properties* myGameProperties;
/** Holds static strings for Cartridge type */
static const PropType ourCartridgeList[20];
static const PropType ourCartridgeList[21];
/** Holds static strings for Controller type */
static const PropType ourControllerList[5];

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: PopUpWidget.cxx,v 1.20 2005-09-30 00:40:34 stephena Exp $
// $Id: PopUpWidget.cxx,v 1.21 2005-10-01 01:42:36 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -26,6 +26,7 @@
#include "Dialog.hxx"
#include "DialogContainer.hxx"
#include "GuiUtils.hxx"
#include "StringListWidget.hxx"
#include "PopUpWidget.hxx"
#define UP_DOWN_BOX_HEIGHT 10
@ -50,22 +51,11 @@ PopUpDialog::PopUpDialog(PopUpWidget* boss, int clickX, int clickY)
// Copy the selection index
_selection = _popUpBoss->_selectedItem;
// Calculate real popup dimensions
// Calculate real popup dimensions
_x = _popUpBoss->getAbsX() + _popUpBoss->_labelWidth;
_y = _popUpBoss->getAbsY() - _popUpBoss->_selectedItem * kLineHeight;
_w = _popUpBoss->_w - 10 - _popUpBoss->_labelWidth;
_h = 2; // this will increase as more items are added
// Perform clipping / switch to scrolling mode if we don't fit on the screen
int height = instance()->frameBuffer().baseHeight();
if(_h >= height)
_h = height - 1;
if(_y < 0)
_y = 0;
else if(_y + _h >= height)
_y = height - _h - 1;
// TODO - implement scrolling if we had to move the menu, or if there are too many entries
_w = _popUpBoss->_w - kLineHeight + 2 - _popUpBoss->_labelWidth;
_h = 2;
// Remember original mouse position
_clickX = clickX - _x;
@ -81,36 +71,28 @@ void PopUpDialog::drawDialog()
if(_dirty)
{
// cerr << "PopUpDialog::drawDialog()\n";
FrameBuffer& fb = _popUpBoss->instance()->frameBuffer();
FrameBuffer& fb = instance()->frameBuffer();
// Draw the menu border
fb.hLine(_x, _y, _x+_w - 1, kColor);
fb.hLine(_x, _y, _x + _w - 1, kColor);
fb.hLine(_x, _y + _h - 1, _x + _w - 1, kShadowColor);
fb.vLine(_x, _y, _y+_h - 1, kColor);
fb.vLine(_x, _y, _y + _h - 1, kColor);
fb.vLine(_x + _w - 1, _y, _y + _h - 1, kShadowColor);
// If necessary, draw dividing line
if(_twoColumns)
fb.vLine(_x + _w / 2, _y, _y + _h - 2, kColor);
// Draw the entries
int count = _popUpBoss->_entries.size();
for(int i = 0; i < count; i++)
{
bool hilite = i == _selection;
int x = _x + 1;
int y = _y + 1 + i * kLineHeight;
int w = _w - 2;
string& name = _popUpBoss->_entries[i].name;
drawMenuEntry(i, i == _selection);
fb.fillRect(x, y, w, kLineHeight, hilite ? kTextColorHi : kBGColor);
// The last entry may be empty. Fill it with black.
if(_twoColumns && (count & 1))
fb.fillRect(_x + 1 + _w / 2, _y + 1 + kLineHeight * (_entriesPerColumn - 1),
_w / 2 - 1, kLineHeight, kBGColor);
if(name.size() == 0)
{
// Draw a separator
fb.hLine(x - 1, y + kLineHeight / 2, x + w, kShadowColor);
fb.hLine(x, y + 1 + kLineHeight / 2, x + w, kColor);
}
else
fb.drawString(_popUpBoss->font(), name, x + 1, y + 2, w - 2,
hilite ? kBGColor : kTextColor);
}
_dirty = false;
fb.addDirtyRect(_x, _y, _w, _h);
}
@ -178,11 +160,137 @@ void PopUpDialog::handleKeyDown(int ascii, int keycode, int modifiers)
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PopUpDialog::drawMenuEntry(int entry, bool hilite)
{
FrameBuffer& fb = instance()->frameBuffer();
// Draw one entry of the popup menu, including selection
int x, y, w;
if(_twoColumns)
{
int n = _popUpBoss->_entries.size() / 2;
if(_popUpBoss->_entries.size() & 1)
n++;
if (entry >= n)
{
x = _x + 1 + _w / 2;
y = _y + 1 + kLineHeight * (entry - n);
}
else
{
x = _x + 1;
y = _y + 1 + kLineHeight * entry;
}
w = _w / 2 - 1;
}
else
{
x = _x + 1;
y = _y + 1 + kLineHeight * entry;
w = _w - 2;
}
string& name = _popUpBoss->_entries[entry].name;
fb.fillRect(x, y, w, kLineHeight, hilite ? kTextColorHi : kBGColor);
if(name.size() == 0)
{
// Draw a separator
fb.hLine(x - 1, y + kLineHeight / 2, x + w, kShadowColor);
fb.hLine(x, y + 1 + kLineHeight / 2, x + w, kColor);
}
else
fb.drawString(_popUpBoss->font(), name, x + 1, y + 2, w - 2,
hilite ? kBGColor : kTextColor);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PopUpDialog::recalc()
{
// Perform clipping / switch to scrolling mode if we don't fit on the screen
const int height = instance()->frameBuffer().baseHeight();
_h = _popUpBoss->_entries.size() * kLineHeight + 2;
// HACK: For now, we do not do scrolling. Instead, we draw the dialog
// in two columns if it's too tall.
if(_h >= height)
{
const int width = instance()->frameBuffer().baseWidth();
_twoColumns = true;
_entriesPerColumn = _popUpBoss->_entries.size() / 2;
if(_popUpBoss->_entries.size() & 1)
_entriesPerColumn++;
_h = _entriesPerColumn * kLineHeight + 2;
_w = 0;
// Find width of largest item
for(unsigned int i = 0; i < _popUpBoss->_entries.size(); i++)
{
int width = _font->getStringWidth(_popUpBoss->_entries[i].name);
if(width > _w)
_w = width;
}
_w = 2 * _w + 10;
if (!(_w & 1))
_w++;
if(_popUpBoss->_selectedItem >= _entriesPerColumn)
{
_x -= _w / 2;
_y = _popUpBoss->getAbsY() - (_popUpBoss->_selectedItem - _entriesPerColumn) * kLineHeight;
}
if(_w >= width)
_w = width - 1;
if(_x < 0)
_x = 0;
if(_x + _w >= width)
_x = width - 1 - _w;
}
else
_twoColumns = false;
if(_h >= height)
_h = height - 1;
if(_y < 0)
_y = 0;
else if(_y + _h >= height)
_y = height - 1 - _h;
// TODO - implement scrolling if we had to move the menu, or if there are too many entries
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int PopUpDialog::findItem(int x, int y) const
{
if(x >= 0 && x < _w && y >= 0 && y < _h)
return (y-2) / kLineHeight;
{
if(_twoColumns)
{
unsigned int entry = (y - 2) / kLineHeight;
if(x > _w / 2)
{
entry += _entriesPerColumn;
if(entry >= _popUpBoss->_entries.size())
return -1;
}
return entry;
}
return (y - 2) / kLineHeight;
}
return -1;
}
@ -307,7 +415,9 @@ void PopUpWidget::appendEntry(const string& entry, int tag)
_entries.push_back(e);
// Each time an entry is added, the popup dialog gets larger
myPopUpDialog->setHeight(myPopUpDialog->getHeight() + kLineHeight);
// This isn't as efficient as it could be, since it's called
// each time an entry is added (which can be dozens of times).
myPopUpDialog->recalc();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: PopUpWidget.hxx,v 1.8 2005-09-11 22:55:51 stephena Exp $
// $Id: PopUpWidget.hxx,v 1.9 2005-10-01 01:42:36 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -93,12 +93,7 @@ class PopUpWidget : public Widget, public CommandSender
//
class PopUpDialog : public Dialog
{
protected:
PopUpWidget* _popUpBoss;
int _clickX, _clickY;
uInt8* _buffer;
int _selection;
int _openTime;
friend class PopUpWidget;
public:
PopUpDialog(PopUpWidget* boss, int clickX, int clickY);
@ -112,7 +107,8 @@ class PopUpDialog : public Dialog
protected:
void drawMenuEntry(int entry, bool hilite);
void recalc();
int findItem(int x, int y) const;
void setSelection(int item);
bool isMouseDown();
@ -122,6 +118,15 @@ class PopUpDialog : public Dialog
private:
void sendSelection();
protected:
PopUpWidget* _popUpBoss;
int _clickX, _clickY;
uInt8* _buffer;
int _selection;
int _openTime;
bool _twoColumns;
int _entriesPerColumn;
};
#endif