aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backends/common/virtual-keyboard.cpp135
-rw-r--r--backends/common/virtual-keyboard.h20
-rw-r--r--common/rect.h4
-rw-r--r--common/shape.h1
-rw-r--r--graphics/surface-keycolored.cpp26
-rw-r--r--graphics/surface-keycolored.h2
6 files changed, 139 insertions, 49 deletions
diff --git a/backends/common/virtual-keyboard.cpp b/backends/common/virtual-keyboard.cpp
index e87d10ab3c..610e6affa4 100644
--- a/backends/common/virtual-keyboard.cpp
+++ b/backends/common/virtual-keyboard.cpp
@@ -38,7 +38,9 @@ VirtualKeyboard::VirtualKeyboard() : _currentMode(0), _keyDown(0) {
_system = g_system;
_parser = new VirtualKeyboardParser(this);
- _loaded = _displaying = false;
+ _loaded = _displaying = _drag = false;
+ _screenWidth = _system->getOverlayWidth();
+ _screenHeight = _system->getOverlayHeight();
}
VirtualKeyboard::~VirtualKeyboard() {
@@ -50,12 +52,16 @@ void VirtualKeyboard::reset() {
// TODO: clean up event data pointers
_modes.clear();
_initialMode = _currentMode = 0;
- _pos.x = _pos.y = 0;
+ _kbdBound.left = _kbdBound.top
+ = _kbdBound.right = _kbdBound.bottom = 0;
_hAlignment = kAlignCentre;
_vAlignment = kAlignBottom;
_keyQueue.clear();
_keyDown = 0;
- _displaying = false;
+ _displaying = _drag = false;
+ _firstRun = true;
+ _screenWidth = _system->getOverlayWidth();
+ _screenHeight = _system->getOverlayHeight();
}
bool VirtualKeyboard::loadKeyboardPack(Common::String packName) {
@@ -105,53 +111,78 @@ bool VirtualKeyboard::loadKeyboardPack(Common::String packName) {
_loaded = _parser->parse();
if (_loaded)
printf("Keyboard pack '%s' loaded successfully!\n", packName.c_str());
+
return _loaded;
}
-void VirtualKeyboard::reposition()
+void VirtualKeyboard::setDefaultPosition()
{
- // calculate keyboard co-ordinates
- int16 scrW = _system->getOverlayWidth(), scrH = _system->getOverlayHeight();
- int16 keyW = _currentMode->image->w, keyH = _currentMode->image->h;
- if (scrW != keyW) {
+ int16 kbdW = _kbdBound.width(), kbdH = _kbdBound.height();
+ int16 posX = 0, posY = 0;
+ if (_screenWidth != kbdW) {
switch (_hAlignment) {
+ case kAlignLeft:
+ posX = 0;
+ break;
case kAlignCentre:
- _pos.x = (scrW - keyW) / 2;
+ posX = (_screenWidth - kbdW) / 2;
break;
case kAlignRight:
- _pos.x = scrW - keyW;
- break;
- default:
+ posX = _screenWidth - kbdW;
break;
}
}
- if (scrH != keyH) {
+ if (_screenHeight != kbdH) {
switch (_vAlignment) {
+ case kAlignTop:
+ posY = 0;
+ break;
case kAlignMiddle:
- _pos.y = (scrH - keyH) / 2;
+ posY = (_screenHeight - kbdH) / 2;
break;
case kAlignBottom:
- _pos.y = scrH - keyH;
- break;
- default:
+ posY = _screenHeight - kbdH;
break;
}
}
+ _kbdBound.moveTo(posX, posY);
}
-void VirtualKeyboard::processClick(int16 x, int16 y)
+void VirtualKeyboard::checkResolution()
{
- x -= _pos.x;
- y -= _pos.y;
- if (x < 0 || x > _currentMode->image->w) return;
- if (y < 0 || y > _currentMode->image->h) return;
-
- Common::String area = _currentMode->imageMap.findMapArea(x, y);
- if (area.empty()) return;
- printf("Map area found! - %s\n", area.c_str());
+ // check if there is a more suitable resolution
+ // in the keyboard pack than the current one
+ // based on the _screenWidth & _screenHeight
+}
+
+void VirtualKeyboard::move(int16 x, int16 y) {
+ // snap to edge of screen
+ if (ABS(x) < SNAP_WIDTH)
+ x = 0;
+ int16 x2 = _system->getOverlayWidth() - _kbdBound.width();
+ if (ABS(x - x2) < SNAP_WIDTH)
+ x = x2;
+ if (ABS(y) < SNAP_WIDTH)
+ y = 0;
+ int16 y2 = _system->getOverlayHeight() - _kbdBound.height();
+ if (ABS(y - y2) < SNAP_WIDTH)
+ y = y2;
+
+ _kbdBound.moveTo(x, y);
+}
+
+Common::String VirtualKeyboard::findArea(int16 x, int16 y) {
+ x -= _kbdBound.left;
+ y -= _kbdBound.top;
+ if (x < 0 || x > _kbdBound.width()) return "";
+ if (y < 0 || y > _kbdBound.height()) return "";
+ return _currentMode->imageMap.findMapArea(x, y);
+}
+
+void VirtualKeyboard::processClick(const Common::String& area) {
if (!_currentMode->events.contains(area)) return;
Event evt = _currentMode->events[area];
-
+
switch (evt.type) {
case kEventKey:
// add virtual keypress to queue
@@ -170,7 +201,8 @@ void VirtualKeyboard::processClick(int16 x, int16 y)
void VirtualKeyboard::switchMode(Mode *newMode) {
_currentMode = newMode;
- reposition();
+ _kbdBound.setWidth(_currentMode->image->w);
+ _kbdBound.setHeight(_currentMode->image->h);
_needRedraw = true;
}
@@ -179,14 +211,20 @@ void VirtualKeyboard::switchMode(const Common::String& newMode) {
warning("Keyboard mode '%s' unknown", newMode.c_str());
return;
}
- _currentMode = &_modes[newMode];
- reposition();
- _needRedraw = true;
+ switchMode(&_modes[newMode]);
}
void VirtualKeyboard::show() {
+ if (_screenWidth != _system->getOverlayWidth() || _screenHeight != _system->getOverlayHeight()) {
+ _screenWidth = _system->getOverlayWidth();
+ _screenHeight = _system->getOverlayHeight();
+ }
switchMode(_initialMode);
_displaying = true;
+ if (_firstRun) {
+ _firstRun = false;
+ setDefaultPosition();
+ }
runLoop();
}
@@ -198,7 +236,7 @@ void VirtualKeyboard::runLoop() {
Common::EventManager *eventMan = _system->getEventManager();
_system->showOverlay();
- // capture mouse clicks
+
while (_displaying) {
if (_needRedraw) redraw();
@@ -207,12 +245,34 @@ void VirtualKeyboard::runLoop() {
while (eventMan->pollEvent(event)) {
switch (event.type) {
case Common::EVENT_LBUTTONDOWN:
- _mouseDown = event.mouse;
+ if (_kbdBound.contains(event.mouse)) {
+ _areaDown = findArea(event.mouse.x, event.mouse.y);
+ if (_areaDown.empty()) {
+ _drag = true;
+ _dragPoint.x = event.mouse.x - _kbdBound.left;
+ _dragPoint.y = event.mouse.y - _kbdBound.top;
+ }
+ } else
+ _areaDown.clear();
break;
case Common::EVENT_LBUTTONUP:
- if (ABS(_mouseDown.x - event.mouse.x) < 5
- && ABS(_mouseDown.y - event.mouse.y) < 5)
- processClick(event.mouse.x, event.mouse.y);
+ if (_drag) _drag = false;
+ if (!_areaDown.empty() && _areaDown == findArea(event.mouse.x, event.mouse.y)) {
+ processClick(_areaDown);
+ _areaDown.clear();
+ }
+ break;
+ case Common::EVENT_MOUSEMOVE:
+ if (_drag) {
+ move(event.mouse.x - _dragPoint.x,
+ event.mouse.y - _dragPoint.y);
+ _needRedraw = true;
+ }
+ break;
+ case Common::EVENT_SCREEN_CHANGED:
+ _screenWidth = _system->getOverlayWidth();
+ _screenHeight = _system->getOverlayHeight();
+ checkResolution();
break;
case Common::EVENT_QUIT:
_system->quit();
@@ -231,9 +291,10 @@ void VirtualKeyboard::redraw() {
surf.create(_system->getOverlayWidth(), _system->getOverlayHeight(), sizeof(OverlayColor));
+ _system->clearOverlay();
_system->grabOverlay((OverlayColor*)surf.pixels, surf.w);
- surf.blit(_currentMode->image, _pos.x, _pos.y, _system->RGBToColor(0xff, 0, 0xff));
+ surf.blit(_currentMode->image, _kbdBound.left, _kbdBound.top, _system->RGBToColor(0xff, 0, 0xff));
_system->copyRectToOverlay((OverlayColor*)surf.pixels, surf.w, 0, 0, surf.w, surf.h);
surf.free();
diff --git a/backends/common/virtual-keyboard.h b/backends/common/virtual-keyboard.h
index ff07384e06..a3585296f9 100644
--- a/backends/common/virtual-keyboard.h
+++ b/backends/common/virtual-keyboard.h
@@ -104,34 +104,44 @@ public:
*/
bool pollEvent(Common::Event &event);
-private:
+protected:
OSystem *_system;
+
+ static const int SNAP_WIDTH = 10;
friend class VirtualKeyboardParser;
VirtualKeyboardParser *_parser;
// TODO : sort order of all this stuff
void reset();
- void reposition();
+ void checkResolution();
+ void setDefaultPosition();
+ void move(int16 x, int16 y);
void switchMode(Mode *newMode);
void switchMode(const Common::String& newMode);
- void processClick(int16 x, int16 y);
+ Common::String findArea(int16 x, int16 y);
+ void processClick(const Common::String &area);
void runLoop();
void redraw();
bool _loaded;
bool _displaying;
bool _needRedraw;
+ bool _firstRun;
ModeMap _modes;
Mode *_initialMode;
Mode *_currentMode;
- Common::Point _pos;
+ int16 _screenWidth, _screenHeight;
+ Common::Rect _kbdBound;
+
HorizontalAlignment _hAlignment;
VerticalAlignment _vAlignment;
- Common::Point _mouseDown;
+ Common::String _areaDown;
+ Common::Point _dragPoint;
+ bool _drag;
Common::Array<Common::KeyState> _keyQueue;
Common::KeyState *_keyDown;
diff --git a/common/rect.h b/common/rect.h
index 0cd10a2147..0c149f613f 100644
--- a/common/rect.h
+++ b/common/rect.h
@@ -40,7 +40,7 @@ namespace Common {
Another very wide spread approach to rectangle classes treats (bottom,right)
also as a part of the rectangle.
- Coneptually, both are sound, but the approach we use saves many intermediate
+ Conceptually, both are sound, but the approach we use saves many intermediate
computations (like computing the height in our case is done by doing this:
height = bottom - top;
while in the alternate system, it would be
@@ -57,6 +57,8 @@ struct Rect : public Shape {
Rect(int16 x1, int16 y1, int16 x2, int16 y2) : top(y1), left(x1), bottom(y2), right(x2) {
assert(isValidRect());
}
+ virtual ~Rect() {}
+
int16 width() const { return right - left; }
int16 height() const { return bottom - top; }
diff --git a/common/shape.h b/common/shape.h
index 981241eee5..2cce365bfc 100644
--- a/common/shape.h
+++ b/common/shape.h
@@ -72,6 +72,7 @@ struct Point {
*/
struct Shape {
+ virtual ~Shape() {}
/*! @brief check if given position is inside this shape
@param x the horizontal position to check
diff --git a/graphics/surface-keycolored.cpp b/graphics/surface-keycolored.cpp
index 79beb5d5b5..f533213fb6 100644
--- a/graphics/surface-keycolored.cpp
+++ b/graphics/surface-keycolored.cpp
@@ -2,22 +2,38 @@
namespace Graphics {
-void SurfaceKeyColored::blit(Surface *surf_src, int16 x, int16 y, OverlayColor trans) {
+void SurfaceKeyColored::blit(Surface *surf_src, int16 x, int16 y, OverlayColor transparent) {
if (bytesPerPixel != sizeof(OverlayColor) || surf_src->bytesPerPixel != sizeof(OverlayColor)) return ;
- OverlayColor *dst = (OverlayColor*) getBasePtr(x, y);
const OverlayColor *src = (const OverlayColor*)surf_src->pixels;
+ int blitW = surf_src->w;
+ int blitH = surf_src->h;
- int blitW = (surf_src->w + x > w) ? w - x : surf_src->w;
- int blitH = (surf_src->h + y > h) ? h - y : surf_src->h;
+ // clip co-ordinates
+ if (x < 0) {
+ blitW += x;
+ src -= x;
+ x = 0;
+ }
+ if (y < 0) {
+ blitH += y;
+ src -= y * surf_src->w;
+ y = 0;
+ }
+ if (blitW > w - x) blitW = w - x;
+ if (blitH > h - y) blitH = h - y;
+ if (blitW <= 0 || blitH <= 0)
+ return;
+
+ OverlayColor *dst = (OverlayColor*) getBasePtr(x, y);
int dstAdd = w - blitW;
int srcAdd = surf_src->w - blitW;
for (int i = 0; i < blitH; ++i) {
for (int j = 0; j < blitW; ++j, ++dst, ++src) {
OverlayColor col = *src;
- if (col != trans)
+ if (col != transparent)
*dst = col;
}
dst += dstAdd;
diff --git a/graphics/surface-keycolored.h b/graphics/surface-keycolored.h
index d2788b204e..608bf7a482 100644
--- a/graphics/surface-keycolored.h
+++ b/graphics/surface-keycolored.h
@@ -8,7 +8,7 @@ namespace Graphics {
struct SurfaceKeyColored : Surface {
- void blit(Surface *surf_src, int16 x, int16 y, OverlayColor trans);
+ void blit(Surface *surf_src, int16 x, int16 y, OverlayColor transparent);
};