Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,79 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_UIBUTTON_H
#define WINTERMUTE_UIBUTTON_H
#include "engines/wintermute/ui/ui_object.h"
#include "engines/wintermute/dctypes.h" // Added by ClassView
namespace Wintermute {
class UIButton : public UIObject {
public:
bool _pixelPerfect;
bool _stayPressed;
bool _centerImage;
bool _oneTimePress;
uint32 _oneTimePressTime{};
DECLARE_PERSISTENT(UIButton, UIObject)
void press();
bool display() override { return display(0, 0); }
bool display(int offsetX, int offsetY) override;
bool _press;
bool _hover;
void correctSize() override;
TTextAlign _align;
BaseSprite *_imageHover;
BaseSprite *_imagePress;
BaseSprite *_imageDisable;
BaseSprite *_imageFocus;
BaseFont *_fontDisable;
BaseFont *_fontPress;
BaseFont *_fontHover;
BaseFont *_fontFocus;
UITiledImage *_backPress;
UITiledImage *_backHover;
UITiledImage *_backDisable;
UITiledImage *_backFocus;
UIButton(BaseGame *inGame = nullptr);
~UIButton() override;
bool loadFile(const char *filename);
bool loadBuffer(char *buffer, bool complete = true);
bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
// scripting interface
ScValue *scGetProperty(const char *name) override;
bool scSetProperty(const char *name, ScValue *value) override;
bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
const char *scToString() override;
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,934 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/ui/ui_edit.h"
#include "engines/wintermute/ui/ui_object.h"
#include "engines/wintermute/ui/ui_tiled_image.h"
#include "engines/wintermute/utils/string_util.h"
#include "engines/wintermute/base/base_active_rect.h"
#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/base/font/base_font.h"
#include "engines/wintermute/base/font/base_font_storage.h"
#include "engines/wintermute/base/base_keyboard_state.h"
#include "engines/wintermute/base/base_dynamic_buffer.h"
#include "engines/wintermute/base/base_parser.h"
#include "engines/wintermute/base/base_sprite.h"
#include "engines/wintermute/base/base_string_table.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_access_mgr.h"
#include "engines/wintermute/base/gfx/base_renderer.h"
#include "engines/wintermute/base/scriptables/script_value.h"
#include "engines/wintermute/base/scriptables/script_stack.h"
#include "engines/wintermute/base/scriptables/script.h"
#include "engines/wintermute/utils/utils.h"
#include "engines/wintermute/platform_osystem.h"
#include "engines/wintermute/dcgf.h"
#include "common/util.h"
#include "common/keyboard.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(UIEdit, false)
//////////////////////////////////////////////////////////////////////////
UIEdit::UIEdit(BaseGame *inGame) : UIObject(inGame) {
_type = UI_EDIT;
_fontSelected = nullptr;
_selStart = _selEnd = 10000;
_scrollOffset = 0;
_cursorChar = nullptr;
setCursorChar("|");
_cursorBlinkRate = 600;
_frameWidth = 0;
setText("");
_lastBlinkTime = 0;
_cursorVisible = true;
_maxLength = -1;
_canFocus = true;
}
//////////////////////////////////////////////////////////////////////////
UIEdit::~UIEdit() {
if (!_sharedFonts) {
if (_fontSelected) {
_game->_fontStorage->removeFont(_fontSelected);
}
}
SAFE_DELETE_ARRAY(_cursorChar);
}
//////////////////////////////////////////////////////////////////////////
bool UIEdit::loadFile(const char *filename) {
char *buffer = (char *)_game->_fileManager->readWholeFile(filename);
if (buffer == nullptr) {
_game->LOG(0, "UIEdit::loadFile failed for file '%s'", filename);
return STATUS_FAILED;
}
bool ret;
setFilename(filename);
if (DID_FAIL(ret = loadBuffer(buffer, true))) {
_game->LOG(0, "Error parsing EDIT file '%s'", filename);
}
delete[] buffer;
return ret;
}
TOKEN_DEF_START
TOKEN_DEF(TEMPLATE)
TOKEN_DEF(DISABLED)
TOKEN_DEF(VISIBLE)
TOKEN_DEF(BACK)
TOKEN_DEF(IMAGE)
TOKEN_DEF(FONT_SELECTED)
TOKEN_DEF(FONT)
TOKEN_DEF(TEXT)
TOKEN_DEF(X)
TOKEN_DEF(Y)
TOKEN_DEF(WIDTH)
TOKEN_DEF(HEIGHT)
TOKEN_DEF(CURSOR_BLINK_RATE)
TOKEN_DEF(CURSOR)
TOKEN_DEF(FRAME_WIDTH)
TOKEN_DEF(NAME)
TOKEN_DEF(SCRIPT)
TOKEN_DEF(PARENT_NOTIFY)
TOKEN_DEF(MAX_LENGTH)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF(EDIT)
TOKEN_DEF(CAPTION)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
bool UIEdit::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(TEMPLATE)
TOKEN_TABLE(DISABLED)
TOKEN_TABLE(VISIBLE)
TOKEN_TABLE(BACK)
TOKEN_TABLE(IMAGE)
TOKEN_TABLE(FONT_SELECTED)
TOKEN_TABLE(FONT)
TOKEN_TABLE(TEXT)
TOKEN_TABLE(X)
TOKEN_TABLE(Y)
TOKEN_TABLE(WIDTH)
TOKEN_TABLE(HEIGHT)
TOKEN_TABLE(CURSOR_BLINK_RATE)
TOKEN_TABLE(CURSOR)
TOKEN_TABLE(FRAME_WIDTH)
TOKEN_TABLE(NAME)
TOKEN_TABLE(SCRIPT)
TOKEN_TABLE(PARENT_NOTIFY)
TOKEN_TABLE(MAX_LENGTH)
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE(EDIT)
TOKEN_TABLE(CAPTION)
TOKEN_TABLE_END
char *params;
int cmd = 2;
BaseParser parser(_game);
if (complete) {
if (parser.getCommand(&buffer, commands, &params) != TOKEN_EDIT) {
_game->LOG(0, "'EDIT' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
while (cmd > 0 && (cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
setName(params);
break;
case TOKEN_BACK:
SAFE_DELETE(_back);
_back = new UITiledImage(_game);
if (!_back || DID_FAIL(_back->loadFile(params))) {
SAFE_DELETE(_back);
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_IMAGE:
SAFE_DELETE(_image);
_image = new BaseSprite(_game);
if (!_image || DID_FAIL(_image->loadFile(params))) {
SAFE_DELETE(_image);
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_FONT:
if (_font) {
_game->_fontStorage->removeFont(_font);
}
_font = _game->_fontStorage->addFont(params);
if (!_font) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_FONT_SELECTED:
if (_fontSelected) {
_game->_fontStorage->removeFont(_fontSelected);
}
_fontSelected = _game->_fontStorage->addFont(params);
if (!_fontSelected) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_TEXT:
setText(params);
_game->_stringTable->expand(&_text);
break;
case TOKEN_X:
parser.scanStr(params, "%d", &_posX);
break;
case TOKEN_Y:
parser.scanStr(params, "%d", &_posY);
break;
case TOKEN_WIDTH:
parser.scanStr(params, "%d", &_width);
break;
case TOKEN_HEIGHT:
parser.scanStr(params, "%d", &_height);
break;
case TOKEN_MAX_LENGTH:
parser.scanStr(params, "%d", &_maxLength);
break;
case TOKEN_CAPTION:
setCaption(params);
break;
case TOKEN_CURSOR:
SAFE_DELETE(_cursor);
_cursor = new BaseSprite(_game);
if (!_cursor || DID_FAIL(_cursor->loadFile(params))) {
SAFE_DELETE(_cursor);
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_CURSOR_BLINK_RATE:
parser.scanStr(params, "%d", &_cursorBlinkRate);
break;
case TOKEN_FRAME_WIDTH:
parser.scanStr(params, "%d", &_frameWidth);
break;
case TOKEN_SCRIPT:
addScript(params);
break;
case TOKEN_PARENT_NOTIFY:
parser.scanStr(params, "%b", &_parentNotify);
break;
case TOKEN_DISABLED:
parser.scanStr(params, "%b", &_disable);
break;
case TOKEN_VISIBLE:
parser.scanStr(params, "%b", &_visible);
break;
case TOKEN_EDITOR_PROPERTY:
parseEditorProperty(params, false);
break;
default:
break;
}
}
if (cmd == PARSERR_TOKENNOTFOUND) {
_game->LOG(0, "Syntax error in EDIT definition");
return STATUS_FAILED;
}
if (cmd == PARSERR_GENERIC) {
_game->LOG(0, "Error loading EDIT definition");
return STATUS_FAILED;
}
correctSize();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool UIEdit::saveAsText(BaseDynamicBuffer *buffer, int indent) {
buffer->putTextIndent(indent, "EDIT\n");
buffer->putTextIndent(indent, "{\n");
buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", _name);
buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption());
buffer->putTextIndent(indent + 2, "\n");
if (_back && _back->_filename && _back->_filename[0]) {
buffer->putTextIndent(indent + 2, "BACK=\"%s\"\n", _back->_filename);
}
if (_image && _image->_filename && _image->_filename[0]) {
buffer->putTextIndent(indent + 2, "IMAGE=\"%s\"\n", _image->_filename);
}
if (_font && _font->_filename && _font->_filename[0]) {
buffer->putTextIndent(indent + 2, "FONT=\"%s\"\n", _font->_filename);
}
if (_fontSelected && _fontSelected->_filename && _fontSelected->_filename[0]) {
buffer->putTextIndent(indent + 2, "FONT_SELECTED=\"%s\"\n", _fontSelected->_filename);
}
if (_cursor && _cursor->_filename && _cursor->_filename[0]) {
buffer->putTextIndent(indent + 2, "CURSOR=\"%s\"\n", _cursor->_filename);
}
buffer->putTextIndent(indent + 2, "\n");
if (_text && _text[0]) {
buffer->putTextIndent(indent + 2, "TEXT=\"%s\"\n", _text);
}
buffer->putTextIndent(indent + 2, "\n");
buffer->putTextIndent(indent + 2, "X=%d\n", _posX);
buffer->putTextIndent(indent + 2, "Y=%d\n", _posY);
buffer->putTextIndent(indent + 2, "WIDTH=%d\n", _width);
buffer->putTextIndent(indent + 2, "HEIGHT=%d\n", _height);
buffer->putTextIndent(indent + 2, "MAX_LENGTH=%d\n", _maxLength);
buffer->putTextIndent(indent + 2, "CURSOR_BLINK_RATE=%d\n", _cursorBlinkRate);
buffer->putTextIndent(indent + 2, "FRAME_WIDTH=%d\n", _frameWidth);
buffer->putTextIndent(indent + 2, "DISABLED=%s\n", _disable ? "TRUE" : "FALSE");
buffer->putTextIndent(indent + 2, "VISIBLE=%s\n", _visible ? "TRUE" : "FALSE");
buffer->putTextIndent(indent + 2, "PARENT_NOTIFY=%s\n", _parentNotify ? "TRUE" : "FALSE");
// scripts
for (int32 i = 0; i < _scripts.getSize(); i++) {
buffer->putTextIndent(indent + 2, "SCRIPT=\"%s\"\n", _scripts[i]->_filename);
}
buffer->putTextIndent(indent + 2, "\n");
// editor properties
BaseClass::saveAsText(buffer, indent + 2);
buffer->putTextIndent(indent, "}\n");
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
bool UIEdit::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
//////////////////////////////////////////////////////////////////////////
// SetSelectedFont
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "SetSelectedFont") == 0) {
stack->correctParams(1);
if (_fontSelected) {
_game->_fontStorage->removeFont(_fontSelected);
}
_fontSelected = _game->_fontStorage->addFont(stack->pop()->getString());
stack->pushBool(_fontSelected != nullptr);
return STATUS_OK;
} else {
return UIObject::scCallMethod(script, stack, thisStack, name);
}
}
//////////////////////////////////////////////////////////////////////////
ScValue *UIEdit::scGetProperty(const char *name) {
_scValue->setNULL();
//////////////////////////////////////////////////////////////////////////
// Type
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Type") == 0) {
_scValue->setString("editor");
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// SelStart
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "SelStart") == 0) {
_scValue->setInt(_selStart);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// SelEnd
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "SelEnd") == 0) {
_scValue->setInt(_selEnd);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// CursorBlinkRate
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "CursorBlinkRate") == 0) {
_scValue->setInt(_cursorBlinkRate);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// CursorChar
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "CursorChar") == 0) {
_scValue->setString(_cursorChar);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// FrameWidth
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "FrameWidth") == 0) {
_scValue->setInt(_frameWidth);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// MaxLength
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "MaxLength") == 0) {
_scValue->setInt(_maxLength);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Text
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Text") == 0) {
if (_game->_textEncoding == TEXT_UTF8) {
WideString wstr = StringUtil::ansiToWide(_text);
_scValue->setString(StringUtil::wideToUtf8(wstr).c_str());
} else {
_scValue->setString(_text);
}
return _scValue;
} else {
return UIObject::scGetProperty(name);
}
}
//////////////////////////////////////////////////////////////////////////
bool UIEdit::scSetProperty(const char *name, ScValue *value) {
//////////////////////////////////////////////////////////////////////////
// SelStart
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "SelStart") == 0) {
_selStart = value->getInt();
_selStart = MAX<int32>(_selStart, 0);
_selStart = MIN(_selStart, (int32)strlen(_text));
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// SelEnd
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "SelEnd") == 0) {
_selEnd = value->getInt();
_selEnd = MAX<int32>(_selEnd, 0);
_selEnd = MIN(_selEnd, (int32)strlen(_text));
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// CursorBlinkRate
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "CursorBlinkRate") == 0) {
_cursorBlinkRate = (uint32)value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// CursorChar
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "CursorChar") == 0) {
setCursorChar(value->getString());
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// FrameWidth
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "FrameWidth") == 0) {
_frameWidth = value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// MaxLength
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "MaxLength") == 0) {
_maxLength = value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Text
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Text") == 0) {
if (_game->_textEncoding == TEXT_UTF8) {
WideString wstr = StringUtil::utf8ToWide(value->getString());
setText(StringUtil::wideToAnsi(wstr).c_str());
} else {
setText(value->getString());
}
return STATUS_OK;
} else {
return UIObject::scSetProperty(name, value);
}
}
//////////////////////////////////////////////////////////////////////////
const char *UIEdit::scToString() {
return "[edit]";
}
//////////////////////////////////////////////////////////////////////////
void UIEdit::setCursorChar(const char *character) {
if (!character) {
return;
}
SAFE_DELETE_ARRAY(_cursorChar);
size_t cursorCharSize = strlen(character) + 1;
_cursorChar = new char [cursorCharSize];
Common::strcpy_s(_cursorChar, cursorCharSize, character);
}
//////////////////////////////////////////////////////////////////////////
bool UIEdit::display(int offsetX, int offsetY) {
if (!_visible) {
return STATUS_OK;
}
// hack!
TTextEncoding OrigEncoding = _game->_textEncoding;
_game->_textEncoding = TEXT_ANSI;
if (_back) {
_back->display(offsetX + _posX, offsetY + _posY, _width, _height);
}
if (_image) {
_image->draw(offsetX + _posX, offsetY + _posY, nullptr);
}
// prepare fonts
BaseFont *font;
BaseFont *sfont;
if (_font) {
font = _font;
} else {
font = _game->_systemFont;
}
if (_fontSelected) {
sfont = _fontSelected;
} else {
sfont = font;
}
bool focused = isFocused();
_selStart = MAX<int32>(_selStart, 0);
_selEnd = MAX<int32>(_selEnd, 0);
_selStart = MIN(_selStart, (int32)strlen(_text));
_selEnd = MIN(_selEnd, (int32)strlen(_text));
//int cursorWidth = font->getCharWidth(_cursorChar[0]);
int cursorWidth = font->getTextWidth((byte *)_cursorChar);
int32 s1, s2;
bool curFirst;
// modify scroll offset
if (_selStart >= _selEnd) {
while (font->getTextWidth((byte *)_text + _scrollOffset, MAX<int32>(0, _selEnd - _scrollOffset)) > _width - cursorWidth - 2 * _frameWidth) {
_scrollOffset++;
if (_scrollOffset >= (int)strlen(_text)) {
break;
}
}
_scrollOffset = MIN(_scrollOffset, _selEnd);
s1 = _selEnd;
s2 = _selStart;
curFirst = true;
} else {
while (font->getTextWidth((byte *)_text + _scrollOffset, MAX<int32>(0, _selStart - _scrollOffset)) +
sfont->getTextWidth((byte *)(_text + MAX<int32>(_scrollOffset, _selStart)), _selEnd - MAX(_scrollOffset, _selStart))
> _width - cursorWidth - 2 * _frameWidth) {
_scrollOffset++;
if (_scrollOffset >= (int32)strlen(_text)) {
break;
}
}
_scrollOffset = MIN(_scrollOffset, _selEnd);
s1 = _selStart;
s2 = _selEnd;
curFirst = false;
}
int alignOffset = 0;
for (int count = 0; count < 2; count++) {
// draw text
int xxx, yyy, width, height;
xxx = _posX + _frameWidth + offsetX;
yyy = _posY + _frameWidth + offsetY;
width = _posX + _width + offsetX - _frameWidth;
height = MAX(font->getLetterHeight(), sfont->getLetterHeight());
if (_game->_textRTL) {
xxx += alignOffset;
}
TTextAlign align = TAL_LEFT;
// unselected 1
if (s1 > _scrollOffset) {
if (count) {
font->drawText((byte *)_text + _scrollOffset, xxx, yyy, width - xxx, align, height, s1 - _scrollOffset);
}
xxx += font->getTextWidth((byte *)_text + _scrollOffset, s1 - _scrollOffset);
alignOffset += font->getTextWidth((byte *)_text + _scrollOffset, s1 - _scrollOffset);
}
// cursor
if (focused && curFirst) {
if (count) {
if (BasePlatform::getTime() - _lastBlinkTime >= _cursorBlinkRate) {
_lastBlinkTime = BasePlatform::getTime();
_cursorVisible = !_cursorVisible;
}
if (_cursorVisible) {
font->drawText((byte *)_cursorChar, xxx, yyy, width - xxx, align, height, 1);
}
}
xxx += cursorWidth;
alignOffset += cursorWidth;
}
// selected
int s3 = MAX(s1, _scrollOffset);
if (s2 - s3 > 0) {
if (count) {
sfont->drawText((byte *)_text + s3, xxx, yyy, width - xxx, align, height, s2 - s3);
}
xxx += sfont->getTextWidth((byte *)_text + s3, s2 - s3);
alignOffset += sfont->getTextWidth((byte *)_text + s3, s2 - s3);
}
// cursor
if (focused && !curFirst) {
if (count) {
if (BasePlatform::getTime() - _lastBlinkTime >= _cursorBlinkRate) {
_lastBlinkTime = BasePlatform::getTime();
_cursorVisible = !_cursorVisible;
}
if (_cursorVisible) {
font->drawText((byte *)_cursorChar, xxx, yyy, width - xxx, align, height, 1);
}
}
xxx += cursorWidth;
alignOffset += cursorWidth;
}
// unselected 2
if (count) {
font->drawText((byte *)_text + s2, xxx, yyy, width - xxx, align, height);
}
alignOffset += font->getTextWidth((byte *)_text + s2);
alignOffset = (_width - 2 * _frameWidth) - alignOffset;
if (alignOffset < 0) {
alignOffset = 0;
}
}
_game->_renderer->_rectList.add(new BaseActiveRect(_game, this, nullptr, offsetX + _posX, offsetY + _posY, _width, _height, 100, 100, false));
if (_game->_accessMgr->getActiveObject() == this) {
Common::Rect32 rc;
BasePlatform::setRect(&rc, offsetX + _posX, offsetY + _posY, offsetX + _posX + _width, offsetY + _posY + _height);
_game->_accessMgr->setHintRect(&rc, true);
}
_game->_textEncoding = OrigEncoding;
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool UIEdit::handleKeypress(Common::Event *event, bool printable) {
if (event->type != Common::EVENT_KEYDOWN) {
return false;
}
switch (event->kbd.keycode) {
// Those keys are 'printable' in WME 1.x, let's ignore them
case Common::KEYCODE_ESCAPE:
case Common::KEYCODE_TAB:
case Common::KEYCODE_KP_ENTER:
case Common::KEYCODE_RETURN:
return false;
// Movement keys are controlling _selEnd and _selStart
case Common::KEYCODE_HOME:
case Common::KEYCODE_END:
case Common::KEYCODE_LEFT:
case Common::KEYCODE_UP:
case Common::KEYCODE_RIGHT:
case Common::KEYCODE_DOWN:
if (event->kbd.keycode == Common::KEYCODE_HOME) {
_selEnd = _game->_textRTL ? strlen(_text) : 0;
} else if (event->kbd.keycode == Common::KEYCODE_END) {
_selEnd = _game->_textRTL ? 0 : strlen(_text);
} else if (event->kbd.keycode == Common::KEYCODE_LEFT ||
event->kbd.keycode == Common::KEYCODE_UP) {
_selEnd--;
} else {
_selEnd++;
}
if (!BaseKeyboardState::isShiftDown()) {
_selStart = _selEnd;
}
return true;
// Delete right
case Common::KEYCODE_DELETE:
if (_selStart == _selEnd) {
if (_game->_textRTL) {
deleteChars(_selStart - 1, _selStart);
_selEnd--;
if (_selEnd < 0) {
_selEnd = 0;
}
} else {
deleteChars(_selStart, _selStart + 1);
}
} else {
deleteChars(_selStart, _selEnd);
}
if (_selEnd > _selStart) {
_selEnd -= (_selEnd - _selStart);
}
_selStart = _selEnd;
return true;
// Delete left
case Common::KEYCODE_BACKSPACE:
if (_selStart == _selEnd) {
if (_game->_textRTL) {
deleteChars(_selStart, _selStart + 1);
} else {
deleteChars(_selStart - 1, _selStart);
}
} else {
deleteChars(_selStart, _selEnd);
}
if (_selEnd >= _selStart) {
_selEnd -= MAX<int32>(1, _selEnd - _selStart);
}
_selStart = _selEnd;
return true;
default:
break;
}
// Ctrl+A = Select All
if (BaseKeyboardState::isControlDown() && event->kbd.keycode == Common::KEYCODE_a) {
_selStart = 0;
_selEnd = strlen(_text);
return true;
}
// Those are actually printable characters
else if (printable) {
if (_selStart != _selEnd) {
deleteChars(_selStart, _selEnd);
}
//WideString wstr = StringUtil::Utf8ToWide(event->kbd.ascii);
WideString wstr;
wstr += (char)event->kbd.ascii;
_selEnd += insertChars(_selEnd, (const byte *)StringUtil::wideToAnsi(wstr).c_str(), 1);
if (_game->_textRTL) {
_selEnd = _selStart;
} else {
_selStart = _selEnd;
}
return true;
}
return false;
}
//////////////////////////////////////////////////////////////////////////
int UIEdit::deleteChars(int start, int end) {
if (start > end) {
BaseUtils::swap(&start, &end);
}
start = MAX(start, (int)0);
end = MIN(end, (int)strlen(_text));
char *str = new char[strlen(_text) - (end - start) + 1];
if (str) {
if (start > 0) {
memcpy(str, _text, start);
}
memcpy(str + MAX(0, start), _text + end, strlen(_text) - end + 1);
SAFE_DELETE_ARRAY(_text);
_text = str;
}
if (_parentNotify && _parent) {
_parent->applyEvent(_name);
}
return end - start;
}
//////////////////////////////////////////////////////////////////////////
int UIEdit::insertChars(int pos, const byte *chars, int num) {
if ((_maxLength != -1) && (int)strlen(_text) + num > _maxLength) {
num -= (strlen(_text) + num - _maxLength);
}
pos = MAX(pos, (int)0);
pos = MIN(pos, (int)strlen(_text));
char *str = new char[strlen(_text) + num + 1];
if (str) {
if (pos > 0) {
memcpy(str, _text, pos);
}
memcpy(str + pos + num, _text + pos, strlen(_text) - pos + 1);
memcpy(str + pos, chars, num);
SAFE_DELETE_ARRAY(_text);
_text = str;
}
if (_parentNotify && _parent) {
_parent->applyEvent(_name);
}
return num;
}
//////////////////////////////////////////////////////////////////////////
bool UIEdit::persist(BasePersistenceManager *persistMgr) {
UIObject::persist(persistMgr);
persistMgr->transferUint32(TMEMBER(_cursorBlinkRate));
persistMgr->transferCharPtr(TMEMBER(_cursorChar));
persistMgr->transferPtr(TMEMBER_PTR(_fontSelected));
persistMgr->transferSint32(TMEMBER(_frameWidth));
persistMgr->transferSint32(TMEMBER(_maxLength));
persistMgr->transferSint32(TMEMBER(_scrollOffset));
persistMgr->transferSint32(TMEMBER(_selEnd));
persistMgr->transferSint32(TMEMBER(_selStart));
if (!persistMgr->getIsSaving()) {
_cursorVisible = false;
_lastBlinkTime = 0;
}
return STATUS_OK;
}
} // End of namespace Wintermute

View File

@@ -0,0 +1,71 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_UIEDIT_H
#define WINTERMUTE_UIEDIT_H
#include "engines/wintermute/persistent.h"
#include "engines/wintermute/ui/ui_object.h"
#include "common/events.h"
namespace Wintermute {
class BaseFont;
class UIEdit : public UIObject {
public:
DECLARE_PERSISTENT(UIEdit, UIObject)
int32 _maxLength;
int insertChars(int pos, const byte *chars, int num);
int deleteChars(int start, int end);
bool _cursorVisible;
uint32 _lastBlinkTime;
bool display(int offsetX, int offsetY) override;
bool handleKeypress(Common::Event *event, bool printable = false) override;
int32 _scrollOffset;
int32 _frameWidth;
uint32 _cursorBlinkRate;
void setCursorChar(const char *character);
char *_cursorChar;
int32 _selEnd;
int32 _selStart;
BaseFont *_fontSelected;
UIEdit(BaseGame *inGame);
~UIEdit() override;
bool loadFile(const char *filename);
bool loadBuffer(char *buffer, bool complete = true);
bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
// scripting interface
ScValue *scGetProperty(const char *name) override;
bool scSetProperty(const char *name, ScValue *value) override;
bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
const char *scToString() override;
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,368 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/ad/ad_entity.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/ui/ui_entity.h"
#include "engines/wintermute/base/base_parser.h"
#include "engines/wintermute/base/base_dynamic_buffer.h"
#include "engines/wintermute/base/scriptables/script_value.h"
#include "engines/wintermute/base/scriptables/script.h"
#include "engines/wintermute/base/scriptables/script_stack.h"
#include "engines/wintermute/dcgf.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(UIEntity, false)
//////////////////////////////////////////////////////////////////////////
UIEntity::UIEntity(BaseGame *inGame) : UIObject(inGame) {
_type = UI_CUSTOM;
_entity = nullptr;
}
//////////////////////////////////////////////////////////////////////////
UIEntity::~UIEntity() {
if (_entity) {
_game->unregisterObject(_entity);
}
_entity = nullptr;
}
//////////////////////////////////////////////////////////////////////////
bool UIEntity::loadFile(const char *filename) {
char *buffer = (char *)_game->_fileManager->readWholeFile(filename);
if (buffer == nullptr) {
_game->LOG(0, "UIEntity::loadFile failed for file '%s'", filename);
return STATUS_FAILED;
}
bool ret;
setFilename(filename);
if (DID_FAIL(ret = loadBuffer(buffer, true))) {
_game->LOG(0, "Error parsing ENTITY container file '%s'", filename);
}
delete[] buffer;
return ret;
}
TOKEN_DEF_START
TOKEN_DEF(ENTITY_CONTAINER)
TOKEN_DEF(TEMPLATE)
TOKEN_DEF(DISABLED)
TOKEN_DEF(VISIBLE)
TOKEN_DEF(X)
TOKEN_DEF(Y)
TOKEN_DEF(NAME)
TOKEN_DEF(ENTITY)
TOKEN_DEF(SCRIPT)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
bool UIEntity::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(ENTITY_CONTAINER)
TOKEN_TABLE(TEMPLATE)
TOKEN_TABLE(DISABLED)
TOKEN_TABLE(VISIBLE)
TOKEN_TABLE(X)
TOKEN_TABLE(Y)
TOKEN_TABLE(NAME)
TOKEN_TABLE(ENTITY)
TOKEN_TABLE(SCRIPT)
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
char *params;
int cmd = 2;
BaseParser parser(_game);
if (complete) {
if (parser.getCommand(&buffer, commands, &params) != TOKEN_ENTITY_CONTAINER) {
_game->LOG(0, "'ENTITY_CONTAINER' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
while (cmd > 0 && (cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
setName(params);
break;
case TOKEN_X:
parser.scanStr(params, "%d", &_posX);
break;
case TOKEN_Y:
parser.scanStr(params, "%d", &_posY);
break;
case TOKEN_DISABLED:
parser.scanStr(params, "%b", &_disable);
break;
case TOKEN_VISIBLE:
parser.scanStr(params, "%b", &_visible);
break;
case TOKEN_ENTITY:
if (DID_FAIL(setEntity(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_SCRIPT:
addScript(params);
break;
case TOKEN_EDITOR_PROPERTY:
parseEditorProperty(params, false);
break;
default:
break;
}
}
if (cmd == PARSERR_TOKENNOTFOUND) {
_game->LOG(0, "Syntax error in ENTITY_CONTAINER definition");
return STATUS_FAILED;
}
if (cmd == PARSERR_GENERIC) {
_game->LOG(0, "Error loading ENTITY_CONTAINER definition");
return STATUS_FAILED;
}
correctSize();
if (_game->_editorMode) {
_width = 50;
_height = 50;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool UIEntity::saveAsText(BaseDynamicBuffer *buffer, int indent) {
buffer->putTextIndent(indent, "ENTITY_CONTAINER\n");
buffer->putTextIndent(indent, "{\n");
buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", _name);
buffer->putTextIndent(indent + 2, "\n");
buffer->putTextIndent(indent + 2, "X=%d\n", _posX);
buffer->putTextIndent(indent + 2, "Y=%d\n", _posY);
buffer->putTextIndent(indent + 2, "DISABLED=%s\n", _disable ? "TRUE" : "FALSE");
buffer->putTextIndent(indent + 2, "VISIBLE=%s\n", _visible ? "TRUE" : "FALSE");
if (_entity && _entity->_filename && _entity->_filename[0]) {
buffer->putTextIndent(indent + 2, "ENTITY=\"%s\"\n", _entity->_filename);
}
buffer->putTextIndent(indent + 2, "\n");
// scripts
for (int32 i = 0; i < _scripts.getSize(); i++) {
buffer->putTextIndent(indent + 2, "SCRIPT=\"%s\"\n", _scripts[i]->_filename);
}
buffer->putTextIndent(indent + 2, "\n");
// editor properties
BaseClass::saveAsText(buffer, indent + 2);
buffer->putTextIndent(indent, "}\n");
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool UIEntity::setEntity(const char *filename) {
if (_entity) {
_game->unregisterObject(_entity);
}
_entity = new AdEntity(_game);
if (!_entity || DID_FAIL(_entity->loadFile(filename))) {
SAFE_DELETE(_entity);
return STATUS_FAILED;
} else {
_entity->_nonIntMouseEvents = true;
_entity->_sceneIndependent = true;
_entity->makeFreezable(false);
_game->registerObject(_entity);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool UIEntity::display(int offsetX, int offsetY) {
if (!_visible) {
return STATUS_OK;
}
if (_entity) {
_entity->_posX = offsetX + _posX;
_entity->_posY = offsetY + _posY;
if (_entity->_scale < 0) {
_entity->_zoomable = false;
}
_entity->_shadowable = false;
_entity->update();
bool origReg = _entity->_registrable;
if (_entity->_registrable && _disable) {
_entity->_registrable = false;
}
_entity->display();
_entity->_registrable = origReg;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
bool UIEntity::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
//////////////////////////////////////////////////////////////////////////
// GetEntity
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "GetEntity") == 0) {
stack->correctParams(0);
if (_entity) {
stack->pushNative(_entity, true);
} else {
stack->pushNULL();
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// SetEntity
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "SetEntity") == 0) {
stack->correctParams(1);
const char *filename = stack->pop()->getString();
if (DID_SUCCEED(setEntity(filename))) {
stack->pushBool(true);
} else {
stack->pushBool(false);
}
return STATUS_OK;
} else {
return UIObject::scCallMethod(script, stack, thisStack, name);
}
}
//////////////////////////////////////////////////////////////////////////
ScValue *UIEntity::scGetProperty(const char *name) {
_scValue->setNULL();
//////////////////////////////////////////////////////////////////////////
// Type
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Type") == 0) {
_scValue->setString("entity container");
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Freezable
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Freezable") == 0) {
if (_entity) {
_scValue->setBool(_entity->_freezable);
} else {
_scValue->setBool(false);
}
return _scValue;
} else {
return UIObject::scGetProperty(name);
}
}
//////////////////////////////////////////////////////////////////////////
bool UIEntity::scSetProperty(const char *name, ScValue *value) {
//////////////////////////////////////////////////////////////////////////
// Freezable
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Freezable") == 0) {
if (_entity) {
_entity->makeFreezable(value->getBool());
}
return STATUS_OK;
} else {
return UIObject::scSetProperty(name, value);
}
}
//////////////////////////////////////////////////////////////////////////
const char *UIEntity::scToString() {
return "[entity container]";
}
//////////////////////////////////////////////////////////////////////////
bool UIEntity::persist(BasePersistenceManager *persistMgr) {
UIObject::persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_entity));
return STATUS_OK;
}
} // End of namespace Wintermute

View File

@@ -0,0 +1,58 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_UIENTITY_H
#define WINTERMUTE_UIENTITY_H
#include "engines/wintermute/ui/ui_object.h"
namespace Wintermute {
class AdEntity;
class UIEntity : public UIObject {
public:
DECLARE_PERSISTENT(UIEntity, UIObject)
UIEntity(BaseGame *inGame);
~UIEntity() override;
bool loadFile(const char *filename);
bool loadBuffer(char *buffer, bool complete);
bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
bool display() override { return display(0, 0); }
bool display(int offsetX, int offsetY) override;
AdEntity *_entity;
bool setEntity(const char *filename);
// scripting interface
ScValue *scGetProperty(const char *name) override;
bool scSetProperty(const char *name, ScValue *value) override;
bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
const char *scToString() override;
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,658 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_sprite.h"
#include "engines/wintermute/ui/ui_object.h"
#include "engines/wintermute/ui/ui_tiled_image.h"
#include "engines/wintermute/ui/ui_window.h"
#include "engines/wintermute/platform_osystem.h"
#include "engines/wintermute/base/gfx/base_renderer.h"
#include "engines/wintermute/base/scriptables/script_value.h"
#include "engines/wintermute/base/scriptables/script_stack.h"
#include "engines/wintermute/base/font/base_font_storage.h"
#include "engines/wintermute/dcgf.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(UIObject, false)
//////////////////////////////////////////////////////////////////////////
UIObject::UIObject(BaseGame *inGame) : BaseObject(inGame) {
_back = nullptr;
_image = nullptr;
_font = nullptr;
_text = nullptr;
_sharedFonts = _sharedImages = false;
_width = _height = 0;
_listenerObject = nullptr;
_listenerParamObject = nullptr;
_listenerParamDWORD = 0;
_disable = false;
_visible = true;
_type = UI_UNKNOWN;
_parent = nullptr;
_parentNotify = false;
_focusedWidget = nullptr;
_canFocus = false;
_nonIntMouseEvents = true;
}
//////////////////////////////////////////////////////////////////////////
UIObject::~UIObject() {
if (!_game->_loadInProgress) {
SystemClassRegistry::getInstance()->enumInstances(BaseGame::invalidateValues, "ScValue", (void *)this);
}
if (_back) {
delete _back;
}
if (_font && !_sharedFonts) {
_game->_fontStorage->removeFont(_font);
}
if (_image && !_sharedImages) {
delete _image;
}
if (_text) {
delete[] _text;
}
_focusedWidget = nullptr; // ref only
}
//////////////////////////////////////////////////////////////////////////
void UIObject::setText(const char *text) {
if (_text) {
delete[] _text;
}
size_t textSize = strlen(text) + 1;
_text = new char [textSize];
Common::strcpy_s(_text, textSize, text);
for (uint32 i = 0; i < strlen(_text); i++) {
if (_text[i] == '|') {
_text[i] = '\n';
}
}
}
//////////////////////////////////////////////////////////////////////////
bool UIObject::display(int offsetX, int offsetY) {
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
void UIObject::setListener(BaseScriptHolder *object, BaseScriptHolder *listenerObject, uint32 listenerParam) {
_listenerObject = object;
_listenerParamObject = listenerObject;
_listenerParamDWORD = listenerParam;
}
//////////////////////////////////////////////////////////////////////////
void UIObject::correctSize() {
Common::Rect32 rect;
if (_width <= 0) {
if (_image) {
_image->getBoundingRect(&rect, 0, 0);
_width = rect.right - rect.left;
} else {
_width = 100;
}
}
if (_height <= 0) {
if (_image) {
_image->getBoundingRect(&rect, 0, 0);
_height = rect.bottom - rect.top;
}
}
if (_back) {
_back->correctSize(&_width, &_height);
}
}
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
bool UIObject::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
//////////////////////////////////////////////////////////////////////////
// SetFont
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "SetFont") == 0) {
stack->correctParams(1);
ScValue *val = stack->pop();
if (_font) {
_game->_fontStorage->removeFont(_font);
}
if (val->isNULL()) {
_font = nullptr;
stack->pushBool(true);
} else {
_font = _game->_fontStorage->addFont(val->getString());
stack->pushBool(_font != nullptr);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// SetImage
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "SetImage") == 0) {
stack->correctParams(1);
ScValue *val = stack->pop();
/* const char *filename = */ val->getString();
SAFE_DELETE(_image);
if (val->isNULL()) {
stack->pushBool(true);
return STATUS_OK;
}
_image = new BaseSprite(_game);
if (!_image || DID_FAIL(_image->loadFile(val->getString()))) {
SAFE_DELETE(_image);
stack->pushBool(false);
} else {
stack->pushBool(true);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// GetImage
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "GetImage") == 0) {
stack->correctParams(0);
if (!_image || !_image->_filename || !_image->_filename[0]) {
stack->pushNULL();
} else {
stack->pushString(_image->_filename);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// GetImageObject
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "GetImageObject") == 0) {
stack->correctParams(0);
if (!_image) {
stack->pushNULL();
} else {
stack->pushNative(_image, true);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Focus
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Focus") == 0) {
stack->correctParams(0);
focus();
stack->pushNULL();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// MoveAfter / MoveBefore
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "MoveAfter") == 0 || strcmp(name, "MoveBefore") == 0) {
stack->correctParams(1);
if (_parent && _parent->_type == UI_WINDOW) {
UIWindow *win = (UIWindow *)_parent;
int32 i;
bool found = false;
ScValue *val = stack->pop();
// find directly
if (val->isNative()) {
UIObject *widget = (UIObject *)val->getNative();
for (i = 0; i < win->_widgets.getSize(); i++) {
if (win->_widgets[i] == widget) {
found = true;
break;
}
}
}
// find by name
else {
const char *findName = val->getString();
for (i = 0; i < win->_widgets.getSize(); i++) {
if (scumm_stricmp(win->_widgets[i]->_name, findName) == 0) {
found = true;
break;
}
}
}
if (found) {
bool done = false;
for (int32 j = 0; j < win->_widgets.getSize(); j++) {
if (win->_widgets[j] == this) {
if (strcmp(name, "MoveAfter") == 0) {
i++;
}
if (j >= i) {
j++;
}
win->_widgets.insertAt(i, this);
win->_widgets.removeAt(j);
done = true;
stack->pushBool(true);
break;
}
}
if (!done) {
stack->pushBool(false);
}
} else {
stack->pushBool(false);
}
} else {
stack->pushBool(false);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// MoveToBottom
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "MoveToBottom") == 0) {
stack->correctParams(0);
if (_parent && _parent->_type == UI_WINDOW) {
UIWindow *win = (UIWindow *)_parent;
for (int32 i = 0; i < win->_widgets.getSize(); i++) {
if (win->_widgets[i] == this) {
win->_widgets.removeAt(i);
win->_widgets.insertAt(0, this);
break;
}
}
stack->pushBool(true);
} else {
stack->pushBool(false);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// MoveToTop
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "MoveToTop") == 0) {
stack->correctParams(0);
if (_parent && _parent->_type == UI_WINDOW) {
UIWindow *win = (UIWindow *)_parent;
for (int32 i = 0; i < win->_widgets.getSize(); i++) {
if (win->_widgets[i] == this) {
win->_widgets.removeAt(i);
win->_widgets.add(this);
break;
}
}
stack->pushBool(true);
} else {
stack->pushBool(false);
}
return STATUS_OK;
} else {
return BaseObject::scCallMethod(script, stack, thisStack, name);
}
}
//////////////////////////////////////////////////////////////////////////
ScValue *UIObject::scGetProperty(const char *name) {
_scValue->setNULL();
//////////////////////////////////////////////////////////////////////////
// Type
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Type") == 0) {
_scValue->setString("ui_object");
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Name
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Name") == 0) {
_scValue->setString(_name);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Parent (RO)
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Parent") == 0) {
_scValue->setNative(_parent, true);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// ParentNotify
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "ParentNotify") == 0) {
_scValue->setBool(_parentNotify);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Width
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Width") == 0) {
_scValue->setInt(_width);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Height
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Height") == 0) {
_scValue->setInt(_height);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Visible
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Visible") == 0) {
_scValue->setBool(_visible);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Disabled
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Disabled") == 0) {
_scValue->setBool(_disable);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Text
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Text") == 0) {
_scValue->setString(_text);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// NextSibling (RO) / PrevSibling (RO)
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "NextSibling") == 0 || strcmp(name, "PrevSibling") == 0) {
_scValue->setNULL();
if (_parent && _parent->_type == UI_WINDOW) {
UIWindow *win = (UIWindow *)_parent;
for (int32 i = 0; i < win->_widgets.getSize(); i++) {
if (win->_widgets[i] == this) {
if (strcmp(name, "NextSibling") == 0) {
if (i < win->_widgets.getSize() - 1) {
_scValue->setNative(win->_widgets[i + 1], true);
}
} else {
if (i > 0) {
_scValue->setNative(win->_widgets[i - 1], true);
}
}
break;
}
}
}
return _scValue;
} else {
return BaseObject::scGetProperty(name);
}
}
//////////////////////////////////////////////////////////////////////////
bool UIObject::scSetProperty(const char *name, ScValue *value) {
//////////////////////////////////////////////////////////////////////////
// Name
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Name") == 0) {
setName(value->getString());
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// ParentNotify
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "ParentNotify") == 0) {
_parentNotify = value->getBool();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Width
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Width") == 0) {
_width = value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Height
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Height") == 0) {
_height = value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Visible
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Visible") == 0) {
_visible = value->getBool();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Disabled
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Disabled") == 0) {
_disable = value->getBool();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Text
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Text") == 0) {
setText(value->getString());
return STATUS_OK;
} else {
return BaseObject::scSetProperty(name, value);
}
}
//////////////////////////////////////////////////////////////////////////
const char *UIObject::scToString() {
return "[ui_object]";
}
//////////////////////////////////////////////////////////////////////////
bool UIObject::isFocused() {
if (!_game->_focusedWindow) {
return false;
}
if (_game->_focusedWindow == this) {
return true;
}
UIObject *obj = _game->_focusedWindow;
while (obj) {
if (obj == this) {
return true;
} else {
obj = obj->_focusedWidget;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////
bool UIObject::handleMouse(TMouseEvent event, TMouseButton button) {
// handle focus change
if (event == MOUSE_CLICK && button == MOUSE_BUTTON_LEFT) {
focus();
}
return BaseObject::handleMouse(event, button);
}
//////////////////////////////////////////////////////////////////////////
bool UIObject::focus() {
UIObject *obj = this;
bool disabled = false;
while (obj) {
if (obj->_disable && obj->_type == UI_WINDOW) {
disabled = true;
break;
}
obj = obj->_parent;
}
if (!disabled) {
obj = this;
while (obj) {
if (obj->_parent) {
if (!obj->_disable && obj->_canFocus) {
obj->_parent->_focusedWidget = obj;
}
} else {
if (obj->_type == UI_WINDOW) {
_game->focusWindow((UIWindow *)obj);
}
}
obj = obj->_parent;
}
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool UIObject::getTotalOffset(int *offsetX, int *offsetY) {
int offX = 0, offY = 0;
UIObject *obj = _parent;
while (obj) {
offX += obj->_posX;
offY += obj->_posY;
obj = obj->_parent;
}
if (offsetX) {
*offsetX = offX;
}
if (offsetY) {
*offsetY = offY;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool UIObject::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_back));
persistMgr->transferBool(TMEMBER(_canFocus));
persistMgr->transferBool(TMEMBER(_disable));
persistMgr->transferPtr(TMEMBER_PTR(_focusedWidget));
persistMgr->transferPtr(TMEMBER_PTR(_font));
persistMgr->transferSint32(TMEMBER(_height));
persistMgr->transferPtr(TMEMBER_PTR(_image));
persistMgr->transferPtr(TMEMBER_PTR(_listenerObject));
persistMgr->transferPtr(TMEMBER_PTR(_listenerParamObject));
persistMgr->transferUint32(TMEMBER(_listenerParamDWORD));
persistMgr->transferPtr(TMEMBER_PTR(_parent));
persistMgr->transferBool(TMEMBER(_parentNotify));
persistMgr->transferBool(TMEMBER(_sharedFonts));
persistMgr->transferBool(TMEMBER(_sharedImages));
persistMgr->transferCharPtr(TMEMBER(_text));
persistMgr->transferSint32(TMEMBER_INT(_type));
persistMgr->transferBool(TMEMBER(_visible));
persistMgr->transferSint32(TMEMBER(_width));
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
const char *UIObject::getAccessCaption() {
if (_accessCaption)
return _accessCaption;
else {
if (_text && _text[0])
return _text;
else
return getCaption();
}
}
//////////////////////////////////////////////////////////////////////////
bool UIObject::saveAsText(BaseDynamicBuffer *buffer, int indent) {
return STATUS_FAILED;
}
} // End of namespace Wintermute

View File

@@ -0,0 +1,85 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_UIOBJECT_H
#define WINTERMUTE_UIOBJECT_H
#include "engines/wintermute/base/base_object.h"
#include "engines/wintermute/dctypes.h" // Added by ClassView
namespace Wintermute {
class UITiledImage;
class BaseFont;
class UIObject : public BaseObject {
public:
const char *getAccessCaption() override;
bool getTotalOffset(int *offsetX, int *offsetY);
bool _canFocus;
bool focus();
bool handleMouse(TMouseEvent event, TMouseButton button) override;
bool isFocused();
bool _parentNotify;
DECLARE_PERSISTENT(UIObject, BaseObject)
UIObject *_parent;
bool display() override { return display(0, 0); }
virtual bool display(int offsetX) { return display(offsetX, 0); }
virtual bool display(int offsetX, int offsetY);
virtual void correctSize();
bool _sharedFonts;
bool _sharedImages;
void setText(const char *text);
char *_text;
BaseFont *_font;
bool _visible;
UITiledImage *_back;
bool _disable;
UIObject(BaseGame *inGame = nullptr);
~UIObject() override;
int32 _width;
int32 _height;
TUIObjectType _type;
BaseSprite *_image;
void setListener(BaseScriptHolder *object, BaseScriptHolder *listenerObject, uint32 listenerParam);
BaseScriptHolder *_listenerParamObject;
uint32 _listenerParamDWORD;
BaseScriptHolder *_listenerObject;
UIObject *_focusedWidget;
bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
// scripting interface
ScValue *scGetProperty(const char *name) override;
bool scSetProperty(const char *name, ScValue *value) override;
bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
const char *scToString() override;
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,521 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/base/base_dynamic_buffer.h"
#include "engines/wintermute/ui/ui_text.h"
#include "engines/wintermute/ui/ui_tiled_image.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_parser.h"
#include "engines/wintermute/base/scriptables/script_value.h"
#include "engines/wintermute/base/font/base_font.h"
#include "engines/wintermute/base/font/base_font_storage.h"
#include "engines/wintermute/base/base_string_table.h"
#include "engines/wintermute/base/scriptables/script.h"
#include "engines/wintermute/base/scriptables/script_stack.h"
#include "engines/wintermute/base/base_sprite.h"
#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/platform_osystem.h"
#include "engines/wintermute/dcgf.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(UIText, false)
//////////////////////////////////////////////////////////////////////////
UIText::UIText(BaseGame *inGame) : UIObject(inGame) {
_textAlign = TAL_LEFT;
_verticalAlign = VAL_CENTER;
_type = UI_STATIC;
_canFocus = false;
}
//////////////////////////////////////////////////////////////////////////
UIText::~UIText() {
}
//////////////////////////////////////////////////////////////////////////
bool UIText::display(int offsetX, int offsetY) {
if (!_visible) {
return STATUS_OK;
}
BaseFont *font = _font;
if (!font) {
font = _game->_systemFont;
}
if (_back) {
_back->display(offsetX + _posX, offsetY + _posY, _width, _height);
}
if (_image) {
_image->draw(offsetX + _posX, offsetY + _posY, nullptr);
}
if (font && _text && _text[0]) {
int textOffset;
switch (_verticalAlign) {
case VAL_TOP:
textOffset = 0;
break;
case VAL_BOTTOM:
textOffset = _height - font->getTextHeight((byte *)_text, _width);
break;
default:
textOffset = (_height - font->getTextHeight((byte *)_text, _width)) / 2;
}
font->drawText((byte *)_text, offsetX + _posX, offsetY + _posY + textOffset, _width, _textAlign, _height);
}
//_game->_renderer->_rectList.add(new BaseActiveRect(_game, this, nullptr, offsetX + _posX, offsetY + _posY, _width, _height, 100, 100, false));
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool UIText::loadFile(const char *filename) {
char *buffer = (char *) _game->_fileManager->readWholeFile(filename);
if (buffer == nullptr) {
_game->LOG(0, "UIText::loadFile failed for file '%s'", filename);
return STATUS_FAILED;
}
bool ret;
setFilename(filename);
if (DID_FAIL(ret = loadBuffer(buffer, true))) {
_game->LOG(0, "Error parsing STATIC file '%s'", filename);
}
delete[] buffer;
return ret;
}
TOKEN_DEF_START
TOKEN_DEF(STATIC)
TOKEN_DEF(TEMPLATE)
TOKEN_DEF(DISABLED)
TOKEN_DEF(VISIBLE)
TOKEN_DEF(BACK)
TOKEN_DEF(IMAGE)
TOKEN_DEF(FONT)
TOKEN_DEF(TEXT_ALIGN)
TOKEN_DEF(VERTICAL_ALIGN)
TOKEN_DEF(TEXT)
TOKEN_DEF(X)
TOKEN_DEF(Y)
TOKEN_DEF(WIDTH)
TOKEN_DEF(HEIGHT)
TOKEN_DEF(CURSOR)
TOKEN_DEF(NAME)
TOKEN_DEF(SCRIPT)
TOKEN_DEF(CAPTION)
TOKEN_DEF(PARENT_NOTIFY)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
bool UIText::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(STATIC)
TOKEN_TABLE(TEMPLATE)
TOKEN_TABLE(DISABLED)
TOKEN_TABLE(VISIBLE)
TOKEN_TABLE(BACK)
TOKEN_TABLE(IMAGE)
TOKEN_TABLE(FONT)
TOKEN_TABLE(TEXT_ALIGN)
TOKEN_TABLE(VERTICAL_ALIGN)
TOKEN_TABLE(TEXT)
TOKEN_TABLE(X)
TOKEN_TABLE(Y)
TOKEN_TABLE(WIDTH)
TOKEN_TABLE(HEIGHT)
TOKEN_TABLE(CURSOR)
TOKEN_TABLE(NAME)
TOKEN_TABLE(SCRIPT)
TOKEN_TABLE(CAPTION)
TOKEN_TABLE(PARENT_NOTIFY)
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
char *params;
int cmd = 2;
BaseParser parser(_game);
if (complete) {
if (parser.getCommand(&buffer, commands, &params) != TOKEN_STATIC) {
_game->LOG(0, "'STATIC' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
while (cmd > 0 && (cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
setName(params);
break;
case TOKEN_CAPTION:
setCaption(params);
break;
case TOKEN_BACK:
SAFE_DELETE(_back);
_back = new UITiledImage(_game);
if (!_back || DID_FAIL(_back->loadFile(params))) {
SAFE_DELETE(_back);
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_IMAGE:
SAFE_DELETE(_image);
_image = new BaseSprite(_game);
if (!_image || DID_FAIL(_image->loadFile(params))) {
SAFE_DELETE(_image);
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_FONT:
if (_font) {
_game->_fontStorage->removeFont(_font);
}
_font = _game->_fontStorage->addFont(params);
if (!_font) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_TEXT:
setText(params);
_game->_stringTable->expand(&_text);
break;
case TOKEN_TEXT_ALIGN:
if (scumm_stricmp(params, "left") == 0) {
_textAlign = TAL_LEFT;
} else if (scumm_stricmp(params, "right") == 0) {
_textAlign = TAL_RIGHT;
} else {
_textAlign = TAL_CENTER;
}
break;
case TOKEN_VERTICAL_ALIGN:
if (scumm_stricmp(params, "top") == 0) {
_verticalAlign = VAL_TOP;
} else if (scumm_stricmp(params, "bottom") == 0) {
_verticalAlign = VAL_BOTTOM;
} else {
_verticalAlign = VAL_CENTER;
}
break;
case TOKEN_X:
parser.scanStr(params, "%d", &_posX);
break;
case TOKEN_Y:
parser.scanStr(params, "%d", &_posY);
break;
case TOKEN_WIDTH:
parser.scanStr(params, "%d", &_width);
break;
case TOKEN_HEIGHT:
parser.scanStr(params, "%d", &_height);
break;
case TOKEN_CURSOR:
SAFE_DELETE(_cursor);
_cursor = new BaseSprite(_game);
if (!_cursor || DID_FAIL(_cursor->loadFile(params))) {
SAFE_DELETE(_cursor);
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_SCRIPT:
addScript(params);
break;
case TOKEN_PARENT_NOTIFY:
parser.scanStr(params, "%b", &_parentNotify);
break;
case TOKEN_DISABLED:
parser.scanStr(params, "%b", &_disable);
break;
case TOKEN_VISIBLE:
parser.scanStr(params, "%b", &_visible);
break;
case TOKEN_EDITOR_PROPERTY:
parseEditorProperty(params, false);
break;
default:
break;
}
}
if (cmd == PARSERR_TOKENNOTFOUND) {
_game->LOG(0, "Syntax error in STATIC definition");
return STATUS_FAILED;
}
if (cmd == PARSERR_GENERIC) {
_game->LOG(0, "Error loading STATIC definition");
return STATUS_FAILED;
}
correctSize();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool UIText::saveAsText(BaseDynamicBuffer *buffer, int indent) {
buffer->putTextIndent(indent, "STATIC\n");
buffer->putTextIndent(indent, "{\n");
buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", _name);
buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption());
buffer->putTextIndent(indent + 2, "\n");
if (_back && _back->_filename && _back->_filename[0]) {
buffer->putTextIndent(indent + 2, "BACK=\"%s\"\n", _back->_filename);
}
if (_image && _image->_filename && _image->_filename[0]) {
buffer->putTextIndent(indent + 2, "IMAGE=\"%s\"\n", _image->_filename);
}
if (_font && _font->_filename && _font->_filename[0]) {
buffer->putTextIndent(indent + 2, "FONT=\"%s\"\n", _font->_filename);
}
if (_cursor && _cursor->_filename && _cursor->_filename[0]) {
buffer->putTextIndent(indent + 2, "CURSOR=\"%s\"\n", _cursor->_filename);
}
if (_text && _text[0]) {
buffer->putTextIndent(indent + 2, "TEXT=\"%s\"\n", _text);
}
switch (_textAlign) {
case TAL_LEFT:
buffer->putTextIndent(indent + 2, "TEXT_ALIGN=\"%s\"\n", "left");
break;
case TAL_RIGHT:
buffer->putTextIndent(indent + 2, "TEXT_ALIGN=\"%s\"\n", "right");
break;
case TAL_CENTER:
buffer->putTextIndent(indent + 2, "TEXT_ALIGN=\"%s\"\n", "center");
break;
default:
break;
}
switch (_verticalAlign) {
case VAL_TOP:
buffer->putTextIndent(indent + 2, "VERTICAL_ALIGN=\"%s\"\n", "top");
break;
case VAL_BOTTOM:
buffer->putTextIndent(indent + 2, "VERTICAL_ALIGN=\"%s\"\n", "bottom");
break;
case VAL_CENTER:
buffer->putTextIndent(indent + 2, "VERTICAL_ALIGN=\"%s\"\n", "center");
break;
default:
break;
}
buffer->putTextIndent(indent + 2, "\n");
buffer->putTextIndent(indent + 2, "X=%d\n", _posX);
buffer->putTextIndent(indent + 2, "Y=%d\n", _posY);
buffer->putTextIndent(indent + 2, "WIDTH=%d\n", _width);
buffer->putTextIndent(indent + 2, "HEIGHT=%d\n", _height);
buffer->putTextIndent(indent + 2, "DISABLED=%s\n", _disable ? "TRUE" : "FALSE");
buffer->putTextIndent(indent + 2, "VISIBLE=%s\n", _visible ? "TRUE" : "FALSE");
buffer->putTextIndent(indent + 2, "PARENT_NOTIFY=%s\n", _parentNotify ? "TRUE" : "FALSE");
buffer->putTextIndent(indent + 2, "\n");
// scripts
for (int32 i = 0; i < _scripts.getSize(); i++) {
buffer->putTextIndent(indent + 2, "SCRIPT=\"%s\"\n", _scripts[i]->_filename);
}
buffer->putTextIndent(indent + 2, "\n");
// editor properties
BaseClass::saveAsText(buffer, indent + 2);
buffer->putTextIndent(indent, "}\n");
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
bool UIText::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
//////////////////////////////////////////////////////////////////////////
// SizeToFit
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "SizeToFit") == 0) {
stack->correctParams(0);
sizeToFit();
stack->pushNULL();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// HeightToFit
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "HeightToFit") == 0) {
stack->correctParams(0);
if (_font && _text) {
_height = _font->getTextHeight((byte *)_text, _width);
}
stack->pushNULL();
return STATUS_OK;
} else {
return UIObject::scCallMethod(script, stack, thisStack, name);
}
}
//////////////////////////////////////////////////////////////////////////
ScValue *UIText::scGetProperty(const char *name) {
_scValue->setNULL();
//////////////////////////////////////////////////////////////////////////
// Type
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Type") == 0) {
_scValue->setString("static");
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// TextAlign
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "TextAlign") == 0) {
_scValue->setInt(_textAlign);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// VerticalAlign
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "VerticalAlign") == 0) {
_scValue->setInt(_verticalAlign);
return _scValue;
} else {
return UIObject::scGetProperty(name);
}
}
//////////////////////////////////////////////////////////////////////////
bool UIText::scSetProperty(const char *name, ScValue *value) {
//////////////////////////////////////////////////////////////////////////
// TextAlign
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "TextAlign") == 0) {
int i = value->getInt();
if (i < 0 || i >= NUM_TEXT_ALIGN) {
i = 0;
}
_textAlign = (TTextAlign)i;
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// VerticalAlign
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "VerticalAlign") == 0) {
int i = value->getInt();
if (i < 0 || i >= NUM_VERTICAL_ALIGN) {
i = 0;
}
_verticalAlign = (TVerticalAlign)i;
return STATUS_OK;
} else {
return UIObject::scSetProperty(name, value);
}
}
//////////////////////////////////////////////////////////////////////////
const char *UIText::scToString() {
return "[static]";
}
//////////////////////////////////////////////////////////////////////////
bool UIText::persist(BasePersistenceManager *persistMgr) {
UIObject::persist(persistMgr);
persistMgr->transferSint32(TMEMBER_INT(_textAlign));
persistMgr->transferSint32(TMEMBER_INT(_verticalAlign));
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool UIText::sizeToFit() {
if (_font && _text && _text[0]) {
_width = _font->getTextWidth((byte *)_text);
_height = _font->getTextHeight((byte *)_text, _width);
}
return STATUS_OK;
}
} // End of namespace Wintermute

View File

@@ -0,0 +1,58 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_UITEXT_H
#define WINTERMUTE_UITEXT_H
#include "engines/wintermute/ui/ui_object.h"
namespace Wintermute {
class UIText : public UIObject {
public:
bool sizeToFit();
bool display(int offsetX, int offsetY) override;
DECLARE_PERSISTENT(UIText, UIObject)
UIText(BaseGame *inGame = nullptr);
~UIText() override;
TTextAlign _textAlign;
TVerticalAlign _verticalAlign;
bool loadFile(const char *filename);
bool loadBuffer(char *buffer, bool complete = true);
bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
// scripting interface
ScValue *scGetProperty(const char *name) override;
bool scSetProperty(const char *name, ScValue *value) override;
bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
const char *scToString() override;
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,387 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/ui/ui_tiled_image.h"
#include "engines/wintermute/base/gfx/base_surface.h"
#include "engines/wintermute/base/base_dynamic_buffer.h"
#include "engines/wintermute/base/base_parser.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_sub_frame.h"
#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/base/gfx/base_renderer.h"
#include "engines/wintermute/platform_osystem.h"
#include "engines/wintermute/dcgf.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(UITiledImage, false)
//////////////////////////////////////////////////////////////////////////
UITiledImage::UITiledImage(BaseGame *inGame) : BaseObject(inGame) {
_image = nullptr;
BasePlatform::setRectEmpty(&_upLeft);
BasePlatform::setRectEmpty(&_upMiddle);
BasePlatform::setRectEmpty(&_upRight);
BasePlatform::setRectEmpty(&_middleLeft);
BasePlatform::setRectEmpty(&_middleMiddle);
BasePlatform::setRectEmpty(&_middleRight);
BasePlatform::setRectEmpty(&_downLeft);
BasePlatform::setRectEmpty(&_downMiddle);
BasePlatform::setRectEmpty(&_downRight);
}
//////////////////////////////////////////////////////////////////////////
UITiledImage::~UITiledImage() {
SAFE_DELETE(_image);
}
//////////////////////////////////////////////////////////////////////////
bool UITiledImage::display(int x, int y, int width, int height) {
if (!_image) {
return STATUS_FAILED;
}
int tileWidth = _middleMiddle.right - _middleMiddle.left;
int tileHeight = _middleMiddle.bottom - _middleMiddle.top;
int numColumns = (width - (_middleLeft.right - _middleLeft.left) - (_middleRight.right - _middleRight.left)) / tileWidth;
int numRows = (height - (_upMiddle.bottom - _upMiddle.top) - (_downMiddle.bottom - _downMiddle.top)) / tileHeight;
_game->_renderer->startSpriteBatch();
// top left/right
_image->_surface->displayTrans(x, y, _upLeft);
_image->_surface->displayTrans(x + (_upLeft.right - _upLeft.left) + numColumns * tileWidth, y, _upRight);
// bottom left/right
_image->_surface->displayTrans(x, y + (_upMiddle.bottom - _upMiddle.top) + numRows * tileHeight, _downLeft);
_image->_surface->displayTrans(x + (_upLeft.right - _upLeft.left) + numColumns * tileWidth, y + (_upMiddle.bottom - _upMiddle.top) + numRows * tileHeight, _downRight);
// left/right
if (numRows > 0) {
int yyy = y + (_upMiddle.bottom - _upMiddle.top);
_image->_surface->displayTiled(x, yyy, _middleLeft, 1, numRows);
_image->_surface->displayTiled(x + (_middleLeft.right - _middleLeft.left) + numColumns * tileWidth, yyy, _middleRight, 1, numRows);
}
// top/bottom
if (numColumns > 0) {
int xxx = x + (_upLeft.right - _upLeft.left);
_image->_surface->displayTiled(xxx, y, _upMiddle, numColumns, 1);
_image->_surface->displayTiled(xxx, y + (_upMiddle.bottom - _upMiddle.top) + numRows * tileHeight, _downMiddle, numColumns, 1);
}
// tiles
if (numRows > 0 && numColumns > 0) {
int yyy = y + (_upMiddle.bottom - _upMiddle.top);
int xxx = x + (_upLeft.right - _upLeft.left);
_image->_surface->displayTiled(xxx, yyy, _middleMiddle, numColumns, numRows);
}
_game->_renderer->endSpriteBatch();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool UITiledImage::loadFile(const char *filename) {
char *buffer = (char *)_game->_fileManager->readWholeFile(filename);
if (buffer == nullptr) {
_game->LOG(0, "UITiledImage::loadFile failed for file '%s'", filename);
return STATUS_FAILED;
}
bool ret;
setFilename(filename);
if (DID_FAIL(ret = loadBuffer(buffer, true))) {
_game->LOG(0, "Error parsing TILED_IMAGE file '%s'", filename);
}
delete[] buffer;
return ret;
}
TOKEN_DEF_START
TOKEN_DEF(TILED_IMAGE)
TOKEN_DEF(TEMPLATE)
TOKEN_DEF(IMAGE)
TOKEN_DEF(UP_LEFT)
TOKEN_DEF(UP_RIGHT)
TOKEN_DEF(UP_MIDDLE)
TOKEN_DEF(DOWN_LEFT)
TOKEN_DEF(DOWN_RIGHT)
TOKEN_DEF(DOWN_MIDDLE)
TOKEN_DEF(MIDDLE_LEFT)
TOKEN_DEF(MIDDLE_RIGHT)
TOKEN_DEF(MIDDLE_MIDDLE)
TOKEN_DEF(VERTICAL_TILES)
TOKEN_DEF(HORIZONTAL_TILES)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
bool UITiledImage::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(TILED_IMAGE)
TOKEN_TABLE(TEMPLATE)
TOKEN_TABLE(IMAGE)
TOKEN_TABLE(UP_LEFT)
TOKEN_TABLE(UP_RIGHT)
TOKEN_TABLE(UP_MIDDLE)
TOKEN_TABLE(DOWN_LEFT)
TOKEN_TABLE(DOWN_RIGHT)
TOKEN_TABLE(DOWN_MIDDLE)
TOKEN_TABLE(MIDDLE_LEFT)
TOKEN_TABLE(MIDDLE_RIGHT)
TOKEN_TABLE(MIDDLE_MIDDLE)
TOKEN_TABLE(VERTICAL_TILES)
TOKEN_TABLE(HORIZONTAL_TILES)
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
char *params;
int cmd;
BaseParser parser(_game);
bool hTiles = false, vTiles = false;
int h1 = 0, h2 = 0, h3 = 0;
int v1 = 0, v2 = 0, v3 = 0;
if (complete) {
if (parser.getCommand(&buffer, commands, &params) != TOKEN_TILED_IMAGE) {
_game->LOG(0, "'TILED_IMAGE' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_IMAGE:
SAFE_DELETE(_image);
_image = new BaseSubFrame(_game);
if (!_image || DID_FAIL(_image->setSurface(params))) {
SAFE_DELETE(_image);
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_UP_LEFT:
parser.scanStr(params, "%d,%d,%d,%d", &_upLeft.left, &_upLeft.top, &_upLeft.right, &_upLeft.bottom);
break;
case TOKEN_UP_RIGHT:
parser.scanStr(params, "%d,%d,%d,%d", &_upRight.left, &_upRight.top, &_upRight.right, &_upRight.bottom);
break;
case TOKEN_UP_MIDDLE:
parser.scanStr(params, "%d,%d,%d,%d", &_upMiddle.left, &_upMiddle.top, &_upMiddle.right, &_upMiddle.bottom);
break;
case TOKEN_DOWN_LEFT:
parser.scanStr(params, "%d,%d,%d,%d", &_downLeft.left, &_downLeft.top, &_downLeft.right, &_downLeft.bottom);
break;
case TOKEN_DOWN_RIGHT:
parser.scanStr(params, "%d,%d,%d,%d", &_downRight.left, &_downRight.top, &_downRight.right, &_downRight.bottom);
break;
case TOKEN_DOWN_MIDDLE:
parser.scanStr(params, "%d,%d,%d,%d", &_downMiddle.left, &_downMiddle.top, &_downMiddle.right, &_downMiddle.bottom);
break;
case TOKEN_MIDDLE_LEFT:
parser.scanStr(params, "%d,%d,%d,%d", &_middleLeft.left, &_middleLeft.top, &_middleLeft.right, &_middleLeft.bottom);
break;
case TOKEN_MIDDLE_RIGHT:
parser.scanStr(params, "%d,%d,%d,%d", &_middleRight.left, &_middleRight.top, &_middleRight.right, &_middleRight.bottom);
break;
case TOKEN_MIDDLE_MIDDLE:
parser.scanStr(params, "%d,%d,%d,%d", &_middleMiddle.left, &_middleMiddle.top, &_middleMiddle.right, &_middleMiddle.bottom);
break;
case TOKEN_HORIZONTAL_TILES:
parser.scanStr(params, "%d,%d,%d", &h1, &h2, &h3);
hTiles = true;
break;
case TOKEN_VERTICAL_TILES:
parser.scanStr(params, "%d,%d,%d", &v1, &v2, &v3);
vTiles = true;
break;
case TOKEN_EDITOR_PROPERTY:
parseEditorProperty(params, false);
break;
default:
break;
}
}
if (cmd == PARSERR_TOKENNOTFOUND) {
_game->LOG(0, "Syntax error in TILED_IMAGE definition");
return STATUS_FAILED;
}
if (cmd == PARSERR_GENERIC) {
_game->LOG(0, "Error loading TILED_IMAGE definition");
return STATUS_FAILED;
}
if (vTiles && hTiles) {
// up row
BasePlatform::setRect(&_upLeft, 0, 0, h1, v1);
BasePlatform::setRect(&_upMiddle, h1, 0, h1 + h2, v1);
BasePlatform::setRect(&_upRight, h1 + h2, 0, h1 + h2 + h3, v1);
// middle row
BasePlatform::setRect(&_middleLeft, 0, v1, h1, v1 + v2);
BasePlatform::setRect(&_middleMiddle, h1, v1, h1 + h2, v1 + v2);
BasePlatform::setRect(&_middleRight, h1 + h2, v1, h1 + h2 + h3, v1 + v2);
// down row
BasePlatform::setRect(&_downLeft, 0, v1 + v2, h1, v1 + v2 + v3);
BasePlatform::setRect(&_downMiddle, h1, v1 + v2, h1 + h2, v1 + v2 + v3);
BasePlatform::setRect(&_downRight, h1 + h2, v1 + v2, h1 + h2 + h3, v1 + v2 + v3);
}
// default
if (_image && _image->_surface) {
int width = _image->_surface->getWidth() / 3;
int height = _image->_surface->getHeight() / 3;
if (BasePlatform::isRectEmpty(&_upLeft)) {
BasePlatform::setRect(&_upLeft, 0, 0, width, height);
}
if (BasePlatform::isRectEmpty(&_upMiddle)) {
BasePlatform::setRect(&_upMiddle, width, 0, 2 * width, height);
}
if (BasePlatform::isRectEmpty(&_upRight)) {
BasePlatform::setRect(&_upRight, 2 * width, 0, 3 * width, height);
}
if (BasePlatform::isRectEmpty(&_middleLeft)) {
BasePlatform::setRect(&_middleLeft, 0, height, width, 2 * height);
}
if (BasePlatform::isRectEmpty(&_middleMiddle)) {
BasePlatform::setRect(&_middleMiddle, width, height, 2 * width, 2 * height);
}
if (BasePlatform::isRectEmpty(&_middleRight)) {
BasePlatform::setRect(&_middleRight, 2 * width, height, 3 * width, 2 * height);
}
if (BasePlatform::isRectEmpty(&_downLeft)) {
BasePlatform::setRect(&_downLeft, 0, 2 * height, width, 3 * height);
}
if (BasePlatform::isRectEmpty(&_downMiddle)) {
BasePlatform::setRect(&_downMiddle, width, 2 * height, 2 * width, 3 * height);
}
if (BasePlatform::isRectEmpty(&_downRight)) {
BasePlatform::setRect(&_downRight, 2 * width, 2 * height, 3 * width, 3 * height);
}
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool UITiledImage::saveAsText(BaseDynamicBuffer *buffer, int indent) {
buffer->putTextIndent(indent, "TILED_IMAGE\n");
buffer->putTextIndent(indent, "{\n");
if (_image && _image->_surfaceFilename && _image->_surfaceFilename[0]) {
buffer->putTextIndent(indent + 2, "IMAGE=\"%s\"\n", _image->_surfaceFilename);
}
int h1, h2, h3;
int v1, v2, v3;
h1 = _upLeft.right;
h2 = _upMiddle.right - _upMiddle.left;
h3 = _upRight.right - _upRight.left;
v1 = _upLeft.bottom;
v2 = _middleLeft.bottom - _middleLeft.top;
v3 = _downLeft.bottom - _downLeft.top;
buffer->putTextIndent(indent + 2, "VERTICAL_TILES { %d, %d, %d }\n", v1, v2, v3);
buffer->putTextIndent(indent + 2, "HORIZONTAL_TILES { %d, %d, %d }\n", h1, h2, h3);
// editor properties
BaseClass::saveAsText(buffer, indent + 2);
buffer->putTextIndent(indent, "}\n");
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
void UITiledImage::correctSize(int32 *width, int32 *height) {
int tileWidth = _middleMiddle.right - _middleMiddle.left;
int tileHeight = _middleMiddle.bottom - _middleMiddle.top;
int numColumns = (*width - (_middleLeft.right - _middleLeft.left) - (_middleRight.right - _middleRight.left)) / tileWidth;
int numRows = (*height - (_upMiddle.bottom - _upMiddle.top) - (_downMiddle.bottom - _downMiddle.top)) / tileHeight;
*width = (_middleLeft.right - _middleLeft.left) + (_middleRight.right - _middleRight.left) + numColumns * tileWidth;
*height = (_upMiddle.bottom - _upMiddle.top) + (_downMiddle.bottom - _downMiddle.top) + numRows * tileHeight;
}
//////////////////////////////////////////////////////////////////////////
bool UITiledImage::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
persistMgr->transferRect32(TMEMBER(_downLeft));
persistMgr->transferRect32(TMEMBER(_downMiddle));
persistMgr->transferRect32(TMEMBER(_downRight));
persistMgr->transferPtr(TMEMBER_PTR(_image));
persistMgr->transferRect32(TMEMBER(_middleLeft));
persistMgr->transferRect32(TMEMBER(_middleMiddle));
persistMgr->transferRect32(TMEMBER(_middleRight));
persistMgr->transferRect32(TMEMBER(_upLeft));
persistMgr->transferRect32(TMEMBER(_upMiddle));
persistMgr->transferRect32(TMEMBER(_upRight));
return STATUS_OK;
}
} // End of namespace Wintermute

View File

@@ -0,0 +1,64 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_UITILEDIMAGE_H
#define WINTERMUTE_UITILEDIMAGE_H
#include "engines/wintermute/ui/ui_object.h"
#include "common/rect.h"
namespace Wintermute {
class BaseSubFrame;
class UITiledImage : public BaseObject {
using Wintermute::BaseObject::display;
public:
DECLARE_PERSISTENT(UITiledImage, BaseObject)
void correctSize(int32 *width, int32 *height);
bool loadFile(const char *filename);
bool loadBuffer(char *buffer, bool complete = true);
bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
bool display(int x, int y, int width, int height);
UITiledImage(BaseGame *inGame = nullptr);
~UITiledImage() override;
BaseSubFrame *_image;
Common::Rect32 _upLeft;
Common::Rect32 _upMiddle;
Common::Rect32 _upRight;
Common::Rect32 _middleLeft;
Common::Rect32 _middleMiddle;
Common::Rect32 _middleRight;
Common::Rect32 _downLeft;
Common::Rect32 _downMiddle;
Common::Rect32 _downRight;
};
} // End of namespace Wintermute
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,94 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_UIWINDOW_H
#define WINTERMUTE_UIWINDOW_H
#include "engines/wintermute/ui/ui_object.h"
#include "common/events.h"
namespace Wintermute {
class UIButton;
class BaseViewport;
class UIWindow : public UIObject {
public:
BaseObject *getPrevAccessObject(BaseObject *currObject);
BaseObject *getNextAccessObject(BaseObject *currObject);
bool getWindowObjects(BaseArray<UIObject *> &objects, bool interactiveOnly);
bool _pauseMusic;
void cleanup();
void makeFreezable(bool freezable) override;
BaseViewport *_viewport;
bool _clipContents;
bool _inGame;
bool _isMenu;
bool _fadeBackground;
uint32 _fadeColor;
bool handleMouseWheel(int32 delta) override;
UIWindow *_shieldWindow;
UIButton *_shieldButton;
bool close();
bool goSystemExclusive();
bool goExclusive();
TWindowMode _mode;
bool moveFocus(bool forward = true);
bool handleMouse(TMouseEvent event, TMouseButton button) override;
Common::Point32 _dragFrom;
bool _dragging;
DECLARE_PERSISTENT(UIWindow, UIObject)
bool _transparent;
bool showWidget(const char *name, bool visible = true);
bool enableWidget(const char *name, bool enable = true);
Common::Rect32 _titleRect;
Common::Rect32 _dragRect;
bool display(int offsetX = 0, int offsetY = 0) override;
UIWindow(BaseGame *inGame);
~UIWindow() override;
bool handleKeypress(Common::Event *event, bool printable = false) override;
BaseArray<UIObject *> _widgets;
TTextAlign _titleAlign;
bool loadFile(const char *filename);
bool loadBuffer(char *buffer, bool complete = true);
UITiledImage *_backInactive;
BaseFont *_fontInactive;
BaseSprite *_imageInactive;
bool listen(BaseScriptHolder *param1, uint32 param2) override;
bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
// scripting interface
ScValue *scGetProperty(const char *name) override;
bool scSetProperty(const char *name, ScValue *value) override;
bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
const char *scToString() override;
};
} // End of namespace Wintermute
#endif