Initial commit
This commit is contained in:
621
engines/bagel/spacebar/boflib/gui/button.cpp
Normal file
621
engines/bagel/spacebar/boflib/gui/button.cpp
Normal file
@@ -0,0 +1,621 @@
|
||||
/* 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/button.h"
|
||||
#include "bagel/spacebar/boflib/app.h"
|
||||
#include "bagel/spacebar/boflib/gfx/text.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define SELECTED_TEXT_OFFSET_DX 1
|
||||
#define SELECTED_TEXT_OFFSET_DY 1
|
||||
|
||||
#define BUTTON_TEXT_SIZE 10
|
||||
|
||||
#define CHECK_BOX_SIZE 14
|
||||
#define CHECK_BOX_OFFSET_DX 4
|
||||
#define CHECK_BOX_OFFSET_DY 4
|
||||
#define CHECK_BOX_TEXT_SIZE 10
|
||||
|
||||
#define RADIO_BOX_SIZE 13
|
||||
#define RADIO_BOX_OFFSET_DX 3
|
||||
#define RADIO_BOX_OFFSET_DY 3
|
||||
#define RADIO_BOX_TEXT_SIZE 10
|
||||
|
||||
|
||||
static ST_COLORSCHEME g_stDefaultColors = {
|
||||
|
||||
RGB(171, 151, 127),
|
||||
RGB(207, 199, 183),
|
||||
RGB(131, 111, 91),
|
||||
RGB(0, 0, 0),
|
||||
RGB(0, 0, 0),
|
||||
RGB(0, 0, 0)
|
||||
};
|
||||
|
||||
CBofButton::CBofButton() {
|
||||
// Inits
|
||||
_nState = BUTTON_UP;
|
||||
|
||||
// Load a default color scheme until another is loaded
|
||||
loadColorScheme(&g_stDefaultColors);
|
||||
}
|
||||
|
||||
|
||||
CBofButton::CBofButton(ST_COLORSCHEME *pColorScheme) {
|
||||
assert(pColorScheme != nullptr);
|
||||
|
||||
// Inits
|
||||
_nState = BUTTON_UP;
|
||||
|
||||
loadColorScheme(pColorScheme);
|
||||
}
|
||||
|
||||
|
||||
CBofButton::~CBofButton() {
|
||||
assert(isValidObject(this));
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofButton::paint(CBofRect *) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Only continue if this button is visible
|
||||
if (isVisible() && (_parent != nullptr) && _parent->isVisible()) {
|
||||
CBofPalette *pPalette = CBofApp::getApp()->getPalette();
|
||||
|
||||
int nWidth = _cRect.width();
|
||||
int nHeight = _cRect.height();
|
||||
|
||||
// Create our off-screen buffer
|
||||
CBofBitmap cBmp(nWidth, nHeight, pPalette);
|
||||
|
||||
cBmp.fillRect(&_cRect, pPalette->getNearestIndex(_cFaceColor));
|
||||
|
||||
int left = _cRect.left;
|
||||
int right = _cRect.right;
|
||||
int top = _cRect.top;
|
||||
int bottom = _cRect.bottom;
|
||||
|
||||
byte iShadow = pPalette->getNearestIndex(_cShadowColor);
|
||||
byte iHighlight = pPalette->getNearestIndex(_cHighlightColor);
|
||||
|
||||
if (_nState == BUTTON_DOWN) {
|
||||
byte iTemp = iShadow;
|
||||
iShadow = iHighlight;
|
||||
iHighlight = iTemp;
|
||||
}
|
||||
|
||||
byte c1 = iShadow;
|
||||
byte c2 = iHighlight;
|
||||
|
||||
int i;
|
||||
for (i = 1; i <= 3; i++) {
|
||||
cBmp.line(left + i, bottom - i, right - i, bottom - i, c1);
|
||||
cBmp.line(right - i, bottom - i, right - i, top + i - 1, c1);
|
||||
}
|
||||
|
||||
for (i = 1; i <= 3; i++) {
|
||||
cBmp.line(left + i, bottom - i, left + i, top + i - 1, c2);
|
||||
cBmp.line(left + i, top + i - 1, right - i, top + i - 1, c2);
|
||||
}
|
||||
|
||||
cBmp.drawRect(&_cRect, pPalette->getNearestIndex(_cOutlineColor));
|
||||
|
||||
// Create a temporary text object
|
||||
CBofRect cTempRect(3, 3, _cRect.right - 3, _cRect.bottom - 3);
|
||||
|
||||
if (_nState == BUTTON_DOWN) {
|
||||
cTempRect += CBofPoint(1, 1);
|
||||
}
|
||||
|
||||
CBofText cText(&cTempRect);
|
||||
|
||||
// Print text into button
|
||||
COLORREF cTextColor = _cTextColor;
|
||||
if (_nState == BUTTON_DISABLED)
|
||||
cTextColor = _cTextDisabledColor;
|
||||
|
||||
cText.display(&cBmp, _szTitle, BUTTON_TEXT_SIZE, TEXT_NORMAL, cTextColor);
|
||||
|
||||
if (_nState == BUTTON_FOCUS) {
|
||||
cBmp.drawRect(&cTempRect, pPalette->getNearestIndex(_cOutlineColor));
|
||||
}
|
||||
|
||||
// Now we can update the window
|
||||
cBmp.paint(this, 0, 0);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
void CBofButton::loadColorScheme(ST_COLORSCHEME *pColorScheme) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
assert(pColorScheme != nullptr);
|
||||
|
||||
// Save all of the color info we need to build a button
|
||||
_cFaceColor = pColorScheme->_cFace;
|
||||
_cHighlightColor = pColorScheme->_cHighlight;
|
||||
_cShadowColor = pColorScheme->_cShadow;
|
||||
_cTextColor = pColorScheme->_cText;
|
||||
_cTextDisabledColor = pColorScheme->_cTextDisabled;
|
||||
_cOutlineColor = pColorScheme->_cOutline;
|
||||
}
|
||||
|
||||
|
||||
void CBofButton::enable() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
CBofWindow::enable();
|
||||
|
||||
setState(BUTTON_UP);
|
||||
}
|
||||
|
||||
|
||||
void CBofButton::disable() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
setState(BUTTON_DISABLED);
|
||||
|
||||
CBofWindow::disable();
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofButton::setState(int nNewState, bool bRepaintNow) {
|
||||
assert(isValidObject(this));
|
||||
assert(nNewState >= BUTTON_UP && nNewState <= BUTTON_DISABLED);
|
||||
|
||||
// Remember last button state
|
||||
int nOldState = _nState;
|
||||
|
||||
_nState = nNewState;
|
||||
|
||||
// Update the window if forced to or if button state has changed
|
||||
if (bRepaintNow || (nOldState != nNewState)) {
|
||||
paint();
|
||||
}
|
||||
|
||||
// I must have a valid parent
|
||||
assert(_parent != nullptr);
|
||||
|
||||
// Tell parent the new state of this button
|
||||
if (_parent != nullptr) {
|
||||
_parent->onBofButton(this, _nState);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
void CBofButton::onPaint(CBofRect *pRect) {
|
||||
assert(isValidObject(this));
|
||||
assert(pRect != nullptr);
|
||||
|
||||
paint(pRect);
|
||||
}
|
||||
|
||||
|
||||
void CBofButton::onLButtonDown(uint32, CBofPoint *pPoint, void *) {
|
||||
assert(isValidObject(this));
|
||||
assert(pPoint != nullptr);
|
||||
|
||||
if (!_bCaptured && _nState != BUTTON_DISABLED) {
|
||||
setCapture();
|
||||
setState(BUTTON_DOWN, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CBofButton::onLButtonUp(uint32, CBofPoint *pPoint, void *) {
|
||||
assert(isValidObject(this));
|
||||
assert(pPoint != nullptr);
|
||||
|
||||
if (_bCaptured) {
|
||||
releaseCapture();
|
||||
setState(BUTTON_UP, true);
|
||||
|
||||
if (_cRect.ptInRect(*pPoint) && (_parent != nullptr)) {
|
||||
_parent->onBofButton(this, BUTTON_CLICKED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* CBofRadioButton */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
void CBofRadioButton::onLButtonDown(uint32, CBofPoint *pPoint, void *) {
|
||||
assert(isValidObject(this));
|
||||
assert(pPoint != nullptr);
|
||||
|
||||
if (_nState == BUTTON_UP) {
|
||||
setState(BUTTON_DOWN, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CBofRadioButton::onLButtonUp(uint32, CBofPoint *pPoint, void *) {
|
||||
assert(isValidObject(this));
|
||||
assert(pPoint != nullptr);
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofRadioButton::paint(CBofRect *) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Only continue if this button is visible
|
||||
if (isVisible() && (_parent != nullptr) && _parent->isVisible()) {
|
||||
|
||||
CBofPalette *pPalette = CBofApp::getApp()->getPalette();
|
||||
|
||||
int nWidth = _cRect.width();
|
||||
int nHeight = _cRect.height();
|
||||
|
||||
// Create a temporary off-screen buffer
|
||||
CBofBitmap cBmp(nWidth, nHeight, pPalette);
|
||||
|
||||
// Fill in the background color
|
||||
cBmp.fillRect(&_cRect, pPalette->getNearestIndex(_cFaceColor));
|
||||
|
||||
COLORREF cTextColor = _cTextColor;
|
||||
if (_nState == BUTTON_DISABLED)
|
||||
cTextColor = _cTextDisabledColor;
|
||||
|
||||
byte iShadow = pPalette->getNearestIndex(cTextColor);
|
||||
byte iHighlight = pPalette->getNearestIndex(cTextColor);
|
||||
|
||||
// Paint the radio button circle
|
||||
int nRadius = 7;
|
||||
int x = nRadius + RADIO_BOX_OFFSET_DX;
|
||||
int y = nHeight / 2;
|
||||
cBmp.circle(x, y, (uint16)nRadius, iShadow);
|
||||
nRadius--;
|
||||
cBmp.circle(x, y, (uint16)nRadius, iShadow);
|
||||
|
||||
// Create a temporary text object
|
||||
CBofRect cTempRect(20, RADIO_BOX_OFFSET_DY, _cRect.right, _cRect.bottom - RADIO_BOX_OFFSET_DY);
|
||||
if (_nState == BUTTON_DOWN) {
|
||||
nRadius = 1;
|
||||
cBmp.circle(x, y, (uint16)nRadius, iHighlight);
|
||||
nRadius = 2;
|
||||
cBmp.circle(x, y, (uint16)nRadius, iHighlight);
|
||||
nRadius = 3;
|
||||
cBmp.circle(x, y, (uint16)nRadius, iHighlight);
|
||||
nRadius = 4;
|
||||
cBmp.circle(x, y, (uint16)nRadius, iHighlight);
|
||||
}
|
||||
CBofText cText(&cTempRect, JUSTIFY_LEFT);
|
||||
|
||||
// Put a box around the whole button
|
||||
cBmp.drawRect(&_cRect, pPalette->getNearestIndex(_cOutlineColor));
|
||||
|
||||
// Show text disabled if button is disabled
|
||||
|
||||
// Print text into button
|
||||
cText.display(&cBmp, _szTitle, RADIO_BOX_TEXT_SIZE, TEXT_NORMAL, cTextColor);
|
||||
|
||||
// If button has focus, then put a box around the text
|
||||
if (_nState == BUTTON_FOCUS) {
|
||||
cBmp.drawRect(&cTempRect, pPalette->getNearestIndex(_cOutlineColor));
|
||||
}
|
||||
|
||||
// Now we can update the window
|
||||
cBmp.paint(this, 0, 0);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* CBofCheckButton */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
void CBofCheckButton::onLButtonDown(uint32, CBofPoint *pPoint, void *) {
|
||||
assert(isValidObject(this));
|
||||
assert(pPoint != nullptr);
|
||||
|
||||
if (_nState == BUTTON_DISABLED)
|
||||
return;
|
||||
|
||||
if (_nState == BUTTON_UP) {
|
||||
setState(BUTTON_DOWN, true);
|
||||
} else if (_nState == BUTTON_DOWN) {
|
||||
setState(BUTTON_UP, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CBofCheckButton::onLButtonUp(uint32, CBofPoint *pPoint, void *) {
|
||||
assert(isValidObject(this));
|
||||
assert(pPoint != nullptr);
|
||||
|
||||
// Do nothing, and don't call the base class version of this function
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofCheckButton::paint(CBofRect *) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Only continue if this button is visible
|
||||
if (isVisible() && (_parent != nullptr) && _parent->isVisible()) {
|
||||
|
||||
CBofPalette *pPalette = CBofApp::getApp()->getPalette();
|
||||
|
||||
int nWidth = _cRect.width();
|
||||
int nHeight = _cRect.height();
|
||||
|
||||
// Create a temporary off-screen buffer
|
||||
CBofBitmap cBmp(nWidth, nHeight, pPalette);
|
||||
|
||||
// Fill in the background color
|
||||
cBmp.fillRect(&_cRect, pPalette->getNearestIndex(_cFaceColor));
|
||||
|
||||
// Show text disabled if button is disabled
|
||||
COLORREF cTextColor = _cTextColor;
|
||||
if (_nState == BUTTON_DISABLED)
|
||||
cTextColor = _cTextDisabledColor;
|
||||
|
||||
byte iShadow = pPalette->getNearestIndex(cTextColor);
|
||||
|
||||
// Draw the check box (centered vertically)
|
||||
int y = ((nHeight - CHECK_BOX_SIZE) / 2);
|
||||
CBofRect cTempRect(CHECK_BOX_OFFSET_DX, y, CHECK_BOX_SIZE + CHECK_BOX_OFFSET_DX - 1, y + CHECK_BOX_SIZE - 1);
|
||||
cBmp.drawRect(&cTempRect, iShadow);
|
||||
|
||||
// if button is in DOWN/ON state, then put an X in the box
|
||||
//
|
||||
if (_nState == BUTTON_DOWN) {
|
||||
cBmp.line(cTempRect.left, cTempRect.top, cTempRect.right, cTempRect.bottom, iShadow);
|
||||
cBmp.line(cTempRect.left, cTempRect.bottom, cTempRect.right, cTempRect.top, iShadow);
|
||||
}
|
||||
|
||||
// Create a temporary text object
|
||||
cTempRect.setRect(CHECK_BOX_SIZE + CHECK_BOX_OFFSET_DX, CHECK_BOX_OFFSET_DX, _cRect.right, _cRect.bottom - CHECK_BOX_OFFSET_DX);
|
||||
CBofText cText(&cTempRect, JUSTIFY_LEFT);
|
||||
|
||||
// Put a box around the whole button
|
||||
cBmp.drawRect(&_cRect, pPalette->getNearestIndex(_cOutlineColor));
|
||||
|
||||
// Print text into button
|
||||
//
|
||||
cText.display(&cBmp, _szTitle, CHECK_BOX_TEXT_SIZE, TEXT_NORMAL, cTextColor);
|
||||
|
||||
// If button has focus, then put a box around the text
|
||||
if (_nState == BUTTON_FOCUS) {
|
||||
cBmp.drawRect(&cTempRect, pPalette->getNearestIndex(_cOutlineColor));
|
||||
}
|
||||
|
||||
// Now we can update the window
|
||||
cBmp.paint(this, 0, 0);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofCheckButton::SetCheck(bool bChecked) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
setState(bChecked ? BUTTON_CHECKED : BUTTON_UNCHECKED, false);
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* CBofBmpButton */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
CBofBmpButton::CBofBmpButton() {
|
||||
_pButtonUp = nullptr;
|
||||
_pButtonDown = nullptr;
|
||||
_pButtonFocus = nullptr;
|
||||
_pButtonDisabled = nullptr;
|
||||
_pBackground = nullptr;
|
||||
_nState = BUTTON_UP;
|
||||
_nMaskColor = NOT_TRANSPARENT;
|
||||
}
|
||||
|
||||
|
||||
CBofBmpButton::~CBofBmpButton() {
|
||||
delete _pButtonUp;
|
||||
_pButtonUp = nullptr;
|
||||
|
||||
delete _pButtonDown;
|
||||
_pButtonDown = nullptr;
|
||||
|
||||
delete _pButtonDisabled;
|
||||
_pButtonDisabled = nullptr;
|
||||
|
||||
delete _pButtonFocus;
|
||||
_pButtonFocus = nullptr;
|
||||
|
||||
delete _pBackground;
|
||||
_pBackground = nullptr;
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofBmpButton::paint(CBofRect *) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// loadBitmaps must be called before the button can be painted
|
||||
assert(_pButtonUp != nullptr);
|
||||
assert(_pButtonDown != nullptr);
|
||||
assert(_pButtonFocus != nullptr);
|
||||
assert(_pButtonDisabled != nullptr);
|
||||
|
||||
// Only continue if this button is visible
|
||||
if (isVisible() && (_parent != nullptr) && _parent->isVisible()) {
|
||||
CBofPalette *pPalette = _pButtonUp->getPalette();
|
||||
|
||||
int nWidth = _cRect.width();
|
||||
int nHeight = _cRect.height();
|
||||
|
||||
// Do all painting off-screen
|
||||
CBofBitmap cOffScreen(nWidth, nHeight, pPalette);
|
||||
|
||||
if (_pBackground == nullptr) {
|
||||
_pBackground = new CBofBitmap(nWidth, nHeight, pPalette);
|
||||
} else {
|
||||
_pBackground->paint(&cOffScreen, 0, 0);
|
||||
}
|
||||
|
||||
// Assume UP state
|
||||
CBofBitmap *pBitmap = _pButtonUp;
|
||||
|
||||
// Display the correct bitmap based on state
|
||||
if (_nState == BUTTON_DOWN) {
|
||||
pBitmap = _pButtonDown;
|
||||
|
||||
} else if (_nState == BUTTON_FOCUS) {
|
||||
pBitmap = _pButtonFocus;
|
||||
|
||||
} else if (_nState == BUTTON_DISABLED) {
|
||||
pBitmap = _pButtonDisabled;
|
||||
}
|
||||
|
||||
// Paint button offscreen
|
||||
pBitmap->paint(&cOffScreen, 0, 0, nullptr, _nMaskColor);
|
||||
|
||||
// Now we can update the window
|
||||
cOffScreen.paint(this, 0, 0);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofBmpButton::loadBitmaps(CBofBitmap *pUp, CBofBitmap *pDown, CBofBitmap *pFocus, CBofBitmap *pDisabled, int nMaskColor) {
|
||||
assert(isValidObject(this));
|
||||
assert(pUp != nullptr);
|
||||
assert(pDown != nullptr);
|
||||
|
||||
// Use the bitmaps passed in
|
||||
_pButtonUp = pUp;
|
||||
_pButtonDown = pDown;
|
||||
_pButtonFocus = pFocus;
|
||||
_pButtonDisabled = pDisabled;
|
||||
|
||||
// Remember the transparent color for these bitmaps
|
||||
_nMaskColor = nMaskColor;
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofBmpButton::loadBitmaps(CBofPalette *pPalette, const char *pszUp, const char *pszDown, const char *pszFocus, const char *pszDisabled, int nMaskColor) {
|
||||
assert(isValidObject(this));
|
||||
assert(pPalette != nullptr);
|
||||
assert(pszUp != nullptr);
|
||||
assert(pszDown != nullptr);
|
||||
assert(pszFocus != nullptr);
|
||||
assert(pszDisabled != nullptr);
|
||||
|
||||
// Remember the button transparent color
|
||||
_nMaskColor = nMaskColor;
|
||||
|
||||
// Load each of the bitmaps that represent the button state
|
||||
_pButtonUp = new CBofBitmap(pszUp, pPalette);
|
||||
_pButtonUp->setReadOnly(true);
|
||||
|
||||
_pButtonDown = new CBofBitmap(pszDown, pPalette);
|
||||
_pButtonDown->setReadOnly(true);
|
||||
|
||||
_pButtonFocus = new CBofBitmap(pszFocus, pPalette);
|
||||
_pButtonFocus->setReadOnly(true);
|
||||
|
||||
_pButtonDisabled = new CBofBitmap(pszDisabled, pPalette);
|
||||
_pButtonDisabled->setReadOnly(true);
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofBmpButton::setState(int nNewState, bool bRepaintNow) {
|
||||
assert(isValidObject(this));
|
||||
assert(nNewState >= BUTTON_UP && nNewState <= BUTTON_DISABLED);
|
||||
|
||||
// Remember last button state
|
||||
int nOldState = _nState;
|
||||
|
||||
_nState = nNewState;
|
||||
|
||||
// Update the window if forced to or if button state has changed
|
||||
if (bRepaintNow || (nOldState != nNewState)) {
|
||||
paint();
|
||||
}
|
||||
|
||||
// I MUST have a valid parent
|
||||
assert(_parent != nullptr);
|
||||
|
||||
// Tell parent the new state of this button
|
||||
if (_parent != nullptr) {
|
||||
_parent->onBofButton(this, _nState);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
void CBofBmpButton::onPaint(CBofRect *pRect) {
|
||||
assert(isValidObject(this));
|
||||
assert(pRect != nullptr);
|
||||
|
||||
paint(pRect);
|
||||
}
|
||||
|
||||
|
||||
void CBofBmpButton::onLButtonDown(uint32, CBofPoint *pPoint, void *) {
|
||||
assert(isValidObject(this));
|
||||
assert(pPoint != nullptr);
|
||||
|
||||
if (!_bCaptured && _nState != BUTTON_DISABLED) {
|
||||
setCapture();
|
||||
|
||||
setState(BUTTON_DOWN, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CBofBmpButton::onLButtonUp(uint32, CBofPoint *pPoint, void *) {
|
||||
assert(isValidObject(this));
|
||||
assert(pPoint != nullptr);
|
||||
|
||||
if (_bCaptured) {
|
||||
releaseCapture();
|
||||
|
||||
setState(BUTTON_UP, true);
|
||||
|
||||
if (_cRect.ptInRect(*pPoint) && (_parent != nullptr)) {
|
||||
_parent->onBofButton(this, BUTTON_CLICKED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
151
engines/bagel/spacebar/boflib/gui/button.h
Normal file
151
engines/bagel/spacebar/boflib/gui/button.h
Normal file
@@ -0,0 +1,151 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BOFLIB_GUI_BUTTON_H
|
||||
#define BAGEL_BOFLIB_GUI_BUTTON_H
|
||||
|
||||
#include "bagel/spacebar/boflib/gui/window.h"
|
||||
#include "bagel/boflib/palette.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
// Button states
|
||||
//
|
||||
#define BUTTON_UP 0
|
||||
#define BUTTON_DOWN 1
|
||||
#define BUTTON_FOCUS 2
|
||||
#define BUTTON_DISABLED 3
|
||||
#define BUTTON_CLICKED 4
|
||||
#define BUTTON_ON BUTTON_DOWN
|
||||
#define BUTTON_OFF BUTTON_UP
|
||||
|
||||
#define BUTTON_CHECKED BUTTON_ON
|
||||
#define BUTTON_UNCHECKED BUTTON_OFF
|
||||
|
||||
struct ST_COLORSCHEME {
|
||||
COLORREF _cFace;
|
||||
COLORREF _cHighlight;
|
||||
COLORREF _cShadow;
|
||||
COLORREF _cText;
|
||||
COLORREF _cTextDisabled;
|
||||
COLORREF _cOutline;
|
||||
};
|
||||
|
||||
class CBofButton : public CBofWindow {
|
||||
public:
|
||||
CBofButton();
|
||||
CBofButton(ST_COLORSCHEME *pColorScheme);
|
||||
virtual ~CBofButton();
|
||||
|
||||
void loadColorScheme(ST_COLORSCHEME *pColorScheme);
|
||||
|
||||
virtual ErrorCode paint(CBofRect *pRect = nullptr);
|
||||
|
||||
void enable() override;
|
||||
void disable() override;
|
||||
|
||||
ErrorCode setState(int nNewState, bool bRepaintNow = true);
|
||||
int getState() {
|
||||
return _nState;
|
||||
}
|
||||
|
||||
protected:
|
||||
void onPaint(CBofRect *pRect) override;
|
||||
void onLButtonDown(uint32 nFlags, CBofPoint *pPoint, void * = nullptr) override;
|
||||
void onLButtonUp(uint32 nFlags, CBofPoint *pPoint, void * = nullptr) override;
|
||||
|
||||
COLORREF _cFaceColor;
|
||||
COLORREF _cHighlightColor;
|
||||
COLORREF _cShadowColor;
|
||||
COLORREF _cTextColor;
|
||||
COLORREF _cTextDisabledColor;
|
||||
COLORREF _cOutlineColor;
|
||||
|
||||
int _nState;
|
||||
};
|
||||
|
||||
class CBofRadioButton : public CBofButton {
|
||||
public:
|
||||
virtual ErrorCode paint(CBofRect *pRect = nullptr);
|
||||
|
||||
protected:
|
||||
virtual void onLButtonDown(uint32 nFlags, CBofPoint *pPoint, void * = nullptr);
|
||||
virtual void onLButtonUp(uint32 nFlags, CBofPoint *pPoint, void * = nullptr);
|
||||
};
|
||||
|
||||
class CBofCheckButton : public CBofButton {
|
||||
public:
|
||||
ErrorCode SetCheck(bool bChecked);
|
||||
bool GetCheck() {
|
||||
return (_nState == BUTTON_CHECKED);
|
||||
}
|
||||
|
||||
ErrorCode paint(CBofRect *pRect = nullptr) override;
|
||||
|
||||
protected:
|
||||
void onLButtonDown(uint32 nFlags, CBofPoint *pPoint, void * = nullptr) override;
|
||||
void onLButtonUp(uint32 nFlags, CBofPoint *pPoint, void * = nullptr) override;
|
||||
};
|
||||
|
||||
class CBofBmpButton : public CBofWindow {
|
||||
public:
|
||||
// Constructors
|
||||
CBofBmpButton();
|
||||
|
||||
virtual ~CBofBmpButton();
|
||||
|
||||
// NOTE: CBofBmpButton takes control of these bitmaps, so there's
|
||||
// no need for the callers to free them afterwards
|
||||
ErrorCode loadBitmaps(CBofBitmap *pUp, CBofBitmap *pDown, CBofBitmap *pFocus, CBofBitmap *pDisabled, int nMaskColor = NOT_TRANSPARENT);
|
||||
ErrorCode loadBitmaps(CBofPalette *pPalette, const char *pszUp, const char *pszDown = nullptr, const char *pszFocus = nullptr, const char *pszDisabled = nullptr, int nMaskColor = NOT_TRANSPARENT);
|
||||
|
||||
ErrorCode paint(CBofRect *pRect = nullptr);
|
||||
|
||||
ErrorCode setState(int nNewState, bool bRepaintNow = true);
|
||||
int getState() {
|
||||
return _nState;
|
||||
}
|
||||
|
||||
CBofBitmap *getButtonBmp() {
|
||||
return _pButtonUp;
|
||||
}
|
||||
|
||||
protected:
|
||||
void onPaint(CBofRect *pRect) override;
|
||||
void onLButtonDown(uint32 nFlags, CBofPoint *pPoint, void * = nullptr) override;
|
||||
void onLButtonUp(uint32 nFlags, CBofPoint *pPoint, void * = nullptr) override;
|
||||
|
||||
CBofBitmap *_pButtonUp;
|
||||
CBofBitmap *_pButtonDown;
|
||||
CBofBitmap *_pButtonFocus;
|
||||
CBofBitmap *_pButtonDisabled;
|
||||
|
||||
CBofBitmap *_pBackground;
|
||||
int _nState;
|
||||
int _nMaskColor;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
294
engines/bagel/spacebar/boflib/gui/dialog.cpp
Normal file
294
engines/bagel/spacebar/boflib/gui/dialog.cpp
Normal file
@@ -0,0 +1,294 @@
|
||||
/* 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
|
||||
144
engines/bagel/spacebar/boflib/gui/dialog.h
Normal file
144
engines/bagel/spacebar/boflib/gui/dialog.h
Normal file
@@ -0,0 +1,144 @@
|
||||
/* 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/".
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BOFLIB_GUI_DIALOG_H
|
||||
#define BAGEL_BOFLIB_GUI_DIALOG_H
|
||||
|
||||
#include "bagel/spacebar/boflib/gui/window.h"
|
||||
#include "bagel/spacebar/boflib/gfx/bitmap.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define IDOK 1
|
||||
#define IDCANCEL 2
|
||||
|
||||
#define BOFDLG_TRANSPARENT 0x00000001
|
||||
#define BOFDLG_SAVEBACKGND 0x00000002
|
||||
|
||||
#define BOFDLG_DEFAULT (BOFDLG_TRANSPARENT /* | BOFDLG_SAVEBACKGND*/)
|
||||
|
||||
class CBofDialog : public CBofWindow {
|
||||
protected:
|
||||
CBofBitmap *_pDlgBackground = nullptr;
|
||||
uint32 _lFlags = 0;
|
||||
int _nReturnValue = 0;
|
||||
|
||||
bool _bFirstTime = false;
|
||||
bool _bTempBitmap = false;
|
||||
bool _bEndDialog = false;
|
||||
bool _bHavePainted = false;
|
||||
|
||||
protected:
|
||||
virtual ErrorCode paint(CBofRect *pRect);
|
||||
virtual ErrorCode paintBackground();
|
||||
virtual ErrorCode saveBackground();
|
||||
virtual ErrorCode killBackground();
|
||||
|
||||
void onPaint(CBofRect *pRect) override;
|
||||
void onClose() override;
|
||||
virtual void onInitDialog();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
CBofDialog();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
CBofDialog(const char *pszFileName, CBofWindow *pParent, uint32 nID = 0, uint32 lFlags = BOFDLG_DEFAULT);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~CBofDialog();
|
||||
|
||||
/**
|
||||
* Creates the dialog
|
||||
* @param pszName Dialog name
|
||||
* @param x Top-left X position
|
||||
* @param y Top-left Y position
|
||||
* @param nWidth Width
|
||||
* @param nHeight Height
|
||||
* @param pParent Parent window
|
||||
* @param nControlID Control Id
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode create(const char *pszName, int x, int y, int nWidth, int nHeight, CBofWindow *pParent, uint32 nControlID = 0) override;
|
||||
|
||||
/**
|
||||
* Creates the dialog
|
||||
* @param pszName Dialog name
|
||||
* @param pRect Dialog bounds
|
||||
* @param pParent Parent window
|
||||
* @param nControlID Control Id
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode create(const char *pszName, CBofRect *pRect, CBofWindow *pParent, uint32 nControlID = 0) override;
|
||||
|
||||
/**
|
||||
* Set the dialog flags
|
||||
*/
|
||||
void setFlags(uint32 lFlags) {
|
||||
_lFlags = lFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the dialog's flags
|
||||
*/
|
||||
uint32 getFlags() const {
|
||||
return _lFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the dialog as a modal
|
||||
*/
|
||||
int doModal();
|
||||
|
||||
/**
|
||||
* End the dialog modal display
|
||||
*/
|
||||
void endModal() {
|
||||
_bEndDialog = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the dialog's return value
|
||||
*/
|
||||
void setReturnValue(int nValue) {
|
||||
_nReturnValue = nValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the dialog's return value
|
||||
* @return
|
||||
*/
|
||||
int getReturnValue() const {
|
||||
return _nReturnValue;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
141
engines/bagel/spacebar/boflib/gui/edit_text.cpp
Normal file
141
engines/bagel/spacebar/boflib/gui/edit_text.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
/* 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/app.h"
|
||||
#include "bagel/spacebar/boflib/gui/edit_text.h"
|
||||
#include "bagel/spacebar/boflib/gfx/text.h"
|
||||
#include "bagel/spacebar/boflib/std_keys.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
CBofEditText::CBofEditText(const char *pszName, int x, int y, int nWidth,
|
||||
int nHeight, CBofWindow *pParent)
|
||||
: CBofWindow(pszName, x, y, nWidth, nHeight, pParent) {
|
||||
create(pszName, x, y, nWidth, nHeight, pParent);
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofEditText::create(const char *pszName, CBofRect *pRect,
|
||||
CBofWindow *pParent, uint32 nControlID) {
|
||||
assert(isValidObject(this));
|
||||
assert(pszName != nullptr);
|
||||
|
||||
// Remember who our parent is
|
||||
_parent = pParent;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofEditText::create(const char *pszName, int x, int y,
|
||||
int nWidth, int nHeight, CBofWindow *pParent, uint32 nControlID) {
|
||||
assert(isValidObject(this));
|
||||
assert(pszName != nullptr);
|
||||
|
||||
// Remember who our parent is
|
||||
_parent = pParent;
|
||||
_nID = nControlID;
|
||||
|
||||
// Remember the name of this window
|
||||
Common::strcpy_s(_szTitle, pszName);
|
||||
|
||||
// Retain screen coordinates for this window
|
||||
_cWindowRect.setRect(x, y, x + nWidth - 1, y + nHeight - 1);
|
||||
|
||||
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 CBofEditText::setText(const char *pszString) {
|
||||
assert(isValidObject(this));
|
||||
assert(isCreated());
|
||||
assert(pszString != nullptr);
|
||||
|
||||
_text = pszString;
|
||||
|
||||
updateWindow();
|
||||
}
|
||||
|
||||
|
||||
void CBofEditText::onPaint(CBofRect *pRect) {
|
||||
assert(isValidObject(this));
|
||||
assert(pRect != nullptr);
|
||||
|
||||
if (hasFocus())
|
||||
fillRect(nullptr, 255);
|
||||
|
||||
// Draw the text, if any
|
||||
if (!_text.isEmpty()) {
|
||||
CBofString tmp = _text + "|";
|
||||
|
||||
paintText(this, &_cRect, tmp.getBuffer(),
|
||||
12, 0, CTEXT_COLOR,
|
||||
JUSTIFY_LEFT,
|
||||
FORMAT_TOP_LEFT | FORMAT_SINGLE_LINE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CBofEditText::onLButtonDown(uint32 nFlags, CBofPoint *pPoint, void *) {
|
||||
// First click focuses text input
|
||||
setFocus();
|
||||
_cursorPos = _text.getBufferSize();
|
||||
|
||||
updateWindow();
|
||||
}
|
||||
|
||||
void CBofEditText::onKeyHit(uint32 lKey, uint32 lRepCount) {
|
||||
if (lKey >= 32 && lKey <= 127) {
|
||||
CBofString tmp = _text + lKey;
|
||||
CBofRect rect = calculateTextRect(this, &tmp, 12, 0);
|
||||
|
||||
if ((_cRect.width() - rect.width()) > 10) {
|
||||
setText(tmp);
|
||||
}
|
||||
|
||||
} else if (lKey == BKEY_BACK && !_text.isEmpty()) {
|
||||
_text.deleteLastChar();
|
||||
updateWindow();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
62
engines/bagel/spacebar/boflib/gui/edit_text.h
Normal file
62
engines/bagel/spacebar/boflib/gui/edit_text.h
Normal file
@@ -0,0 +1,62 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BOFLIB_GUI_EDIT_TEXT_H
|
||||
#define BAGEL_BOFLIB_GUI_EDIT_TEXT_H
|
||||
|
||||
#include "bagel/spacebar/boflib/gui/window.h"
|
||||
#include "bagel/boflib/string.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class CBofEditText : public CBofWindow {
|
||||
private:
|
||||
CBofString _text;
|
||||
size_t _cursorPos = 0;
|
||||
|
||||
protected:
|
||||
void onLButtonDown(uint32 nFlags, CBofPoint *pPoint, void * = nullptr) override;
|
||||
void onKeyHit(uint32 lKey, uint32 lRepCount) override;
|
||||
|
||||
public:
|
||||
CBofEditText() {
|
||||
}
|
||||
|
||||
CBofEditText(const char *pszName, int x, int y, int nWidth, int nHeight, CBofWindow *pParent);
|
||||
|
||||
ErrorCode create(const char *pszName, int x, int y, int nWidth, int nHeight, CBofWindow *pParent, uint32 nControlID = 0) override;
|
||||
ErrorCode create(const char *pszName, CBofRect *pRect, CBofWindow *pParent, uint32 nControlID = 0) override;
|
||||
|
||||
CBofString getText() const {
|
||||
return _text;
|
||||
}
|
||||
|
||||
void setText(const char *pszString);
|
||||
|
||||
void onPaint(CBofRect *pRect) override;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
549
engines/bagel/spacebar/boflib/gui/list_box.cpp
Normal file
549
engines/bagel/spacebar/boflib/gui/list_box.cpp
Normal file
@@ -0,0 +1,549 @@
|
||||
/* 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/app.h"
|
||||
#include "bagel/spacebar/boflib/gfx/text.h"
|
||||
#include "bagel/spacebar/boflib/gui/list_box.h"
|
||||
|
||||
#include "bagel/spacebar/boflib/std_keys.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define TEXT_ITEM_HEIGHT 24
|
||||
|
||||
|
||||
CBofListBox::CBofListBox() {
|
||||
_cTextColor = CTEXT_COLOR;
|
||||
_cHighColor = CTEXT_COLOR;
|
||||
_nTextSize = 10;
|
||||
_nTextWeight = TEXT_NORMAL;
|
||||
_nNumItems = 0;
|
||||
_n1stVisible = 0;
|
||||
_nPageSize = 0;
|
||||
_pWork = nullptr;
|
||||
_nItemHeight = TEXT_ITEM_HEIGHT;
|
||||
_nState = LISTBOX_NORMAL;
|
||||
_nTextFont = FONT_DEFAULT;
|
||||
|
||||
// Initialized the selected item
|
||||
CBofListBox::clearSelection();
|
||||
}
|
||||
|
||||
|
||||
CBofListBox::~CBofListBox() {
|
||||
// Kill the temporary work area
|
||||
delete _pWork;
|
||||
_pWork = nullptr;
|
||||
|
||||
deleteAll(false);
|
||||
}
|
||||
|
||||
void CBofListBox::clearSelection() {
|
||||
_nSelectedItem = -1;
|
||||
}
|
||||
|
||||
void CBofListBox::insertBefore(int nIndex, const CBofString &cString, bool bRepaint) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
ListBoxItem lbi;
|
||||
lbi._pTextStr = new CBofString(cString);
|
||||
lbi._nTextLineColor = COLOR_USE_DEFAULT;
|
||||
|
||||
_cTextItems.insertBefore(nIndex, lbi);
|
||||
|
||||
// One more item
|
||||
_nNumItems++;
|
||||
|
||||
clearSelection();
|
||||
|
||||
if (bRepaint && isCreated() && isVisible()) {
|
||||
repaintAll();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CBofListBox::insertAfter(int nIndex, const CBofString &cString, bool bRepaint) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
ListBoxItem lbi;
|
||||
lbi._pTextStr = new CBofString(cString);
|
||||
lbi._nTextLineColor = COLOR_USE_DEFAULT;
|
||||
|
||||
_cTextItems.insertAfter(nIndex, lbi);
|
||||
|
||||
// One more item
|
||||
_nNumItems++;
|
||||
|
||||
if (bRepaint && isCreated() && isVisible()) {
|
||||
repaintAll();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CBofListBox::addToHead(const CBofString &cString, bool bRepaint) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
ListBoxItem lbi;
|
||||
lbi._pTextStr = new CBofString(cString);
|
||||
lbi._nTextLineColor = COLOR_USE_DEFAULT;
|
||||
|
||||
_cTextItems.addToHead(lbi);
|
||||
|
||||
// One more item
|
||||
_nNumItems++;
|
||||
|
||||
clearSelection();
|
||||
|
||||
if (bRepaint && isCreated() && isVisible()) {
|
||||
repaintAll();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CBofListBox::addToTail(const CBofString &cString, bool bRepaint) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
ListBoxItem lbi;
|
||||
lbi._pTextStr = new CBofString(cString);
|
||||
lbi._nTextLineColor = COLOR_USE_DEFAULT;
|
||||
|
||||
_cTextItems.addToTail(lbi);
|
||||
|
||||
// One more item
|
||||
_nNumItems++;
|
||||
|
||||
clearSelection();
|
||||
|
||||
if (bRepaint && isCreated() && isVisible()) {
|
||||
repaintAll();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofListBox::delItem(int nIndex, bool bRepaint) {
|
||||
assert(isValidObject(this));
|
||||
assert(nIndex >= 0 && nIndex < _nNumItems);
|
||||
|
||||
_cTextItems.remove(nIndex);
|
||||
|
||||
// One less item
|
||||
_nNumItems--;
|
||||
|
||||
if (_n1stVisible >= _nNumItems) {
|
||||
_n1stVisible = _nNumItems - 1;
|
||||
if (_n1stVisible < 0)
|
||||
_n1stVisible = 0;
|
||||
}
|
||||
|
||||
clearSelection();
|
||||
|
||||
|
||||
if (bRepaint && isCreated() && isVisible()) {
|
||||
repaintAll();
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBofListBox::deleteAll(bool bRepaint) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Switch item to be pointer to cbofstring instead of the item itself
|
||||
int nCount = _cTextItems.getCount();
|
||||
|
||||
for (int i = 0; i < nCount; i++) {
|
||||
ListBoxItem lbi = _cTextItems.getNodeItem(i);
|
||||
delete lbi._pTextStr;
|
||||
}
|
||||
|
||||
_cTextItems.removeAll();
|
||||
_nNumItems = 0;
|
||||
_n1stVisible = 0;
|
||||
|
||||
clearSelection();
|
||||
|
||||
if (bRepaint && isCreated() && isVisible()) {
|
||||
repaintAll();
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
void CBofListBox::onLButtonDown(uint32 /*nFlags*/, CBofPoint *pPoint, void *) {
|
||||
assert(isValidObject(this));
|
||||
assert(pPoint != nullptr);
|
||||
|
||||
int nIndex = (pPoint->y / _nItemHeight) + _n1stVisible;
|
||||
if (nIndex < _nNumItems) {
|
||||
|
||||
_nSelectedItem = nIndex; // Set the selected item
|
||||
_nState = LISTBOX_SELECT;
|
||||
|
||||
if (_parent != nullptr) {
|
||||
_parent->setPrevMouseDown(*pPoint);
|
||||
_parent->onBofListBox(this, nIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CBofListBox::onLButtonDblClk(uint32 /*nFlags*/, CBofPoint *pPoint) {
|
||||
assert(isValidObject(this));
|
||||
assert(pPoint != nullptr);
|
||||
|
||||
int nIndex = (pPoint->y / _nItemHeight) + _n1stVisible;
|
||||
|
||||
if (nIndex < _nNumItems) {
|
||||
_nSelectedItem = nIndex; // Set the selected item
|
||||
_nState = LISTBOX_USENOW;
|
||||
|
||||
if (_parent != nullptr) {
|
||||
_parent->setPrevMouseDown(*pPoint);
|
||||
_parent->onBofListBox(this, nIndex);
|
||||
}
|
||||
}
|
||||
|
||||
setFocus();
|
||||
}
|
||||
|
||||
|
||||
void CBofListBox::onKeyHit(uint32 lKey, uint32 lRepCount) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
switch (lKey) {
|
||||
case BKEY_HOME:
|
||||
scrollTo(0);
|
||||
break;
|
||||
|
||||
case BKEY_END:
|
||||
scrollTo(_nNumItems);
|
||||
break;
|
||||
|
||||
case BKEY_UP:
|
||||
lineUp();
|
||||
break;
|
||||
|
||||
case BKEY_DOWN:
|
||||
lineDown();
|
||||
break;
|
||||
|
||||
case BKEY_PAGEUP:
|
||||
pageUp();
|
||||
break;
|
||||
|
||||
case BKEY_PAGEDOWN:
|
||||
pageDown();
|
||||
break;
|
||||
|
||||
default:
|
||||
// Call the previous windows onkeyhit
|
||||
CBofWindow *pParent = getParent();
|
||||
if (pParent && pParent != this) {
|
||||
pParent->onKeyHit(lKey, lRepCount);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofListBox::scrollUp(const int nLines) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// If all the items fit on a single page, make this operation a no-op.
|
||||
if (_nNumItems <= _nPageSize) {
|
||||
return scrollTo(_n1stVisible);
|
||||
}
|
||||
|
||||
int nNewLine = _n1stVisible - nLines;
|
||||
|
||||
if (nNewLine < 0) {
|
||||
nNewLine = 0;
|
||||
|
||||
} else if (nNewLine > (_nNumItems - _nPageSize)) {
|
||||
// If the line requested to be the top of the page
|
||||
// would cause fewer than _nPageSize lines to be displayed,
|
||||
// snap nNewLine to be equal to the top of the last full page.
|
||||
nNewLine = (_nNumItems - _nPageSize);
|
||||
}
|
||||
|
||||
return scrollTo(nNewLine);
|
||||
}
|
||||
|
||||
ErrorCode CBofListBox::scrollTo(const int nLine) {
|
||||
assert(isValidObject(this));
|
||||
assert(nLine >= 0 && nLine <= _nNumItems);
|
||||
|
||||
// Only update the screen if the list actually moved
|
||||
if (_n1stVisible != nLine) {
|
||||
_n1stVisible = nLine;
|
||||
|
||||
if (nLine >= _nNumItems) {
|
||||
assert(_nNumItems > 0);
|
||||
_n1stVisible--;
|
||||
}
|
||||
|
||||
// Show the text box
|
||||
repaintAll();
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
void CBofListBox::onPaint(CBofRect * /*pRect*/) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
_nPageSize = height() / _nItemHeight;
|
||||
|
||||
if (_pBackdrop == nullptr) {
|
||||
saveBackground();
|
||||
}
|
||||
|
||||
repaintAll();
|
||||
}
|
||||
|
||||
|
||||
void CBofListBox::killBackground() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
delete _pBackdrop;
|
||||
_pBackdrop = nullptr;
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofListBox::saveBackground() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
killBackground();
|
||||
_pBackdrop = new CBofBitmap(width(), height(), CBofApp::getApp()->getPalette());
|
||||
|
||||
if ((_parent != nullptr) && (_parent->getBackdrop() != nullptr)) {
|
||||
CBofRect cRect = _pBackdrop->getRect();
|
||||
_parent->getBackdrop()->paint(_pBackdrop, &cRect, &_cWindowRect);
|
||||
} else {
|
||||
_pBackdrop->captureScreen(this, &_cRect);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBofListBox::createWorkArea() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (_pBackdrop == nullptr) {
|
||||
saveBackground();
|
||||
}
|
||||
|
||||
if (_pWork == nullptr) {
|
||||
assert(_pBackdrop != nullptr);
|
||||
_pWork = new CBofBitmap(width(), height(), _pBackdrop->getPalette());
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofListBox::repaintAll() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (!errorOccurred()) {
|
||||
assert(isCreated());
|
||||
|
||||
int nCurFont = getFont();
|
||||
setFont(_nTextFont);
|
||||
|
||||
createWorkArea();
|
||||
|
||||
if (_pWork != nullptr) {
|
||||
_pWork->lock();
|
||||
|
||||
int nIndexedColor = _pWork->getPalette()->getNearestIndex(_cTextColor);
|
||||
|
||||
// prepare the background
|
||||
//
|
||||
assert(_pBackdrop != nullptr);
|
||||
_pBackdrop->paint(_pWork);
|
||||
|
||||
for (int i = 0; i < _nPageSize; i++) {
|
||||
CBofRect cRect;
|
||||
cRect.setRect(0, i * _nItemHeight, width() - 1, (i + 1) * _nItemHeight - 1);
|
||||
|
||||
if (i + _n1stVisible < _nNumItems) {
|
||||
// If this item is currently selected and we have a high color
|
||||
if ((i + _n1stVisible == _nSelectedItem) && (_cHighColor != _cTextColor)) {
|
||||
// display text highlighted
|
||||
paintText(_pWork,
|
||||
&cRect,
|
||||
*(_cTextItems.getNodeItem(i + _n1stVisible)._pTextStr),
|
||||
_nTextSize,
|
||||
_nTextWeight,
|
||||
_cHighColor,
|
||||
JUSTIFY_LEFT,
|
||||
FORMAT_TOP_LEFT | FORMAT_SINGLE_LINE,
|
||||
getFont());
|
||||
} else {
|
||||
// Display text
|
||||
// Allow list items of different colors.
|
||||
COLORREF rgbTextColor = _cTextColor;
|
||||
if (_cTextItems.getNodeItem(i + _n1stVisible)._nTextLineColor != COLOR_USE_DEFAULT) {
|
||||
rgbTextColor = _cTextItems.getNodeItem(i + _n1stVisible)._nTextLineColor;
|
||||
}
|
||||
|
||||
paintText(_pWork,
|
||||
&cRect,
|
||||
*(_cTextItems.getNodeItem(i + _n1stVisible)._pTextStr),
|
||||
_nTextSize,
|
||||
_nTextWeight,
|
||||
rgbTextColor,
|
||||
JUSTIFY_LEFT,
|
||||
FORMAT_TOP_LEFT | FORMAT_SINGLE_LINE,
|
||||
getFont());
|
||||
}
|
||||
|
||||
CBofPoint bl(cRect.bottomLeft()), br(cRect.bottomRight());
|
||||
_pWork->line(&bl, &br, (byte)nIndexedColor);
|
||||
}
|
||||
}
|
||||
|
||||
// Show final image on screen
|
||||
_pWork->paint(this);
|
||||
|
||||
_pWork->unlock();
|
||||
}
|
||||
|
||||
// Reset the font
|
||||
setFont(nCurFont);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofListBox::repaintItem(int nIndex) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (!errorOccurred()) {
|
||||
assert(nIndex >= 0 && nIndex < _nNumItems);
|
||||
int nCurFont = getFont();
|
||||
setFont(_nTextFont); // Set the proper font
|
||||
|
||||
// If this item is visible, then repaint it.
|
||||
if (nIndex >= _n1stVisible && nIndex <= _n1stVisible + _nPageSize) {
|
||||
int i = nIndex - _n1stVisible;
|
||||
|
||||
createWorkArea();
|
||||
int nIndexedColor = _pWork->getPalette()->getNearestIndex(_cTextColor);
|
||||
|
||||
_pWork->lock();
|
||||
|
||||
// Calculate area for this text item
|
||||
CBofRect cRect;
|
||||
cRect.setRect(0, i * _nItemHeight, width() - 1, (i + 1) * _nItemHeight - 1);
|
||||
|
||||
// Prepare the background
|
||||
assert(_pBackdrop != nullptr);
|
||||
_pBackdrop->paint(_pWork, &cRect, &cRect);
|
||||
|
||||
// If this item is currently selected and we have a high color
|
||||
if ((nIndex == _nSelectedItem) && (_cHighColor != _cTextColor)) {
|
||||
// Display text highlighted
|
||||
paintText(_pWork,
|
||||
&cRect,
|
||||
*(_cTextItems.getNodeItem(nIndex)._pTextStr),
|
||||
_nTextSize,
|
||||
_nTextWeight,
|
||||
_cHighColor,
|
||||
JUSTIFY_LEFT,
|
||||
FORMAT_TOP_LEFT | FORMAT_SINGLE_LINE,
|
||||
getFont());
|
||||
|
||||
} else {
|
||||
// Display text
|
||||
// Allow list items of different colors.
|
||||
COLORREF rgbTextColor = _cTextColor;
|
||||
if (_cTextItems.getNodeItem(i + _n1stVisible)._nTextLineColor != COLOR_USE_DEFAULT) {
|
||||
rgbTextColor = _cTextItems.getNodeItem(i + _n1stVisible)._nTextLineColor;
|
||||
}
|
||||
paintText(_pWork,
|
||||
&cRect,
|
||||
*(_cTextItems.getNodeItem(nIndex)._pTextStr),
|
||||
_nTextSize,
|
||||
_nTextWeight,
|
||||
rgbTextColor,
|
||||
JUSTIFY_LEFT,
|
||||
FORMAT_TOP_LEFT | FORMAT_SINGLE_LINE,
|
||||
getFont());
|
||||
}
|
||||
CBofPoint bl(cRect.bottomLeft()), br(cRect.bottomRight());
|
||||
_pWork->line(&bl, &br, (byte)nIndexedColor);
|
||||
|
||||
// Show final image on screen
|
||||
_pWork->paint(this, &cRect, &cRect);
|
||||
|
||||
_pWork->unlock();
|
||||
}
|
||||
|
||||
// Reset the font
|
||||
setFont(nCurFont);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
void CBofListBox::setSelectedItem(int nItem, bool bRepaint) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Set highlighted item
|
||||
_nSelectedItem = nItem;
|
||||
|
||||
if (bRepaint) {
|
||||
repaintAll();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CBofString CBofListBox::getText(int nIndex) {
|
||||
return *(_cTextItems.getNodeItem(nIndex)._pTextStr);
|
||||
}
|
||||
|
||||
|
||||
void CBofListBox::setText(int nIndex, const CBofString &cStr) {
|
||||
|
||||
ListBoxItem lbi = _cTextItems.getNodeItem(nIndex);
|
||||
*lbi._pTextStr = cStr;
|
||||
|
||||
_cTextItems.setNodeItem(nIndex, lbi);
|
||||
}
|
||||
|
||||
|
||||
void CBofListBox::setTextLineColor(int nIndex, COLORREF rgbColor) {
|
||||
|
||||
ListBoxItem lbi = _cTextItems.getNodeItem(nIndex);
|
||||
lbi._nTextLineColor = rgbColor;
|
||||
|
||||
_cTextItems.setNodeItem(nIndex, lbi);
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
179
engines/bagel/spacebar/boflib/gui/list_box.h
Normal file
179
engines/bagel/spacebar/boflib/gui/list_box.h
Normal file
@@ -0,0 +1,179 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BOFLIB_GUI_LIST_BOX_H
|
||||
#define BAGEL_BOFLIB_GUI_LIST_BOX_H
|
||||
|
||||
#include "bagel/spacebar/boflib/gui/window.h"
|
||||
#include "bagel/spacebar/boflib/list.h"
|
||||
#include "bagel/boflib/string.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define LISTBOX_NORMAL 0
|
||||
#define LISTBOX_SELECT 1
|
||||
#define LISTBOX_USENOW 2
|
||||
#define COLOR_USE_DEFAULT 0xFFFFFFFF
|
||||
|
||||
class ListBoxItem {
|
||||
public:
|
||||
ListBoxItem() {
|
||||
_pTextStr = nullptr;
|
||||
_nTextLineColor = COLOR_USE_DEFAULT;
|
||||
}
|
||||
|
||||
|
||||
CBofString *_pTextStr;
|
||||
COLORREF _nTextLineColor;
|
||||
};
|
||||
|
||||
class CBofListBox : public CBofWindow {
|
||||
public:
|
||||
CBofListBox();
|
||||
~CBofListBox();
|
||||
|
||||
void setSelectedItem(int nItem, bool bRepaint = true);
|
||||
|
||||
void insertBefore(int nIndex, const CBofString &cString, bool bRepaint = true);
|
||||
void insertAfter(int nIndex, const CBofString &cString, bool bRepaint = true);
|
||||
|
||||
void addToHead(const CBofString &cString, bool bRepaint = true);
|
||||
void addToTail(const CBofString &cString, bool bRepaint = true);
|
||||
|
||||
ErrorCode delItem(int nIndex, bool bRepaint = true);
|
||||
ErrorCode deleteAll(bool bRepaint = true);
|
||||
|
||||
int getNumItems() {
|
||||
return _nNumItems;
|
||||
}
|
||||
CBofString getText(int nIndex);
|
||||
void setText(int nIndex, const CBofString &cStr);
|
||||
|
||||
void setTextLineColor(int nIndex, COLORREF rgbColor);
|
||||
|
||||
ErrorCode lineUp() {
|
||||
return scrollUp(1);
|
||||
}
|
||||
ErrorCode lineDown() {
|
||||
return scrollDown(1);
|
||||
}
|
||||
|
||||
ErrorCode pageUp() {
|
||||
return scrollUp(_nPageSize);
|
||||
}
|
||||
ErrorCode pageDown() {
|
||||
return scrollDown(_nPageSize);
|
||||
}
|
||||
|
||||
ErrorCode scrollUp(int nLines);
|
||||
ErrorCode scrollDown(const int nLines) {
|
||||
return scrollUp(-nLines);
|
||||
}
|
||||
|
||||
ErrorCode scrollTo(int nLine);
|
||||
|
||||
ErrorCode createWorkArea();
|
||||
ErrorCode saveBackground();
|
||||
void killBackground();
|
||||
|
||||
void setHighlightColor(COLORREF cHighColor) {
|
||||
_cHighColor = cHighColor;
|
||||
}
|
||||
COLORREF getHighlightColor() {
|
||||
return _cHighColor;
|
||||
}
|
||||
|
||||
void setTextColor(COLORREF cColor) {
|
||||
_cTextColor = cColor;
|
||||
}
|
||||
COLORREF getTextColor() {
|
||||
return _cTextColor;
|
||||
}
|
||||
|
||||
void setPointSize(int nSize) {
|
||||
_nTextSize = nSize;
|
||||
}
|
||||
int getPointSize() {
|
||||
return _nTextSize;
|
||||
}
|
||||
|
||||
void setWeight(int nWeight) {
|
||||
_nTextWeight = nWeight;
|
||||
}
|
||||
int getWeight() {
|
||||
return _nTextWeight;
|
||||
}
|
||||
|
||||
void setItemHeight(int nHeight) {
|
||||
_nItemHeight = nHeight;
|
||||
}
|
||||
int getItemHeight() {
|
||||
return _nItemHeight;
|
||||
}
|
||||
|
||||
void setFont(int nFont) {
|
||||
_nTextFont = nFont;
|
||||
}
|
||||
int getFont() {
|
||||
return _nTextFont;
|
||||
}
|
||||
|
||||
int getState() {
|
||||
return _nState;
|
||||
}
|
||||
|
||||
virtual ErrorCode repaintItem(int nIndex);
|
||||
virtual ErrorCode repaintAll();
|
||||
|
||||
protected:
|
||||
virtual void onLButtonDown(uint32 nFlags, CBofPoint *pPoint, void * = nullptr);
|
||||
virtual void onLButtonDblClk(uint32 nFlags, CBofPoint *pPoint);
|
||||
virtual void onKeyHit(uint32 lKey, uint32 lRepCount);
|
||||
virtual void onPaint(CBofRect *pRect);
|
||||
|
||||
/**
|
||||
* Clears the currently selected item
|
||||
*/
|
||||
virtual void clearSelection();
|
||||
|
||||
CBofList<ListBoxItem> _cTextItems;
|
||||
CBofBitmap *_pWork;
|
||||
int _nNumItems;
|
||||
int _n1stVisible;
|
||||
|
||||
int _nPageSize;
|
||||
|
||||
int _nTextSize;
|
||||
int _nTextWeight;
|
||||
COLORREF _cTextColor;
|
||||
COLORREF _cHighColor;
|
||||
int _nSelectedItem;
|
||||
int _nItemHeight;
|
||||
int _nTextFont;
|
||||
int _nState;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
376
engines/bagel/spacebar/boflib/gui/movie.cpp
Normal file
376
engines/bagel/spacebar/boflib/gui/movie.cpp
Normal file
@@ -0,0 +1,376 @@
|
||||
/* 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 "graphics/cursorman.h"
|
||||
|
||||
#include "bagel/boflib/string.h"
|
||||
#include "bagel/spacebar/boflib/gui/movie.h"
|
||||
#include "bagel/spacebar/boflib/gfx/cursor.h"
|
||||
#include "bagel/spacebar/boflib/std_keys.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
CBofMovie::CBofMovie(CBofWindow *pParent, const char *pszFilename, CBofRect *pBounds, bool bStretch, bool bUseNewPalette, bool bBlackOutWindow) {
|
||||
_bStretch = bStretch;
|
||||
|
||||
// Allow movie to not shift to new palette.
|
||||
_bUseNewPalette = bUseNewPalette;
|
||||
|
||||
// Black out first and last frame of flythroughs and examine movies
|
||||
_bBlackOutWindow = bBlackOutWindow;
|
||||
|
||||
initialize(pParent);
|
||||
open(pszFilename, pBounds);
|
||||
}
|
||||
|
||||
CBofMovie::~CBofMovie() {
|
||||
closeMovie();
|
||||
}
|
||||
|
||||
ErrorCode CBofMovie::initialize(CBofWindow *pParent) {
|
||||
// Movie Stuff
|
||||
_eMovStatus = STOPPED;
|
||||
_bEscCanStop = true;
|
||||
|
||||
// Smacker Stuff
|
||||
_pSbuf = nullptr;
|
||||
_pSmk = nullptr;
|
||||
_bLoop = false;
|
||||
|
||||
// Call dialog box creates
|
||||
if (create("MovieWin", 0, 0, 1, 1, pParent, 1) == ERR_NONE) {
|
||||
setCapture();
|
||||
}
|
||||
|
||||
return ERR_NONE;
|
||||
|
||||
}
|
||||
|
||||
bool CBofMovie::open(const char *sFilename, CBofRect *pBounds) {
|
||||
if (sFilename == nullptr) {
|
||||
assert(sFilename);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pBounds != nullptr) {
|
||||
_cRect = *pBounds;
|
||||
}
|
||||
|
||||
if (openMovie(sFilename)) {
|
||||
// We were given specific rect for movie
|
||||
if (pBounds)
|
||||
reSize(pBounds, true);
|
||||
else
|
||||
// Center the movie to the parent window
|
||||
centerRect();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CBofMovie::openMovie(const char *sFilename) {
|
||||
assert(sFilename[0] != '\0');
|
||||
|
||||
if (_pSmk) {
|
||||
closeMovie();
|
||||
}
|
||||
_pSmk = new Video::SmackerDecoder();
|
||||
_pSmk->setSoundType(Audio::Mixer::kSFXSoundType);
|
||||
|
||||
if (!_pSmk->loadFile(sFilename)) {
|
||||
// Opened failed
|
||||
error("Movie not found=%s", sFilename);
|
||||
}
|
||||
|
||||
// If supposed to stretch into specified window
|
||||
if (_bStretch) {
|
||||
_pSbuf = new Graphics::ManagedSurface(width(), height(), _pSmk->getPixelFormat());
|
||||
} else {
|
||||
_pSbuf = new Graphics::ManagedSurface(_pSmk->getWidth(), _pSmk->getHeight(), _pSmk->getPixelFormat());
|
||||
}
|
||||
|
||||
_srcRect = Common::Rect(_pSmk->getWidth(), _pSmk->getHeight());
|
||||
_dstRect = Common::Rect(_pSbuf->w, _pSbuf->h);
|
||||
|
||||
if (!_bStretch) {
|
||||
_dstRect.moveTo((_pSbuf->w - _pSmk->getWidth()) / 2, (_pSbuf->h - _pSmk->getHeight()) / 2);
|
||||
}
|
||||
|
||||
CBofRect MovieBounds(0, 0, (uint16)_pSbuf->w - 1, (uint16)_pSbuf->h - 1);
|
||||
reSize(&MovieBounds, true);
|
||||
|
||||
// If we have a window that is going to cause a single frame
|
||||
// palette shift, then black it out here.
|
||||
if (_bBlackOutWindow) {
|
||||
fillWindow(COLOR_BLACK);
|
||||
}
|
||||
|
||||
// Smack the current frame into the buffer
|
||||
const Graphics::Surface *frame = _pSmk->decodeNextFrame();
|
||||
if (frame) {
|
||||
_pSbuf->setPalette(_pSmk->getPalette(), 0, 256);
|
||||
_pSbuf->blitFrom(*frame, _srcRect, _dstRect);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CBofMovie::onKeyHit(uint32 lKey, uint32 /*lRepCount*/) {
|
||||
if (_bEscCanStop && lKey == BKEY_ESC) {
|
||||
// Clean up and exit
|
||||
_bLoop = false;
|
||||
stop();
|
||||
onMovieDone();
|
||||
}
|
||||
}
|
||||
|
||||
void CBofMovie::onMainLoop() {
|
||||
if (!_pSmk->needsUpdate() || _eMovStatus == STOPPED)
|
||||
return;
|
||||
|
||||
// Smack the current frame into the buffer
|
||||
const Graphics::Surface *frame = _pSmk->decodeNextFrame();
|
||||
if (_pSmk->hasDirtyPalette()) {
|
||||
_pSbuf->setPalette(_pSmk->getPalette(), 0, 256);
|
||||
}
|
||||
if (frame) {
|
||||
_pSbuf->blitFrom(*frame, _srcRect, _dstRect);
|
||||
updateWindow();
|
||||
}
|
||||
|
||||
if (_eMovStatus == FORWARD) {
|
||||
if (_pSmk->getCurFrame() == (int)_pSmk->getFrameCount() - 1) {
|
||||
if (_bLoop == false) {
|
||||
onMovieDone();
|
||||
} else {
|
||||
seekToStart();
|
||||
_pSmk->start();
|
||||
}
|
||||
}
|
||||
} else if (_eMovStatus == REVERSE) {
|
||||
if ((_pSmk->getCurFrame() == 0) || (_pSmk->getCurFrame() == 1)) {
|
||||
if (_bLoop == false) {
|
||||
onMovieDone();
|
||||
} else {
|
||||
seekToEnd();
|
||||
}
|
||||
} else {
|
||||
setFrame(_pSmk->getCurFrame() - 2); // HACK: Reverse playback
|
||||
}
|
||||
}// MOVIE_REVERSE
|
||||
}
|
||||
|
||||
void CBofMovie::onPaint(CBofRect *) {
|
||||
if (_pSbuf) {
|
||||
getSurface()->blitFrom(*_pSbuf);
|
||||
}
|
||||
}
|
||||
|
||||
void CBofMovie::closeMovie() {
|
||||
delete _pSbuf;
|
||||
_pSbuf = nullptr;
|
||||
|
||||
delete _pSmk;
|
||||
_pSmk = nullptr;
|
||||
}
|
||||
|
||||
void CBofMovie::onClose() {
|
||||
closeMovie();
|
||||
CBofDialog::onClose();
|
||||
}
|
||||
|
||||
void CBofMovie::onMovieDone() {
|
||||
if (!_bLoop) {
|
||||
if (_bCaptured)
|
||||
releaseCapture();
|
||||
|
||||
getParent()->enable();
|
||||
_bEndDialog = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool CBofMovie::play(bool bLoop, bool bEscCanStop) {
|
||||
|
||||
_bEscCanStop = bEscCanStop;
|
||||
_bLoop = bLoop;
|
||||
|
||||
bool bSuccess = play();
|
||||
|
||||
getParent()->disable();
|
||||
getParent()->flushAllMessages();
|
||||
|
||||
CursorMan.showMouse(false);
|
||||
|
||||
doModal();
|
||||
|
||||
CursorMan.showMouse(true);
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
|
||||
bool CBofMovie::play() {
|
||||
if (_pSmk) {
|
||||
_pSmk->pauseVideo(false);
|
||||
//_pSmk->setReverse(false); // TODO: Not supported by SMK
|
||||
_pSmk->start();
|
||||
_eMovStatus = FORWARD;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool CBofMovie::reverse(bool bLoop, bool bEscCanStop) {
|
||||
_bEscCanStop = bEscCanStop;
|
||||
_bLoop = bLoop;
|
||||
|
||||
bool bSuccess = reverse();
|
||||
|
||||
getParent()->disable();
|
||||
getParent()->flushAllMessages();
|
||||
doModal();
|
||||
|
||||
return bSuccess;
|
||||
|
||||
}
|
||||
|
||||
bool CBofMovie::reverse() {
|
||||
|
||||
if (_pSmk) {
|
||||
_pSmk->pauseVideo(false);
|
||||
//_smk->setReverse(true); // TODO: Not supported by SMK
|
||||
_pSmk->start();
|
||||
_eMovStatus = REVERSE;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool CBofMovie::stop() {
|
||||
if (_pSmk) {
|
||||
_pSmk->stop();
|
||||
_eMovStatus = STOPPED;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool CBofMovie::pause() {
|
||||
if (_pSmk) {
|
||||
_pSmk->pauseVideo(true);
|
||||
_eMovStatus = PAUSED;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool CBofMovie::seekToStart() {
|
||||
if (_pSmk) {
|
||||
_pSmk->rewind();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CBofMovie::seekToEnd() {
|
||||
if (_pSmk) {
|
||||
setFrame(_pSmk->getFrameCount() - 2); // HACK: Reverse rewind
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 CBofMovie::getFrame() {
|
||||
if (_pSmk) {
|
||||
return _pSmk->getCurFrame();
|
||||
}
|
||||
|
||||
return (uint32) -1;
|
||||
}
|
||||
|
||||
|
||||
bool CBofMovie::setFrame(uint32 dwFrameNum) {
|
||||
if (_pSmk) {
|
||||
dwFrameNum = CLIP<uint32>(dwFrameNum, 0, _pSmk->getFrameCount() - 1);
|
||||
_pSmk->forceSeekToFrame(dwFrameNum);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CBofMovie::onReSize(CBofSize *pSize) {
|
||||
}
|
||||
|
||||
bool CBofMovie::centerRect() {
|
||||
CBofRect cBofRect = getParent()->getClientRect();
|
||||
RECT rcParentRect = cBofRect.getWinRect();
|
||||
int ClientWidth = rcParentRect.right - rcParentRect.left;
|
||||
int ClientHeight = rcParentRect.bottom - rcParentRect.top;
|
||||
|
||||
// Get Movies width and height
|
||||
int MovieWidth = _pSmk->getWidth();
|
||||
int MovieHeight = _pSmk->getHeight();
|
||||
|
||||
RECT rcMovieBounds;
|
||||
rcMovieBounds.left = (ClientWidth - MovieWidth) / 2;
|
||||
rcMovieBounds.top = (ClientHeight - MovieHeight) / 2;
|
||||
rcMovieBounds.right = rcMovieBounds.left + MovieWidth;
|
||||
rcMovieBounds.bottom = rcMovieBounds.top + MovieHeight;
|
||||
|
||||
// Reposition the playback window
|
||||
cBofRect = rcMovieBounds;
|
||||
reSize(&cBofRect, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CBofMovie::onButtonUp(uint32 /*nFlags*/, CBofPoint */*pPoint*/) {
|
||||
}
|
||||
|
||||
|
||||
ErrorCode bofPlayMovie(CBofWindow *pParent, const char *pszMovieFile, CBofRect *pRect) {
|
||||
assert(pParent != nullptr);
|
||||
assert(pszMovieFile != nullptr);
|
||||
|
||||
CBofMovie cMovie(pParent, pszMovieFile, pRect);
|
||||
if (!cMovie.errorOccurred()) {
|
||||
cMovie.play(false, true);
|
||||
}
|
||||
|
||||
return cMovie.getErrorCode();
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
111
engines/bagel/spacebar/boflib/gui/movie.h
Normal file
111
engines/bagel/spacebar/boflib/gui/movie.h
Normal file
@@ -0,0 +1,111 @@
|
||||
|
||||
/* 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/".
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BOFLIB_GUI_MOVIE_H
|
||||
#define BAGEL_BOFLIB_GUI_MOVIE_H
|
||||
|
||||
#include "graphics/managed_surface.h"
|
||||
#include "video/smk_decoder.h"
|
||||
#include "bagel/boflib/error.h"
|
||||
#include "bagel/spacebar/boflib/gui/dialog.h"
|
||||
#include "bagel/boflib/rect.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class CBofMovie : public CBofDialog {
|
||||
public:
|
||||
enum MVSTATUS {
|
||||
STOPPED, PAUSED, FORWARD, REVERSE
|
||||
};
|
||||
protected:
|
||||
Graphics::ManagedSurface *_pSbuf;
|
||||
Video::SmackerDecoder *_pSmk;
|
||||
bool _bEscCanStop;
|
||||
bool _bLoop;
|
||||
bool _bStretch;
|
||||
bool _bUseNewPalette;
|
||||
bool _bBlackOutWindow;
|
||||
MVSTATUS _eMovStatus;
|
||||
Common::Rect _srcRect, _dstRect;
|
||||
|
||||
virtual ErrorCode initialize(CBofWindow *pParent);
|
||||
|
||||
virtual bool openMovie(const char *sFilename);
|
||||
virtual void closeMovie();
|
||||
|
||||
virtual void onReSize(CBofSize *pSize);
|
||||
|
||||
virtual bool play();
|
||||
virtual bool reverse();
|
||||
|
||||
virtual void onLButtonUp(uint32 nFlags, CBofPoint *pPoint, void * = nullptr) {
|
||||
onButtonUp(nFlags, pPoint);
|
||||
}
|
||||
virtual void onRButtonUp(uint32 nFlags, CBofPoint *pPoint) {
|
||||
onButtonUp(nFlags, pPoint);
|
||||
}
|
||||
virtual void onButtonUp(uint32 nFlags, CBofPoint *pPoint);
|
||||
virtual void onPaint(CBofRect *pRect);
|
||||
virtual void onMovieDone();
|
||||
virtual void onClose();
|
||||
virtual void onMainLoop();
|
||||
virtual void onKeyHit(uint32 lKey, uint32 lRepCount);
|
||||
|
||||
public:
|
||||
|
||||
CBofMovie(CBofWindow *pParent = nullptr, const char *pszFilename = nullptr, CBofRect *pBounds = nullptr, bool bStretch = false, bool bUseNewPalette = true, bool bBlackOutWindow = false);
|
||||
~CBofMovie();
|
||||
|
||||
virtual bool open(const char *sFilename = nullptr, CBofRect *pBounds = nullptr);
|
||||
|
||||
virtual bool play(bool bLoop, bool bEscCanStop = true);
|
||||
virtual bool reverse(bool bLoop, bool bEscCanStop = true);
|
||||
virtual bool pause();
|
||||
virtual bool stop();
|
||||
|
||||
virtual MVSTATUS status() {
|
||||
return _eMovStatus;
|
||||
}
|
||||
|
||||
virtual bool seekToStart();
|
||||
virtual bool seekToEnd();
|
||||
|
||||
virtual uint32 getFrame();
|
||||
virtual bool setFrame(uint32 dwFrameNum);
|
||||
|
||||
virtual bool centerRect();
|
||||
|
||||
Graphics::ManagedSurface *getSmackBuffer() {
|
||||
return _pSbuf;
|
||||
}
|
||||
Video::SmackerDecoder *getSmackMovie() {
|
||||
return _pSmk;
|
||||
}
|
||||
};
|
||||
|
||||
ErrorCode bofPlayMovie(CBofWindow *pParent, const char *pszMovieFile, CBofRect *pRect = nullptr);
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
489
engines/bagel/spacebar/boflib/gui/scroll_bar.cpp
Normal file
489
engines/bagel/spacebar/boflib/gui/scroll_bar.cpp
Normal file
@@ -0,0 +1,489 @@
|
||||
/* 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/app.h"
|
||||
#include "bagel/spacebar/boflib/gui/scroll_bar.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define BMP_SCROLL_TIMER 9999
|
||||
#define DEF_TIMER_INTERVAL 100
|
||||
|
||||
|
||||
CBofScrollBar::CBofScrollBar() {
|
||||
_pLeftBtnUp = nullptr;
|
||||
_pRightBtnUp = nullptr;
|
||||
_pLeftBtnDn = nullptr;
|
||||
_pRightBtnDn = nullptr;
|
||||
_pThumb = nullptr;
|
||||
_nMin = 0;
|
||||
_nMax = 10;
|
||||
_nPos = 0;
|
||||
_nLineDelta = 1;
|
||||
_nPageDelta = 1;
|
||||
|
||||
_pScrollText = nullptr;
|
||||
_szScrollText[0] = '\0';
|
||||
|
||||
_cThumbSize.cx = 0;
|
||||
_cThumbSize.cy = 0;
|
||||
_cBkSize.cx = 0;
|
||||
_cBkSize.cy = 0;
|
||||
_cCurPoint.x = 0;
|
||||
_cCurPoint.y = 0;
|
||||
_cThumbPos.x = 0;
|
||||
_cThumbPos.y = 0;
|
||||
|
||||
_nOffset = 0;
|
||||
_nScrollWidth = 0;
|
||||
_nRange = 0;
|
||||
_bMouseCaptured = false;
|
||||
_nScrollState = 0;
|
||||
|
||||
_nTimerCount = DEF_TIMER_INTERVAL;
|
||||
}
|
||||
|
||||
|
||||
CBofScrollBar::~CBofScrollBar() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
_szScrollText[0] = '\0';
|
||||
|
||||
delete _pScrollText;
|
||||
_pScrollText = nullptr;
|
||||
|
||||
delete _pThumb;
|
||||
_pThumb = nullptr;
|
||||
|
||||
delete _pLeftBtnUp;
|
||||
_pLeftBtnUp = nullptr;
|
||||
|
||||
delete _pRightBtnUp;
|
||||
_pRightBtnUp = nullptr;
|
||||
|
||||
delete _pLeftBtnDn;
|
||||
_pLeftBtnDn = nullptr;
|
||||
|
||||
delete _pRightBtnDn;
|
||||
_pRightBtnDn = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void CBofScrollBar::onPaint(CBofRect *pDirtyRect) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
paint(pDirtyRect);
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofScrollBar::setText(const char *pszText, int nJustify) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
_szScrollText[0] = '\0';
|
||||
|
||||
if ((pszText != nullptr) && (_parent != nullptr)) {
|
||||
Common::strlcpy(_szScrollText, pszText, MAX_TEXT);
|
||||
|
||||
if (_pScrollText == nullptr) {
|
||||
|
||||
CBofPoint cPoint = _parent->getWindowRect().topLeft();
|
||||
CBofRect cTempRect = _cWindowRect - cPoint;
|
||||
|
||||
cTempRect -= CBofPoint(0, 20);
|
||||
cTempRect.right += 20;
|
||||
|
||||
_pScrollText = new CBofText(&cTempRect, nJustify);
|
||||
}
|
||||
|
||||
if (_pScrollText != nullptr) {
|
||||
_pScrollText->display(_parent, _szScrollText, FONT_DEFAULT_SIZE, TEXT_DEFAULT_FACE);
|
||||
}
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofScrollBar::setPos(const int nPos, bool bRepaint, bool isInitial) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Save old position
|
||||
int nOriginalPos = _nPos;
|
||||
|
||||
_nPos = nPos;
|
||||
if (nPos < _nMin)
|
||||
_nPos = _nMin;
|
||||
if (nPos > _nMax)
|
||||
_nPos = _nMax;
|
||||
|
||||
assert(_nRange != 0);
|
||||
|
||||
_cThumbPos.x = (int)(((int32)(_nScrollWidth - _cThumbSize.cx) * _nPos) / (_nRange - 1)) + _nOffset;
|
||||
_cThumbPos.y = (int)(_cBkSize.cy / 2) - (int)(_cThumbSize.cy / 2);
|
||||
|
||||
if (_cThumbPos.x < 0)
|
||||
_cThumbPos.x = 0;
|
||||
if (_cThumbPos.x > (_nScrollWidth - _cThumbSize.cx + _nOffset))
|
||||
_cThumbPos.x = _nScrollWidth - _cThumbSize.cx + _nOffset;
|
||||
|
||||
// If forced to repaint
|
||||
if (bRepaint) {
|
||||
|
||||
paint();
|
||||
|
||||
} else if (_nPos != nOriginalPos) {
|
||||
// Otherwise, only paint the thumb if it's position changed
|
||||
if (_pThumb != nullptr) {
|
||||
if (_pThumb->paintSprite(this, _cThumbPos) == false) {
|
||||
reportError(ERR_UNKNOWN, "_pThumb->paintSprite() failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the thumb actually moved, then tell our parent about it
|
||||
if (_nPos != nOriginalPos && !isInitial) {
|
||||
_parent->onBofScrollBar(this, _nPos);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
void CBofScrollBar::getScrollRange(int &nMin, int &nMax) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
nMin = _nMin;
|
||||
nMax = _nMax;
|
||||
}
|
||||
|
||||
|
||||
void CBofScrollBar::setScrollRange(int nMin, int nMax, bool bRepaint) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
_nMin = nMin;
|
||||
_nMax = nMax;
|
||||
|
||||
_nRange = _nMax - _nMin + 1;
|
||||
|
||||
// Should we repaint the scroll bar now?
|
||||
if (bRepaint) {
|
||||
paint();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofScrollBar::loadBitmaps(const char *pszBack, const char *pszThumb, const char *pszLeftBtnUp, const char *pszRightBtnUp, const char *pszLeftBtnDn, const char *pszRightBtnDn) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if ((pszBack == nullptr) || (pszThumb == nullptr))
|
||||
return _errCode;
|
||||
|
||||
_cLeftBtnRect.setRect(0, 0, 0, 0);
|
||||
_cRightBtnRect.setRect(0, 0, 0, 0);
|
||||
|
||||
if (_pThumb != nullptr) {
|
||||
_pThumb->eraseSprite(this);
|
||||
delete _pThumb;
|
||||
_pThumb = nullptr;
|
||||
}
|
||||
|
||||
killBackdrop();
|
||||
setBackdrop(pszBack);
|
||||
|
||||
CBofPalette *pPalette = CBofApp::getApp()->getPalette();
|
||||
|
||||
_cBkSize = _pBackdrop->getSize();
|
||||
_nScrollWidth = _cBkSize.cx;
|
||||
|
||||
_pThumb = new CBofSprite;
|
||||
|
||||
if (_pThumb->loadSprite(pszThumb) != false) {
|
||||
_pThumb->setMaskColor(COLOR_WHITE);
|
||||
_cThumbSize = _pThumb->getSize();
|
||||
}
|
||||
|
||||
delete _pLeftBtnUp;
|
||||
_pLeftBtnUp = nullptr;
|
||||
|
||||
CBofPoint cPoint;
|
||||
if (pszLeftBtnUp != nullptr) {
|
||||
_pLeftBtnUp = new CBofBitmap(pszLeftBtnUp, pPalette);
|
||||
|
||||
cPoint.x = 0;
|
||||
cPoint.y = (_pBackdrop->height() / 2) - (_pLeftBtnUp->height() / 2);
|
||||
|
||||
_cLeftBtnRect = _pLeftBtnUp->getRect() + cPoint;
|
||||
|
||||
_nOffset = _pLeftBtnUp->width();
|
||||
_nScrollWidth -= _nOffset;
|
||||
}
|
||||
|
||||
delete _pRightBtnUp;
|
||||
_pRightBtnUp = nullptr;
|
||||
|
||||
if (pszRightBtnUp != nullptr) {
|
||||
_pRightBtnUp = new CBofBitmap(pszRightBtnUp, pPalette);
|
||||
|
||||
cPoint.x = _pBackdrop->width() - _pRightBtnUp->width();
|
||||
cPoint.y = (_pBackdrop->height() / 2) - (_pRightBtnUp->height() / 2);
|
||||
_cRightBtnRect = _pLeftBtnUp->getRect() + cPoint;
|
||||
|
||||
_nScrollWidth -= _cRightBtnRect.width();
|
||||
}
|
||||
|
||||
delete _pLeftBtnDn;
|
||||
_pLeftBtnDn = nullptr;
|
||||
|
||||
if (pszLeftBtnDn != nullptr) {
|
||||
_pLeftBtnDn = new CBofBitmap(pszLeftBtnDn, pPalette);
|
||||
}
|
||||
|
||||
delete _pRightBtnDn;
|
||||
_pRightBtnDn = nullptr;
|
||||
|
||||
if (pszRightBtnDn != nullptr) {
|
||||
_pRightBtnDn = new CBofBitmap(pszRightBtnDn, pPalette);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofScrollBar::paint(CBofRect *pDirtyRect) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (!errorOccurred()) {
|
||||
CBofPalette *pPalette = CBofApp::getApp()->getPalette();
|
||||
|
||||
//
|
||||
// This function needs to be optimized to paint only the section that is
|
||||
// invalidated. Right now it just repaints the entire scroll bar each time.
|
||||
//
|
||||
|
||||
if ((_pBackdrop != nullptr) && (_pThumb != nullptr)) {
|
||||
// Do all painting offscreen
|
||||
CBofBitmap *pBmp = new CBofBitmap(_cBkSize.cx, _cBkSize.cy, pPalette);
|
||||
_pBackdrop->paint(pBmp, 0, 0, nullptr, COLOR_WHITE);
|
||||
|
||||
if ((_nScrollState == 1) && (_pLeftBtnDn != nullptr)) {
|
||||
CBofPoint cPoint = _cLeftBtnRect.topLeft();
|
||||
_pLeftBtnDn->paint(pBmp, cPoint.x, cPoint.y, nullptr, COLOR_WHITE);
|
||||
|
||||
} else if (_pLeftBtnUp != nullptr) {
|
||||
CBofPoint cPoint = _cLeftBtnRect.topLeft();
|
||||
_pLeftBtnUp->paint(pBmp, cPoint.x, cPoint.y, nullptr, COLOR_WHITE);
|
||||
}
|
||||
|
||||
if ((_nScrollState == 4) && (_pRightBtnDn != nullptr)) {
|
||||
CBofPoint cPoint = _cRightBtnRect.topLeft();
|
||||
_pRightBtnDn->paint(pBmp, cPoint.x, cPoint.y, nullptr, COLOR_WHITE);
|
||||
|
||||
} else if (_pRightBtnUp != nullptr) {
|
||||
CBofPoint cPoint = _cRightBtnRect.topLeft();
|
||||
_pRightBtnUp->paint(pBmp, cPoint.x, cPoint.y, nullptr, COLOR_WHITE);
|
||||
}
|
||||
|
||||
_cThumbPos.x = (int)(((int32)(_nScrollWidth - _cThumbSize.cx) * _nPos) / (_nRange - 1)) + _nOffset;
|
||||
_cThumbPos.y = (int)(_cBkSize.cy / 2) - (int)(_cThumbSize.cy / 2);
|
||||
|
||||
if (_cThumbPos.x < 0)
|
||||
_cThumbPos.x = 0;
|
||||
if (_cThumbPos.x > (_nScrollWidth - _cThumbSize.cx + _nOffset))
|
||||
_cThumbPos.x = _nScrollWidth - _cThumbSize.cx + _nOffset;
|
||||
|
||||
_pThumb->paintSprite(pBmp, _cThumbPos);
|
||||
|
||||
// now we can paint the offscreen buffer to the screen
|
||||
pBmp->paint(this, 0, 0);
|
||||
|
||||
delete pBmp;
|
||||
}
|
||||
|
||||
if ((_pScrollText != nullptr) && (_parent != nullptr)) {
|
||||
_pScrollText->display(_parent, _szScrollText, FONT_DEFAULT_SIZE, TEXT_DEFAULT_FACE);
|
||||
}
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
void CBofScrollBar::onLButtonDown(uint32 nFlags, CBofPoint *pPoint, void *) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
CBofRect cLeftPageRect, cRightPageRect;
|
||||
|
||||
bool bDoNothing = false;
|
||||
|
||||
cLeftPageRect.setRect(_nOffset, 0, (_nScrollWidth / _nRange) * _nPos + _nOffset - 1, _cBkSize.cy - 1);
|
||||
cRightPageRect.setRect(((_nScrollWidth / _nRange) * _nPos) + _nOffset + _cThumbSize.cx, 0, _nOffset + _nScrollWidth - 1, _cBkSize.cy - 1);
|
||||
|
||||
_cCurPoint = *pPoint;
|
||||
|
||||
if (_pLeftBtnUp != nullptr && _cLeftBtnRect.ptInRect(*pPoint)) {
|
||||
// Let timer know what happened
|
||||
_nScrollState = 1;
|
||||
|
||||
// Set new thumb position
|
||||
setPos(_nPos - _nLineDelta, true);
|
||||
|
||||
} else if (_pThumb->getRect().ptInRect(*pPoint)) {
|
||||
_nScrollState = 5;
|
||||
|
||||
} else if (cLeftPageRect.ptInRect(*pPoint)) {
|
||||
_nScrollState = 2;
|
||||
|
||||
// Set new thumb position
|
||||
setPos(_nPos - _nPageDelta, true);
|
||||
|
||||
} else if (cRightPageRect.ptInRect(*pPoint)) {
|
||||
_nScrollState = 3;
|
||||
|
||||
// Set new thumb position
|
||||
setPos(_nPos + _nPageDelta, true);
|
||||
|
||||
} else if (_pRightBtnUp != nullptr && _cRightBtnRect.ptInRect(*pPoint)) {
|
||||
// Let timer know what happened
|
||||
_nScrollState = 4;
|
||||
|
||||
// Set new thumb position
|
||||
setPos(_nPos + _nLineDelta, true);
|
||||
|
||||
} else {
|
||||
bDoNothing = true;
|
||||
}
|
||||
|
||||
if (!bDoNothing) {
|
||||
_bMouseCaptured = true;
|
||||
setCapture();
|
||||
if (_nScrollState != 5)
|
||||
setTimer(BMP_SCROLL_TIMER, _nTimerCount);
|
||||
}
|
||||
|
||||
CBofWindow::onLButtonDown(nFlags, pPoint);
|
||||
}
|
||||
|
||||
|
||||
int CBofScrollBar::pointToPos(CBofPoint *pPoint) {
|
||||
assert(isValidObject(this));
|
||||
assert(pPoint != nullptr);
|
||||
|
||||
int nPos = _nPos;
|
||||
|
||||
if (_cRect.ptInRect(*pPoint)) {
|
||||
nPos = (pPoint->x - _nOffset) / (int)(_nScrollWidth / _nRange);
|
||||
}
|
||||
|
||||
return nPos;
|
||||
}
|
||||
|
||||
|
||||
void CBofScrollBar::onLButtonUp(uint32 nFlags, CBofPoint *pPoint, void *) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (_bMouseCaptured) {
|
||||
killTimer(BMP_SCROLL_TIMER);
|
||||
_bMouseCaptured = false;
|
||||
releaseCapture();
|
||||
|
||||
int x, y;
|
||||
|
||||
switch (_nScrollState) {
|
||||
case 5:
|
||||
setPos(pointToPos(pPoint));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (_pLeftBtnUp != nullptr) {
|
||||
x = 0;
|
||||
y = (int)(_cBkSize.cy / 2) - (int)(_cLeftBtnRect.height() / 2);
|
||||
_pLeftBtnUp->paint(this, x, y, nullptr, COLOR_WHITE);
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (_pRightBtnUp != nullptr) {
|
||||
x = _cBkSize.cx - _cRightBtnRect.width();
|
||||
y = (int)(_cBkSize.cy / 2) - (int)(_cRightBtnRect.height() / 2);
|
||||
_pRightBtnUp->paint(this, x, y, nullptr, COLOR_WHITE);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_nScrollState = 0;
|
||||
}
|
||||
|
||||
CBofWindow::onLButtonUp(nFlags, pPoint);
|
||||
}
|
||||
|
||||
|
||||
void CBofScrollBar::onMouseMove(uint32 nFlags, CBofPoint *pPoint, void *) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (_bMouseCaptured) {
|
||||
_cCurPoint = *pPoint;
|
||||
|
||||
if (_nScrollState == 5) {
|
||||
setPos(pointToPos(pPoint));
|
||||
}
|
||||
}
|
||||
|
||||
CBofWindow::onMouseMove(nFlags, pPoint);
|
||||
}
|
||||
|
||||
|
||||
void CBofScrollBar::setRepeatTimer(uint32 nTimerInt) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
_nTimerCount = nTimerInt;
|
||||
}
|
||||
|
||||
|
||||
void CBofScrollBar::onTimer(uint32 nWhichTimer) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
CBofRect cLeftPageRect, cRightPageRect;
|
||||
|
||||
cLeftPageRect.setRect(_nOffset, 0, (_nScrollWidth / _nRange) * _nPos + _nOffset - 1, _cBkSize.cy - 1);
|
||||
cRightPageRect.setRect(((_nScrollWidth / _nRange) * _nPos) + _nOffset + _cThumbSize.cx, 0, _nOffset + _nScrollWidth - 1, _cBkSize.cy - 1);
|
||||
|
||||
if (nWhichTimer == BMP_SCROLL_TIMER) {
|
||||
if ((_nScrollState == 1) && _cLeftBtnRect.ptInRect(_cCurPoint)) {
|
||||
lineLeft();
|
||||
|
||||
} else if ((_nScrollState == 2) && cLeftPageRect.ptInRect(_cCurPoint)) {
|
||||
pageLeft();
|
||||
|
||||
} else if ((_nScrollState == 3) && cRightPageRect.ptInRect(_cCurPoint)) {
|
||||
pageRight();
|
||||
|
||||
} else if ((_nScrollState == 4) && _cRightBtnRect.ptInRect(_cCurPoint)) {
|
||||
lineRight();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
155
engines/bagel/spacebar/boflib/gui/scroll_bar.h
Normal file
155
engines/bagel/spacebar/boflib/gui/scroll_bar.h
Normal file
@@ -0,0 +1,155 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BOFLIB_GUI_SCROLL_BAR_H
|
||||
#define BAGEL_BOFLIB_GUI_SCROLL_BAR_H
|
||||
|
||||
#include "bagel/spacebar/boflib/gui/window.h"
|
||||
#include "bagel/spacebar/boflib/gfx/sprite.h"
|
||||
#include "bagel/spacebar/boflib/gfx/text.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define BSB_LEFT 800
|
||||
#define BSB_RIGHT 801
|
||||
#define BSB_LINE_LEFT 802
|
||||
#define BSB_LINE_RIGHT 803
|
||||
#define BSB_PAGE_LEFT 804
|
||||
#define BSB_PAGE_RIGHT 805
|
||||
#define BSB_THUMB_POS 806
|
||||
#define BSB_THUMB_TRACK 807
|
||||
|
||||
#define MAX_TEXT 128
|
||||
|
||||
class CBofScrollBar : public CBofWindow {
|
||||
public:
|
||||
CBofScrollBar();
|
||||
|
||||
virtual ~CBofScrollBar();
|
||||
|
||||
// Implementation
|
||||
//
|
||||
|
||||
ErrorCode loadBitmaps(const char *pszBack, const char *pszThumb, const char *pszLeftUp = nullptr, const char *pszRightUp = nullptr, const char *pszLeftDown = nullptr, const char *pszRightDown = nullptr);
|
||||
|
||||
ErrorCode setPos(int nPos, bool bRepaint = true, bool isInitial = false);
|
||||
int getPos() const {
|
||||
return _nPos;
|
||||
}
|
||||
|
||||
ErrorCode lineLeft() {
|
||||
return setPos(_nPos - _nLineDelta);
|
||||
}
|
||||
ErrorCode lineRight() {
|
||||
return setPos(_nPos + _nLineDelta);
|
||||
}
|
||||
ErrorCode pageLeft() {
|
||||
return setPos(_nPos - _nPageDelta);
|
||||
}
|
||||
ErrorCode pageRight() {
|
||||
return setPos(_nPos + _nPageDelta);
|
||||
}
|
||||
|
||||
ErrorCode home() {
|
||||
return setPos(_nMin);
|
||||
}
|
||||
ErrorCode end() {
|
||||
return setPos(_nMax);
|
||||
}
|
||||
|
||||
int getScrollMin() const {
|
||||
return _nMin;
|
||||
}
|
||||
int getScrollMax() const {
|
||||
return _nMax;
|
||||
}
|
||||
|
||||
void setLineDelta(const int nDelta) {
|
||||
_nLineDelta = nDelta;
|
||||
}
|
||||
int getLineDelta() const {
|
||||
return _nLineDelta;
|
||||
}
|
||||
|
||||
void setPageDelta(const int nDelta) {
|
||||
_nPageDelta = nDelta;
|
||||
}
|
||||
int getPageDelta() const {
|
||||
return _nPageDelta;
|
||||
}
|
||||
|
||||
void getScrollRange(int &nMin, int &nMax);
|
||||
void setScrollRange(int nMin, int nMax, bool bRepaint = true);
|
||||
|
||||
ErrorCode setText(const char *pszText, int nFlags = JUSTIFY_CENTER);
|
||||
|
||||
void setRepeatTimer(uint32 nMilliSeconds);
|
||||
ErrorCode paint(CBofRect *pRect = nullptr);
|
||||
|
||||
protected:
|
||||
int pointToPos(CBofPoint *pPoint);
|
||||
|
||||
void onPaint(CBofRect *pDirtyRect) override;
|
||||
void onLButtonDown(uint32 nFlags, CBofPoint *pPoint, void * = nullptr) override;
|
||||
void onLButtonUp(uint32 nFlags, CBofPoint *pPoint, void * = nullptr) override;
|
||||
void onMouseMove(uint32 nFlags, CBofPoint *pPoint, void * = nullptr) override;
|
||||
void onTimer(uint32) override;
|
||||
|
||||
//
|
||||
// Data members
|
||||
//
|
||||
CBofBitmap *_pLeftBtnUp;
|
||||
CBofBitmap *_pRightBtnUp;
|
||||
CBofBitmap *_pLeftBtnDn;
|
||||
CBofBitmap *_pRightBtnDn;
|
||||
CBofSprite *_pThumb;
|
||||
|
||||
CBofRect _cLeftBtnRect;
|
||||
CBofRect _cRightBtnRect;
|
||||
|
||||
int _nMin;
|
||||
int _nMax;
|
||||
int _nPos;
|
||||
int _nLineDelta;
|
||||
int _nPageDelta;
|
||||
|
||||
CBofText *_pScrollText;
|
||||
char _szScrollText[MAX_TEXT];
|
||||
|
||||
CBofSize _cThumbSize;
|
||||
CBofSize _cBkSize;
|
||||
|
||||
int _nOffset;
|
||||
int _nScrollWidth;
|
||||
int _nRange;
|
||||
bool _bMouseCaptured;
|
||||
CBofPoint _cCurPoint;
|
||||
CBofPoint _cThumbPos;
|
||||
int _nScrollState;
|
||||
uint32 _nTimerCount;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
273
engines/bagel/spacebar/boflib/gui/text_box.cpp
Normal file
273
engines/bagel/spacebar/boflib/gui/text_box.cpp
Normal file
@@ -0,0 +1,273 @@
|
||||
/* 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/text_box.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define DEFAULT_PAGE_SIZE 10
|
||||
#define DEFAULT_WEIGHT TEXT_NORMAL
|
||||
#define DEFAULT_POINT_SIZE FONT_12POINT
|
||||
#define DEFAULT_COLOR CTEXT_COLOR
|
||||
|
||||
|
||||
CBofTextBox::CBofTextBox() {
|
||||
// Inits
|
||||
_pDestWindow = nullptr;
|
||||
_pDestBitmap = nullptr;
|
||||
_pTextField = nullptr;
|
||||
_nWeight = DEFAULT_WEIGHT;
|
||||
_nPointSize = DEFAULT_POINT_SIZE;
|
||||
_cTextColor = DEFAULT_COLOR;
|
||||
_nTextFont = FONT_DEFAULT;
|
||||
_nPageSize = DEFAULT_PAGE_SIZE;
|
||||
_nCurrentLine = 0;
|
||||
_nCurrentIndex = 0;
|
||||
_nNumLines = 0;
|
||||
}
|
||||
|
||||
|
||||
CBofTextBox::CBofTextBox(CBofWindow *pWindow, const CBofRect *pRect, const CBofString &cText) {
|
||||
assert(pWindow != nullptr);
|
||||
assert(pRect != nullptr);
|
||||
|
||||
// Inits
|
||||
_pDestWindow = nullptr;
|
||||
_pDestBitmap = nullptr;
|
||||
_pTextField = nullptr;
|
||||
_nWeight = DEFAULT_WEIGHT;
|
||||
_nPointSize = DEFAULT_POINT_SIZE;
|
||||
_cTextColor = DEFAULT_COLOR;
|
||||
_nPageSize = DEFAULT_PAGE_SIZE;
|
||||
_nCurrentLine = 0;
|
||||
_nCurrentIndex = 0;
|
||||
_nNumLines = 0;
|
||||
_nTextFont = FONT_DEFAULT;
|
||||
|
||||
setText(cText);
|
||||
setBox(pRect);
|
||||
setDisplay(pWindow);
|
||||
}
|
||||
|
||||
|
||||
CBofTextBox::CBofTextBox(CBofBitmap *pBitmap, const CBofRect *pRect, const CBofString &cText) {
|
||||
assert(pBitmap != nullptr);
|
||||
assert(pRect != nullptr);
|
||||
|
||||
// Inits
|
||||
_pDestWindow = nullptr;
|
||||
_pDestBitmap = nullptr;
|
||||
_pTextField = nullptr;
|
||||
_nWeight = DEFAULT_WEIGHT;
|
||||
_nPointSize = DEFAULT_POINT_SIZE;
|
||||
_cTextColor = DEFAULT_COLOR;
|
||||
_nPageSize = DEFAULT_PAGE_SIZE;
|
||||
_nCurrentLine = 0;
|
||||
_nCurrentIndex = 0;
|
||||
_nNumLines = 0;
|
||||
_nTextFont = FONT_DEFAULT;
|
||||
|
||||
setText(cText);
|
||||
setBox(pRect);
|
||||
setDisplay(pBitmap);
|
||||
}
|
||||
|
||||
|
||||
CBofTextBox::~CBofTextBox() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (_pTextField != nullptr) {
|
||||
delete _pTextField;
|
||||
_pTextField = nullptr;
|
||||
}
|
||||
_pDestWindow = nullptr;
|
||||
_pDestBitmap = nullptr;
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofTextBox::setBox(const CBofRect *pRect) {
|
||||
assert(isValidObject(this));
|
||||
assert(pRect != nullptr);
|
||||
|
||||
// Remove previous text field (if any)
|
||||
delete _pTextField;
|
||||
_pTextField = nullptr;
|
||||
|
||||
// Create a new text field the size of the box we want
|
||||
_pTextField = new CBofText(pRect, JUSTIFY_WRAP);
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
void CBofTextBox::setDisplay(CBofWindow *pWindow) {
|
||||
assert(isValidObject(this));
|
||||
assert(pWindow != nullptr);
|
||||
|
||||
_pDestWindow = pWindow;
|
||||
_pDestBitmap = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void CBofTextBox::setDisplay(CBofBitmap *pBitmap) {
|
||||
assert(isValidObject(this));
|
||||
assert(pBitmap != nullptr);
|
||||
|
||||
_pDestBitmap = pBitmap;
|
||||
_pDestWindow = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void CBofTextBox::setTextAttribs(const int nSize, const int nWeight, const COLORREF cColor, const int nFont) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
_nPointSize = nSize;
|
||||
_nWeight = nWeight;
|
||||
_cTextColor = cColor;
|
||||
_nTextFont = nFont;
|
||||
}
|
||||
|
||||
|
||||
void CBofTextBox::setText(const CBofString &cString) {
|
||||
_cBuffer = cString;
|
||||
assert(_cBuffer.getLength() != 0);
|
||||
|
||||
_cBuffer.replaceStr("\r\n", "\n");
|
||||
_cBuffer.replaceStr("\r", "\n");
|
||||
|
||||
_nCurrentLine = 0;
|
||||
_nCurrentIndex = 0;
|
||||
_nNumLines = _cBuffer.findNumOccurrences("\n");
|
||||
}
|
||||
|
||||
int CBofTextBox::getIndex(const int nLine) {
|
||||
assert(nLine >= 0 && nLine <= _nNumLines);
|
||||
|
||||
// Find the index into our buffer that represents the top left of the
|
||||
// buffer that is nLine from current the beginning of the buffer.
|
||||
const char *pszCur, *pszBuffer;
|
||||
const char *pszLast = pszCur = pszBuffer = _cBuffer;
|
||||
for (int i = 0; i < nLine; i++) {
|
||||
pszLast = pszCur;
|
||||
pszCur = strstr(pszCur, "\n");
|
||||
|
||||
// Make sure we don't go too far (nLines is invalid)
|
||||
assert(pszCur != nullptr);
|
||||
|
||||
pszCur++;
|
||||
}
|
||||
int nChars = pszCur - pszBuffer;
|
||||
if (nLine == _nNumLines) {
|
||||
nChars = pszLast - pszBuffer;
|
||||
_nCurrentLine--;
|
||||
}
|
||||
|
||||
return nChars;
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofTextBox::scrollUp(const int nLines) {
|
||||
// Make scroll a no-op if all the lines in the box appear on one screen.
|
||||
if (_nNumLines <= _nPageSize) {
|
||||
return scrollTo(_nCurrentLine);
|
||||
}
|
||||
|
||||
int nNewLine = _nCurrentLine - nLines;
|
||||
|
||||
if (nNewLine < 0) {
|
||||
nNewLine = 0;
|
||||
} else if (nNewLine > (_nNumLines - _nPageSize)) {
|
||||
// If the line requested to be the top of the page
|
||||
// would cause fewer than _nPageSize lines to be displayed,
|
||||
// snap nNewLine to be the top of the last full page.
|
||||
//
|
||||
nNewLine = (_nNumLines - _nPageSize);
|
||||
}
|
||||
return scrollTo(nNewLine);
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofTextBox::scrollTo(const int nLine) {
|
||||
assert(isValidObject(this));
|
||||
assert(nLine >= 0 && nLine <= _nNumLines);
|
||||
|
||||
_nCurrentIndex = getIndex(nLine);
|
||||
_nCurrentLine = nLine;
|
||||
|
||||
// Show the text box
|
||||
display();
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofTextBox::display() {
|
||||
assert(isValidObject(this));
|
||||
assert(_nCurrentLine >= 0 && _nCurrentLine <= _nNumLines);
|
||||
assert(_nCurrentIndex >= 0 && _nCurrentIndex < _cBuffer.getLength());
|
||||
|
||||
// The actual text box must have been created before it can be displayed
|
||||
assert(_pTextField != nullptr);
|
||||
|
||||
// If painting to a window
|
||||
if (_pDestWindow != nullptr) {
|
||||
_pTextField->display(_pDestWindow, _cBuffer.mid(_nCurrentIndex), _nPointSize, _nWeight, _cTextColor, _nTextFont);
|
||||
|
||||
} else {
|
||||
// Otherwise, must be painting to a bitmap
|
||||
assert(_pDestBitmap != nullptr);
|
||||
|
||||
_pTextField->display(_pDestBitmap, _cBuffer.mid(_nCurrentIndex), _nPointSize, _nWeight, _cTextColor, _nTextFont);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofTextBox::erase() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// The actual text box must have been created before it can be displayed
|
||||
assert(_pTextField != nullptr);
|
||||
|
||||
if (_pDestWindow != nullptr) {
|
||||
_errCode = _pTextField->erase(_pDestWindow);
|
||||
|
||||
} else {
|
||||
assert(_pDestBitmap != nullptr);
|
||||
_errCode = _pTextField->erase(_pDestBitmap);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
void CBofTextBox::flushBackground() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (_pTextField != nullptr) {
|
||||
_pTextField->flushBackground();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
140
engines/bagel/spacebar/boflib/gui/text_box.h
Normal file
140
engines/bagel/spacebar/boflib/gui/text_box.h
Normal file
@@ -0,0 +1,140 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BOFLIB_GUI_TEXT_BOX_H
|
||||
#define BAGEL_BOFLIB_GUI_TEXT_BOX_H
|
||||
|
||||
#include "bagel/spacebar/boflib/gfx/bitmap.h"
|
||||
#include "bagel/boflib/error.h"
|
||||
#include "bagel/boflib/string.h"
|
||||
#include "bagel/spacebar/boflib/gfx/text.h"
|
||||
#include "bagel/spacebar/boflib/gui/window.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class CBofTextBox : public CBofObject, public CBofError {
|
||||
public:
|
||||
CBofTextBox();
|
||||
CBofTextBox(CBofWindow *pWindow, const CBofRect *pRect, const CBofString &cText);
|
||||
CBofTextBox(CBofBitmap *pBitmap, const CBofRect *pRect, const CBofString &cText);
|
||||
virtual ~CBofTextBox();
|
||||
|
||||
void setText(const CBofString &cText);
|
||||
ErrorCode setBox(const CBofRect *pRect);
|
||||
void setDisplay(CBofWindow *pWindow);
|
||||
void setDisplay(CBofBitmap *pBitmap);
|
||||
|
||||
void setTextAttribs(int nSize, int nWeight, COLORREF cColor = CTEXT_COLOR, int nFont = FONT_DEFAULT);
|
||||
|
||||
void setPointSize(const int nSize) {
|
||||
_nPointSize = nSize;
|
||||
}
|
||||
int getPointSize() const {
|
||||
return _nPointSize;
|
||||
}
|
||||
|
||||
void setWeight(const int nWeight) {
|
||||
_nWeight = nWeight;
|
||||
}
|
||||
int getWeight() const {
|
||||
return _nWeight;
|
||||
}
|
||||
|
||||
void setPageLength(const int nSize) {
|
||||
_nPageSize = nSize;
|
||||
}
|
||||
int getPageLength() const {
|
||||
return _nPageSize;
|
||||
}
|
||||
|
||||
void setColor(const COLORREF cColor) {
|
||||
_cTextColor = cColor;
|
||||
}
|
||||
COLORREF getColor() const {
|
||||
return _cTextColor;
|
||||
}
|
||||
|
||||
void setFont(int nFont) {
|
||||
_nTextFont = nFont;
|
||||
}
|
||||
int getFont() const {
|
||||
return _nTextFont;
|
||||
}
|
||||
|
||||
ErrorCode lineUp() {
|
||||
return scrollUp(1);
|
||||
}
|
||||
ErrorCode lineDown() {
|
||||
return scrollDown(1);
|
||||
}
|
||||
|
||||
ErrorCode pageUp() {
|
||||
return scrollUp(_nPageSize);
|
||||
}
|
||||
ErrorCode pageDown() {
|
||||
return scrollDown(_nPageSize);
|
||||
}
|
||||
|
||||
ErrorCode scrollUp(int nLines);
|
||||
ErrorCode scrollDown(const int nLines) {
|
||||
return scrollUp(-nLines);
|
||||
}
|
||||
|
||||
ErrorCode scrollTo(int nLine);
|
||||
|
||||
ErrorCode display();
|
||||
ErrorCode erase();
|
||||
|
||||
void flushBackground();
|
||||
|
||||
int getCurrLine() {
|
||||
return _nCurrentLine;
|
||||
}
|
||||
ErrorCode setCurrLine(const int nLine) {
|
||||
return scrollTo(nLine);
|
||||
}
|
||||
|
||||
protected:
|
||||
int getIndex(int nLines);
|
||||
|
||||
// Data
|
||||
CBofString _cBuffer;
|
||||
CBofText *_pTextField;
|
||||
CBofWindow *_pDestWindow;
|
||||
CBofBitmap *_pDestBitmap;
|
||||
|
||||
int _nCurrentLine;
|
||||
int _nCurrentIndex;
|
||||
int _nNumLines;
|
||||
int _nPageSize;
|
||||
|
||||
COLORREF _cTextColor;
|
||||
int _nPointSize;
|
||||
int _nWeight;
|
||||
int _nTextFont;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
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
|
||||
480
engines/bagel/spacebar/boflib/gui/window.h
Normal file
480
engines/bagel/spacebar/boflib/gui/window.h
Normal file
@@ -0,0 +1,480 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BOFLIB_GUI_WINDOW_H
|
||||
#define BAGEL_BOFLIB_GUI_WINDOW_H
|
||||
|
||||
#include "common/list.h"
|
||||
#include "common/events.h"
|
||||
#include "bagel/spacebar/boflib/array.h"
|
||||
#include "bagel/boflib/stdinc.h"
|
||||
#include "bagel/boflib/error.h"
|
||||
#include "bagel/boflib/object.h"
|
||||
#include "bagel/boflib/point.h"
|
||||
#include "bagel/boflib/rect.h"
|
||||
#include "bagel/boflib/size.h"
|
||||
#include "bagel/spacebar/boflib/timer.h"
|
||||
#include "bagel/boflib/llist.h"
|
||||
#include "bagel/spacebar/boflib/gfx/bitmap.h"
|
||||
#include "bagel/boflib/palette.h"
|
||||
#include "bagel/spacebar/boflib/gfx/text.h"
|
||||
|
||||
namespace Bagel {
|
||||
|
||||
class CBofString;
|
||||
|
||||
namespace SpaceBar {
|
||||
|
||||
#define MAX_TITLE 64
|
||||
#define USE_DEFAULT (-1)
|
||||
|
||||
class CBofBitmap;
|
||||
class CBofTimerPacket;
|
||||
|
||||
class CBofWindow : public CLList, public CBofObject, public CBofError {
|
||||
private:
|
||||
bool _visible = true;
|
||||
bool _enabled = true;
|
||||
Common::List<WindowTimer> _timers;
|
||||
uint32 _lastLButtonTime = 0, _lastRButtonTime = 0;
|
||||
|
||||
/**
|
||||
* Handles translating from a ScummVM event structure to
|
||||
* a code used by the game engine
|
||||
*/
|
||||
uint32 translateKey(const Common::Event &event) const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Checks window timers for expiry
|
||||
*/
|
||||
void checkTimers();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
CBofWindow();
|
||||
|
||||
/**
|
||||
* Constructor for CBofWindow
|
||||
* @param pszName Name of window
|
||||
* @param x X position
|
||||
* @param y Y position
|
||||
* @param nWidth Width of window to create (optional)
|
||||
* @param nHeight Height of window to create (optional)
|
||||
* @param pParent Parent of this window (optional)
|
||||
*/
|
||||
CBofWindow(const char *pszName, int x, int y, int nWidth, int nHeight, CBofWindow *pParent);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~CBofWindow();
|
||||
|
||||
static ErrorCode initialize();
|
||||
static ErrorCode shutdown();
|
||||
static Common::Point getMousePos();
|
||||
|
||||
/**
|
||||
* Creates a window
|
||||
* @param pszName Name of window
|
||||
* @param x X position of upper-left corner
|
||||
* @param y Y position of upper-left corner
|
||||
* @param nWidth Width of window to create (optional)
|
||||
* @param nHeight Height of window to create (optional)
|
||||
* @param pParent Parent of this window (optional)
|
||||
* @param nControlID User defined ID of this window
|
||||
* @return Error return code
|
||||
*/
|
||||
virtual ErrorCode create(const char *pszName, int x, int y, int nWidth, int nHeight, CBofWindow *pParent, uint32 nControlID = 0);
|
||||
|
||||
/**
|
||||
* Creates a window
|
||||
* @param pszName Name of window
|
||||
* @param pRect Rectangle for window placement
|
||||
* @param pParent Parent of this window (optional)
|
||||
* @param nControlID User defined ID of this window
|
||||
* @return Error return code
|
||||
*/
|
||||
virtual ErrorCode create(const char *pszName, CBofRect *pRect, CBofWindow *pParent, uint32 nControlID = 0);
|
||||
|
||||
/**
|
||||
* Destroys the Window attached to this CBofWindow (if any)
|
||||
*/
|
||||
virtual void destroy();
|
||||
virtual void destroyWindow() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows current window (if hidden)
|
||||
*/
|
||||
void show();
|
||||
|
||||
void select();
|
||||
|
||||
/**
|
||||
* Hides current window (if shown)
|
||||
*/
|
||||
void hide();
|
||||
|
||||
/**
|
||||
* Centers current window in parent window or in screen
|
||||
*/
|
||||
void center();
|
||||
|
||||
/**
|
||||
* Moves current window to specified location in parent
|
||||
* @param x New upper left corner X position
|
||||
* @param y New upper left corner Y position
|
||||
* @param bRepaint true if should update the window
|
||||
*/
|
||||
void move(int x, int y, bool bRepaint = false);
|
||||
|
||||
/**
|
||||
* Resizes current window to specified area
|
||||
* @param pRect New area for window
|
||||
* @param bRepaint Optional repaint after resize
|
||||
*/
|
||||
void reSize(CBofRect *pRect, bool bRepaint = false);
|
||||
|
||||
virtual ErrorCode close() {
|
||||
onClose();
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Posts a message
|
||||
* @param nMessage Message to post
|
||||
* @param lParam1 User info
|
||||
* @param lParam2 More user info
|
||||
*/
|
||||
void postMessage(uint32 nMessage, uint32 lParam1, uint32 lParam2);
|
||||
|
||||
/**
|
||||
* Posts a user defined message
|
||||
*/
|
||||
void postUserMessage(uint32 lMessage, uint32 lExtraInfo);
|
||||
|
||||
/**
|
||||
* Sets a timer which calls specified callback (or onTimer)
|
||||
* @param nID ID of timer to set
|
||||
* @param nInterval Number of milliseconds till event
|
||||
* @param pCallBack Function to call when time is up
|
||||
*/
|
||||
void setTimer(uint32 nID, uint32 nInterval, BofCallback pCallBack = nullptr);
|
||||
|
||||
/**
|
||||
* Stops specified timer
|
||||
* @param nID ID of timer to stop
|
||||
*/
|
||||
void killTimer(uint32 nID);
|
||||
|
||||
/**
|
||||
* Stops all timers associated with current window
|
||||
*/
|
||||
void killMyTimers();
|
||||
|
||||
/**
|
||||
* Returns the parent window element, if any
|
||||
*/
|
||||
CBofWindow *getParent() const {
|
||||
return _parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Causes all parent windows to have valid paint regions
|
||||
* @param pRect Area to validate
|
||||
*/
|
||||
void validateAnscestors(CBofRect *pRect = nullptr);
|
||||
|
||||
static CBofWindow *getActiveWindow() {
|
||||
return _pActiveWindow;
|
||||
}
|
||||
|
||||
void setActive() {
|
||||
_pActiveWindow = this;
|
||||
}
|
||||
|
||||
static CBofWindow *getWindowList() {
|
||||
return _pWindowList;
|
||||
}
|
||||
|
||||
CBofRect getWindowRect() const {
|
||||
return _cWindowRect;
|
||||
}
|
||||
CBofRect getClientRect();
|
||||
|
||||
CBofRect getRect() const {
|
||||
return _cRect;
|
||||
}
|
||||
|
||||
int width() const {
|
||||
return _cRect.width();
|
||||
}
|
||||
int height() const {
|
||||
return _cRect.height();
|
||||
}
|
||||
|
||||
void screenToClient(CBofPoint *pPoint);
|
||||
|
||||
/**
|
||||
* Selects and Realizes specified palette into current DC
|
||||
* @param pPal Palette to select
|
||||
*/
|
||||
void selectPalette(CBofPalette *pPal);
|
||||
|
||||
/**
|
||||
* Associates a new background bitmap to this window
|
||||
* @param pNewBitmap New background bitmap
|
||||
* @param bRefresh true if should repaint now
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode setBackdrop(CBofBitmap *pNewBitmap, bool bRefresh = false);
|
||||
|
||||
/**
|
||||
* Associates a new background bitmap to this window
|
||||
* @param pszFileName new background bitmap from file
|
||||
* @param bRefresh true if should repaint now
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode setBackdrop(const char *pszFileName, bool bRefresh = false);
|
||||
|
||||
void clearBackdrop() {
|
||||
_pBackdrop = nullptr;
|
||||
}
|
||||
|
||||
CBofBitmap *getBackdrop() const {
|
||||
return _pBackdrop;
|
||||
}
|
||||
|
||||
bool hasBackdrop() const {
|
||||
return _pBackdrop != nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the background bitmap associated with this window
|
||||
*/
|
||||
void killBackdrop();
|
||||
|
||||
/**
|
||||
* Updates the specified section of the background bitmap
|
||||
* @param pRect Area of bitmap to update on screen
|
||||
* @param nTransparentColor Color index used for transparency (-1 = none)
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode paintBackdrop(CBofRect *pRect = nullptr, int nTransparentColor = -1);
|
||||
|
||||
void setControlID(uint32 nID) {
|
||||
_nID = nID;
|
||||
}
|
||||
uint32 getControlID() const {
|
||||
return _nID;
|
||||
}
|
||||
|
||||
void setBkColor(COLORREF cColor) {
|
||||
_cBkColor = cColor;
|
||||
}
|
||||
COLORREF getBkColor() const {
|
||||
return _cBkColor;
|
||||
}
|
||||
|
||||
void setFgColor(COLORREF cColor) {
|
||||
_cFgColor = cColor;
|
||||
}
|
||||
COLORREF getFgColor() const {
|
||||
return _cFgColor;
|
||||
}
|
||||
|
||||
void setPrevMouseDown(CBofPoint p) {
|
||||
_cPrevMouseDown = p;
|
||||
}
|
||||
CBofPoint getPrevMouseDown() const {
|
||||
return _cPrevMouseDown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets mouse capture for this window
|
||||
*/
|
||||
void setCapture();
|
||||
|
||||
/**
|
||||
* Release mouse capture for this window
|
||||
*/
|
||||
void releaseCapture();
|
||||
|
||||
/**
|
||||
* Returns true if the control is capturing mouse events
|
||||
*/
|
||||
bool hasCapture() const;
|
||||
|
||||
/**
|
||||
* Sets the focus on a control for keyboard input
|
||||
*/
|
||||
void setFocus();
|
||||
|
||||
/**
|
||||
* Releases focus from an edit control
|
||||
*/
|
||||
void releaseFocus();
|
||||
|
||||
/**
|
||||
* Returns true if the control has focus
|
||||
*/
|
||||
bool hasFocus() const;
|
||||
|
||||
void flushAllMessages();
|
||||
|
||||
/**
|
||||
* Adds specified rectangle to dirty rect list for this window
|
||||
* @param pRect Rectangle to add to dirty list
|
||||
*/
|
||||
void validateRect(const CBofRect *pRect);
|
||||
|
||||
/**
|
||||
* Removes specified rectangle from dirty rect for this window
|
||||
* @param pRect Rectangle to remove from dirty list
|
||||
*/
|
||||
void invalidateRect(const CBofRect *pRect);
|
||||
|
||||
virtual void onBofButton(CBofObject *pButton, int nExtraInfo);
|
||||
virtual void onBofScrollBar(CBofObject *pButton, int nNewPos);
|
||||
virtual void onBofListBox(CBofObject *pListBox, int nItemIndex);
|
||||
virtual void onMainLoop();
|
||||
|
||||
virtual void onSoundNotify(CBofObject *pObject, uint32 lParam2);
|
||||
virtual void onMovieNotify(uint32 lParam1, uint32 lParam2);
|
||||
|
||||
virtual void onMCINotify(uint32 wParam, uint32 lParam);
|
||||
|
||||
virtual void onTimer(uint32 nTimerId);
|
||||
|
||||
/**
|
||||
* Handles a pending ScummVM event
|
||||
* @param event Event to process
|
||||
*/
|
||||
virtual void handleEvent(const Common::Event &event);
|
||||
|
||||
Graphics::ManagedSurface *getSurface();
|
||||
|
||||
bool isCreated() const {
|
||||
return _surface != nullptr;
|
||||
}
|
||||
|
||||
virtual void enable() {
|
||||
_enabled = true;
|
||||
updateWindow();
|
||||
}
|
||||
virtual void disable() {
|
||||
_enabled = false;
|
||||
updateWindow();
|
||||
}
|
||||
bool isVisible() const {
|
||||
return _visible;
|
||||
}
|
||||
bool isEnabled() const {
|
||||
return _enabled;
|
||||
}
|
||||
|
||||
void updateWindow();
|
||||
|
||||
void setParent(CBofWindow *parent);
|
||||
|
||||
/**
|
||||
* Handle all pending ScummVM events
|
||||
*/
|
||||
void handleEvents();
|
||||
|
||||
virtual void onKeyHit(uint32 lKey, uint32 lRepCount);
|
||||
void fillWindow(byte iColor);
|
||||
void fillRect(CBofRect *pRect, byte iColor);
|
||||
|
||||
ErrorCode paintBeveledText(CBofRect *rect, const CBofString &string, int size, int weight, COLORREF color, int justify, uint32 format);
|
||||
|
||||
|
||||
protected:
|
||||
CBofWindow *_parent = nullptr; // Pointer to parent window
|
||||
Array<CBofWindow *> _children; // Child element pointers
|
||||
|
||||
virtual void onMouseMove(uint32 nFlags, CBofPoint *pPoint, void * = nullptr);
|
||||
virtual void onLButtonDown(uint32 nFlags, CBofPoint *pPoint, void * = nullptr);
|
||||
virtual void onLButtonUp(uint32 nFlags, CBofPoint *pPoint, void * = nullptr);
|
||||
virtual void onLButtonDblClk(uint32 nFlags, CBofPoint *pPoint);
|
||||
|
||||
virtual void onRButtonDown(uint32 nFlags, CBofPoint *pPoint);
|
||||
virtual void onRButtonUp(uint32 nFlags, CBofPoint *pPoint);
|
||||
virtual void onRButtonDblClk(uint32 nFlags, CBofPoint *pPoint);
|
||||
|
||||
virtual void onReSize(CBofSize *pSize);
|
||||
virtual void onPaint(CBofRect *pRect);
|
||||
virtual void onClose();
|
||||
|
||||
virtual void onUserMessage(uint32 nMessage, uint32 lParam);
|
||||
|
||||
virtual void onActivate();
|
||||
virtual void onDeActivate();
|
||||
|
||||
// Window Data
|
||||
char _szTitle[MAX_TITLE] = { 0 }; // Title of window
|
||||
CBofRect _cWindowRect; // Screen based area of this window
|
||||
CBofRect _cRect; // Window-based area of this window
|
||||
CBofBitmap *_pBackdrop = nullptr; // Backdrop bitmap
|
||||
uint32 _nID = 0; // ID of this window
|
||||
|
||||
COLORREF _cBkColor = RGB(255, 255, 255);
|
||||
COLORREF _cFgColor = RGB(0, 0, 0);
|
||||
|
||||
bool _bCaptured = false;
|
||||
Graphics::ManagedSurface *_surface = nullptr;
|
||||
|
||||
static CBofWindow *_pWindowList;
|
||||
static CBofWindow *_pActiveWindow;
|
||||
static CBofTimerPacket *_pTimerList;
|
||||
CBofPoint _cPrevMouseDown;
|
||||
static int _mouseX;
|
||||
static int _mouseY;
|
||||
};
|
||||
|
||||
class CBofMessage : public CBofObject {
|
||||
public:
|
||||
CBofWindow *_pWindow; // destination window for message
|
||||
uint32 _nMessage; // message to send (usually WM_USER)
|
||||
uint32 _lParam1; // user defined info
|
||||
uint32 _lParam2; // more user defined info
|
||||
};
|
||||
|
||||
class CBofTimerPacket : public CBofObject, public CLList {
|
||||
public:
|
||||
CBofWindow *_pOwnerWindow;
|
||||
BofCallback _pCallBack;
|
||||
uint32 _nID;
|
||||
uint32 _nInterval;
|
||||
};
|
||||
|
||||
extern CBofWindow *g_hackWindow;
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user