mirror of https://github.com/stella-emu/stella.git
Added much more functionality to the CheatWidget. Currently, everything
is working except for changing values (but you can still use the RAM tab to do that). Basically, the rules are as follows: 1) Only works on decimal input for now. 2) Search with empty input returns all addresses (128 bytes). 3) Comparing a value after a search inspects the current result set for the given value. 4) Compare can make use of 'comparitive' operators '+' and '-'. If specified at the start of input, they search by offset. Typical uses are as follows: 1) Search for a '3', then compare to a '2'. This finds the memory location that at first contained 3, then later changed to 2 (maybe you lost a life or something). 2) Search for all values (leave input blank), then compare to '-1'. This finds all memory locations that have decreased by 1 (useful when you don't know where to start). I guess after this, Stella will officially be banned from hi-score contests :) git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@497 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
bf16e9a6f9
commit
3af4b74147
|
@ -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: makefile,v 1.95 2005-06-14 01:55:47 urchlay Exp $
|
||||
## $Id: makefile,v 1.96 2005-06-14 18:55:35 stephena Exp $
|
||||
##============================================================================
|
||||
|
||||
##============================================================================
|
||||
|
@ -157,7 +157,7 @@ M6502_OBJS = D6502.o Device.o M6502.o M6502Low.o M6502Hi.o NullDev.o System.o
|
|||
|
||||
GUI_OBJS = Font.o Menu.o Launcher.o \
|
||||
Widget.o PopUpWidget.o ScrollBarWidget.o ListWidget.o TabWidget.o \
|
||||
EditableWidget.o EditTextWidget.o \
|
||||
EditableWidget.o EditTextWidget.o EditNumWidget.o \
|
||||
Dialog.o DialogContainer.o OptionsDialog.o VideoDialog.o AudioDialog.o \
|
||||
EventMappingDialog.o GameInfoDialog.o HelpDialog.o AboutDialog.o \
|
||||
LauncherDialog.o LauncherOptionsDialog.o BrowserDialog.o GameList.o \
|
||||
|
@ -414,6 +414,9 @@ EditableWidget.o: $(GUI)/EditableWidget.cxx $(GUI)/EditableWidget.hxx
|
|||
EditTextWidget.o: $(GUI)/EditTextWidget.cxx $(GUI)/EditTextWidget.hxx
|
||||
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(GUI)/EditTextWidget.cxx
|
||||
|
||||
EditNumWidget.o: $(GUI)/EditNumWidget.cxx $(GUI)/EditNumWidget.hxx
|
||||
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(GUI)/EditNumWidget.cxx
|
||||
|
||||
Dialog.o: $(GUI)/Dialog.cxx $(GUI)/Dialog.hxx
|
||||
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(GUI)/Dialog.cxx
|
||||
|
||||
|
|
|
@ -13,27 +13,29 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: CheatWidget.cxx,v 1.2 2005-06-14 01:11:48 stephena Exp $
|
||||
// $Id: CheatWidget.cxx,v 1.3 2005-06-14 18:55:36 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2002-2004 The ScummVM project
|
||||
//============================================================================
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "OSystem.hxx"
|
||||
#include "FrameBuffer.hxx"
|
||||
#include "GuiUtils.hxx"
|
||||
#include "GuiObject.hxx"
|
||||
#include "Debugger.hxx"
|
||||
#include "Widget.hxx"
|
||||
|
||||
#include "EditNumWidget.hxx"
|
||||
#include "ListWidget.hxx"
|
||||
#include "EditTextWidget.hxx"
|
||||
|
||||
#include "CheatWidget.hxx"
|
||||
|
||||
enum {
|
||||
kSearchCmd,
|
||||
kCmpCmd,
|
||||
kRestartCmd
|
||||
kSearchCmd = 'CSEA',
|
||||
kCmpCmd = 'CCMP',
|
||||
kRestartCmd = 'CRST'
|
||||
};
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -41,63 +43,262 @@ CheatWidget::CheatWidget(GuiObject* boss, int x, int y, int w, int h)
|
|||
: Widget(boss, x, y, w, h),
|
||||
CommandSender(boss)
|
||||
{
|
||||
int xpos = 10;
|
||||
const int bwidth = 50, space = 20;
|
||||
const int border = 20;
|
||||
const int bwidth = 50;
|
||||
const int charWidth = instance()->consoleFont().getMaxCharWidth();
|
||||
const int charHeight = instance()->consoleFont().getFontHeight() + 2;
|
||||
int xpos = x + border;
|
||||
int ypos = y + border;
|
||||
|
||||
// Add the edit textbox, set to accept decimal values
|
||||
myEditBox = new EditTextWidget(boss, 10, 10, 80, 16, "");
|
||||
// Add the numedit label and box
|
||||
new StaticTextWidget(boss, xpos, ypos, 70, kLineHeight,
|
||||
"Enter a value:", kTextAlignLeft);
|
||||
|
||||
myEditBox = new EditNumWidget(boss, 90, ypos - 2, charWidth*10, charHeight, "");
|
||||
myEditBox->setFont(_boss->instance()->consoleFont());
|
||||
myEditBox->setEditString("HELLO!");
|
||||
// myEditBox->setTarget(this);
|
||||
myActiveWidget = myEditBox;
|
||||
ypos += border;
|
||||
|
||||
// myResult = new StaticTextWidget();
|
||||
// Add the result text string area
|
||||
myResult = new StaticTextWidget(boss, border + 5, ypos, 175, kLineHeight,
|
||||
"", kTextAlignLeft);
|
||||
myResult->setColor(kTextColorEm);
|
||||
|
||||
// Add the three search-related buttons
|
||||
mySearchButton = new ButtonWidget(boss, xpos, _h - space, bwidth, 16,
|
||||
xpos = x + border;
|
||||
ypos += border * 2;
|
||||
mySearchButton = new ButtonWidget(boss, xpos, ypos, bwidth, 16,
|
||||
"Search", kSearchCmd, 0);
|
||||
mySearchButton->setTarget(this);
|
||||
xpos += 8 + bwidth;
|
||||
|
||||
myCompareButton = new ButtonWidget(boss, xpos, _h - space, bwidth, 16,
|
||||
myCompareButton = new ButtonWidget(boss, xpos, ypos, bwidth, 16,
|
||||
"Compare", kCmpCmd, 0);
|
||||
myCompareButton->setTarget(this);
|
||||
xpos += 8 + bwidth;
|
||||
|
||||
myRestartButton = new ButtonWidget(boss, xpos, _h - space, bwidth, 16,
|
||||
myRestartButton = new ButtonWidget(boss, xpos, ypos, bwidth, 16,
|
||||
"Restart", kRestartCmd, 0);
|
||||
myRestartButton->setTarget(this);
|
||||
xpos += 8 + bwidth;
|
||||
|
||||
ListWidget* myList = new ListWidget(boss, 10, 24, 100, h - 50);
|
||||
myList->setTarget(this);
|
||||
myList->setEditable(false);
|
||||
myList->setNumberingMode(kListNumberingOff);
|
||||
myActiveWidget = myList;
|
||||
// Add the list showing the results of a search/compare
|
||||
// FIXME - change this to a AddrValueWidget (or something like that)
|
||||
xpos = 200; ypos = border/2;
|
||||
|
||||
StringList l;
|
||||
for (int i = 0; i < 10; ++i)
|
||||
l.push_back("TESTING!!!");
|
||||
myList->setList(l);
|
||||
new StaticTextWidget(boss, xpos + 10, ypos, 70, kLineHeight,
|
||||
"Address Value", kTextAlignLeft);
|
||||
ypos += kLineHeight;
|
||||
|
||||
myResultsList = new ListWidget(boss, xpos, ypos, 100, 75);
|
||||
myResultsList->setNumberingMode(kListNumberingOff);
|
||||
myResultsList->setFont(instance()->consoleFont());
|
||||
myResultsList->setTarget(this);
|
||||
|
||||
ListWidget* myList2 = new ListWidget(boss, 150, 24, 100, h - 70);
|
||||
myList2->setTarget(this);
|
||||
myList2->setEditable(false);
|
||||
myList2->setNumberingMode(kListNumberingOff);
|
||||
|
||||
StringList l2;
|
||||
for (int i = 0; i < 10; ++i)
|
||||
l2.push_back("TESTING AGAIN!!!");
|
||||
myList2->setList(l2);
|
||||
// Start in a known state
|
||||
doRestart();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CheatWidget::~CheatWidget()
|
||||
{
|
||||
cerr << "CheatWidget::~CheatWidget()\n";
|
||||
mySearchArray.clear();
|
||||
myCompareArray.clear();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CheatWidget::handleCommand(CommandSender* sender, int cmd, int data)
|
||||
{
|
||||
switch(cmd)
|
||||
{
|
||||
case kSearchCmd:
|
||||
doSearch();
|
||||
break;
|
||||
|
||||
case kCmpCmd:
|
||||
doCompare();
|
||||
break;
|
||||
|
||||
case kRestartCmd:
|
||||
doRestart();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CheatWidget::doSearch()
|
||||
{
|
||||
bool comparisonSearch = true;
|
||||
|
||||
string str = myEditBox->getEditString();
|
||||
if(str.length() == 0)
|
||||
{
|
||||
// An empty field means return all memory locations
|
||||
comparisonSearch = false;
|
||||
}
|
||||
else if(str[0] == '+' || str[0] == '-')
|
||||
{
|
||||
// Don't accept these characters here, only in compare
|
||||
myEditBox->setEditString("");
|
||||
return; // FIXME - message about invalid format
|
||||
}
|
||||
|
||||
int searchVal = atoi(str.c_str());
|
||||
|
||||
// Clear the search array of previous items
|
||||
mySearchArray.clear();
|
||||
|
||||
// Now, search all memory locations for this value, and add it to the
|
||||
// search array
|
||||
Debugger& dbg = _boss->instance()->debugger();
|
||||
AddrValue av;
|
||||
int searchCount = 0;
|
||||
for(int addr = 0; addr < kRamSize; ++addr)
|
||||
{
|
||||
if(comparisonSearch)
|
||||
{
|
||||
av.addr = addr;
|
||||
av.value = searchVal;
|
||||
|
||||
if(dbg.readRAM(av.addr) == av.value)
|
||||
{
|
||||
mySearchArray.push_back(av);
|
||||
++searchCount;
|
||||
}
|
||||
}
|
||||
else // match all memory locations
|
||||
{
|
||||
av.addr = addr;
|
||||
av.value = dbg.readRAM(av.addr);
|
||||
mySearchArray.push_back(av);
|
||||
++searchCount;
|
||||
}
|
||||
}
|
||||
|
||||
// If we have some hits, enable the comparison methods
|
||||
if(searchCount)
|
||||
{
|
||||
mySearchButton->setEnabled(false);
|
||||
myCompareButton->setEnabled(true);
|
||||
myRestartButton->setEnabled(true);
|
||||
}
|
||||
|
||||
// Show number of hits
|
||||
ostringstream buf;
|
||||
buf << "Search found " << searchCount << " result(s)";
|
||||
myResult->setLabel(buf.str());
|
||||
|
||||
// Finally, show the search results in the list
|
||||
fillResultsList();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CheatWidget::doCompare()
|
||||
{
|
||||
bool comparitiveSearch = false;
|
||||
int searchVal = 0;
|
||||
|
||||
string str = myEditBox->getEditString();
|
||||
if(str.length() == 0)
|
||||
{
|
||||
myResult->setLabel("Enter an absolute or comparitive value");
|
||||
return;
|
||||
}
|
||||
|
||||
// Do some pre-processing on the string
|
||||
if(str[0] == '+' || str[0] == '-')
|
||||
{
|
||||
bool negative = false;
|
||||
if(str[0] == '-')
|
||||
negative = true;
|
||||
|
||||
str.erase(0, 1); // remove the operator
|
||||
searchVal = atoi(str.c_str());
|
||||
if(negative)
|
||||
searchVal = -searchVal;
|
||||
|
||||
comparitiveSearch = true;
|
||||
}
|
||||
else
|
||||
searchVal = atoi(str.c_str());
|
||||
|
||||
AddrValueList tempList;
|
||||
|
||||
// Now, search all memory locations specified in mySearchArray for this value
|
||||
Debugger& dbg = _boss->instance()->debugger();
|
||||
AddrValue av;
|
||||
int searchCount = 0;
|
||||
|
||||
// A comparitive search searches memory for locations that have changed by
|
||||
// the specified amount, vs. for exact values
|
||||
for(unsigned int i = 0; i < mySearchArray.size(); i++)
|
||||
{
|
||||
av.addr = mySearchArray[i].addr;
|
||||
if(comparitiveSearch)
|
||||
{
|
||||
int temp = mySearchArray[i].value + searchVal;
|
||||
if(temp < 0 || temp > 255) // skip values which are out of range
|
||||
continue;
|
||||
av.value = temp;
|
||||
}
|
||||
else
|
||||
av.value = searchVal;
|
||||
|
||||
if(dbg.readRAM(av.addr) == av.value)
|
||||
{
|
||||
tempList.push_back(av);
|
||||
++searchCount;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the searchArray to the new results
|
||||
mySearchArray = tempList;
|
||||
|
||||
// If we have some hits, enable the comparison methods
|
||||
if(searchCount)
|
||||
{
|
||||
myCompareButton->setEnabled(true);
|
||||
myRestartButton->setEnabled(true);
|
||||
}
|
||||
|
||||
// Show number of hits
|
||||
ostringstream buf;
|
||||
buf << "Compare found " << searchCount << " result(s)";
|
||||
myResult->setLabel(buf.str());
|
||||
|
||||
// Finally, show the search results in the list
|
||||
fillResultsList();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CheatWidget::doRestart()
|
||||
{
|
||||
// Erase all search buffers, reset to start mode
|
||||
mySearchArray.clear();
|
||||
myCompareArray.clear();
|
||||
myEditBox->setEditString("");
|
||||
myResult->setLabel("");
|
||||
fillResultsList();
|
||||
|
||||
mySearchButton->setEnabled(true);
|
||||
myCompareButton->setEnabled(false);
|
||||
myRestartButton->setEnabled(false);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CheatWidget::fillResultsList()
|
||||
{
|
||||
StringList l;
|
||||
char buf[1024];
|
||||
|
||||
// FIXME - add to an editable two-column widget instead
|
||||
for(unsigned int i = 0; i < mySearchArray.size(); i++)
|
||||
{
|
||||
snprintf(buf, 1023, "%s : %3d",
|
||||
Debugger::to_hex_16(kRamStart + mySearchArray[i].addr),
|
||||
mySearchArray[i].value);
|
||||
l.push_back(buf);
|
||||
}
|
||||
|
||||
myResultsList->setList(l);
|
||||
}
|
||||
|
|
|
@ -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: CheatWidget.hxx,v 1.2 2005-06-14 01:11:48 stephena Exp $
|
||||
// $Id: CheatWidget.hxx,v 1.3 2005-06-14 18:55:36 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2002-2004 The ScummVM project
|
||||
|
@ -25,13 +25,27 @@
|
|||
class GuiObject;
|
||||
class ButtonWidget;
|
||||
class StaticTextWidget;
|
||||
class EditTextWidget;
|
||||
class EditNumWidget;
|
||||
class ListWidget;
|
||||
|
||||
#include "Array.hxx"
|
||||
#include "Widget.hxx"
|
||||
#include "Command.hxx"
|
||||
|
||||
|
||||
class CheatWidget : public Widget, public CommandSender
|
||||
{
|
||||
private:
|
||||
struct AddrValue {
|
||||
uInt16 addr;
|
||||
uInt8 value;
|
||||
};
|
||||
|
||||
typedef GUI::Array<AddrValue> AddrValueList;
|
||||
|
||||
AddrValueList mySearchArray;
|
||||
AddrValueList myCompareArray;
|
||||
|
||||
public:
|
||||
CheatWidget(GuiObject *boss, int x, int y, int w, int h);
|
||||
virtual ~CheatWidget();
|
||||
|
@ -40,15 +54,24 @@ class CheatWidget : public Widget, public CommandSender
|
|||
|
||||
void handleCommand(CommandSender* sender, int cmd, int data);
|
||||
|
||||
private:
|
||||
void doSearch();
|
||||
void doCompare();
|
||||
void doRestart();
|
||||
|
||||
void fillResultsList();
|
||||
|
||||
private:
|
||||
Widget* myActiveWidget;
|
||||
|
||||
EditTextWidget* myEditBox;
|
||||
EditNumWidget* myEditBox;
|
||||
StaticTextWidget* myResult;
|
||||
|
||||
ButtonWidget* mySearchButton;
|
||||
ButtonWidget* myCompareButton;
|
||||
ButtonWidget* myRestartButton;
|
||||
|
||||
ListWidget* myResultsList;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2005 by Bradford W. Mott
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: EditNumWidget.cxx,v 1.1 2005-06-14 18:55:36 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2002-2004 The ScummVM project
|
||||
//============================================================================
|
||||
|
||||
#include "OSystem.hxx"
|
||||
#include "FrameBuffer.hxx"
|
||||
#include "Dialog.hxx"
|
||||
#include "EditNumWidget.hxx"
|
||||
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
EditNumWidget::EditNumWidget(GuiObject* boss, int x, int y, int w, int h,
|
||||
const string& text)
|
||||
: EditableWidget(boss, x, y - 1, w, h + 2)
|
||||
{
|
||||
_flags = WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS |
|
||||
WIDGET_TAB_NAVIGATE;
|
||||
_type = kEditTextWidget;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EditNumWidget::setEditString(const string& str)
|
||||
{
|
||||
EditableWidget::setEditString(str);
|
||||
_backupString = str;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool EditNumWidget::tryInsertChar(char c, int pos)
|
||||
{
|
||||
// Only allow numbers (FIXME - maybe allow A .. F for hex?)
|
||||
if(isprint(c) && ((c >= '0' && c <= '9') || c == '+' || c == '-'))
|
||||
{
|
||||
_editString.insert(pos, 1, c);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EditNumWidget::handleMouseDown(int x, int y, int button, int clickCount)
|
||||
{
|
||||
x += _editScrollOffset;
|
||||
|
||||
int width = 0;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < _editString.size(); ++i)
|
||||
{
|
||||
width += _font->getCharWidth(_editString[i]);
|
||||
if (width >= x)
|
||||
break;
|
||||
}
|
||||
|
||||
if (setCaretPos(i))
|
||||
{
|
||||
draw();
|
||||
_boss->instance()->frameBuffer().refresh();
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EditNumWidget::drawWidget(bool hilite)
|
||||
{
|
||||
FrameBuffer& fb = _boss->instance()->frameBuffer();
|
||||
|
||||
// Draw a thin frame around us.
|
||||
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 + _w - 1, _y, _y + _h - 1, kShadowColor);
|
||||
|
||||
// Draw the text
|
||||
adjustOffset();
|
||||
fb.drawString(_font, _editString, _x + 2, _y + 2, getEditRect().width(),
|
||||
kTextColor, kTextAlignLeft, -_editScrollOffset, false);
|
||||
|
||||
// Draw the caret
|
||||
drawCaret();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
GUI::Rect EditNumWidget::getEditRect() const
|
||||
{
|
||||
GUI::Rect r(2, 1, _w - 2, _h);
|
||||
return r;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EditNumWidget::receivedFocusWidget()
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EditNumWidget::lostFocusWidget()
|
||||
{
|
||||
// If we loose focus, 'commit' the user changes
|
||||
_backupString = _editString;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EditNumWidget::startEditMode()
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EditNumWidget::endEditMode()
|
||||
{
|
||||
releaseFocus();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EditNumWidget::abortEditMode()
|
||||
{
|
||||
setEditString(_backupString);
|
||||
releaseFocus();
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2005 by Bradford W. Mott
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: EditNumWidget.hxx,v 1.1 2005-06-14 18:55:36 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2002-2004 The ScummVM project
|
||||
//============================================================================
|
||||
|
||||
#ifndef EDIT_NUM_WIDGET_HXX
|
||||
#define EDIT_NUM_WIDGET_HXX
|
||||
|
||||
#include "Rect.hxx"
|
||||
#include "EditableWidget.hxx"
|
||||
|
||||
|
||||
/* EditNumWidget */
|
||||
class EditNumWidget : public EditableWidget
|
||||
{
|
||||
public:
|
||||
EditNumWidget(GuiObject* boss, int x, int y, int w, int h, const string& text);
|
||||
|
||||
void setEditString(const string& str);
|
||||
|
||||
virtual void handleMouseDown(int x, int y, int button, int clickCount);
|
||||
|
||||
virtual bool wantsFocus() { return true; }
|
||||
|
||||
protected:
|
||||
void drawWidget(bool hilite);
|
||||
void receivedFocusWidget();
|
||||
void lostFocusWidget();
|
||||
|
||||
void startEditMode();
|
||||
void endEditMode();
|
||||
void abortEditMode();
|
||||
|
||||
bool tryInsertChar(char c, int pos);
|
||||
|
||||
GUI::Rect getEditRect() const;
|
||||
|
||||
protected:
|
||||
string _backupString;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -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: EditTextWidget.cxx,v 1.1 2005-06-14 01:11:48 stephena Exp $
|
||||
// $Id: EditTextWidget.cxx,v 1.2 2005-06-14 18:55:36 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2002-2004 The ScummVM project
|
||||
|
@ -45,10 +45,6 @@ void EditTextWidget::setEditString(const string& str)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EditTextWidget::handleMouseDown(int x, int y, int button, int clickCount)
|
||||
{
|
||||
// First remove caret
|
||||
if (_caretVisible)
|
||||
drawCaret(true);
|
||||
|
||||
x += _editScrollOffset;
|
||||
|
||||
int width = 0;
|
||||
|
@ -62,7 +58,10 @@ void EditTextWidget::handleMouseDown(int x, int y, int button, int clickCount)
|
|||
}
|
||||
|
||||
if (setCaretPos(i))
|
||||
{
|
||||
draw();
|
||||
_boss->instance()->frameBuffer().refresh();
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -80,6 +79,9 @@ void EditTextWidget::drawWidget(bool hilite)
|
|||
adjustOffset();
|
||||
fb.drawString(_font, _editString, _x + 2, _y + 2, getEditRect().width(),
|
||||
kTextColor, kTextAlignLeft, -_editScrollOffset, false);
|
||||
|
||||
// Draw the caret
|
||||
drawCaret();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -99,7 +101,6 @@ void EditTextWidget::lostFocusWidget()
|
|||
{
|
||||
// If we loose focus, 'commit' the user changes
|
||||
_backupString = _editString;
|
||||
drawCaret(true);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -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: EditableWidget.cxx,v 1.1 2005-06-14 01:11:48 stephena Exp $
|
||||
// $Id: EditableWidget.cxx,v 1.2 2005-06-14 18:55:36 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2002-2004 The ScummVM project
|
||||
|
@ -51,6 +51,9 @@ void EditableWidget::setEditString(const string& str)
|
|||
_editScrollOffset = (_font->getStringWidth(_editString) - (getEditRect().width()));
|
||||
if (_editScrollOffset < 0)
|
||||
_editScrollOffset = 0;
|
||||
|
||||
// Make sure the new string is seen onscreen
|
||||
_boss->instance()->frameBuffer().refresh();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -58,32 +61,23 @@ bool EditableWidget::tryInsertChar(char c, int pos)
|
|||
{
|
||||
if (isprint(c))
|
||||
{
|
||||
_editString.insert(pos, c, 1);
|
||||
_editString.insert(pos, 1, c);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
void EditableWidget::handleTickle() {
|
||||
uint32 time = getMillis();
|
||||
if (_caretTime < time) {
|
||||
_caretTime = time + kCaretBlinkTime;
|
||||
drawCaret(_caretVisible);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool EditableWidget::handleKeyDown(int ascii, int keycode, int modifiers)
|
||||
{
|
||||
// Ignore all mod keys
|
||||
if(instance()->eventHandler().kbdControl(modifiers) ||
|
||||
instance()->eventHandler().kbdAlt(modifiers))
|
||||
return true;
|
||||
|
||||
bool handled = true;
|
||||
bool dirty = false;
|
||||
|
||||
// First remove caret
|
||||
if (_caretVisible)
|
||||
drawCaret(true);
|
||||
|
||||
switch (keycode)
|
||||
{
|
||||
case '\n': // enter/return
|
||||
|
@ -102,13 +96,13 @@ bool EditableWidget::handleKeyDown(int ascii, int keycode, int modifiers)
|
|||
if (_caretPos > 0)
|
||||
{
|
||||
_caretPos--;
|
||||
_editString.erase(_caretPos);
|
||||
_editString.erase(_caretPos, 1);
|
||||
dirty = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 127: // delete
|
||||
_editString.erase(_caretPos);
|
||||
_editString.erase(_caretPos, 1);
|
||||
dirty = true;
|
||||
break;
|
||||
|
||||
|
@ -141,7 +135,10 @@ bool EditableWidget::handleKeyDown(int ascii, int keycode, int modifiers)
|
|||
}
|
||||
|
||||
if (dirty)
|
||||
{
|
||||
draw();
|
||||
_boss->instance()->frameBuffer().refresh();
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
@ -159,7 +156,7 @@ int EditableWidget::getCaretOffset() const
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EditableWidget::drawCaret(bool erase)
|
||||
void EditableWidget::drawCaret()
|
||||
{
|
||||
// Only draw if item is visible
|
||||
if (!isVisible() || !_boss->isVisible())
|
||||
|
@ -167,23 +164,25 @@ void EditableWidget::drawCaret(bool erase)
|
|||
|
||||
GUI::Rect editRect = getEditRect();
|
||||
|
||||
OverlayColor color = (erase ^ _caretInverse) ? kBGColor : kTextColorHi;
|
||||
OverlayColor color = kTextColorHi;
|
||||
int x = editRect.left;
|
||||
int y = editRect.top + 1;
|
||||
int y = editRect.top;
|
||||
|
||||
x += getCaretOffset();
|
||||
|
||||
if (y < 0 || y + editRect.height() - 2 >= _h)
|
||||
return;
|
||||
|
||||
x += getAbsX();
|
||||
y += getAbsY();
|
||||
y += _y;
|
||||
|
||||
/*
|
||||
cerr << "draw caret: " << endl
|
||||
<< "x = " << x << endl
|
||||
<< "y = " << y << endl
|
||||
<< "h = " << editRect.height() - 2 << endl
|
||||
<< "c = " << color << endl
|
||||
<< endl;
|
||||
*/
|
||||
FrameBuffer& fb = _boss->instance()->frameBuffer();
|
||||
fb.vLine(x, y, y + editRect.height() - 2, color);
|
||||
fb.refresh();//FIXMEfb.addDirtyRect(x, y, 2, editRect.height() - 2);
|
||||
|
||||
_caretVisible = !erase;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -201,6 +200,9 @@ bool EditableWidget::adjustOffset()
|
|||
// check if the caret is still within the textbox; if it isn't,
|
||||
// adjust _editScrollOffset
|
||||
|
||||
// For some reason (differences in ScummVM event handling??),
|
||||
// this method should always return true.
|
||||
|
||||
int caretpos = getCaretOffset();
|
||||
const int editWidth = getEditRect().width();
|
||||
|
||||
|
@ -208,13 +210,11 @@ bool EditableWidget::adjustOffset()
|
|||
{
|
||||
// scroll left
|
||||
_editScrollOffset += caretpos;
|
||||
return true;
|
||||
}
|
||||
else if (caretpos >= editWidth)
|
||||
{
|
||||
// scroll right
|
||||
_editScrollOffset -= (editWidth - caretpos);
|
||||
return true;
|
||||
}
|
||||
else if (_editScrollOffset > 0)
|
||||
{
|
||||
|
@ -228,5 +228,5 @@ bool EditableWidget::adjustOffset()
|
|||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -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: EditableWidget.hxx,v 1.1 2005-06-14 01:11:48 stephena Exp $
|
||||
// $Id: EditableWidget.hxx,v 1.2 2005-06-14 18:55:36 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2002-2004 The ScummVM project
|
||||
|
@ -47,7 +47,7 @@ class EditableWidget : public Widget
|
|||
|
||||
virtual GUI::Rect getEditRect() const = 0;
|
||||
virtual int getCaretOffset() const;
|
||||
void drawCaret(bool erase);
|
||||
void drawCaret();
|
||||
bool setCaretPos(int newPos);
|
||||
bool adjustOffset();
|
||||
|
||||
|
|
|
@ -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: GuiObject.hxx,v 1.10 2005-06-10 17:46:06 stephena Exp $
|
||||
// $Id: GuiObject.hxx,v 1.11 2005-06-14 18:55:36 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2002-2004 The ScummVM project
|
||||
|
@ -27,13 +27,12 @@ class DialogContainer;
|
|||
class Widget;
|
||||
|
||||
#include "Command.hxx"
|
||||
#include "bspf.hxx"
|
||||
|
||||
/**
|
||||
This is the base class for all GUI objects/widgets.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: GuiObject.hxx,v 1.10 2005-06-10 17:46:06 stephena Exp $
|
||||
@version $Id: GuiObject.hxx,v 1.11 2005-06-14 18:55:36 stephena Exp $
|
||||
*/
|
||||
class GuiObject : public CommandReceiver
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue