mirror of https://github.com/stella-emu/stella.git
Finally fixed text-entry bug in the debugger. In the process, moved to
C++11 lambdas for enabling per-widget text filtering. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@3159 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
8232045971
commit
72ec5f2371
10
Changes.txt
10
Changes.txt
|
@ -12,6 +12,14 @@
|
|||
Release History
|
||||
===========================================================================
|
||||
|
||||
4.6 to 4.6.1: (April xx, 2015)
|
||||
|
||||
* Fixed bug whereby text input could not be entered in certain widgets
|
||||
in the debugger.
|
||||
|
||||
-Have fun!
|
||||
|
||||
|
||||
4.5 to 4.6: (March 21, 2015)
|
||||
|
||||
* Finally fixed fullscreen rendering issues on some OpenGL
|
||||
|
@ -46,8 +54,6 @@
|
|||
|
||||
* Updated included PNG library to latest stable version.
|
||||
|
||||
-Have fun!
|
||||
|
||||
|
||||
4.2 to 4.5: (January 1, 2015)
|
||||
|
||||
|
|
2
Makefile
2
Makefile
|
@ -51,7 +51,7 @@ else
|
|||
endif
|
||||
CXXFLAGS+= -Wall
|
||||
ifdef HAVE_GCC
|
||||
CXXFLAGS+= -Wno-multichar -Wunused -fno-rtti -Woverloaded-virtual -std=c++11
|
||||
CXXFLAGS+= -Wno-multichar -Wunused -fno-rtti -Woverloaded-virtual -Wnon-virtual-dtor -std=c++11
|
||||
endif
|
||||
|
||||
ifdef PROFILE
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include <cstdlib>
|
||||
|
||||
#define STELLA_VERSION "4.7_pre"
|
||||
#define STELLA_VERSION "4.6.1_pre"
|
||||
#define STELLA_BUILD atoi("$Rev$" + 6)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -82,6 +82,24 @@ DataGridWidget::DataGridWidget(GuiObject* boss, const GUI::Font& font,
|
|||
_scrollBar->_entriesPerPage = 1;
|
||||
_scrollBar->_wheel_lines = 1;
|
||||
}
|
||||
|
||||
// Add filtering
|
||||
EditableWidget::TextFilter f = [&](char c) {
|
||||
bool isBin = c == '0' || c == '1',
|
||||
isDec = c >= '0' && c <= '9',
|
||||
isHex = isDec || (c >= 'a' && c <= 'f'),
|
||||
isOp = c == '$' || c == '#' || c == '\\';
|
||||
|
||||
if(BSPF_startsWithIgnoreCase(editString(), "$"))
|
||||
return isHex;
|
||||
else if(BSPF_startsWithIgnoreCase(editString(), "#"))
|
||||
return isDec;
|
||||
else if(BSPF_startsWithIgnoreCase(editString(), "\\"))
|
||||
return isBin;
|
||||
else
|
||||
return isHex || isDec || isBin || isOp;
|
||||
};
|
||||
setTextFilter(f);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -123,7 +141,7 @@ cerr << "_addrList.size() = " << _addrList.size()
|
|||
<< ", _valueStringList.size() = " << _valueStringList.size()
|
||||
<< ", _rows*_cols = " << _rows * _cols << endl << endl;
|
||||
*/
|
||||
_editMode = false;
|
||||
enableEditMode(false);
|
||||
|
||||
// Send item selected signal for starting with cell 0
|
||||
sendCommand(DataGridWidget::kSelectionChangedCmd, _selectedItem, _id);
|
||||
|
@ -193,9 +211,9 @@ void DataGridWidget::setValue(int position, int value, bool changed)
|
|||
if(position >= 0 && uInt32(position) < _valueList.size())
|
||||
{
|
||||
// Correctly format the data for viewing
|
||||
_editString = Common::Base::toString(value, _base);
|
||||
editString() = Common::Base::toString(value, _base);
|
||||
|
||||
_valueStringList[position] = _editString;
|
||||
_valueStringList[position] = editString();
|
||||
_changedList[position] = changed;
|
||||
_valueList[position] = value;
|
||||
|
||||
|
@ -248,7 +266,7 @@ void DataGridWidget::handleMouseUp(int x, int y, int button, int clickCount)
|
|||
sendCommand(DataGridWidget::kItemDoubleClickedCmd, _selectedItem, _id);
|
||||
|
||||
// Start edit mode
|
||||
if(_editable && !_editMode)
|
||||
if(isEditable() && !_editMode)
|
||||
startEditMode();
|
||||
}
|
||||
}
|
||||
|
@ -258,7 +276,7 @@ void DataGridWidget::handleMouseWheel(int x, int y, int direction)
|
|||
{
|
||||
if(_scrollBar)
|
||||
_scrollBar->handleMouseWheel(x, y, direction);
|
||||
else if(_editable)
|
||||
else if(isEditable())
|
||||
{
|
||||
if(direction > 0)
|
||||
decrementCell();
|
||||
|
@ -413,39 +431,39 @@ bool DataGridWidget::handleKeyDown(StellaKey key, StellaMod mod)
|
|||
break;
|
||||
|
||||
case KBDK_N: // negate
|
||||
if(_editable)
|
||||
if(isEditable())
|
||||
negateCell();
|
||||
break;
|
||||
|
||||
case KBDK_I: // invert
|
||||
if(_editable)
|
||||
if(isEditable())
|
||||
invertCell();
|
||||
break;
|
||||
|
||||
case KBDK_MINUS: // decrement
|
||||
case KBDK_KP_MINUS:
|
||||
if(_editable)
|
||||
if(isEditable())
|
||||
decrementCell();
|
||||
break;
|
||||
|
||||
case KBDK_EQUALS: // increment
|
||||
case KBDK_KP_PLUS:
|
||||
if(_editable)
|
||||
if(isEditable())
|
||||
incrementCell();
|
||||
break;
|
||||
|
||||
case KBDK_COMMA: // shift left
|
||||
if(_editable)
|
||||
if(isEditable())
|
||||
lshiftCell();
|
||||
break;
|
||||
|
||||
case KBDK_PERIOD: // shift right
|
||||
if(_editable)
|
||||
if(isEditable())
|
||||
rshiftCell();
|
||||
break;
|
||||
|
||||
case KBDK_Z: // zero
|
||||
if(_editable)
|
||||
if(isEditable())
|
||||
zeroCell();
|
||||
break;
|
||||
|
||||
|
@ -491,7 +509,7 @@ void DataGridWidget::receivedFocusWidget()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void DataGridWidget::lostFocusWidget()
|
||||
{
|
||||
_editMode = false;
|
||||
enableEditMode(false);
|
||||
|
||||
// Disable the operations widget
|
||||
if(_opsWidget)
|
||||
|
@ -542,7 +560,6 @@ void DataGridWidget::handleCommand(CommandSender* sender, int cmd,
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void DataGridWidget::drawWidget(bool hilite)
|
||||
{
|
||||
//cerr << "DataGridWidget::drawWidget\n";
|
||||
FBSurface& s = _boss->dialog().surface();
|
||||
int row, col;
|
||||
|
||||
|
@ -571,8 +588,7 @@ void DataGridWidget::drawWidget(bool hilite)
|
|||
if (_selectedItem == pos && _editMode)
|
||||
{
|
||||
adjustOffset();
|
||||
|
||||
s.drawString(_font, _editString, x, y, _colWidth, kTextColor,
|
||||
s.drawString(_font, editString(), x, y, _colWidth, kTextColor,
|
||||
kTextAlignLeft, -_editScrollOffset, false);
|
||||
}
|
||||
else
|
||||
|
@ -627,10 +643,10 @@ int DataGridWidget::getWidth() const
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void DataGridWidget::startEditMode()
|
||||
{
|
||||
if (_editable && !_editMode && _selectedItem >= 0)
|
||||
if (isEditable() && !_editMode && _selectedItem >= 0)
|
||||
{
|
||||
_editMode = true;
|
||||
setText("", true ); // Erase current entry when starting editing
|
||||
enableEditMode(true);
|
||||
setText("", true); // Erase current entry when starting editing
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -640,11 +656,11 @@ void DataGridWidget::endEditMode()
|
|||
if (!_editMode)
|
||||
return;
|
||||
|
||||
_editMode = false;
|
||||
enableEditMode(false);
|
||||
|
||||
// Update the both the string representation and the real data
|
||||
if(_editString.size() > 0 && !(_editString[0] == '$' ||
|
||||
_editString[0] == '#' || _editString[0] == '\\'))
|
||||
if(editString().size() > 0 && !(editString()[0] == '$' ||
|
||||
editString()[0] == '#' || editString()[0] == '\\'))
|
||||
{
|
||||
switch(_base)
|
||||
{
|
||||
|
@ -653,21 +669,21 @@ void DataGridWidget::endEditMode()
|
|||
case Common::Base::F_16_2:
|
||||
case Common::Base::F_16_4:
|
||||
case Common::Base::F_16_8:
|
||||
_editString.insert(0, 1, '$');
|
||||
editString().insert(0, 1, '$');
|
||||
break;
|
||||
case Common::Base::F_2:
|
||||
case Common::Base::F_2_8:
|
||||
case Common::Base::F_2_16:
|
||||
_editString.insert(0, 1, '\\');
|
||||
editString().insert(0, 1, '\\');
|
||||
break;
|
||||
case Common::Base::F_10:
|
||||
_editString.insert(0, 1, '#');
|
||||
editString().insert(0, 1, '#');
|
||||
break;
|
||||
case Common::Base::F_DEFAULT:
|
||||
break;
|
||||
}
|
||||
}
|
||||
int value = instance().debugger().stringToValue(_editString);
|
||||
int value = instance().debugger().stringToValue(editString());
|
||||
if(value < _lowerBound || value >= _upperBound)
|
||||
{
|
||||
abortEditMode();
|
||||
|
@ -680,42 +696,12 @@ void DataGridWidget::endEditMode()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void DataGridWidget::abortEditMode()
|
||||
{
|
||||
// undo any changes made
|
||||
assert(_selectedItem >= 0);
|
||||
_editMode = false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool DataGridWidget::tryInsertChar(char c, int pos)
|
||||
{
|
||||
// Input is very strict here, to eliminate time-consuming error checking
|
||||
// elsewhere, and includes the following restrictions:
|
||||
// Cannot contain spaces
|
||||
// Starts with leading specifier ($, #, \), or with a base character
|
||||
// Only one specifier is allowed
|
||||
// If starting with a specifier, only allow numbers applicable to that
|
||||
// base to follow
|
||||
|
||||
c = tolower(c);
|
||||
bool isBin = c == '0' || c == '1',
|
||||
isDec = c >= '0' && c <= '9',
|
||||
isHex = isDec || (c >= 'a' && c <= 'f'),
|
||||
isOp = c == '$' || c == '#' || c == '\\',
|
||||
insert = false;
|
||||
|
||||
if(BSPF_startsWithIgnoreCase(_editString, "$"))
|
||||
insert = isHex && pos > 0;
|
||||
else if(BSPF_startsWithIgnoreCase(_editString, "#"))
|
||||
insert = isDec && pos > 0;
|
||||
else if(BSPF_startsWithIgnoreCase(_editString, "\\"))
|
||||
insert = isBin && pos > 0;
|
||||
else
|
||||
insert = isHex || isDec || isBin || isOp;
|
||||
|
||||
if(insert)
|
||||
_editString.insert(pos, 1, c);
|
||||
|
||||
return insert;
|
||||
if(_editMode)
|
||||
{
|
||||
// Undo any changes made
|
||||
assert(_selectedItem >= 0);
|
||||
enableEditMode(false);
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -71,21 +71,10 @@ class DataGridWidget : public EditableWidget
|
|||
|
||||
void setRange(int lower, int upper);
|
||||
|
||||
virtual void handleMouseDown(int x, int y, int button, int clickCount);
|
||||
virtual void handleMouseUp(int x, int y, int button, int clickCount);
|
||||
virtual void handleMouseWheel(int x, int y, int direction);
|
||||
virtual bool handleText(char text);
|
||||
virtual bool handleKeyDown(StellaKey key, StellaMod mod);
|
||||
virtual bool handleKeyUp(StellaKey key, StellaMod mod);
|
||||
virtual void handleCommand(CommandSender* sender, int cmd, int data, int id);
|
||||
|
||||
virtual bool wantsFocus() { return true; }
|
||||
bool wantsFocus() { return true; }
|
||||
|
||||
// Account for the extra width of embedded scrollbar
|
||||
virtual int getWidth() const;
|
||||
|
||||
void startEditMode();
|
||||
void endEditMode();
|
||||
int getWidth() const;
|
||||
|
||||
int colWidth() { return _colWidth; }
|
||||
|
||||
|
@ -96,6 +85,8 @@ class DataGridWidget : public EditableWidget
|
|||
|
||||
int findItem(int x, int y);
|
||||
|
||||
void startEditMode();
|
||||
void endEditMode();
|
||||
void abortEditMode();
|
||||
|
||||
GUI::Rect getEditRect() const;
|
||||
|
@ -103,7 +94,13 @@ class DataGridWidget : public EditableWidget
|
|||
void receivedFocusWidget();
|
||||
void lostFocusWidget();
|
||||
|
||||
bool tryInsertChar(char c, int pos);
|
||||
void handleMouseDown(int x, int y, int button, int clickCount);
|
||||
void handleMouseUp(int x, int y, int button, int clickCount);
|
||||
void handleMouseWheel(int x, int y, int direction);
|
||||
bool handleText(char text);
|
||||
bool handleKeyDown(StellaKey key, StellaMod mod);
|
||||
bool handleKeyUp(StellaKey key, StellaMod mod);
|
||||
void handleCommand(CommandSender* sender, int cmd, int data, int id);
|
||||
|
||||
protected:
|
||||
int _rows;
|
||||
|
@ -141,6 +138,8 @@ class DataGridWidget : public EditableWidget
|
|||
void lshiftCell();
|
||||
void rshiftCell();
|
||||
void zeroCell();
|
||||
|
||||
void enableEditMode(bool state) { _editMode = state; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -88,6 +88,33 @@ RomListWidget::RomListWidget(GuiObject* boss, const GUI::Font& lfont,
|
|||
|
||||
myCheckList.push_back(t);
|
||||
}
|
||||
|
||||
// Add filtering
|
||||
EditableWidget::TextFilter f = [&](char c)
|
||||
{
|
||||
switch(_base)
|
||||
{
|
||||
case Common::Base::F_16:
|
||||
case Common::Base::F_16_1:
|
||||
case Common::Base::F_16_2:
|
||||
case Common::Base::F_16_4:
|
||||
case Common::Base::F_16_8:
|
||||
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || c == ' ';
|
||||
|
||||
case Common::Base::F_2:
|
||||
case Common::Base::F_2_8:
|
||||
case Common::Base::F_2_16:
|
||||
return c == '0' || c == '1' || c == ' ';
|
||||
|
||||
case Common::Base::F_10:
|
||||
return (c >= '0' && c <= '9') || c == ' ';
|
||||
|
||||
case Common::Base::F_DEFAULT:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
setTextFilter(f);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -153,15 +180,6 @@ void RomListWidget::setHighlighted(int item)
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const string& RomListWidget::getText() const
|
||||
{
|
||||
if(_selectedItem < -1 || _selectedItem >= (int)myDisasm->list.size())
|
||||
return EmptyString;
|
||||
else
|
||||
return _editString;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
int RomListWidget::findItem(int x, int y) const
|
||||
{
|
||||
|
@ -258,7 +276,7 @@ void RomListWidget::handleMouseUp(int x, int y, int button, int clickCount)
|
|||
if (clickCount == 2 && (_selectedItem == findItem(x, y)))
|
||||
{
|
||||
// Start edit mode
|
||||
if(_editable && !_editMode)
|
||||
if(isEditable() && !_editMode)
|
||||
startEditMode();
|
||||
}
|
||||
}
|
||||
|
@ -345,7 +363,7 @@ bool RomListWidget::handleEvent(Event::Type e)
|
|||
case Event::UISelect:
|
||||
if (_selectedItem >= 0)
|
||||
{
|
||||
if (_editable)
|
||||
if (isEditable())
|
||||
startEditMode();
|
||||
}
|
||||
break;
|
||||
|
@ -431,7 +449,6 @@ void RomListWidget::lostFocusWidget()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void RomListWidget::drawWidget(bool hilite)
|
||||
{
|
||||
//cerr << "RomListWidget::drawWidget\n";
|
||||
FBSurface& s = _boss->dialog().surface();
|
||||
const CartDebug::DisassemblyList& dlist = myDisasm->list;
|
||||
int i, pos, xpos, ypos, len = (int)dlist.size();
|
||||
|
@ -506,7 +523,7 @@ void RomListWidget::drawWidget(bool hilite)
|
|||
if (_selectedItem == pos && _editMode)
|
||||
{
|
||||
adjustOffset();
|
||||
s.drawString(_font, _editString, _x + r.x(), ypos, r.width(), kTextColor,
|
||||
s.drawString(_font, editString(), _x + r.x(), ypos, r.width(), kTextColor,
|
||||
kTextAlignLeft, -_editScrollOffset, false);
|
||||
|
||||
drawCaret();
|
||||
|
@ -553,44 +570,10 @@ GUI::Rect RomListWidget::getEditRect() const
|
|||
return r;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool RomListWidget::tryInsertChar(char c, int pos)
|
||||
{
|
||||
// Not sure how efficient this is, or should we even care?
|
||||
bool insert = false;
|
||||
c = tolower(c);
|
||||
switch(_base)
|
||||
{
|
||||
case Common::Base::F_16:
|
||||
case Common::Base::F_16_1:
|
||||
case Common::Base::F_16_2:
|
||||
case Common::Base::F_16_4:
|
||||
case Common::Base::F_16_8:
|
||||
insert = (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || c == ' ';
|
||||
break;
|
||||
case Common::Base::F_2:
|
||||
case Common::Base::F_2_8:
|
||||
case Common::Base::F_2_16:
|
||||
insert = c == '0' || c == '1' || c == ' ';
|
||||
break;
|
||||
case Common::Base::F_10:
|
||||
if((c >= '0' && c <= '9') || c == ' ')
|
||||
insert = true;
|
||||
break;
|
||||
case Common::Base::F_DEFAULT:
|
||||
break;
|
||||
}
|
||||
|
||||
if(insert)
|
||||
_editString.insert(pos, 1, c);
|
||||
|
||||
return insert;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void RomListWidget::startEditMode()
|
||||
{
|
||||
if (_editable && !_editMode && _selectedItem >= 0)
|
||||
if (isEditable() && !_editMode && _selectedItem >= 0)
|
||||
{
|
||||
// Does this line represent an editable area?
|
||||
if(myDisasm->list[_selectedItem].bytes == "")
|
||||
|
|
|
@ -59,10 +59,6 @@ class RomListWidget : public EditableWidget
|
|||
void setSelected(int item);
|
||||
void setHighlighted(int item);
|
||||
|
||||
const string& getText() const;
|
||||
void startEditMode();
|
||||
void endEditMode();
|
||||
|
||||
protected:
|
||||
void handleMouseDown(int x, int y, int button, int clickCount);
|
||||
void handleMouseUp(int x, int y, int button, int clickCount);
|
||||
|
@ -80,8 +76,8 @@ class RomListWidget : public EditableWidget
|
|||
int findItem(int x, int y) const;
|
||||
void recalc();
|
||||
|
||||
bool tryInsertChar(char c, int pos);
|
||||
|
||||
void startEditMode();
|
||||
void endEditMode();
|
||||
void abortEditMode();
|
||||
void lostFocusWidget();
|
||||
void scrollToSelected() { scrollToCurrent(_selectedItem); }
|
||||
|
|
|
@ -87,7 +87,6 @@ void CheckListWidget::drawWidget(bool hilite)
|
|||
//cerr << "CheckListWidget::drawWidget\n";
|
||||
FBSurface& s = _boss->dialog().surface();
|
||||
int i, pos, len = (int)_list.size();
|
||||
string buffer;
|
||||
|
||||
// Draw a thin frame around the list and to separate columns
|
||||
s.hLine(_x, _y, _x + _w - 1, kColor);
|
||||
|
@ -121,17 +120,12 @@ void CheckListWidget::drawWidget(bool hilite)
|
|||
|
||||
if (_selectedItem == pos && _editMode)
|
||||
{
|
||||
buffer = _editString;
|
||||
adjustOffset();
|
||||
|
||||
s.drawString(_font, buffer, _x + r.left, y, r.width(), kTextColor,
|
||||
s.drawString(_font, editString(), _x + r.left, y, r.width(), kTextColor,
|
||||
kTextAlignLeft, -_editScrollOffset, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = _list[pos];
|
||||
s.drawString(_font, buffer, _x + r.left, y, r.width(), kTextColor);
|
||||
}
|
||||
s.drawString(_font, _list[pos], _x + r.left, y, r.width(), kTextColor);
|
||||
}
|
||||
|
||||
// Only draw the caret while editing, and if it's in the current viewport
|
||||
|
|
|
@ -90,7 +90,7 @@ void Dialog::close(bool refresh)
|
|||
if (_mouseWidget)
|
||||
{
|
||||
_mouseWidget->handleMouseLeft(0);
|
||||
_mouseWidget = 0;
|
||||
_mouseWidget = nullptr;
|
||||
}
|
||||
|
||||
releaseFocus();
|
||||
|
@ -118,7 +118,7 @@ void Dialog::releaseFocus()
|
|||
if(_focusedWidget)
|
||||
{
|
||||
_focusedWidget->lostFocus();
|
||||
_focusedWidget = 0;
|
||||
_focusedWidget = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -253,24 +253,12 @@ void Dialog::buildCurrentFocusList(int tabID)
|
|||
_focusedWidget = _focusList[0];
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::redrawFocus()
|
||||
{
|
||||
if(_focusedWidget)
|
||||
_focusedWidget = Widget::setFocusForChain(this, getFocusList(), _focusedWidget, 0);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::addSurface(shared_ptr<FBSurface> surface)
|
||||
{
|
||||
mySurfaceStack.push(surface);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::draw()
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::drawDialog()
|
||||
{
|
||||
|
@ -298,7 +286,11 @@ void Dialog::drawDialog()
|
|||
}
|
||||
|
||||
// Draw outlines for focused widgets
|
||||
redrawFocus();
|
||||
// Don't change focus, since this will trigger lost and received
|
||||
// focus events
|
||||
if(_focusedWidget)
|
||||
_focusedWidget = Widget::setFocusForChain(this, getFocusList(),
|
||||
_focusedWidget, 0, false);
|
||||
|
||||
// Tell the surface(s) this area is dirty
|
||||
s.setDirty();
|
||||
|
|
|
@ -59,17 +59,16 @@ class Dialog : public GuiObject
|
|||
|
||||
virtual void center();
|
||||
virtual void drawDialog();
|
||||
virtual void loadConfig() {}
|
||||
virtual void saveConfig() {}
|
||||
virtual void setDefaults() {}
|
||||
virtual void loadConfig() { }
|
||||
virtual void saveConfig() { }
|
||||
virtual void setDefaults() { }
|
||||
|
||||
void addFocusWidget(Widget* w);
|
||||
void addToFocusList(WidgetArray& list);
|
||||
void addToFocusList(WidgetArray& list, TabWidget* w, int tabId);
|
||||
void addBGroupToFocusList(WidgetArray& list) { _buttonGroup = list; }
|
||||
void redrawFocus();
|
||||
void addTabWidget(TabWidget* w);
|
||||
void addOKWidget(Widget* w) { _okWidget = w; }
|
||||
void addOKWidget(Widget* w) { _okWidget = w; }
|
||||
void addCancelWidget(Widget* w) { _cancelWidget = w; }
|
||||
void setFocus(Widget* w);
|
||||
|
||||
|
@ -84,7 +83,7 @@ class Dialog : public GuiObject
|
|||
void addSurface(shared_ptr<FBSurface> surface);
|
||||
|
||||
protected:
|
||||
virtual void draw();
|
||||
virtual void draw() { };
|
||||
void releaseFocus();
|
||||
|
||||
virtual void handleText(char text);
|
||||
|
|
|
@ -47,7 +47,7 @@ void EditTextWidget::setText(const string& str, bool changed)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EditTextWidget::handleMouseDown(int x, int y, int button, int clickCount)
|
||||
{
|
||||
if(!_editable)
|
||||
if(!isEditable())
|
||||
return;
|
||||
|
||||
x += _editScrollOffset;
|
||||
|
@ -55,9 +55,9 @@ void EditTextWidget::handleMouseDown(int x, int y, int button, int clickCount)
|
|||
int width = 0;
|
||||
uInt32 i;
|
||||
|
||||
for (i = 0; i < _editString.size(); ++i)
|
||||
for (i = 0; i < editString().size(); ++i)
|
||||
{
|
||||
width += _font.getCharWidth(_editString[i]);
|
||||
width += _font.getCharWidth(editString()[i]);
|
||||
if (width >= x)
|
||||
break;
|
||||
}
|
||||
|
@ -69,7 +69,6 @@ void EditTextWidget::handleMouseDown(int x, int y, int button, int clickCount)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EditTextWidget::drawWidget(bool hilite)
|
||||
{
|
||||
//cerr << "EditTextWidget::drawWidget\n";
|
||||
FBSurface& s = _boss->dialog().surface();
|
||||
|
||||
// Highlight changes
|
||||
|
@ -84,7 +83,7 @@ void EditTextWidget::drawWidget(bool hilite)
|
|||
|
||||
// Draw the text
|
||||
adjustOffset();
|
||||
s.drawString(_font, _editString, _x + 2, _y + 2, getEditRect().width(),
|
||||
s.drawString(_font, editString(), _x + 2, _y + 2, getEditRect().width(),
|
||||
!_changed ? _textcolor : kDbgChangedTextColor,
|
||||
kTextAlignLeft, -_editScrollOffset, false);
|
||||
|
||||
|
@ -103,7 +102,7 @@ GUI::Rect EditTextWidget::getEditRect() const
|
|||
void EditTextWidget::lostFocusWidget()
|
||||
{
|
||||
// If we loose focus, 'commit' the user changes
|
||||
_backupString = _editString;
|
||||
_backupString = editString();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -65,9 +65,6 @@ void EditableWidget::setText(const string& str, bool)
|
|||
if (_editScrollOffset < 0)
|
||||
_editScrollOffset = 0;
|
||||
|
||||
if(_editable)
|
||||
startEditMode();
|
||||
|
||||
setDirty();
|
||||
}
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -198,7 +195,6 @@ int EditableWidget::getCaretOffset() const
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EditableWidget::drawCaret()
|
||||
{
|
||||
//cerr << "EditableWidget::drawCaret()\n";
|
||||
// Only draw if item is visible
|
||||
if (!_editable || !isVisible() || !_boss->isVisible() || !_hasFocus)
|
||||
return;
|
||||
|
|
|
@ -28,11 +28,15 @@
|
|||
/**
|
||||
* Base class for widgets which need to edit text, like ListWidget and
|
||||
* EditTextWidget.
|
||||
*
|
||||
* Widgets wishing to enforce their own editing restrictions are able
|
||||
* to use a 'TextFilter' as described below.
|
||||
*/
|
||||
class EditableWidget : public Widget, public CommandSender
|
||||
{
|
||||
public:
|
||||
/** Function used by 'tryInsertChar' to test validity of a character */
|
||||
/** Function used to test if a specified character can be inserted
|
||||
into the internal buffer */
|
||||
using TextFilter = std::function<bool(char)>;
|
||||
|
||||
enum {
|
||||
|
@ -47,7 +51,7 @@ class EditableWidget : public Widget, public CommandSender
|
|||
virtual ~EditableWidget();
|
||||
|
||||
virtual void setText(const string& str, bool changed = false);
|
||||
virtual const string& getText() const { return _editString; }
|
||||
const string& getText() const { return _editString; }
|
||||
|
||||
bool isEditable() const { return _editable; }
|
||||
void setEditable(bool editable);
|
||||
|
@ -58,7 +62,7 @@ class EditableWidget : public Widget, public CommandSender
|
|||
// We only want to focus this widget when we can edit its contents
|
||||
virtual bool wantsFocus() { return _editable; }
|
||||
|
||||
// Set filter used by 'tryInsertChar'
|
||||
// Set filter used to test whether a character can be inserted
|
||||
void setTextFilter(TextFilter& filter) { _filter = filter; }
|
||||
|
||||
protected:
|
||||
|
@ -72,10 +76,9 @@ class EditableWidget : public Widget, public CommandSender
|
|||
bool setCaretPos(int newPos);
|
||||
bool adjustOffset();
|
||||
|
||||
// This method will use the current TextFilter to insert a character
|
||||
// Note that classes which override this method will no longer use the
|
||||
// current TextFilter, and will assume all responsibility for filtering
|
||||
virtual bool tryInsertChar(char c, int pos);
|
||||
// This method is used internally by child classes wanting to
|
||||
// access/edit the internal buffer
|
||||
string& editString() { return _editString; }
|
||||
|
||||
private:
|
||||
// Line editing
|
||||
|
@ -89,7 +92,11 @@ class EditableWidget : public Widget, public CommandSender
|
|||
void copySelectedText();
|
||||
void pasteSelectedText();
|
||||
|
||||
protected:
|
||||
// Use the current TextFilter to insert a character into the
|
||||
// internal buffer
|
||||
bool tryInsertChar(char c, int pos);
|
||||
|
||||
private:
|
||||
bool _editable;
|
||||
string _editString;
|
||||
|
||||
|
@ -97,6 +104,7 @@ class EditableWidget : public Widget, public CommandSender
|
|||
int _caretTime;
|
||||
int _caretPos;
|
||||
|
||||
protected:
|
||||
bool _caretInverse;
|
||||
|
||||
int _editScrollOffset;
|
||||
|
|
|
@ -225,7 +225,7 @@ void ListWidget::handleMouseUp(int x, int y, int button, int clickCount)
|
|||
sendCommand(ListWidget::kDoubleClickedCmd, _selectedItem, _id);
|
||||
|
||||
// Start edit mode
|
||||
if(_editable && !_editMode)
|
||||
if(isEditable() && !_editMode)
|
||||
startEditMode();
|
||||
}
|
||||
}
|
||||
|
@ -346,7 +346,7 @@ bool ListWidget::handleEvent(Event::Type e)
|
|||
case Event::UISelect:
|
||||
if (_selectedItem >= 0)
|
||||
{
|
||||
if (_editable)
|
||||
if (isEditable())
|
||||
startEditMode();
|
||||
else
|
||||
sendCommand(ListWidget::kActivatedCmd, _selectedItem, _id);
|
||||
|
@ -462,7 +462,7 @@ void ListWidget::scrollToCurrent(int item)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ListWidget::startEditMode()
|
||||
{
|
||||
if (_editable && !_editMode && _selectedItem >= 0)
|
||||
if (isEditable() && !_editMode && _selectedItem >= 0)
|
||||
{
|
||||
_editMode = true;
|
||||
setText(_list[_selectedItem]);
|
||||
|
@ -480,7 +480,7 @@ void ListWidget::endEditMode()
|
|||
|
||||
// Send a message that editing finished with a return/enter key press
|
||||
_editMode = false;
|
||||
_list[_selectedItem] = _editString;
|
||||
_list[_selectedItem] = editString();
|
||||
sendCommand(ListWidget::kDataChangedCmd, _selectedItem, _id);
|
||||
|
||||
// Reset to normal data entry
|
||||
|
|
|
@ -49,7 +49,6 @@ void StringListWidget::drawWidget(bool hilite)
|
|||
{
|
||||
FBSurface& s = _boss->dialog().surface();
|
||||
int i, pos, len = (int)_list.size();
|
||||
string buffer;
|
||||
|
||||
// Draw a thin frame around the list.
|
||||
s.hLine(_x, _y, _x + _w - 1, kColor);
|
||||
|
@ -73,17 +72,12 @@ void StringListWidget::drawWidget(bool hilite)
|
|||
GUI::Rect r(getEditRect());
|
||||
if (_selectedItem == pos && _editMode)
|
||||
{
|
||||
buffer = _editString;
|
||||
adjustOffset();
|
||||
|
||||
s.drawString(_font, buffer, _x + r.left, y, r.width(), kTextColor,
|
||||
s.drawString(_font, editString(), _x + r.left, y, r.width(), kTextColor,
|
||||
kTextAlignLeft, -_editScrollOffset, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = _list[pos];
|
||||
s.drawString(_font, buffer, _x + r.left, y, r.width(), kTextColor);
|
||||
}
|
||||
s.drawString(_font, _list[pos], _x + r.left, y, r.width(), kTextColor);
|
||||
}
|
||||
|
||||
// Only draw the caret while editing, and if it's in the current viewport
|
||||
|
|
|
@ -197,7 +197,8 @@ bool Widget::isWidgetInChain(WidgetArray& list, Widget* find)
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Widget* Widget::setFocusForChain(GuiObject* boss, WidgetArray& arr,
|
||||
Widget* wid, int direction)
|
||||
Widget* wid, int direction,
|
||||
bool emitFocusEvents)
|
||||
{
|
||||
FBSurface& s = boss->dialog().surface();
|
||||
int size = (int)arr.size(), pos = -1;
|
||||
|
@ -220,7 +221,11 @@ Widget* Widget::setFocusForChain(GuiObject* boss, WidgetArray& arr,
|
|||
// First clear area surrounding all widgets
|
||||
if(tmp->_hasFocus)
|
||||
{
|
||||
tmp->lostFocus();
|
||||
if(emitFocusEvents)
|
||||
tmp->lostFocus();
|
||||
else
|
||||
tmp->_hasFocus = false;
|
||||
|
||||
s.frameRect(x, y, w, h, kDlgColor);
|
||||
|
||||
tmp->setDirty();
|
||||
|
@ -230,7 +235,7 @@ Widget* Widget::setFocusForChain(GuiObject* boss, WidgetArray& arr,
|
|||
|
||||
// Figure out which which should be active
|
||||
if(pos == -1)
|
||||
return 0;
|
||||
return nullptr;
|
||||
else
|
||||
{
|
||||
switch(direction)
|
||||
|
@ -263,7 +268,11 @@ Widget* Widget::setFocusForChain(GuiObject* boss, WidgetArray& arr,
|
|||
int x = tmp->getAbsX() - 1, y = tmp->getAbsY() - 1,
|
||||
w = tmp->getWidth() + 2, h = tmp->getHeight() + 2;
|
||||
|
||||
tmp->receivedFocus();
|
||||
if(emitFocusEvents)
|
||||
tmp->receivedFocus();
|
||||
else
|
||||
tmp->_hasFocus = true;
|
||||
|
||||
s.frameRect(x, y, w, h, kWidFrameColor, kDashLine);
|
||||
|
||||
tmp->setDirty();
|
||||
|
|
|
@ -152,7 +152,8 @@ class Widget : public GuiObject
|
|||
/** Select either previous, current, or next widget in chain to have
|
||||
focus, and deselects all others */
|
||||
static Widget* setFocusForChain(GuiObject* boss, WidgetArray& arr,
|
||||
Widget* w, int direction);
|
||||
Widget* w, int direction,
|
||||
bool emitFocusEvents = true);
|
||||
|
||||
/** Sets all widgets in this chain to be dirty (must be redrawn) */
|
||||
static void setDirtyInChain(Widget* start);
|
||||
|
|
Loading…
Reference in New Issue