295 lines
6.7 KiB
C++
295 lines
6.7 KiB
C++
/* 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 "common/system.h"
|
|
#include "common/events.h"
|
|
#include "graphics/framelimiter.h"
|
|
#include "bagel/spacebar/boflib/gui/dialog.h"
|
|
#include "bagel/spacebar/boflib/app.h"
|
|
#include "bagel/spacebar/boflib/timer.h"
|
|
#include "bagel/boflib/sound.h"
|
|
#include "bagel/bagel.h"
|
|
|
|
namespace Bagel {
|
|
namespace SpaceBar {
|
|
|
|
CBofDialog::CBofDialog() {
|
|
// Inits
|
|
_pDlgBackground = nullptr;
|
|
_bFirstTime = true;
|
|
_bTempBitmap = false;
|
|
_lFlags = BOFDLG_DEFAULT;
|
|
_bEndDialog = false;
|
|
_bHavePainted = false;
|
|
}
|
|
|
|
|
|
CBofDialog::CBofDialog(const char *pszFileName, CBofWindow *pParent, const uint32 nID, const uint32 lFlags) {
|
|
assert(pszFileName != nullptr);
|
|
assert(pParent != nullptr);
|
|
|
|
// Inits
|
|
_pDlgBackground = nullptr;
|
|
_bFirstTime = true;
|
|
_bTempBitmap = false;
|
|
_lFlags = lFlags;
|
|
_bEndDialog = false;
|
|
_bHavePainted = false;
|
|
|
|
CBofBitmap *pBmp = loadBitmap(pszFileName);
|
|
|
|
if (pBmp != nullptr) {
|
|
// Use specified bitmap as this dialog's image
|
|
setBackdrop(pBmp);
|
|
}
|
|
|
|
assert(_pBackdrop != nullptr);
|
|
CBofRect cRect = _pBackdrop->getRect();
|
|
|
|
// Create the dialog box
|
|
create("DialogBox", cRect.left, cRect.top, cRect.width(), cRect.height(), pParent, nID);
|
|
}
|
|
|
|
CBofDialog::~CBofDialog() {
|
|
assert(isValidObject(this));
|
|
|
|
delete _pDlgBackground;
|
|
_pDlgBackground = nullptr;
|
|
}
|
|
|
|
|
|
ErrorCode CBofDialog::create(const char *pszName, int x, int y, int nWidth, int nHeight, CBofWindow *pParent, uint32 nControlID) {
|
|
assert(isValidObject(this));
|
|
assert(pszName != nullptr);
|
|
|
|
// Dialog boxes must have parent windows
|
|
assert(pParent != nullptr);
|
|
|
|
// Inits
|
|
_parent = pParent;
|
|
_nID = nControlID;
|
|
|
|
// Remember the name of this window
|
|
Common::strlcpy(_szTitle, pszName, MAX_TITLE);
|
|
|
|
// Calculate effective bounds
|
|
Common::Rect stRect(x, y, x + nWidth, y + nHeight);
|
|
if (pParent != nullptr)
|
|
stRect.translate(pParent->getWindowRect().left, pParent->getWindowRect().top);
|
|
|
|
_cRect = stRect;
|
|
|
|
delete _surface;
|
|
_surface = new Graphics::ManagedSurface(*g_engine->getScreen(), stRect);
|
|
|
|
return _errCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBofDialog::create(const char *pszName, CBofRect *pRect, CBofWindow *pParent, uint32 nControlID) {
|
|
assert(isValidObject(this));
|
|
assert(pszName != nullptr);
|
|
|
|
CBofRect cRect;
|
|
int x = 0;
|
|
int y = 0;
|
|
int nWidth = USE_DEFAULT;
|
|
int nHeight = USE_DEFAULT;
|
|
|
|
if ((pRect == nullptr) && (_pBackdrop != nullptr)) {
|
|
cRect = _pBackdrop->getRect();
|
|
pRect = &cRect;
|
|
}
|
|
|
|
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 CBofDialog::onClose() {
|
|
assert(isValidObject(this));
|
|
|
|
// Release any capture/focus that was active
|
|
CBofApp *app = CBofApp::getApp();
|
|
app->setCaptureControl(nullptr);
|
|
app->setFocusControl(nullptr);
|
|
|
|
if (_parent != nullptr) {
|
|
CBofWindow *pParent = _parent;
|
|
pParent->enable();
|
|
|
|
// The parent window MUST now be enabled
|
|
assert(pParent->isEnabled());
|
|
}
|
|
|
|
// If we saved the background, then paint it
|
|
if (_lFlags & BOFDLG_SAVEBACKGND) {
|
|
paintBackground();
|
|
|
|
} else if (_parent != nullptr) {
|
|
// Need to validate the portion of the parent window that we obscured
|
|
// (but that we also have already repainted)
|
|
// Otherwise, we need to cause the parent to repaint itself
|
|
_parent->invalidateRect(nullptr);
|
|
}
|
|
|
|
CBofWindow::onClose();
|
|
|
|
// Stop our personal message loop
|
|
_bEndDialog = true;
|
|
}
|
|
|
|
|
|
ErrorCode CBofDialog::paint(CBofRect *pRect) {
|
|
assert(isValidObject(this));
|
|
assert(pRect != nullptr);
|
|
|
|
// Repaint the background behind the dialog
|
|
if (!_bFirstTime) {
|
|
paintBackground();
|
|
}
|
|
_bFirstTime = false;
|
|
|
|
// Paint the dialog (uses bitmap instead of standard windows dialog)
|
|
if (hasBackdrop()) {
|
|
paintBackdrop(pRect, COLOR_WHITE);
|
|
}
|
|
|
|
return _errCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBofDialog::paintBackground() {
|
|
assert(isValidObject(this));
|
|
|
|
// Paint back the background
|
|
if (_pDlgBackground != nullptr) {
|
|
_errCode = _pDlgBackground->paint(this, 0, 0);
|
|
}
|
|
|
|
return _errCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBofDialog::saveBackground() {
|
|
assert(isValidObject(this));
|
|
|
|
if (_lFlags & BOFDLG_SAVEBACKGND) {
|
|
CBofPalette *pPalette = CBofApp::getApp()->getPalette();
|
|
|
|
// Remove any previous background
|
|
delete _pDlgBackground;
|
|
// Save a copy of the background
|
|
_pDlgBackground = new CBofBitmap(width(), height(), pPalette);
|
|
|
|
_pDlgBackground->captureScreen(this, &_cRect);
|
|
_pDlgBackground->setReadOnly(true);
|
|
}
|
|
|
|
_bFirstTime = false;
|
|
|
|
return _errCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBofDialog::killBackground() {
|
|
delete _pDlgBackground;
|
|
_pDlgBackground = nullptr;
|
|
|
|
return _errCode;
|
|
}
|
|
|
|
|
|
void CBofDialog::onPaint(CBofRect *pRect) {
|
|
assert(isValidObject(this));
|
|
assert(pRect != nullptr);
|
|
|
|
if (_bFirstTime) {
|
|
saveBackground();
|
|
}
|
|
|
|
paint(pRect);
|
|
|
|
_bHavePainted = true;
|
|
}
|
|
|
|
|
|
int CBofDialog::doModal() {
|
|
assert(isValidObject(this));
|
|
|
|
// The dialog box must have been successfully created first
|
|
assert(isCreated());
|
|
|
|
CBofWindow *pLastActive = getActiveWindow();
|
|
setActive();
|
|
onInitDialog();
|
|
|
|
// Display the window
|
|
show();
|
|
|
|
updateWindow();
|
|
|
|
// Start our own message loop (simulate Modal)
|
|
_bEndDialog = false;
|
|
|
|
// Acquire and dispatch messages until quit message is received,
|
|
// or until there are too many errors.
|
|
Graphics::FrameLimiter limiter(g_system, 60, false);
|
|
|
|
while (!_bEndDialog && !g_engine->shouldQuit() && (CBofError::getErrorCount() < MAX_ERRORS)) {
|
|
CBofSound::audioTask();
|
|
CBofTimer::handleTimers();
|
|
|
|
if (isCreated()) {
|
|
onMainLoop();
|
|
}
|
|
|
|
handleEvents();
|
|
|
|
limiter.delayBeforeSwap();
|
|
g_engine->getScreen()->update();
|
|
limiter.startFrame();
|
|
}
|
|
|
|
if (pLastActive != nullptr) {
|
|
pLastActive->setActive();
|
|
} else {
|
|
_pActiveWindow = nullptr;
|
|
}
|
|
|
|
return _nReturnValue;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
// Virtual functions that the user can override if they want to
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
void CBofDialog::onInitDialog() {}
|
|
|
|
} // namespace SpaceBar
|
|
} // namespace Bagel
|