Initial commit
This commit is contained in:
859
engines/bagel/spacebar/boflib/gui/window.cpp
Normal file
859
engines/bagel/spacebar/boflib/gui/window.cpp
Normal file
@@ -0,0 +1,859 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "bagel/spacebar/boflib/gui/window.h"
|
||||
#include "bagel/spacebar/boflib/app.h"
|
||||
#include "bagel/spacebar/boflib/events.h"
|
||||
#include "bagel/boflib/sound.h"
|
||||
#include "bagel/spacebar/boflib/std_keys.h"
|
||||
#include "bagel/metaengine.h"
|
||||
#include "bagel/bagel.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define DOUBLE_CLICK_TIME 250
|
||||
|
||||
// Static members defined here
|
||||
CBofWindow *CBofWindow::_pWindowList = nullptr;
|
||||
CBofWindow *CBofWindow::_pActiveWindow = nullptr;
|
||||
CBofTimerPacket *CBofWindow::_pTimerList = nullptr;
|
||||
int CBofWindow::_mouseX = 0;
|
||||
int CBofWindow::_mouseY = 0;
|
||||
|
||||
CBofWindow::CBofWindow() {
|
||||
if (_pActiveWindow == nullptr)
|
||||
_pActiveWindow = this;
|
||||
|
||||
if (_pWindowList == nullptr) {
|
||||
_pWindowList = this;
|
||||
} else {
|
||||
_pWindowList->Insert(this);
|
||||
}
|
||||
}
|
||||
|
||||
CBofWindow::CBofWindow(const char *pszName, int x, int y, int nWidth, int nHeight, CBofWindow *pParent) {
|
||||
if (_pWindowList == nullptr) {
|
||||
_pWindowList = this;
|
||||
} else {
|
||||
_pWindowList->Insert(this);
|
||||
}
|
||||
|
||||
create(pszName, x, y, nWidth, nHeight, pParent);
|
||||
}
|
||||
|
||||
CBofWindow::~CBofWindow() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
delete _surface;
|
||||
_surface = nullptr;
|
||||
|
||||
killMyTimers();
|
||||
|
||||
// Remove it from any parent
|
||||
if (_parent != nullptr)
|
||||
setParent(nullptr);
|
||||
|
||||
// Remove this window from the list
|
||||
if (_pWindowList == this) {
|
||||
_pWindowList = (CBofWindow *)getNext();
|
||||
}
|
||||
|
||||
killBackdrop();
|
||||
|
||||
CBofWindow::destroy();
|
||||
}
|
||||
|
||||
ErrorCode CBofWindow::initialize() {
|
||||
_pWindowList = nullptr;
|
||||
_pActiveWindow = nullptr;
|
||||
_pTimerList = nullptr;
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
ErrorCode CBofWindow::shutdown() {
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
Common::Point CBofWindow::getMousePos() {
|
||||
return Common::Point(_mouseX, _mouseY);
|
||||
}
|
||||
|
||||
void CBofWindow::destroy() {
|
||||
releaseCapture();
|
||||
|
||||
delete _surface;
|
||||
_surface = nullptr;
|
||||
|
||||
// When gui elements are destroyed, remove them
|
||||
// from the _children array of their parent
|
||||
setParent(nullptr);
|
||||
}
|
||||
|
||||
void CBofWindow::validateAnscestors(CBofRect *pRect) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Validate all anscestors
|
||||
CBofWindow *pParent = _parent;
|
||||
while (pParent != nullptr) {
|
||||
pParent->validateRect(pRect);
|
||||
pParent = pParent->getParent();
|
||||
}
|
||||
}
|
||||
|
||||
ErrorCode CBofWindow::create(const char *pszName, int x, int y, int nWidth, int nHeight, CBofWindow *pParent, uint32 nControlID) {
|
||||
assert(isValidObject(this));
|
||||
assert(pszName != nullptr);
|
||||
assert(pParent != this);
|
||||
|
||||
// Remember who our parent is
|
||||
if (pParent != nullptr)
|
||||
setParent(pParent);
|
||||
|
||||
_nID = nControlID;
|
||||
|
||||
// Remember the name of this window
|
||||
Common::strlcpy(_szTitle, pszName, MAX_TITLE);
|
||||
|
||||
// Retain screen coordinates for this window
|
||||
_cWindowRect.setRect(x, y, x + nWidth - 1, y + nHeight - 1);
|
||||
|
||||
// Calculate effective bounds
|
||||
Common::Rect stRect(x, y, x + nWidth, y + nHeight);
|
||||
if (pParent != nullptr)
|
||||
stRect.translate(pParent->getWindowRect().left,
|
||||
pParent->getWindowRect().top);
|
||||
|
||||
delete _surface;
|
||||
_surface = new Graphics::ManagedSurface(*g_engine->getScreen(), stRect);
|
||||
|
||||
if (!errorOccurred()) {
|
||||
CBofPalette *pPalette = CBofApp::getApp()->getPalette();
|
||||
if (pPalette != nullptr) {
|
||||
selectPalette(pPalette);
|
||||
}
|
||||
|
||||
// Retain local coordinates (based on own window)
|
||||
_cRect.setRect(0, 0, _cWindowRect.width() - 1, _cWindowRect.height() - 1);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
void CBofWindow::updateWindow() {
|
||||
if (_visible) {
|
||||
if (isVisible())
|
||||
onPaint(&_cRect);
|
||||
|
||||
for (uint i = 0; i < _children.size(); ++i)
|
||||
_children[i]->updateWindow();
|
||||
}
|
||||
}
|
||||
|
||||
void CBofWindow::setParent(CBofWindow *parent) {
|
||||
if (_parent != nullptr)
|
||||
_parent->_children.remove(this);
|
||||
|
||||
_parent = parent;
|
||||
if (parent)
|
||||
parent->_children.push_back(this);
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofWindow::create(const char *pszName, CBofRect *pRect, CBofWindow *pParent, uint32 nControlID) {
|
||||
assert(isValidObject(this));
|
||||
assert(pszName != nullptr);
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
int nWidth = USE_DEFAULT;
|
||||
int nHeight = USE_DEFAULT;
|
||||
|
||||
if (pRect != nullptr) {
|
||||
x = pRect->left;
|
||||
y = pRect->top;
|
||||
nWidth = pRect->width();
|
||||
nHeight = pRect->height();
|
||||
}
|
||||
|
||||
return create(pszName, x, y, nWidth, nHeight, pParent, nControlID);
|
||||
}
|
||||
|
||||
void CBofWindow::releaseCapture() {
|
||||
_bCaptured = false;
|
||||
if (hasCapture())
|
||||
CBofApp::getApp()->setCaptureControl(nullptr);
|
||||
}
|
||||
|
||||
void CBofWindow::setCapture() {
|
||||
_bCaptured = true;
|
||||
CBofApp::getApp()->setCaptureControl(this);
|
||||
}
|
||||
|
||||
bool CBofWindow::hasCapture() const {
|
||||
return CBofApp::getApp()->getCaptureControl() == this;
|
||||
}
|
||||
|
||||
void CBofWindow::releaseFocus() {
|
||||
CBofApp::getApp()->setFocusControl(nullptr);
|
||||
}
|
||||
|
||||
void CBofWindow::setFocus() {
|
||||
CBofApp::getApp()->setFocusControl(this);
|
||||
}
|
||||
|
||||
bool CBofWindow::hasFocus() const {
|
||||
return CBofApp::getApp()->getFocusControl() == this;
|
||||
}
|
||||
|
||||
void CBofWindow::center() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
CBofWindow *pParent = _parent;
|
||||
int x, y;
|
||||
|
||||
if (pParent != nullptr) {
|
||||
CBofRect cWindowRect = pParent->getWindowRect();
|
||||
x = cWindowRect.left + (pParent->width() - width()) / 2;
|
||||
y = cWindowRect.top + (pParent->height() - height()) / 2;
|
||||
|
||||
} else {
|
||||
x = (CBofApp::getApp()->screenWidth() - width()) / 2;
|
||||
y = (CBofApp::getApp()->screenHeight() - height()) / 2;
|
||||
}
|
||||
|
||||
move(x, y);
|
||||
}
|
||||
|
||||
void CBofWindow::move(const int x, const int y, bool bRepaint) {
|
||||
assert(isValidObject(this));
|
||||
assert(isCreated());
|
||||
|
||||
// We now have a new position (in screen coordinates)
|
||||
_cWindowRect.setRect(x, y, x + _cRect.width() - 1, y + _cRect.height() - 1);
|
||||
|
||||
// Recreate the surface at the new screen position
|
||||
delete _surface;
|
||||
_surface = new Graphics::ManagedSurface(*g_engine->getScreen(), _cWindowRect);
|
||||
}
|
||||
|
||||
void CBofWindow::reSize(CBofRect *pRect, bool bRepaint) {
|
||||
assert(isValidObject(this));
|
||||
assert(isCreated());
|
||||
assert(pRect != nullptr);
|
||||
|
||||
// We now have a new position (in screen coordinates)
|
||||
_cWindowRect = *pRect;
|
||||
_cRect.setRect(0, 0, _cWindowRect.width() - 1, _cWindowRect.height() - 1);
|
||||
|
||||
// Recreate the surface at the new screen position
|
||||
delete _surface;
|
||||
_surface = new Graphics::ManagedSurface(*g_engine->getScreen(), _cWindowRect);
|
||||
}
|
||||
|
||||
void CBofWindow::select() {
|
||||
// No implementation in ScummVM
|
||||
}
|
||||
|
||||
void CBofWindow::show() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (!errorOccurred()) {
|
||||
assert(isCreated());
|
||||
|
||||
if (isCreated()) {
|
||||
_visible = true;
|
||||
invalidateRect(&_cRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBofWindow::hide() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (!errorOccurred()) {
|
||||
assert(isCreated());
|
||||
|
||||
_visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
void CBofWindow::postMessage(uint32 nMessage, uint32 lParam1, uint32 lParam2) {
|
||||
assert(isValidObject(this));
|
||||
assert(isCreated());
|
||||
}
|
||||
|
||||
void CBofWindow::setTimer(uint32 nID, uint32 nInterval, BofCallback pCallBack) {
|
||||
assert(isValidObject(this));
|
||||
assert(isCreated());
|
||||
|
||||
// Don't add it if there's already a timer there with the same id.
|
||||
CBofTimerPacket *pPacket = _pTimerList;
|
||||
|
||||
while (pPacket != nullptr) {
|
||||
if (pPacket->_nID == nID)
|
||||
return;
|
||||
|
||||
pPacket = (CBofTimerPacket *)pPacket->getNext();
|
||||
}
|
||||
|
||||
pPacket = new CBofTimerPacket;
|
||||
pPacket->_nID = nID;
|
||||
pPacket->_nInterval = nInterval;
|
||||
pPacket->_pCallBack = pCallBack;
|
||||
pPacket->_pOwnerWindow = this;
|
||||
|
||||
// Add this timer to the list of current timers
|
||||
if (_pTimerList != nullptr) {
|
||||
_pTimerList->addToHead(pPacket);
|
||||
}
|
||||
|
||||
_pTimerList = pPacket;
|
||||
|
||||
// Add the timer to the window
|
||||
_timers.push_back(WindowTimer(nInterval, nID, pCallBack));
|
||||
}
|
||||
|
||||
void CBofWindow::killTimer(uint32 nID) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Remove the timer from the window timer list
|
||||
for (Common::List<WindowTimer>::iterator it = _timers.begin(); it != _timers.end(); ++it) {
|
||||
if (it->_id == nID) {
|
||||
_timers.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Find and remove the timer packet for this timer
|
||||
CBofTimerPacket *pPacket = _pTimerList;
|
||||
|
||||
while (pPacket != nullptr) {
|
||||
if (pPacket->_nID == nID) {
|
||||
if (pPacket == _pTimerList) {
|
||||
_pTimerList = (CBofTimerPacket *)_pTimerList->getNext();
|
||||
}
|
||||
|
||||
delete pPacket;
|
||||
break;
|
||||
}
|
||||
|
||||
pPacket = (CBofTimerPacket *)pPacket->getNext();
|
||||
}
|
||||
}
|
||||
|
||||
void CBofWindow::killMyTimers() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
CBofTimerPacket *pTimer = _pTimerList;
|
||||
while (pTimer != nullptr) {
|
||||
CBofTimerPacket *pNextTimer = (CBofTimerPacket *)pTimer->getNext();
|
||||
|
||||
if (pTimer->_pOwnerWindow == this) {
|
||||
killTimer(pTimer->_nID);
|
||||
}
|
||||
|
||||
pTimer = pNextTimer;
|
||||
}
|
||||
}
|
||||
|
||||
void CBofWindow::checkTimers() {
|
||||
for (uint i = 0; i < _children.size(); ++i)
|
||||
_children[i]->checkTimers();
|
||||
|
||||
for (bool timersChanged = true; timersChanged;) {
|
||||
timersChanged = false;
|
||||
uint32 currTime = g_system->getMillis();
|
||||
|
||||
// Iterate over the timers looking for any that have expired
|
||||
for (auto &timer : _timers) {
|
||||
if (currTime >= (timer._lastExpiryTime + timer._interval)) {
|
||||
// Timer has expired
|
||||
timer._lastExpiryTime = currTime;
|
||||
|
||||
if (timer._callback) {
|
||||
(timer._callback)(timer._id, this);
|
||||
} else {
|
||||
onTimer(timer._id);
|
||||
}
|
||||
|
||||
// Flag to restart scanning through the timer list
|
||||
// for any other expired timers, since the timer call
|
||||
// may have modified the existing list
|
||||
timersChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBofWindow::screenToClient(CBofPoint *pPoint) {
|
||||
// Not needed in ScummVM
|
||||
}
|
||||
|
||||
CBofRect CBofWindow::getClientRect() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
CBofRect cRect(0, 0, _cRect.width() - 1, _cRect.height() - 1);
|
||||
return cRect;
|
||||
}
|
||||
|
||||
void CBofWindow::postUserMessage(uint32 lMessage, uint32 lExtraInfo) {
|
||||
Common::Event e;
|
||||
e.type = (Common::EventType)EVENT_USER;
|
||||
e.mouse.x = lMessage;
|
||||
e.mouse.y = lExtraInfo;
|
||||
|
||||
g_system->getEventManager()->pushEvent(e);
|
||||
}
|
||||
|
||||
void CBofWindow::flushAllMessages() {
|
||||
// Make sure this is a valid window
|
||||
assert(isValidObject(this));
|
||||
assert(isCreated());
|
||||
}
|
||||
|
||||
void CBofWindow::validateRect(const CBofRect *pRect) {
|
||||
// No implementation in ScummVM
|
||||
}
|
||||
|
||||
void CBofWindow::invalidateRect(const CBofRect *pRect) {
|
||||
}
|
||||
|
||||
ErrorCode CBofWindow::setBackdrop(CBofBitmap *pNewBitmap, bool bRefresh) {
|
||||
assert(isValidObject(this));
|
||||
assert(pNewBitmap != nullptr);
|
||||
|
||||
// Destroy old backdrop (if any)
|
||||
killBackdrop();
|
||||
|
||||
// We take ownership of this bitmap!
|
||||
_pBackdrop = pNewBitmap;
|
||||
|
||||
if (bRefresh) {
|
||||
_pBackdrop->paint(this, 0, 0);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBofWindow::setBackdrop(const char *pszFileName, bool bRefresh) {
|
||||
assert(isValidObject(this));
|
||||
assert(pszFileName != nullptr);
|
||||
|
||||
// Use Application's palette if none supplied
|
||||
CBofPalette *pPalette = CBofApp::getApp()->getPalette();
|
||||
CBofBitmap *pBmp = new CBofBitmap(pszFileName, pPalette);
|
||||
|
||||
return setBackdrop(pBmp, bRefresh);
|
||||
}
|
||||
|
||||
void CBofWindow::killBackdrop() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
delete _pBackdrop;
|
||||
_pBackdrop = nullptr;
|
||||
}
|
||||
|
||||
ErrorCode CBofWindow::paintBackdrop(CBofRect *pRect, int nTransparentColor) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (_pBackdrop != nullptr) {
|
||||
if (pRect == nullptr) {
|
||||
_errCode = _pBackdrop->paint(this, &_cRect, nullptr, nTransparentColor);
|
||||
} else {
|
||||
_errCode = _pBackdrop->paint(this, pRect, pRect, nTransparentColor);
|
||||
}
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
void CBofWindow::selectPalette(CBofPalette *pPal) {
|
||||
assert(isValidObject(this));
|
||||
assert(isCreated());
|
||||
}
|
||||
|
||||
Graphics::ManagedSurface *CBofWindow::getSurface() {
|
||||
return _surface;
|
||||
}
|
||||
|
||||
|
||||
// Default version of these virtual functions don't do anything
|
||||
//
|
||||
void CBofWindow::onMouseMove(uint32, CBofPoint *, void *) {
|
||||
}
|
||||
|
||||
void CBofWindow::onLButtonDown(uint32, CBofPoint *, void *) {
|
||||
}
|
||||
void CBofWindow::onLButtonUp(uint32, CBofPoint *, void *) {
|
||||
}
|
||||
void CBofWindow::onLButtonDblClk(uint32, CBofPoint *) {
|
||||
}
|
||||
|
||||
void CBofWindow::onRButtonDown(uint32, CBofPoint *) {
|
||||
}
|
||||
void CBofWindow::onRButtonUp(uint32, CBofPoint *) {
|
||||
}
|
||||
void CBofWindow::onRButtonDblClk(uint32, CBofPoint *) {
|
||||
}
|
||||
|
||||
void CBofWindow::onKeyHit(uint32, uint32) {
|
||||
}
|
||||
|
||||
void CBofWindow::onReSize(CBofSize *) {
|
||||
}
|
||||
void CBofWindow::onPaint(CBofRect *) {
|
||||
}
|
||||
void CBofWindow::onTimer(uint32) {
|
||||
}
|
||||
|
||||
void CBofWindow::onClose() {
|
||||
}
|
||||
|
||||
void CBofWindow::onBofButton(CBofObject *, int) {
|
||||
}
|
||||
void CBofWindow::onBofScrollBar(CBofObject *, int) {
|
||||
}
|
||||
void CBofWindow::onBofListBox(CBofObject *, int) {
|
||||
}
|
||||
void CBofWindow::onUserMessage(uint32, uint32) {
|
||||
}
|
||||
void CBofWindow::onMainLoop() {
|
||||
}
|
||||
|
||||
void CBofWindow::onSoundNotify(CBofObject *, uint32) {
|
||||
}
|
||||
void CBofWindow::onMovieNotify(uint32, uint32) {
|
||||
}
|
||||
|
||||
void CBofWindow::onActivate() {
|
||||
}
|
||||
void CBofWindow::onDeActivate() {
|
||||
}
|
||||
|
||||
void CBofWindow::onMCINotify(uint32 wParam, uint32 lParam) {
|
||||
assert(isValidObject(this));
|
||||
}
|
||||
|
||||
void CBofWindow::handleEvents() {
|
||||
Common::Event e;
|
||||
CBofWindow *capture = CBofApp::getApp()->getCaptureControl();
|
||||
CBofWindow *focus = CBofApp::getApp()->getFocusControl();
|
||||
bool eventsPresent = false;
|
||||
|
||||
while (g_system->getEventManager()->pollEvent(e)) {
|
||||
if (capture)
|
||||
capture->handleEvent(e);
|
||||
else if (e.type == Common::EVENT_KEYDOWN && focus)
|
||||
focus->handleEvent(e);
|
||||
else
|
||||
handleEvent(e);
|
||||
|
||||
if (e.type >= Common::EVENT_MOUSEMOVE && e.type <= Common::EVENT_MBUTTONUP) {
|
||||
_mouseX = e.mouse.x;
|
||||
_mouseY = e.mouse.y;
|
||||
}
|
||||
|
||||
if (e.type != Common::EVENT_MOUSEMOVE) {
|
||||
eventsPresent = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Only do timer checks when not processing other pending events.
|
||||
// This simulates Windows behaviour, where the WM_TIMER events
|
||||
// would be added at the end of the event queue
|
||||
if (!eventsPresent)
|
||||
// Check for expired timers
|
||||
checkTimers();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CBofWindow::handleEvent(const Common::Event &event) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (!_enabled || !_visible)
|
||||
// Window is disabled or hidden
|
||||
return;
|
||||
|
||||
CBofPoint mousePos(event.mouse.x - _cWindowRect.left,
|
||||
event.mouse.y - _cWindowRect.top);
|
||||
for (auto parent = _parent; parent; parent = parent->_parent) {
|
||||
mousePos.x -= parent->_cWindowRect.left;
|
||||
mousePos.y -= parent->_cWindowRect.top;
|
||||
}
|
||||
|
||||
switch (event.type) {
|
||||
case Common::EVENT_MOUSEMOVE:
|
||||
case Common::EVENT_LBUTTONDOWN:
|
||||
case Common::EVENT_LBUTTONUP:
|
||||
case Common::EVENT_RBUTTONDOWN:
|
||||
case Common::EVENT_RBUTTONUP: {
|
||||
// Check if the mouse is within the area of a child control
|
||||
for (uint i = 0; i < _children.size(); ++i) {
|
||||
auto &child = *_children[i];
|
||||
if (child.isVisible() && child.isEnabled() &&
|
||||
child.getWindowRect().ptInRect(mousePos)) {
|
||||
child.handleEvent(event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
uint32 currTime = g_system->getMillis();
|
||||
|
||||
switch ((int)event.type) {
|
||||
case Common::EVENT_MOUSEMOVE:
|
||||
onMouseMove(0, &mousePos);
|
||||
break;
|
||||
|
||||
case Common::EVENT_LBUTTONDOWN:
|
||||
if ((currTime - _lastLButtonTime) <= DOUBLE_CLICK_TIME) {
|
||||
_lastLButtonTime = 0;
|
||||
onLButtonDblClk(1, &mousePos);
|
||||
} else {
|
||||
onLButtonDown(1, &mousePos);
|
||||
_lastLButtonTime = currTime;
|
||||
}
|
||||
break;
|
||||
|
||||
case Common::EVENT_LBUTTONUP:
|
||||
onLButtonUp(0, &mousePos);
|
||||
break;
|
||||
|
||||
case Common::EVENT_RBUTTONDOWN:
|
||||
if ((currTime - _lastRButtonTime) <= DOUBLE_CLICK_TIME) {
|
||||
_lastRButtonTime = 0;
|
||||
onRButtonDblClk(2, &mousePos);
|
||||
} else {
|
||||
onRButtonDown(2, &mousePos);
|
||||
_lastRButtonTime = currTime;
|
||||
}
|
||||
break;
|
||||
|
||||
case Common::EVENT_RBUTTONUP:
|
||||
onRButtonUp(0, &mousePos);
|
||||
break;
|
||||
|
||||
case Common::EVENT_KEYDOWN:
|
||||
uint32 lNewKey;
|
||||
|
||||
if ((lNewKey = translateKey(event)) != BKEY_UNKNOWN) {
|
||||
onKeyHit(lNewKey, event.kbdRepeat ? 1 : 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
|
||||
if (event.customType != KEYBIND_NONE)
|
||||
onKeyHit((event.customType == KEYBIND_WAIT)
|
||||
? BKEY_SPACE : BKEY_SCRL_LOCK, 0);
|
||||
break;
|
||||
|
||||
case EVENT_USER:
|
||||
// Message type and param are stored in mouse x/y
|
||||
onUserMessage(event.mouse.x, event.mouse.y);
|
||||
break;
|
||||
|
||||
case Common::EVENT_QUIT:
|
||||
onClose();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32 CBofWindow::translateKey(const Common::Event &event) const {
|
||||
uint32 nCode = BKEY_UNKNOWN;
|
||||
|
||||
switch (event.kbd.keycode) {
|
||||
case Common::KEYCODE_F1:
|
||||
nCode = BKEY_F1;
|
||||
break;
|
||||
case Common::KEYCODE_F2:
|
||||
nCode = BKEY_SAVE;
|
||||
break;
|
||||
case Common::KEYCODE_F3:
|
||||
nCode = BKEY_RESTORE;
|
||||
break;
|
||||
case Common::KEYCODE_F4:
|
||||
nCode = BKEY_F4;
|
||||
break;
|
||||
case Common::KEYCODE_F5:
|
||||
nCode = BKEY_SAVE;
|
||||
break;
|
||||
case Common::KEYCODE_F6:
|
||||
nCode = BKEY_F6;
|
||||
break;
|
||||
case Common::KEYCODE_F7:
|
||||
nCode = BKEY_RESTORE;
|
||||
break;
|
||||
case Common::KEYCODE_F8:
|
||||
nCode = BKEY_F8;
|
||||
break;
|
||||
case Common::KEYCODE_F9:
|
||||
nCode = BKEY_F9;
|
||||
break;
|
||||
case Common::KEYCODE_F10:
|
||||
nCode = BKEY_F10;
|
||||
break;
|
||||
case Common::KEYCODE_F11:
|
||||
nCode = BKEY_F11;
|
||||
break;
|
||||
case Common::KEYCODE_F12:
|
||||
nCode = BKEY_F12;
|
||||
break;
|
||||
|
||||
case Common::KEYCODE_END:
|
||||
nCode = BKEY_END;
|
||||
break;
|
||||
case Common::KEYCODE_HOME:
|
||||
nCode = BKEY_HOME;
|
||||
break;
|
||||
case Common::KEYCODE_LEFT:
|
||||
nCode = BKEY_LEFT;
|
||||
break;
|
||||
case Common::KEYCODE_RIGHT:
|
||||
nCode = BKEY_RIGHT;
|
||||
break;
|
||||
case Common::KEYCODE_UP:
|
||||
nCode = BKEY_UP;
|
||||
break;
|
||||
case Common::KEYCODE_DOWN:
|
||||
nCode = BKEY_DOWN;
|
||||
break;
|
||||
case Common::KEYCODE_RETURN:
|
||||
nCode = BKEY_ENTER;
|
||||
break;
|
||||
case Common::KEYCODE_INSERT:
|
||||
nCode = BKEY_INS;
|
||||
break;
|
||||
case Common::KEYCODE_BACKSPACE:
|
||||
nCode = BKEY_BACK;
|
||||
break;
|
||||
case Common::KEYCODE_DELETE:
|
||||
nCode = BKEY_DEL;
|
||||
break;
|
||||
case Common::KEYCODE_SCROLLOCK:
|
||||
nCode = BKEY_SCRL_LOCK;
|
||||
break;
|
||||
case Common::KEYCODE_PAGEUP:
|
||||
nCode = BKEY_PAGEUP;
|
||||
break;
|
||||
case Common::KEYCODE_PAGEDOWN:
|
||||
nCode = BKEY_PAGEDOWN;
|
||||
break;
|
||||
case Common::KEYCODE_ESCAPE:
|
||||
nCode = BKEY_ESC;
|
||||
break;
|
||||
|
||||
default:
|
||||
// No translation for this key
|
||||
if (event.kbd.ascii >= 32 && event.kbd.ascii <= 127)
|
||||
nCode = event.kbd.ascii;
|
||||
break;
|
||||
}
|
||||
|
||||
if (nCode != BKEY_UNKNOWN) {
|
||||
if (event.kbd.flags & Common::KBD_ALT) {
|
||||
nCode = tolower(nCode) | BKF_ALT;
|
||||
}
|
||||
}
|
||||
|
||||
return nCode;
|
||||
}
|
||||
|
||||
void CBofWindow::fillWindow(byte iColor) {
|
||||
fillRect(nullptr, iColor);
|
||||
}
|
||||
|
||||
void CBofWindow::fillRect(CBofRect *pRect, byte iColor) {
|
||||
CBofBitmap cBmp(width(), height(), CBofApp::getApp()->getPalette());
|
||||
cBmp.fillRect(pRect, iColor);
|
||||
cBmp.paint(this, 0, 0);
|
||||
}
|
||||
|
||||
ErrorCode CBofWindow::paintBeveledText(CBofRect *rect, const CBofString &cString, const int size, const int weight, const COLORREF color, int justify, uint32 format) {
|
||||
assert(rect != nullptr);
|
||||
|
||||
CBofBitmap bmp(rect->width(), rect->height(), nullptr, false);
|
||||
|
||||
// Assume no error
|
||||
ErrorCode errorCode = ERR_NONE;
|
||||
|
||||
CBofRect r = bmp.getRect();
|
||||
CBofPalette *palette = nullptr;
|
||||
CBofApp *app = CBofApp::getApp();
|
||||
if (app != nullptr) {
|
||||
palette = app->getPalette();
|
||||
}
|
||||
|
||||
if (palette != nullptr) {
|
||||
bmp.fillRect(nullptr, palette->getNearestIndex(RGB(92, 92, 92)));
|
||||
|
||||
bmp.drawRect(&r, palette->getNearestIndex(RGB(0, 0, 0)));
|
||||
} else {
|
||||
bmp.fillRect(nullptr, COLOR_BLACK);
|
||||
}
|
||||
|
||||
byte c1 = 3;
|
||||
byte c2 = 9;
|
||||
CBofRect cBevel = r;
|
||||
|
||||
int left = cBevel.left;
|
||||
int top = cBevel.top;
|
||||
int right = cBevel.right;
|
||||
int bottom = cBevel.bottom;
|
||||
|
||||
r.left += 6;
|
||||
r.top += 3;
|
||||
r.right -= 5;
|
||||
r.bottom -= 5;
|
||||
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
bmp.line(left + i, bottom - i, right - i, bottom - i, c1);
|
||||
bmp.line(right - i, bottom - i, right - i, top + i - 1, c1);
|
||||
}
|
||||
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
bmp.line(left + i, bottom - i, left + i, top + i - 1, c2);
|
||||
bmp.line(left + i, top + i - 1, right - i, top + i - 1, c2);
|
||||
}
|
||||
|
||||
paintText(&bmp, &r, cString, size, weight, color, justify, format, FONT_DEFAULT);
|
||||
|
||||
bmp.paint(this, rect);
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
Reference in New Issue
Block a user