mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-03 09:23:37 +00:00
Optimization and cleanup of VirtualKeyboardGUI
svn-id: r33916
This commit is contained in:
parent
93780d51ca
commit
8c2340d323
@ -30,9 +30,9 @@
|
|||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
VirtualKeyboardGUI::VirtualKeyboardGUI(VirtualKeyboard *kbd)
|
VirtualKeyboardGUI::VirtualKeyboardGUI(VirtualKeyboard *kbd)
|
||||||
: _kbd(kbd), _displaying(false), _needRedraw(false), _drag(false),
|
: _kbd(kbd), _displaying(false), _drag(false),
|
||||||
_drawCaret(false), _refreshDisplay(false), _displayEnabled(false),
|
_drawCaret(false), _displayEnabled(false), _firstRun(true),
|
||||||
_firstRun(true), _cursorAnimateTimer(0), _cursorAnimateCounter(0) {
|
_cursorAnimateTimer(0), _cursorAnimateCounter(0) {
|
||||||
|
|
||||||
assert(_kbd);
|
assert(_kbd);
|
||||||
assert(g_system);
|
assert(g_system);
|
||||||
@ -51,16 +51,21 @@ VirtualKeyboardGUI::~VirtualKeyboardGUI() {
|
|||||||
void VirtualKeyboardGUI::initMode(VirtualKeyboard::Mode *mode) {
|
void VirtualKeyboardGUI::initMode(VirtualKeyboard::Mode *mode) {
|
||||||
_kbdSurface = mode->image;
|
_kbdSurface = mode->image;
|
||||||
_kbdTransparentColor = mode->transparentColor;
|
_kbdTransparentColor = mode->transparentColor;
|
||||||
_kbdBound.setWidth(_kbdSurface->w + 1);
|
_kbdBound.setWidth(_kbdSurface->w);
|
||||||
_kbdBound.setHeight(_kbdSurface->h + 1);
|
_kbdBound.setHeight(_kbdSurface->h);
|
||||||
_needRedraw = true;
|
|
||||||
|
|
||||||
_dispSurface.free();
|
_dispSurface.free();
|
||||||
_displayEnabled = false;
|
_displayEnabled = false;
|
||||||
if (!mode->displayArea)
|
if (mode->displayArea)
|
||||||
return;
|
setupDisplayArea(*(mode->displayArea), mode->displayFontColor);
|
||||||
Rect r = *(mode->displayArea);
|
|
||||||
|
|
||||||
|
if (_displaying) {
|
||||||
|
extendDirtyRect(_kbdBound);
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualKeyboardGUI::setupDisplayArea(Rect& r, OverlayColor forecolor) {
|
||||||
// choose font
|
// choose font
|
||||||
_dispFont = FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont);
|
_dispFont = FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont);
|
||||||
if (!fontIsSuitable(_dispFont, r)) {
|
if (!fontIsSuitable(_dispFont, r)) {
|
||||||
@ -68,12 +73,13 @@ void VirtualKeyboardGUI::initMode(VirtualKeyboard::Mode *mode) {
|
|||||||
if (!fontIsSuitable(_dispFont, r))
|
if (!fontIsSuitable(_dispFont, r))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_dispX = r.left;
|
_dispX = _kbdBound.left + r.left;
|
||||||
_dispY = r.top + (r.height() + 1 - _dispFont->getFontHeight()) / 2;
|
_dispY = _kbdBound.top + r.top + (r.height() - _dispFont->getFontHeight()) / 2;
|
||||||
_dispSurface.create(r.width() + 1, _dispFont->getFontHeight(), sizeof(OverlayColor));
|
|
||||||
_dispI = 0;
|
_dispI = 0;
|
||||||
_dispForeColor = mode->displayFontColor;
|
_dispForeColor = forecolor;
|
||||||
_dispBackColor = _dispForeColor + 0xFF;
|
_dispBackColor = _dispForeColor + 0xFF;
|
||||||
|
_dispSurface.create(r.width(), _dispFont->getFontHeight(), sizeof(OverlayColor));
|
||||||
|
_dispSurface.fillRect(r, _dispBackColor);
|
||||||
_displayEnabled = true;
|
_displayEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,10 +92,10 @@ void VirtualKeyboardGUI::run() {
|
|||||||
if (_lastScreenChanged != _system->getScreenChangeID())
|
if (_lastScreenChanged != _system->getScreenChangeID())
|
||||||
screenChanged();
|
screenChanged();
|
||||||
|
|
||||||
// TODO: set default position if position is somehow invalid
|
// TODO: set default position if position is somehow invalid (ie. after screen change)
|
||||||
if (_firstRun) {
|
if (_firstRun) {
|
||||||
_firstRun = false;
|
_firstRun = false;
|
||||||
setDefaultPosition();
|
moveToDefaultPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_gui.isActive()) {
|
if (!g_gui.isActive()) {
|
||||||
@ -98,10 +104,10 @@ void VirtualKeyboardGUI::run() {
|
|||||||
}
|
}
|
||||||
_overlayBackup.create(_system->getOverlayWidth(), _system->getOverlayHeight(), sizeof(OverlayColor));
|
_overlayBackup.create(_system->getOverlayWidth(), _system->getOverlayHeight(), sizeof(OverlayColor));
|
||||||
_system->grabOverlay((OverlayColor*)_overlayBackup.pixels, _overlayBackup.w);
|
_system->grabOverlay((OverlayColor*)_overlayBackup.pixels, _overlayBackup.w);
|
||||||
resetDirtyRect();
|
|
||||||
|
|
||||||
setupCursor();
|
setupCursor();
|
||||||
|
|
||||||
|
forceRedraw();
|
||||||
_displaying = true;
|
_displaying = true;
|
||||||
mainLoop();
|
mainLoop();
|
||||||
|
|
||||||
@ -127,44 +133,43 @@ void VirtualKeyboardGUI::reset() {
|
|||||||
_kbdSurface = 0;
|
_kbdSurface = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualKeyboardGUI::setDefaultPosition()
|
void VirtualKeyboardGUI::moveToDefaultPosition()
|
||||||
{
|
{
|
||||||
int16 scrW = _system->getOverlayWidth(), scrH = _system->getOverlayHeight();
|
int16 scrW = _system->getOverlayWidth(), scrH = _system->getOverlayHeight();
|
||||||
int16 kbdW = _kbdBound.width(), kbdH = _kbdBound.height();
|
int16 kbdW = _kbdBound.width(), kbdH = _kbdBound.height();
|
||||||
int16 posX = 0, posY = 0;
|
int16 x = 0, y = 0;
|
||||||
if (scrW != kbdW) {
|
if (scrW != kbdW) {
|
||||||
switch (_kbd->_hAlignment) {
|
switch (_kbd->_hAlignment) {
|
||||||
case VirtualKeyboard::kAlignLeft:
|
case VirtualKeyboard::kAlignLeft:
|
||||||
posX = 0;
|
x = 0;
|
||||||
break;
|
break;
|
||||||
case VirtualKeyboard::kAlignCentre:
|
case VirtualKeyboard::kAlignCentre:
|
||||||
posX = (scrW - kbdW) / 2;
|
x = (scrW - kbdW) / 2;
|
||||||
break;
|
break;
|
||||||
case VirtualKeyboard::kAlignRight:
|
case VirtualKeyboard::kAlignRight:
|
||||||
posX = scrW - kbdW;
|
x = scrW - kbdW;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (scrH != kbdH) {
|
if (scrH != kbdH) {
|
||||||
switch (_kbd->_vAlignment) {
|
switch (_kbd->_vAlignment) {
|
||||||
case VirtualKeyboard::kAlignTop:
|
case VirtualKeyboard::kAlignTop:
|
||||||
posY = 0;
|
y = 0;
|
||||||
break;
|
break;
|
||||||
case VirtualKeyboard::kAlignMiddle:
|
case VirtualKeyboard::kAlignMiddle:
|
||||||
posY = (scrH - kbdH) / 2;
|
y = (scrH - kbdH) / 2;
|
||||||
break;
|
break;
|
||||||
case VirtualKeyboard::kAlignBottom:
|
case VirtualKeyboard::kAlignBottom:
|
||||||
posY = scrH - kbdH;
|
y = scrH - kbdH;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_kbdBound.moveTo(posX, posY);
|
move(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualKeyboardGUI::move(int16 x, int16 y) {
|
void VirtualKeyboardGUI::move(int16 x, int16 y) {
|
||||||
// add old position to dirty area
|
// add old position to dirty area
|
||||||
extendDirtyRect(_kbdBound);
|
extendDirtyRect(_kbdBound);
|
||||||
_needRedraw = true;
|
|
||||||
|
|
||||||
// snap to edge of screen
|
// snap to edge of screen
|
||||||
if (ABS(x) < SNAP_WIDTH)
|
if (ABS(x) < SNAP_WIDTH)
|
||||||
@ -178,7 +183,14 @@ void VirtualKeyboardGUI::move(int16 x, int16 y) {
|
|||||||
if (ABS(y - y2) < SNAP_WIDTH)
|
if (ABS(y - y2) < SNAP_WIDTH)
|
||||||
y = y2;
|
y = y2;
|
||||||
|
|
||||||
|
_dispX += x - _kbdBound.left;
|
||||||
|
_dispY += y - _kbdBound.top;
|
||||||
_kbdBound.moveTo(x, y);
|
_kbdBound.moveTo(x, y);
|
||||||
|
|
||||||
|
// add new position to dirty area
|
||||||
|
extendDirtyRect(_kbdBound);
|
||||||
|
|
||||||
|
redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualKeyboardGUI::screenChanged() {
|
void VirtualKeyboardGUI::screenChanged() {
|
||||||
@ -192,13 +204,9 @@ void VirtualKeyboardGUI::mainLoop() {
|
|||||||
Common::EventManager *eventMan = _system->getEventManager();
|
Common::EventManager *eventMan = _system->getEventManager();
|
||||||
|
|
||||||
while (_displaying) {
|
while (_displaying) {
|
||||||
if (_displayEnabled) {
|
if (_kbd->_keyQueue.hasStringChanged())
|
||||||
if (_kbd->_keyQueue.hasStringChanged())
|
updateDisplay();
|
||||||
_refreshDisplay = true;
|
animateCaret();
|
||||||
animateCaret();
|
|
||||||
if (_refreshDisplay) updateDisplay();
|
|
||||||
}
|
|
||||||
if (_needRedraw) redraw();
|
|
||||||
animateCursor();
|
animateCursor();
|
||||||
_system->updateScreen();
|
_system->updateScreen();
|
||||||
Common::Event event;
|
Common::Event event;
|
||||||
@ -252,18 +260,21 @@ void VirtualKeyboardGUI::extendDirtyRect(const Rect &r) {
|
|||||||
} else {
|
} else {
|
||||||
_dirtyRect = r;
|
_dirtyRect = r;
|
||||||
}
|
}
|
||||||
_dirtyRect.clip(Rect(0, 0, _overlayBackup.w, _overlayBackup.h));
|
_dirtyRect.clip(Rect(_overlayBackup.w, _overlayBackup.h));
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualKeyboardGUI::resetDirtyRect() {
|
void VirtualKeyboardGUI::resetDirtyRect() {
|
||||||
_dirtyRect.setWidth(-1);
|
_dirtyRect.setWidth(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VirtualKeyboardGUI::forceRedraw() {
|
||||||
|
extendDirtyRect(Rect(_overlayBackup.w, _overlayBackup.h));
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
|
||||||
void VirtualKeyboardGUI::redraw() {
|
void VirtualKeyboardGUI::redraw() {
|
||||||
assert(_kbdSurface);
|
assert(_kbdSurface);
|
||||||
|
|
||||||
extendDirtyRect(_kbdBound);
|
|
||||||
|
|
||||||
Graphics::SurfaceKeyColored surf;
|
Graphics::SurfaceKeyColored surf;
|
||||||
surf.create(_dirtyRect.width(), _dirtyRect.height(), sizeof(OverlayColor));
|
surf.create(_dirtyRect.width(), _dirtyRect.height(), sizeof(OverlayColor));
|
||||||
|
|
||||||
@ -277,16 +288,12 @@ void VirtualKeyboardGUI::redraw() {
|
|||||||
src += _overlayBackup.w;
|
src += _overlayBackup.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16 keyX = _kbdBound.left - _dirtyRect.left;
|
surf.blit(_kbdSurface, _kbdBound.left - _dirtyRect.left, _kbdBound.top - _dirtyRect.top, _kbdTransparentColor);
|
||||||
int16 keyY = _kbdBound.top - _dirtyRect.top;
|
if (_displayEnabled) surf.blit(&_dispSurface, _dispX - _dirtyRect.left, _dispY - _dirtyRect.top, _dispBackColor);
|
||||||
surf.blit(_kbdSurface, keyX, keyY, _kbdTransparentColor);
|
|
||||||
if (_displayEnabled) surf.blit(&_dispSurface, keyX + _dispX, keyY + _dispY, _dispBackColor);
|
|
||||||
_system->copyRectToOverlay((OverlayColor*)surf.pixels, surf.w,
|
_system->copyRectToOverlay((OverlayColor*)surf.pixels, surf.w,
|
||||||
_dirtyRect.left, _dirtyRect.top, surf.w, surf.h);
|
_dirtyRect.left, _dirtyRect.top, surf.w, surf.h);
|
||||||
|
|
||||||
surf.free();
|
surf.free();
|
||||||
|
|
||||||
_needRedraw = false;
|
|
||||||
|
|
||||||
resetDirtyRect();
|
resetDirtyRect();
|
||||||
}
|
}
|
||||||
@ -301,15 +308,21 @@ uint VirtualKeyboardGUI::calculateEndIndex(const String& str, uint startIndex) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VirtualKeyboardGUI::animateCaret() {
|
void VirtualKeyboardGUI::animateCaret() {
|
||||||
|
if (!_displayEnabled) return;
|
||||||
|
|
||||||
if (_system->getMillis() % kCaretBlinkTime < kCaretBlinkTime / 2) {
|
if (_system->getMillis() % kCaretBlinkTime < kCaretBlinkTime / 2) {
|
||||||
if (!_drawCaret) {
|
if (!_drawCaret) {
|
||||||
_drawCaret = true;
|
_drawCaret = true;
|
||||||
_refreshDisplay = true;
|
_dispSurface.drawLine(_caretX, 0, _caretX, _dispSurface.h, _dispForeColor);
|
||||||
|
extendDirtyRect(Rect(_dispX + _caretX, _dispY, _dispX + _caretX + 1, _dispY + _dispSurface.h));
|
||||||
|
redraw();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (_drawCaret) {
|
if (_drawCaret) {
|
||||||
_drawCaret = false;
|
_drawCaret = false;
|
||||||
_refreshDisplay = true;
|
_dispSurface.drawLine(_caretX, 0, _caretX, _dispSurface.h, _dispBackColor);
|
||||||
|
extendDirtyRect(Rect(_dispX + _caretX, _dispY, _dispX + _caretX + 1, _dispY + _dispSurface.h));
|
||||||
|
redraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -317,8 +330,6 @@ void VirtualKeyboardGUI::animateCaret() {
|
|||||||
void VirtualKeyboardGUI::updateDisplay() {
|
void VirtualKeyboardGUI::updateDisplay() {
|
||||||
if (!_displayEnabled) return;
|
if (!_displayEnabled) return;
|
||||||
|
|
||||||
_refreshDisplay = false;
|
|
||||||
|
|
||||||
// calculate the text to display
|
// calculate the text to display
|
||||||
uint cursorPos = _kbd->_keyQueue.getInsertIndex();
|
uint cursorPos = _kbd->_keyQueue.getInsertIndex();
|
||||||
String wholeText = _kbd->_keyQueue.getString();
|
String wholeText = _kbd->_keyQueue.getString();
|
||||||
@ -333,15 +344,15 @@ void VirtualKeyboardGUI::updateDisplay() {
|
|||||||
String dispText = String(wholeText.c_str() + _dispI, wholeText.c_str() + dispTextEnd);
|
String dispText = String(wholeText.c_str() + _dispI, wholeText.c_str() + dispTextEnd);
|
||||||
|
|
||||||
// draw to display surface
|
// draw to display surface
|
||||||
_dispSurface.fillRect(Rect(0, 0, _dispSurface.w, _dispSurface.h), _dispBackColor);
|
_dispSurface.fillRect(Rect(_dispSurface.w, _dispSurface.h), _dispBackColor);
|
||||||
_dispFont->drawString(&_dispSurface, dispText, 0, 0, _dispSurface.w, _dispForeColor);
|
_dispFont->drawString(&_dispSurface, dispText, 0, 0, _dispSurface.w, _dispForeColor);
|
||||||
if (_drawCaret) {
|
|
||||||
String beforeCaret(wholeText.c_str() + _dispI, wholeText.c_str() + cursorPos);
|
String beforeCaret(wholeText.c_str() + _dispI, wholeText.c_str() + cursorPos);
|
||||||
int16 caretX = _dispFont->getStringWidth(beforeCaret);
|
_caretX = _dispFont->getStringWidth(beforeCaret);
|
||||||
_dispSurface.drawLine(caretX, 0, caretX, _dispSurface.h, _dispForeColor);
|
if (_drawCaret) _dispSurface.drawLine(_caretX, 0, _caretX, _dispSurface.h, _dispForeColor);
|
||||||
}
|
|
||||||
|
|
||||||
_needRedraw = true;
|
extendDirtyRect(Rect(_dispX, _dispY, _dispX + _dispSurface.w, _dispY + _dispSurface.h));
|
||||||
|
redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualKeyboardGUI::setupCursor() {
|
void VirtualKeyboardGUI::setupCursor() {
|
||||||
|
@ -53,45 +53,43 @@ private:
|
|||||||
|
|
||||||
OSystem *_system;
|
OSystem *_system;
|
||||||
VirtualKeyboard *_kbd;
|
VirtualKeyboard *_kbd;
|
||||||
|
Rect _kbdBound;
|
||||||
Graphics::Surface *_kbdSurface;
|
Graphics::Surface *_kbdSurface;
|
||||||
OverlayColor _kbdTransparentColor;
|
OverlayColor _kbdTransparentColor;
|
||||||
|
|
||||||
|
Point _dragPoint;
|
||||||
|
bool _drag;
|
||||||
static const int SNAP_WIDTH = 10;
|
static const int SNAP_WIDTH = 10;
|
||||||
|
|
||||||
Graphics::Surface _overlayBackup;
|
Graphics::Surface _overlayBackup;
|
||||||
|
|
||||||
Rect _dirtyRect;
|
Rect _dirtyRect;
|
||||||
|
|
||||||
bool _displayEnabled;
|
bool _displayEnabled;
|
||||||
bool _refreshDisplay;
|
|
||||||
Graphics::Surface _dispSurface;
|
Graphics::Surface _dispSurface;
|
||||||
const Graphics::Font *_dispFont;
|
const Graphics::Font *_dispFont;
|
||||||
int16 _dispX, _dispY;
|
int16 _dispX, _dispY;
|
||||||
uint _dispI;
|
uint _dispI;
|
||||||
OverlayColor _dispForeColor, _dispBackColor;
|
OverlayColor _dispForeColor, _dispBackColor;
|
||||||
|
|
||||||
Rect _kbdBound;
|
|
||||||
|
|
||||||
Point _dragPoint;
|
|
||||||
bool _drag;
|
|
||||||
|
|
||||||
bool _displaying;
|
bool _displaying;
|
||||||
bool _firstRun;
|
bool _firstRun;
|
||||||
bool _needRedraw;
|
|
||||||
int _lastScreenChanged;
|
int _lastScreenChanged;
|
||||||
|
|
||||||
void setDefaultPosition();
|
void setupDisplayArea(Rect& r, OverlayColor forecolor);
|
||||||
void move(int16 x, int16 y);
|
void move(int16 x, int16 y);
|
||||||
|
void moveToDefaultPosition();
|
||||||
void screenChanged();
|
void screenChanged();
|
||||||
void mainLoop();
|
void mainLoop();
|
||||||
void extendDirtyRect(const Rect &r);
|
void extendDirtyRect(const Rect &r);
|
||||||
void resetDirtyRect();
|
void resetDirtyRect();
|
||||||
void redraw();
|
void redraw();
|
||||||
|
void forceRedraw();
|
||||||
void updateDisplay();
|
void updateDisplay();
|
||||||
bool fontIsSuitable(const Graphics::Font *font, const Rect& rect);
|
bool fontIsSuitable(const Graphics::Font *font, const Rect& rect);
|
||||||
uint calculateEndIndex(const String& str, uint startIndex);
|
uint calculateEndIndex(const String& str, uint startIndex);
|
||||||
|
|
||||||
bool _drawCaret;
|
bool _drawCaret;
|
||||||
|
int16 _caretX;
|
||||||
static const int kCaretBlinkTime = 500;
|
static const int kCaretBlinkTime = 500;
|
||||||
void animateCaret();
|
void animateCaret();
|
||||||
|
|
||||||
|
@ -308,6 +308,7 @@ void VirtualKeyboard::KeyPressQueue::deleteKey() {
|
|||||||
while((it->strLen)-- > 0)
|
while((it->strLen)-- > 0)
|
||||||
_keysStr.deleteChar(_strPos);
|
_keysStr.deleteChar(_strPos);
|
||||||
_keys.erase(it);
|
_keys.erase(it);
|
||||||
|
_strChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualKeyboard::KeyPressQueue::moveLeft() {
|
void VirtualKeyboard::KeyPressQueue::moveLeft() {
|
||||||
@ -315,6 +316,7 @@ void VirtualKeyboard::KeyPressQueue::moveLeft() {
|
|||||||
return;
|
return;
|
||||||
_keyPos--;
|
_keyPos--;
|
||||||
_strPos -= _keyPos->strLen;
|
_strPos -= _keyPos->strLen;
|
||||||
|
_strChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualKeyboard::KeyPressQueue::moveRight() {
|
void VirtualKeyboard::KeyPressQueue::moveRight() {
|
||||||
@ -322,6 +324,7 @@ void VirtualKeyboard::KeyPressQueue::moveRight() {
|
|||||||
return;
|
return;
|
||||||
_strPos += _keyPos->strLen;
|
_strPos += _keyPos->strLen;
|
||||||
_keyPos++;
|
_keyPos++;
|
||||||
|
_strChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyState VirtualKeyboard::KeyPressQueue::pop() {
|
KeyState VirtualKeyboard::KeyPressQueue::pop() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user