SCI/newgui: SciGuiMenu partially implemented

svn-id: r45634
This commit is contained in:
Martin Kiewitz 2009-11-03 19:33:31 +00:00
parent 34aaac37fc
commit d758538eaa
7 changed files with 243 additions and 18 deletions

View File

@ -47,7 +47,18 @@ reg_t kAddMenu(EngineState *s, int argc, reg_t *argv) {
reg_t kSetMenu(EngineState *s, int argc, reg_t *argv) {
s->_gui->menuSet(argc, argv);
uint16 menuId = argv[0].toUint16() >> 8;
uint16 itemId = argv[0].toUint16() & 0xFF;
uint16 attributeId;
int argPos = 1;
while (argPos < argc) {
attributeId = argv[argPos].toUint16();
if ((argPos + 1) >= argc)
error("Too few parameters for kSetMenu");
s->_gui->menuSet(menuId, itemId, attributeId, argv[argPos + 1]);
argPos += 2;
}
return s->r_acc;
}

View File

@ -306,21 +306,24 @@ void SciGui::drawStatus(const char *text, int16 colorPen, int16 colorBack) {
void SciGui::drawMenuBar(bool clear) {
if (!clear) {
warning("TODO: drawMenuBar()");
GuiPort *oldPort = _gfx->SetPort(_gfx->_menuPort);
_menu->drawBar();
_gfx->SetPort(oldPort);
} else {
drawStatus("", 0, 0);
}
}
void SciGui::menuAdd(Common::String title, Common::String content, reg_t entriesBase) {
warning("menuAdd");
_menu->add(title, content);
}
void SciGui::menuSet(int argc, reg_t *argv) {
void SciGui::menuSet(uint16 menuId, uint16 itemId, uint16 attributeId, reg_t value) {
_menu->setAttribute(menuId, itemId, attributeId, value);
}
reg_t SciGui::menuGet(uint16 menuId, uint16 itemId, uint16 attributeId) {
return NULL_REG;
return _menu->getAttribute(menuId, itemId, attributeId);
}
reg_t SciGui::menuSelect(reg_t eventObject) {

View File

@ -82,7 +82,7 @@ public:
virtual void drawStatus(const char *text, int16 colorPen, int16 colorBack);
virtual void drawMenuBar(bool clear);
virtual void menuAdd(Common::String title, Common::String content, reg_t entriesBase);
virtual void menuSet(int argc, reg_t *argv);
virtual void menuSet(uint16 menuId, uint16 itemId, uint16 attributeId, reg_t value);
virtual reg_t menuGet(uint16 menuId, uint16 itemId, uint16 attributeId);
virtual reg_t menuSelect(reg_t eventObject);

View File

@ -39,13 +39,181 @@ namespace Sci {
SciGuiMenu::SciGuiMenu(SciGuiGfx *gfx, SciGuiText *text, SciGuiScreen *screen)
: _gfx(gfx), _text(text), _screen(screen) {
init();
}
SciGuiMenu::~SciGuiMenu() {
}
void SciGuiMenu::init() {
void SciGuiMenu::add(Common::String title, Common::String content) {
GuiMenuEntry *menuEntry;
uint16 itemCount = 0;
GuiMenuItemEntry *itemEntry;
int contentSize = content.size();
int separatorCount;
int curPos, beginPos, endPos, tempPos;
int tagPos, rightAlignedPos, functionPos, altPos, controlPos;
// Sierra SCI starts with id 1, so we do so as well
_listCount++;
menuEntry = new GuiMenuEntry(_listCount);
menuEntry->text = title;
_list.push_back(menuEntry);
curPos = 0;
do {
itemCount++;
itemEntry = new GuiMenuItemEntry(_listCount, itemCount);
beginPos = curPos;
// Now go through the content till we find end-marker and collect data about it
// ':' is an end-marker for each item
tagPos = 0; rightAlignedPos = 0;
controlPos = 0; altPos = 0; functionPos = 0;
while ((curPos < contentSize) && (content[curPos] != ':')) {
switch (content[curPos]) {
case '=': // Set tag
if (tagPos)
error("multiple tag markers within one menu-item");
tagPos = curPos;
break;
case '`': // Right-aligned
if (rightAlignedPos)
error("multiple right-aligned markers within one menu-item");
rightAlignedPos = curPos;
break;
case '^': // Ctrl-prefix
if (controlPos)
error("multiple control markers within one menu-item");
controlPos = curPos;
break;
case '@': // Alt-prefix
if (altPos)
error("multiple alt markers within one menu-item");
altPos = curPos;
break;
case '#': // Function-prefix
if (functionPos)
error("multiple function markers within one menu-item");
functionPos = curPos;
break;
}
curPos++;
}
endPos = curPos;
// Control/Alt/Function key mapping...
if (controlPos) {
content.setChar(SCI_MENU_REPLACE_ONCONTROL, controlPos);
itemEntry->keyModifier = SCI_EVM_CTRL;
tempPos = controlPos + 1;
if (tempPos >= contentSize)
error("control marker at end of item");
itemEntry->keyPress = tolower(content[tempPos]);
content.setChar(toupper(content[tempPos]), tempPos);
}
if (altPos) {
content.setChar(SCI_MENU_REPLACE_ONALT, altPos);
itemEntry->keyModifier = SCI_EVM_ALT;
tempPos = altPos + 1;
if (tempPos >= contentSize)
error("alt marker at end of item");
itemEntry->keyPress = tolower(content[tempPos]);
content.setChar(toupper(content[tempPos]), tempPos);
}
if (functionPos) {
content.setChar(SCI_MENU_REPLACE_ONFUNCTION, functionPos);
tempPos = functionPos + 1;
if (tempPos >= contentSize)
error("function marker at end of item");
itemEntry->keyPress = content[tempPos];
switch (content[functionPos + 1]) {
case '1': itemEntry->keyPress = SCI_K_F1; break;
case '2': itemEntry->keyPress = SCI_K_F2; break;
case '3': itemEntry->keyPress = SCI_K_F3; break;
case '4': itemEntry->keyPress = SCI_K_F4; break;
case '5': itemEntry->keyPress = SCI_K_F5; break;
case '6': itemEntry->keyPress = SCI_K_F6; break;
case '7': itemEntry->keyPress = SCI_K_F7; break;
case '8': itemEntry->keyPress = SCI_K_F8; break;
case '9': itemEntry->keyPress = SCI_K_F9; break;
case '0': itemEntry->keyPress = SCI_K_F10; break;
default:
error("illegal function key specified");
}
}
// Now get all strings
tempPos = endPos;
if (rightAlignedPos) {
tempPos = rightAlignedPos;
} else if (tagPos) {
tempPos = tagPos;
}
curPos = beginPos;
separatorCount = 0;
while (curPos < tempPos) {
switch (content[curPos]) {
case '!':
case '-':
case ' ':
separatorCount++;
}
curPos++;
}
if (separatorCount == tempPos - beginPos) {
itemEntry->separatorLine = true;
} else {
itemEntry->text = Common::String(content.c_str() + beginPos, tempPos - beginPos);
}
if (rightAlignedPos) {
rightAlignedPos++;
tempPos = endPos;
if (tagPos)
tempPos = tagPos;
itemEntry->textRightAligned = Common::String(content.c_str() + rightAlignedPos, tempPos - rightAlignedPos);
}
if (tagPos) {
tempPos = functionPos + 1;
if (tempPos >= contentSize)
error("tag marker at end of item");
itemEntry->tag = atoi(content.c_str() + tempPos);
}
curPos = endPos + 1;
_itemList.push_back(itemEntry);
} while (curPos < contentSize);
}
void SciGuiMenu::setAttribute(uint16 menuId, uint16 itemId, uint16 attributeId, reg_t value) {
warning("setAttr: %d %d %d", menuId, itemId, attributeId);
}
reg_t SciGuiMenu::getAttribute(uint16 menuId, uint16 itemId, uint16 attributeId) {
return NULL_REG;
}
void SciGuiMenu::drawBar() {
GuiMenuEntry *listEntry;
GuiMenuList::iterator listIterator;
GuiMenuList::iterator listEnd = _list.end();
// Hardcoded black on white
_gfx->FillRect(_gfx->_menuRect, 1, _screen->_colorWhite);
_gfx->PenColor(0);
_gfx->MoveTo(8, 1);
listIterator = _list.begin();
while (listIterator != listEnd) {
listEntry = *listIterator;
_text->Draw_String(listEntry->text.c_str());
listIterator++;
}
_gfx->BitsShow(_gfx->_menuRect);
}
} // End of namespace Sci

View File

@ -28,18 +28,67 @@
namespace Sci {
enum {
SCI_MENU_ATTRIBUTE_SAID = 0x6d,
SCI_MENU_ATTRIBUTE_TEXT = 0x6e,
SCI_MENU_ATTRIBUTE_KEY = 0x6f,
SCI_MENU_ATTRIBUTE_ENABLED = 0x70,
SCI_MENU_ATTRIBUTE_TAG = 0x71
};
enum {
SCI_MENU_REPLACE_ONCONTROL = 0x03,
SCI_MENU_REPLACE_ONALT = 0x02,
SCI_MENU_REPLACE_ONFUNCTION = 'F'
};
struct GuiMenuEntry {
uint16 id;
Common::String text;
GuiMenuEntry(uint16 id)
: id(id) { }
};
typedef Common::List<GuiMenuEntry *> GuiMenuList;
struct GuiMenuItemEntry {
uint16 menuId;
uint16 id;
bool enabled;
uint16 tag;
uint16 keyPress;
uint16 keyModifier;
bool separatorLine;
Common::String said;
Common::String text;
Common::String textRightAligned;
GuiMenuItemEntry(uint16 menuId, uint16 id)
: menuId(menuId), id(id),
enabled(true), tag(0), keyPress(0), keyModifier(0), separatorLine(false) { }
};
typedef Common::List<GuiMenuItemEntry *> GuiMenuItemList;
class SciGuiMenu {
public:
SciGuiMenu(SciGuiGfx *gfx, SciGuiText *text, SciGuiScreen *screen);
~SciGuiMenu();
void add(Common::String title, Common::String content);
void setAttribute(uint16 menuId, uint16 itemId, uint16 attributeId, reg_t value);
reg_t getAttribute(uint16 menuId, uint16 itemId, uint16 attributeId);
void drawBar();
private:
void init(void);
SciGuiGfx *_gfx;
SciGuiText *_text;
SciGuiScreen *_screen;
uint16 _listCount;
GuiMenuList _list;
GuiMenuItemList _itemList;
};
} // End of namespace Sci

View File

@ -834,14 +834,8 @@ void SciGui32::menuAdd(Common::String title, Common::String content, reg_t entri
_s->_menubar->addMenu(_s->gfx_state, title, content, titlebarFont, entriesBase);
}
void SciGui32::menuSet(int argc, reg_t *argv) {
int index = argv[0].toUint16();
int i = 2;
while (i < argc) {
_s->_menubar->setAttribute(_s, (index >> 8) - 1, (index & 0xff) - 1, argv[i - 1].toUint16(), argv[i]);
i += 2;
}
void SciGui32::menuSet(uint16 menuId, uint16 itemId, uint16 attributeId, reg_t value) {
_s->_menubar->setAttribute(_s, menuId - 1, itemId - 1, attributeId, value);
}
reg_t SciGui32::menuGet(uint16 menuId, uint16 itemId, uint16 attributeId) {

View File

@ -61,7 +61,7 @@ public:
void drawStatus(const char *text, int16 colorPen, int16 colorBack);
void drawMenuBar(bool clear);
void menuAdd(Common::String title, Common::String content, reg_t entriesBase);
void menuSet(int argc, reg_t *argv);
void menuSet(uint16 menuId, uint16 itemId, uint16 attributeId, reg_t value);
reg_t menuGet(uint16 menuId, uint16 itemId, uint16 attributeId);
reg_t menuSelect(reg_t eventObject);