From b4090ead4d4334e08725323ff72fd355c93b63d5 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Tue, 4 Sep 2012 22:17:23 +0200 Subject: WINTERMUTE: Convert CRLF to LF --- engines/wintermute/ui/ui_button.cpp | 2416 ++++++++++++------------- engines/wintermute/ui/ui_button.h | 160 +- engines/wintermute/ui/ui_edit.cpp | 1902 ++++++++++---------- engines/wintermute/ui/ui_edit.h | 144 +- engines/wintermute/ui/ui_entity.cpp | 732 ++++---- engines/wintermute/ui/ui_entity.h | 118 +- engines/wintermute/ui/ui_object.cpp | 1300 +++++++------- engines/wintermute/ui/ui_object.h | 170 +- engines/wintermute/ui/ui_text.cpp | 1044 +++++------ engines/wintermute/ui/ui_text.h | 120 +- engines/wintermute/ui/ui_tiled_image.cpp | 786 ++++---- engines/wintermute/ui/ui_tiled_image.h | 126 +- engines/wintermute/ui/ui_window.cpp | 2888 +++++++++++++++--------------- engines/wintermute/ui/ui_window.h | 188 +- 14 files changed, 6047 insertions(+), 6047 deletions(-) (limited to 'engines/wintermute/ui') diff --git a/engines/wintermute/ui/ui_button.cpp b/engines/wintermute/ui/ui_button.cpp index c5ca63081c..f2ac5b2fdd 100644 --- a/engines/wintermute/ui/ui_button.cpp +++ b/engines/wintermute/ui/ui_button.cpp @@ -1,1208 +1,1208 @@ -/* 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 2 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -/* - * 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/base/base_game.h" -#include "engines/wintermute/ui/ui_button.h" -#include "engines/wintermute/ui/ui_tiled_image.h" -#include "engines/wintermute/base/base_parser.h" -#include "engines/wintermute/base/base_active_rect.h" -#include "engines/wintermute/base/font/base_font_storage.h" -#include "engines/wintermute/base/font/base_font.h" -#include "engines/wintermute/base/base_string_table.h" -#include "engines/wintermute/base/base_sprite.h" -#include "engines/wintermute/base/base_file_manager.h" -#include "engines/wintermute/base/scriptables/script_value.h" -#include "engines/wintermute/base/scriptables/script.h" -#include "engines/wintermute/base/scriptables/script_stack.h" - -namespace Wintermute { - -IMPLEMENT_PERSISTENT(UIButton, false) - -////////////////////////////////////////////////////////////////////////// -UIButton::UIButton(BaseGame *inGame) : UIObject(inGame) { - _backPress = _backHover = _backDisable = _backFocus = NULL; - - _fontHover = _fontPress = _fontDisable = _fontFocus = NULL; - - _imageDisable = _imagePress = _imageHover = _imageFocus = NULL; - - _align = TAL_CENTER; - - _hover = _press = false; - - _type = UI_BUTTON; - - _canFocus = false; - _stayPressed = false; - - _oneTimePress = false; - _centerImage = false; - - _pixelPerfect = false; -} - - -////////////////////////////////////////////////////////////////////////// -UIButton::~UIButton() { - delete _backPress; - delete _backHover; - delete _backDisable; - delete _backFocus; - - if (!_sharedFonts) { - if (_fontHover) { - _gameRef->_fontStorage->removeFont(_fontHover); - } - if (_fontPress) { - _gameRef->_fontStorage->removeFont(_fontPress); - } - if (_fontDisable) { - _gameRef->_fontStorage->removeFont(_fontDisable); - } - if (_fontFocus) { - _gameRef->_fontStorage->removeFont(_fontFocus); - } - } - - if (!_sharedImages) { - delete _imageHover; - delete _imagePress; - delete _imageDisable; - delete _imageFocus; - } -} - - -////////////////////////////////////////////////////////////////////////// -bool UIButton::loadFile(const char *filename) { - byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename); - if (buffer == NULL) { - _gameRef->LOG(0, "UIButton::LoadFile failed for file '%s'", filename); - return STATUS_FAILED; - } - - bool ret; - - setFilename(filename); - - if (DID_FAIL(ret = loadBuffer(buffer, true))) { - _gameRef->LOG(0, "Error parsing BUTTON file '%s'", filename); - } - - delete[] buffer; - - return ret; -} - - -TOKEN_DEF_START -TOKEN_DEF(BUTTON) -TOKEN_DEF(TEMPLATE) -TOKEN_DEF(DISABLED) -TOKEN_DEF(VISIBLE) -TOKEN_DEF(FOCUSABLE) -TOKEN_DEF(BACK_HOVER) -TOKEN_DEF(BACK_PRESS) -TOKEN_DEF(BACK_DISABLE) -TOKEN_DEF(BACK_FOCUS) -TOKEN_DEF(BACK) -TOKEN_DEF(CENTER_IMAGE) -TOKEN_DEF(IMAGE_HOVER) -TOKEN_DEF(IMAGE_PRESS) -TOKEN_DEF(IMAGE_DISABLE) -TOKEN_DEF(IMAGE_FOCUS) -TOKEN_DEF(IMAGE) -TOKEN_DEF(FONT_HOVER) -TOKEN_DEF(FONT_PRESS) -TOKEN_DEF(FONT_DISABLE) -TOKEN_DEF(FONT_FOCUS) -TOKEN_DEF(FONT) -TOKEN_DEF(TEXT_ALIGN) -TOKEN_DEF(TEXT) -TOKEN_DEF(X) -TOKEN_DEF(Y) -TOKEN_DEF(WIDTH) -TOKEN_DEF(HEIGHT) -TOKEN_DEF(CURSOR) -TOKEN_DEF(NAME) -TOKEN_DEF(EVENTS) -TOKEN_DEF(SCRIPT) -TOKEN_DEF(CAPTION) -TOKEN_DEF(PARENT_NOTIFY) -TOKEN_DEF(PRESSED) -TOKEN_DEF(PIXEL_PERFECT) -TOKEN_DEF(EDITOR_PROPERTY) -TOKEN_DEF_END -////////////////////////////////////////////////////////////////////////// -bool UIButton::loadBuffer(byte *buffer, bool complete) { - TOKEN_TABLE_START(commands) - TOKEN_TABLE(BUTTON) - TOKEN_TABLE(TEMPLATE) - TOKEN_TABLE(DISABLED) - TOKEN_TABLE(VISIBLE) - TOKEN_TABLE(FOCUSABLE) - TOKEN_TABLE(BACK_HOVER) - TOKEN_TABLE(BACK_PRESS) - TOKEN_TABLE(BACK_DISABLE) - TOKEN_TABLE(BACK_FOCUS) - TOKEN_TABLE(BACK) - TOKEN_TABLE(CENTER_IMAGE) - TOKEN_TABLE(IMAGE_HOVER) - TOKEN_TABLE(IMAGE_PRESS) - TOKEN_TABLE(IMAGE_DISABLE) - TOKEN_TABLE(IMAGE_FOCUS) - TOKEN_TABLE(IMAGE) - TOKEN_TABLE(FONT_HOVER) - TOKEN_TABLE(FONT_PRESS) - TOKEN_TABLE(FONT_DISABLE) - TOKEN_TABLE(FONT_FOCUS) - TOKEN_TABLE(FONT) - TOKEN_TABLE(TEXT_ALIGN) - TOKEN_TABLE(TEXT) - TOKEN_TABLE(X) - TOKEN_TABLE(Y) - TOKEN_TABLE(WIDTH) - TOKEN_TABLE(HEIGHT) - TOKEN_TABLE(CURSOR) - TOKEN_TABLE(NAME) - TOKEN_TABLE(EVENTS) - TOKEN_TABLE(SCRIPT) - TOKEN_TABLE(CAPTION) - TOKEN_TABLE(PARENT_NOTIFY) - TOKEN_TABLE(PRESSED) - TOKEN_TABLE(PIXEL_PERFECT) - TOKEN_TABLE(EDITOR_PROPERTY) - TOKEN_TABLE_END - - byte *params; - int cmd = 2; - BaseParser parser; - - if (complete) { - if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_BUTTON) { - _gameRef->LOG(0, "'BUTTON' keyword expected."); - return STATUS_FAILED; - } - buffer = params; - } - - while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { - switch (cmd) { - case TOKEN_TEMPLATE: - if (DID_FAIL(loadFile((char *)params))) { - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_NAME: - setName((char *)params); - break; - - case TOKEN_CAPTION: - setCaption((char *)params); - break; - - case TOKEN_BACK: - delete _back; - _back = new UITiledImage(_gameRef); - if (!_back || DID_FAIL(_back->loadFile((char *)params))) { - delete _back; - _back = NULL; - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_BACK_HOVER: - delete _backHover; - _backHover = new UITiledImage(_gameRef); - if (!_backHover || DID_FAIL(_backHover->loadFile((char *)params))) { - delete _backHover; - _backHover = NULL; - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_BACK_PRESS: - delete _backPress; - _backPress = new UITiledImage(_gameRef); - if (!_backPress || DID_FAIL(_backPress->loadFile((char *)params))) { - delete _backPress; - _backPress = NULL; - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_BACK_DISABLE: - delete _backDisable; - _backDisable = new UITiledImage(_gameRef); - if (!_backDisable || DID_FAIL(_backDisable->loadFile((char *)params))) { - delete _backDisable; - _backDisable = NULL; - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_BACK_FOCUS: - delete _backFocus; - _backFocus = new UITiledImage(_gameRef); - if (!_backFocus || DID_FAIL(_backFocus->loadFile((char *)params))) { - delete _backFocus; - _backFocus = NULL; - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_IMAGE: - delete _image; - _image = new BaseSprite(_gameRef); - if (!_image || DID_FAIL(_image->loadFile((char *)params))) { - delete _image; - _image = NULL; - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_IMAGE_HOVER: - delete _imageHover; - _imageHover = new BaseSprite(_gameRef); - if (!_imageHover || DID_FAIL(_imageHover->loadFile((char *)params))) { - delete _imageHover; - _imageHover = NULL; - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_IMAGE_PRESS: - delete _imagePress; - _imagePress = new BaseSprite(_gameRef); - if (!_imagePress || DID_FAIL(_imagePress->loadFile((char *)params))) { - delete _imagePress; - _imagePress = NULL; - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_IMAGE_DISABLE: - delete _imageDisable; - _imageDisable = new BaseSprite(_gameRef); - if (!_imageDisable || DID_FAIL(_imageDisable->loadFile((char *)params))) { - delete _imageDisable; - _imageDisable = NULL; - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_IMAGE_FOCUS: - delete _imageFocus; - _imageFocus = new BaseSprite(_gameRef); - if (!_imageFocus || DID_FAIL(_imageFocus->loadFile((char *)params))) { - delete _imageFocus; - _imageFocus = NULL; - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_FONT: - if (_font) { - _gameRef->_fontStorage->removeFont(_font); - } - _font = _gameRef->_fontStorage->addFont((char *)params); - if (!_font) { - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_FONT_HOVER: - if (_fontHover) { - _gameRef->_fontStorage->removeFont(_fontHover); - } - _fontHover = _gameRef->_fontStorage->addFont((char *)params); - if (!_fontHover) { - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_FONT_PRESS: - if (_fontPress) { - _gameRef->_fontStorage->removeFont(_fontPress); - } - _fontPress = _gameRef->_fontStorage->addFont((char *)params); - if (!_fontPress) { - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_FONT_DISABLE: - if (_fontDisable) { - _gameRef->_fontStorage->removeFont(_fontDisable); - } - _fontDisable = _gameRef->_fontStorage->addFont((char *)params); - if (!_fontDisable) { - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_FONT_FOCUS: - if (_fontFocus) { - _gameRef->_fontStorage->removeFont(_fontFocus); - } - _fontFocus = _gameRef->_fontStorage->addFont((char *)params); - if (!_fontFocus) { - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_TEXT: - setText((char *)params); - _gameRef->_stringTable->expand(&_text); - break; - - case TOKEN_TEXT_ALIGN: - if (scumm_stricmp((char *)params, "left") == 0) { - _align = TAL_LEFT; - } else if (scumm_stricmp((char *)params, "right") == 0) { - _align = TAL_RIGHT; - } else { - _align = TAL_CENTER; - } - break; - - case TOKEN_X: - parser.scanStr((char *)params, "%d", &_posX); - break; - - case TOKEN_Y: - parser.scanStr((char *)params, "%d", &_posY); - break; - - case TOKEN_WIDTH: - parser.scanStr((char *)params, "%d", &_width); - break; - - case TOKEN_HEIGHT: - parser.scanStr((char *)params, "%d", &_height); - break; - - case TOKEN_CURSOR: - delete _cursor; - _cursor = new BaseSprite(_gameRef); - if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) { - delete _cursor; - _cursor = NULL; - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_SCRIPT: - addScript((char *)params); - break; - - case TOKEN_PARENT_NOTIFY: - parser.scanStr((char *)params, "%b", &_parentNotify); - break; - - case TOKEN_DISABLED: - parser.scanStr((char *)params, "%b", &_disable); - break; - - case TOKEN_VISIBLE: - parser.scanStr((char *)params, "%b", &_visible); - break; - - case TOKEN_FOCUSABLE: - parser.scanStr((char *)params, "%b", &_canFocus); - break; - - case TOKEN_CENTER_IMAGE: - parser.scanStr((char *)params, "%b", &_centerImage); - break; - - case TOKEN_PRESSED: - parser.scanStr((char *)params, "%b", &_stayPressed); - break; - - case TOKEN_PIXEL_PERFECT: - parser.scanStr((char *)params, "%b", &_pixelPerfect); - break; - - case TOKEN_EDITOR_PROPERTY: - parseEditorProperty(params, false); - break; - } - } - if (cmd == PARSERR_TOKENNOTFOUND) { - _gameRef->LOG(0, "Syntax error in BUTTON definition"); - return STATUS_FAILED; - } - if (cmd == PARSERR_GENERIC) { - _gameRef->LOG(0, "Error loading BUTTON definition"); - return STATUS_FAILED; - } - - correctSize(); - - return STATUS_OK; -} - -////////////////////////////////////////////////////////////////////////// -bool UIButton::saveAsText(BaseDynamicBuffer *buffer, int indent) { - buffer->putTextIndent(indent, "BUTTON\n"); - buffer->putTextIndent(indent, "{\n"); - - buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", getName()); - buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption()); - - buffer->putTextIndent(indent + 2, "\n"); - - if (_back && _back->getFilename()) { - buffer->putTextIndent(indent + 2, "BACK=\"%s\"\n", _back->getFilename()); - } - if (_backHover && _backHover->getFilename()) { - buffer->putTextIndent(indent + 2, "BACK_HOVER=\"%s\"\n", _backHover->getFilename()); - } - if (_backPress && _backPress->getFilename()) { - buffer->putTextIndent(indent + 2, "BACK_PRESS=\"%s\"\n", _backPress->getFilename()); - } - if (_backDisable && _backDisable->getFilename()) { - buffer->putTextIndent(indent + 2, "BACK_DISABLE=\"%s\"\n", _backDisable->getFilename()); - } - if (_backFocus && _backFocus->getFilename()) { - buffer->putTextIndent(indent + 2, "BACK_FOCUS=\"%s\"\n", _backFocus->getFilename()); - } - - if (_image && _image->getFilename()) { - buffer->putTextIndent(indent + 2, "IMAGE=\"%s\"\n", _image->getFilename()); - } - if (_imageHover && _imageHover->getFilename()) { - buffer->putTextIndent(indent + 2, "IMAGE_HOVER=\"%s\"\n", _imageHover->getFilename()); - } - if (_imagePress && _imagePress->getFilename()) { - buffer->putTextIndent(indent + 2, "IMAGE_PRESS=\"%s\"\n", _imagePress->getFilename()); - } - if (_imageDisable && _imageDisable->getFilename()) { - buffer->putTextIndent(indent + 2, "IMAGE_DISABLE=\"%s\"\n", _imageDisable->getFilename()); - } - if (_imageFocus && _imageFocus->getFilename()) { - buffer->putTextIndent(indent + 2, "IMAGE_FOCUS=\"%s\"\n", _imageFocus->getFilename()); - } - - if (_font && _font->getFilename()) { - buffer->putTextIndent(indent + 2, "FONT=\"%s\"\n", _font->getFilename()); - } - if (_fontHover && _fontHover->getFilename()) { - buffer->putTextIndent(indent + 2, "FONT_HOVER=\"%s\"\n", _fontHover->getFilename()); - } - if (_fontPress && _fontPress->getFilename()) { - buffer->putTextIndent(indent + 2, "FONT_PRESS=\"%s\"\n", _fontPress->getFilename()); - } - if (_fontDisable && _fontDisable->getFilename()) { - buffer->putTextIndent(indent + 2, "FONT_DISABLE=\"%s\"\n", _fontDisable->getFilename()); - } - if (_fontFocus && _fontFocus->getFilename()) { - buffer->putTextIndent(indent + 2, "FONT_FOCUS=\"%s\"\n", _fontFocus->getFilename()); - } - - if (_cursor && _cursor->getFilename()) { - buffer->putTextIndent(indent + 2, "CURSOR=\"%s\"\n", _cursor->getFilename()); - } - - - buffer->putTextIndent(indent + 2, "\n"); - - if (_text) { - buffer->putTextIndent(indent + 2, "TEXT=\"%s\"\n", _text); - } - - switch (_align) { - 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: - warning("UIButton::SaveAsText - unhandled enum"); - 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, "FOCUSABLE=%s\n", _canFocus ? "TRUE" : "FALSE"); - buffer->putTextIndent(indent + 2, "CENTER_IMAGE=%s\n", _centerImage ? "TRUE" : "FALSE"); - buffer->putTextIndent(indent + 2, "PRESSED=%s\n", _stayPressed ? "TRUE" : "FALSE"); - buffer->putTextIndent(indent + 2, "PIXEL_PERFECT=%s\n", _pixelPerfect ? "TRUE" : "FALSE"); - - buffer->putTextIndent(indent + 2, "\n"); - - // scripts - for (uint32 i = 0; i < _scripts.size(); 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; -} - -////////////////////////////////////////////////////////////////////////// -void UIButton::correctSize() { - Rect32 rect; - - BaseSprite *img = NULL; - if (_image) { - img = _image; - } else if (_imageDisable) { - img = _imageDisable; - } else if (_imageHover) { - img = _imageHover; - } else if (_imagePress) { - img = _imagePress; - } else if (_imageFocus) { - img = _imageFocus; - } - - if (_width <= 0) { - if (img) { - img->getBoundingRect(&rect, 0, 0); - _width = rect.right - rect.left; - } else { - _width = 100; - } - } - - if (_height <= 0) { - if (img) { - img->getBoundingRect(&rect, 0, 0); - _height = rect.bottom - rect.top; - } - } - - if (_text) { - int text_height; - if (_font) { - text_height = _font->getTextHeight((byte *)_text, _width); - } else { - text_height = _gameRef->_systemFont->getTextHeight((byte *)_text, _width); - } - - if (text_height > _height) { - _height = text_height; - } - } - - if (_height <= 0) { - _height = 100; - } - - if (_back) { - _back->correctSize(&_width, &_height); - } -} - - -////////////////////////////////////////////////////////////////////////// -bool UIButton::display(int offsetX, int offsetY) { - if (!_visible) { - return STATUS_OK; - } - - UITiledImage *back = NULL; - BaseSprite *image = NULL; - BaseFont *font = 0; - - //RECT rect; - //BasePlatform::setRect(&rect, OffsetX + _posX, OffsetY + _posY, OffsetX+_posX+_width, OffsetY+_posY+_height); - //_hover = (!_disable && BasePlatform::ptInRect(&rect, _gameRef->_mousePos)!=FALSE); - _hover = (!_disable && _gameRef->_activeObject == this && (_gameRef->_interactive || _gameRef->_state == GAME_SEMI_FROZEN)); - - if ((_press && _hover && !_gameRef->_mouseLeftDown) || - (_oneTimePress && g_system->getMillis() - _oneTimePressTime >= 100)) { - press(); - } - - - if (_disable) { - if (_backDisable) { - back = _backDisable; - } - if (_imageDisable) { - image = _imageDisable; - } - if (_text && _fontDisable) { - font = _fontDisable; - } - } else if (_press || _oneTimePress || _stayPressed) { - if (_backPress) { - back = _backPress; - } - if (_imagePress) { - image = _imagePress; - } - if (_text && _fontPress) { - font = _fontPress; - } - } else if (_hover) { - if (_backHover) { - back = _backHover; - } - if (_imageHover) { - image = _imageHover; - } - if (_text && _fontHover) { - font = _fontHover; - } - } else if (_canFocus && isFocused()) { - if (_backFocus) { - back = _backFocus; - } - if (_imageFocus) { - image = _imageFocus; - } - if (_text && _fontFocus) { - font = _fontFocus; - } - } - - if (!back && _back) { - back = _back; - } - if (!image && _image) { - image = _image; - } - if (_text && !font) { - if (_font) { - font = _font; - } else { - font = _gameRef->_systemFont; - } - } - - int imageX = offsetX + _posX; - int imageY = offsetY + _posY; - - if (image && _centerImage) { - Rect32 rc; - image->getBoundingRect(&rc, 0, 0); - imageX += (_width - (rc.right - rc.left)) / 2; - imageY += (_height - (rc.bottom - rc.top)) / 2; - } - - if (back) { - back->display(offsetX + _posX, offsetY + _posY, _width, _height); - } - //if (image) image->Draw(ImageX +((_press||_oneTimePress)&&back?1:0), ImageY +((_press||_oneTimePress)&&back?1:0), NULL); - if (image) { - image->draw(imageX + ((_press || _oneTimePress) && back ? 1 : 0), imageY + ((_press || _oneTimePress) && back ? 1 : 0), _pixelPerfect ? this : NULL); - } - - if (font && _text) { - int text_offset = (_height - font->getTextHeight((byte *)_text, _width)) / 2; - font->drawText((byte *)_text, offsetX + _posX + ((_press || _oneTimePress) ? 1 : 0), offsetY + _posY + text_offset + ((_press || _oneTimePress) ? 1 : 0), _width, _align); - } - - if (!_pixelPerfect || !_image) { - _gameRef->_renderer->addRectToList(new BaseActiveRect(_gameRef, this, NULL, offsetX + _posX, offsetY + _posY, _width, _height, 100, 100, false)); - } - - // reset unused sprites - if (_image && _image != image) { - _image->reset(); - } - if (_imageDisable && _imageDisable != image) { - _imageDisable->reset(); - } - if (_imageFocus && _imageFocus != image) { - _imageFocus->reset(); - } - if (_imagePress && _imagePress != image) { - _imagePress->reset(); - } - if (_imageHover && _imageHover != image) { - _imageHover->reset(); - } - - _press = _hover && _gameRef->_mouseLeftDown && _gameRef->_capturedObject == this; - - return STATUS_OK; -} - - -////////////////////////////////////////////////////////////////////////// -void UIButton::press() { - applyEvent("Press"); - if (_listenerObject) { - _listenerObject->listen(_listenerParamObject, _listenerParamDWORD); - } - if (_parentNotify && _parent) { - _parent->applyEvent(getName()); - } - - _oneTimePress = false; -} - - -////////////////////////////////////////////////////////////////////////// -// high level scripting interface -////////////////////////////////////////////////////////////////////////// -bool UIButton::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) { - ////////////////////////////////////////////////////////////////////////// - // SetDisabledFont - ////////////////////////////////////////////////////////////////////////// - if (strcmp(name, "SetDisabledFont") == 0) { - stack->correctParams(1); - ScValue *val = stack->pop(); - - if (_fontDisable) { - _gameRef->_fontStorage->removeFont(_fontDisable); - } - if (val->isNULL()) { - _fontDisable = NULL; - stack->pushBool(true); - } else { - _fontDisable = _gameRef->_fontStorage->addFont(val->getString()); - stack->pushBool(_fontDisable != NULL); - } - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // SetHoverFont - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "SetHoverFont") == 0) { - stack->correctParams(1); - ScValue *val = stack->pop(); - - if (_fontHover) { - _gameRef->_fontStorage->removeFont(_fontHover); - } - if (val->isNULL()) { - _fontHover = NULL; - stack->pushBool(true); - } else { - _fontHover = _gameRef->_fontStorage->addFont(val->getString()); - stack->pushBool(_fontHover != NULL); - } - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // SetPressedFont - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "SetPressedFont") == 0) { - stack->correctParams(1); - ScValue *val = stack->pop(); - - if (_fontPress) { - _gameRef->_fontStorage->removeFont(_fontPress); - } - if (val->isNULL()) { - _fontPress = NULL; - stack->pushBool(true); - } else { - _fontPress = _gameRef->_fontStorage->addFont(val->getString()); - stack->pushBool(_fontPress != NULL); - } - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // SetFocusedFont - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "SetFocusedFont") == 0) { - stack->correctParams(1); - ScValue *val = stack->pop(); - - if (_fontFocus) { - _gameRef->_fontStorage->removeFont(_fontFocus); - } - if (val->isNULL()) { - _fontFocus = NULL; - stack->pushBool(true); - } else { - _fontFocus = _gameRef->_fontStorage->addFont(val->getString()); - stack->pushBool(_fontFocus != NULL); - } - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // SetDisabledImage - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "SetDisabledImage") == 0) { - stack->correctParams(1); - - delete _imageDisable; - _imageDisable = new BaseSprite(_gameRef); - const char *filename = stack->pop()->getString(); - if (!_imageDisable || DID_FAIL(_imageDisable->loadFile(filename))) { - delete _imageDisable; - _imageDisable = NULL; - stack->pushBool(false); - } else { - stack->pushBool(true); - } - - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // GetDisabledImage - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "GetDisabledImage") == 0) { - stack->correctParams(0); - if (!_imageDisable || !_imageDisable->getFilename()) { - stack->pushNULL(); - } else { - stack->pushString(_imageDisable->getFilename()); - } - - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // GetDisabledImageObject - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "GetDisabledImageObject") == 0) { - stack->correctParams(0); - if (!_imageDisable) { - stack->pushNULL(); - } else { - stack->pushNative(_imageDisable, true); - } - - return STATUS_OK; - } - - - ////////////////////////////////////////////////////////////////////////// - // SetHoverImage - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "SetHoverImage") == 0) { - stack->correctParams(1); - - delete _imageHover; - _imageHover = new BaseSprite(_gameRef); - const char *filename = stack->pop()->getString(); - if (!_imageHover || DID_FAIL(_imageHover->loadFile(filename))) { - delete _imageHover; - _imageHover = NULL; - stack->pushBool(false); - } else { - stack->pushBool(true); - } - - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // GetHoverImage - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "GetHoverImage") == 0) { - stack->correctParams(0); - if (!_imageHover || !_imageHover->getFilename()) { - stack->pushNULL(); - } else { - stack->pushString(_imageHover->getFilename()); - } - - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // GetHoverImageObject - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "GetHoverImageObject") == 0) { - stack->correctParams(0); - if (!_imageHover) { - stack->pushNULL(); - } else { - stack->pushNative(_imageHover, true); - } - - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // SetPressedImage - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "SetPressedImage") == 0) { - stack->correctParams(1); - - delete _imagePress; - _imagePress = new BaseSprite(_gameRef); - const char *filename = stack->pop()->getString(); - if (!_imagePress || DID_FAIL(_imagePress->loadFile(filename))) { - delete _imagePress; - _imagePress = NULL; - stack->pushBool(false); - } else { - stack->pushBool(true); - } - - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // GetPressedImage - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "GetPressedImage") == 0) { - stack->correctParams(0); - if (!_imagePress || !_imagePress->getFilename()) { - stack->pushNULL(); - } else { - stack->pushString(_imagePress->getFilename()); - } - - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // GetPressedImageObject - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "GetPressedImageObject") == 0) { - stack->correctParams(0); - if (!_imagePress) { - stack->pushNULL(); - } else { - stack->pushNative(_imagePress, true); - } - - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // SetFocusedImage - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "SetFocusedImage") == 0) { - stack->correctParams(1); - - delete _imageFocus; - _imageFocus = new BaseSprite(_gameRef); - const char *filename = stack->pop()->getString(); - if (!_imageFocus || DID_FAIL(_imageFocus->loadFile(filename))) { - delete _imageFocus; - _imageFocus = NULL; - stack->pushBool(false); - } else { - stack->pushBool(true); - } - - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // GetFocusedImage - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "GetFocusedImage") == 0) { - stack->correctParams(0); - if (!_imageFocus || !_imageFocus->getFilename()) { - stack->pushNULL(); - } else { - stack->pushString(_imageFocus->getFilename()); - } - - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // GetFocusedImageObject - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "GetFocusedImageObject") == 0) { - stack->correctParams(0); - if (!_imageFocus) { - stack->pushNULL(); - } else { - stack->pushNative(_imageFocus, true); - } - - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // Press - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "Press") == 0) { - stack->correctParams(0); - - if (_visible && !_disable) { - _oneTimePress = true; - _oneTimePressTime = g_system->getMillis(); - } - stack->pushNULL(); - - return STATUS_OK; - } else { - return UIObject::scCallMethod(script, stack, thisStack, name); - } -} - - -////////////////////////////////////////////////////////////////////////// -ScValue *UIButton::scGetProperty(const char *name) { - _scValue->setNULL(); - - ////////////////////////////////////////////////////////////////////////// - // Type - ////////////////////////////////////////////////////////////////////////// - if (strcmp(name, "Type") == 0) { - _scValue->setString("button"); - return _scValue; - } - - ////////////////////////////////////////////////////////////////////////// - // TextAlign - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "TextAlign") == 0) { - _scValue->setInt(_align); - return _scValue; - } - - ////////////////////////////////////////////////////////////////////////// - // Focusable - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "Focusable") == 0) { - _scValue->setBool(_canFocus); - return _scValue; - } - ////////////////////////////////////////////////////////////////////////// - // Pressed - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "Pressed") == 0) { - _scValue->setBool(_stayPressed); - return _scValue; - } - ////////////////////////////////////////////////////////////////////////// - // PixelPerfect - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "PixelPerfect") == 0) { - _scValue->setBool(_pixelPerfect); - return _scValue; - } else { - return UIObject::scGetProperty(name); - } -} - - -////////////////////////////////////////////////////////////////////////// -bool UIButton::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; - } - _align = (TTextAlign)i; - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // Focusable - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "Focusable") == 0) { - _canFocus = value->getBool(); - return STATUS_OK; - } - ////////////////////////////////////////////////////////////////////////// - // Pressed - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "Pressed") == 0) { - _stayPressed = value->getBool(); - return STATUS_OK; - } - ////////////////////////////////////////////////////////////////////////// - // PixelPerfect - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "PixelPerfect") == 0) { - _pixelPerfect = value->getBool(); - return STATUS_OK; - } else { - return UIObject::scSetProperty(name, value); - } -} - - -////////////////////////////////////////////////////////////////////////// -const char *UIButton::scToString() { - return "[button]"; -} - - -////////////////////////////////////////////////////////////////////////// -bool UIButton::persist(BasePersistenceManager *persistMgr) { - - UIObject::persist(persistMgr); - - persistMgr->transfer(TMEMBER_INT(_align)); - persistMgr->transfer(TMEMBER(_backDisable)); - persistMgr->transfer(TMEMBER(_backFocus)); - persistMgr->transfer(TMEMBER(_backHover)); - persistMgr->transfer(TMEMBER(_backPress)); - persistMgr->transfer(TMEMBER(_centerImage)); - persistMgr->transfer(TMEMBER(_fontDisable)); - persistMgr->transfer(TMEMBER(_fontFocus)); - persistMgr->transfer(TMEMBER(_fontHover)); - persistMgr->transfer(TMEMBER(_fontPress)); - persistMgr->transfer(TMEMBER(_hover)); - persistMgr->transfer(TMEMBER(_image)); - persistMgr->transfer(TMEMBER(_imageDisable)); - persistMgr->transfer(TMEMBER(_imageFocus)); - persistMgr->transfer(TMEMBER(_imageHover)); - persistMgr->transfer(TMEMBER(_imagePress)); - persistMgr->transfer(TMEMBER(_pixelPerfect)); - persistMgr->transfer(TMEMBER(_press)); - persistMgr->transfer(TMEMBER(_stayPressed)); - - if (!persistMgr->getIsSaving()) { - _oneTimePress = false; - _oneTimePressTime = 0; - } - - return STATUS_OK; -} - -} // end of namespace Wintermute +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + * 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/base/base_game.h" +#include "engines/wintermute/ui/ui_button.h" +#include "engines/wintermute/ui/ui_tiled_image.h" +#include "engines/wintermute/base/base_parser.h" +#include "engines/wintermute/base/base_active_rect.h" +#include "engines/wintermute/base/font/base_font_storage.h" +#include "engines/wintermute/base/font/base_font.h" +#include "engines/wintermute/base/base_string_table.h" +#include "engines/wintermute/base/base_sprite.h" +#include "engines/wintermute/base/base_file_manager.h" +#include "engines/wintermute/base/scriptables/script_value.h" +#include "engines/wintermute/base/scriptables/script.h" +#include "engines/wintermute/base/scriptables/script_stack.h" + +namespace Wintermute { + +IMPLEMENT_PERSISTENT(UIButton, false) + +////////////////////////////////////////////////////////////////////////// +UIButton::UIButton(BaseGame *inGame) : UIObject(inGame) { + _backPress = _backHover = _backDisable = _backFocus = NULL; + + _fontHover = _fontPress = _fontDisable = _fontFocus = NULL; + + _imageDisable = _imagePress = _imageHover = _imageFocus = NULL; + + _align = TAL_CENTER; + + _hover = _press = false; + + _type = UI_BUTTON; + + _canFocus = false; + _stayPressed = false; + + _oneTimePress = false; + _centerImage = false; + + _pixelPerfect = false; +} + + +////////////////////////////////////////////////////////////////////////// +UIButton::~UIButton() { + delete _backPress; + delete _backHover; + delete _backDisable; + delete _backFocus; + + if (!_sharedFonts) { + if (_fontHover) { + _gameRef->_fontStorage->removeFont(_fontHover); + } + if (_fontPress) { + _gameRef->_fontStorage->removeFont(_fontPress); + } + if (_fontDisable) { + _gameRef->_fontStorage->removeFont(_fontDisable); + } + if (_fontFocus) { + _gameRef->_fontStorage->removeFont(_fontFocus); + } + } + + if (!_sharedImages) { + delete _imageHover; + delete _imagePress; + delete _imageDisable; + delete _imageFocus; + } +} + + +////////////////////////////////////////////////////////////////////////// +bool UIButton::loadFile(const char *filename) { + byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename); + if (buffer == NULL) { + _gameRef->LOG(0, "UIButton::LoadFile failed for file '%s'", filename); + return STATUS_FAILED; + } + + bool ret; + + setFilename(filename); + + if (DID_FAIL(ret = loadBuffer(buffer, true))) { + _gameRef->LOG(0, "Error parsing BUTTON file '%s'", filename); + } + + delete[] buffer; + + return ret; +} + + +TOKEN_DEF_START +TOKEN_DEF(BUTTON) +TOKEN_DEF(TEMPLATE) +TOKEN_DEF(DISABLED) +TOKEN_DEF(VISIBLE) +TOKEN_DEF(FOCUSABLE) +TOKEN_DEF(BACK_HOVER) +TOKEN_DEF(BACK_PRESS) +TOKEN_DEF(BACK_DISABLE) +TOKEN_DEF(BACK_FOCUS) +TOKEN_DEF(BACK) +TOKEN_DEF(CENTER_IMAGE) +TOKEN_DEF(IMAGE_HOVER) +TOKEN_DEF(IMAGE_PRESS) +TOKEN_DEF(IMAGE_DISABLE) +TOKEN_DEF(IMAGE_FOCUS) +TOKEN_DEF(IMAGE) +TOKEN_DEF(FONT_HOVER) +TOKEN_DEF(FONT_PRESS) +TOKEN_DEF(FONT_DISABLE) +TOKEN_DEF(FONT_FOCUS) +TOKEN_DEF(FONT) +TOKEN_DEF(TEXT_ALIGN) +TOKEN_DEF(TEXT) +TOKEN_DEF(X) +TOKEN_DEF(Y) +TOKEN_DEF(WIDTH) +TOKEN_DEF(HEIGHT) +TOKEN_DEF(CURSOR) +TOKEN_DEF(NAME) +TOKEN_DEF(EVENTS) +TOKEN_DEF(SCRIPT) +TOKEN_DEF(CAPTION) +TOKEN_DEF(PARENT_NOTIFY) +TOKEN_DEF(PRESSED) +TOKEN_DEF(PIXEL_PERFECT) +TOKEN_DEF(EDITOR_PROPERTY) +TOKEN_DEF_END +////////////////////////////////////////////////////////////////////////// +bool UIButton::loadBuffer(byte *buffer, bool complete) { + TOKEN_TABLE_START(commands) + TOKEN_TABLE(BUTTON) + TOKEN_TABLE(TEMPLATE) + TOKEN_TABLE(DISABLED) + TOKEN_TABLE(VISIBLE) + TOKEN_TABLE(FOCUSABLE) + TOKEN_TABLE(BACK_HOVER) + TOKEN_TABLE(BACK_PRESS) + TOKEN_TABLE(BACK_DISABLE) + TOKEN_TABLE(BACK_FOCUS) + TOKEN_TABLE(BACK) + TOKEN_TABLE(CENTER_IMAGE) + TOKEN_TABLE(IMAGE_HOVER) + TOKEN_TABLE(IMAGE_PRESS) + TOKEN_TABLE(IMAGE_DISABLE) + TOKEN_TABLE(IMAGE_FOCUS) + TOKEN_TABLE(IMAGE) + TOKEN_TABLE(FONT_HOVER) + TOKEN_TABLE(FONT_PRESS) + TOKEN_TABLE(FONT_DISABLE) + TOKEN_TABLE(FONT_FOCUS) + TOKEN_TABLE(FONT) + TOKEN_TABLE(TEXT_ALIGN) + TOKEN_TABLE(TEXT) + TOKEN_TABLE(X) + TOKEN_TABLE(Y) + TOKEN_TABLE(WIDTH) + TOKEN_TABLE(HEIGHT) + TOKEN_TABLE(CURSOR) + TOKEN_TABLE(NAME) + TOKEN_TABLE(EVENTS) + TOKEN_TABLE(SCRIPT) + TOKEN_TABLE(CAPTION) + TOKEN_TABLE(PARENT_NOTIFY) + TOKEN_TABLE(PRESSED) + TOKEN_TABLE(PIXEL_PERFECT) + TOKEN_TABLE(EDITOR_PROPERTY) + TOKEN_TABLE_END + + byte *params; + int cmd = 2; + BaseParser parser; + + if (complete) { + if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_BUTTON) { + _gameRef->LOG(0, "'BUTTON' keyword expected."); + return STATUS_FAILED; + } + buffer = params; + } + + while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { + switch (cmd) { + case TOKEN_TEMPLATE: + if (DID_FAIL(loadFile((char *)params))) { + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_NAME: + setName((char *)params); + break; + + case TOKEN_CAPTION: + setCaption((char *)params); + break; + + case TOKEN_BACK: + delete _back; + _back = new UITiledImage(_gameRef); + if (!_back || DID_FAIL(_back->loadFile((char *)params))) { + delete _back; + _back = NULL; + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_BACK_HOVER: + delete _backHover; + _backHover = new UITiledImage(_gameRef); + if (!_backHover || DID_FAIL(_backHover->loadFile((char *)params))) { + delete _backHover; + _backHover = NULL; + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_BACK_PRESS: + delete _backPress; + _backPress = new UITiledImage(_gameRef); + if (!_backPress || DID_FAIL(_backPress->loadFile((char *)params))) { + delete _backPress; + _backPress = NULL; + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_BACK_DISABLE: + delete _backDisable; + _backDisable = new UITiledImage(_gameRef); + if (!_backDisable || DID_FAIL(_backDisable->loadFile((char *)params))) { + delete _backDisable; + _backDisable = NULL; + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_BACK_FOCUS: + delete _backFocus; + _backFocus = new UITiledImage(_gameRef); + if (!_backFocus || DID_FAIL(_backFocus->loadFile((char *)params))) { + delete _backFocus; + _backFocus = NULL; + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_IMAGE: + delete _image; + _image = new BaseSprite(_gameRef); + if (!_image || DID_FAIL(_image->loadFile((char *)params))) { + delete _image; + _image = NULL; + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_IMAGE_HOVER: + delete _imageHover; + _imageHover = new BaseSprite(_gameRef); + if (!_imageHover || DID_FAIL(_imageHover->loadFile((char *)params))) { + delete _imageHover; + _imageHover = NULL; + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_IMAGE_PRESS: + delete _imagePress; + _imagePress = new BaseSprite(_gameRef); + if (!_imagePress || DID_FAIL(_imagePress->loadFile((char *)params))) { + delete _imagePress; + _imagePress = NULL; + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_IMAGE_DISABLE: + delete _imageDisable; + _imageDisable = new BaseSprite(_gameRef); + if (!_imageDisable || DID_FAIL(_imageDisable->loadFile((char *)params))) { + delete _imageDisable; + _imageDisable = NULL; + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_IMAGE_FOCUS: + delete _imageFocus; + _imageFocus = new BaseSprite(_gameRef); + if (!_imageFocus || DID_FAIL(_imageFocus->loadFile((char *)params))) { + delete _imageFocus; + _imageFocus = NULL; + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_FONT: + if (_font) { + _gameRef->_fontStorage->removeFont(_font); + } + _font = _gameRef->_fontStorage->addFont((char *)params); + if (!_font) { + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_FONT_HOVER: + if (_fontHover) { + _gameRef->_fontStorage->removeFont(_fontHover); + } + _fontHover = _gameRef->_fontStorage->addFont((char *)params); + if (!_fontHover) { + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_FONT_PRESS: + if (_fontPress) { + _gameRef->_fontStorage->removeFont(_fontPress); + } + _fontPress = _gameRef->_fontStorage->addFont((char *)params); + if (!_fontPress) { + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_FONT_DISABLE: + if (_fontDisable) { + _gameRef->_fontStorage->removeFont(_fontDisable); + } + _fontDisable = _gameRef->_fontStorage->addFont((char *)params); + if (!_fontDisable) { + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_FONT_FOCUS: + if (_fontFocus) { + _gameRef->_fontStorage->removeFont(_fontFocus); + } + _fontFocus = _gameRef->_fontStorage->addFont((char *)params); + if (!_fontFocus) { + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_TEXT: + setText((char *)params); + _gameRef->_stringTable->expand(&_text); + break; + + case TOKEN_TEXT_ALIGN: + if (scumm_stricmp((char *)params, "left") == 0) { + _align = TAL_LEFT; + } else if (scumm_stricmp((char *)params, "right") == 0) { + _align = TAL_RIGHT; + } else { + _align = TAL_CENTER; + } + break; + + case TOKEN_X: + parser.scanStr((char *)params, "%d", &_posX); + break; + + case TOKEN_Y: + parser.scanStr((char *)params, "%d", &_posY); + break; + + case TOKEN_WIDTH: + parser.scanStr((char *)params, "%d", &_width); + break; + + case TOKEN_HEIGHT: + parser.scanStr((char *)params, "%d", &_height); + break; + + case TOKEN_CURSOR: + delete _cursor; + _cursor = new BaseSprite(_gameRef); + if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) { + delete _cursor; + _cursor = NULL; + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_SCRIPT: + addScript((char *)params); + break; + + case TOKEN_PARENT_NOTIFY: + parser.scanStr((char *)params, "%b", &_parentNotify); + break; + + case TOKEN_DISABLED: + parser.scanStr((char *)params, "%b", &_disable); + break; + + case TOKEN_VISIBLE: + parser.scanStr((char *)params, "%b", &_visible); + break; + + case TOKEN_FOCUSABLE: + parser.scanStr((char *)params, "%b", &_canFocus); + break; + + case TOKEN_CENTER_IMAGE: + parser.scanStr((char *)params, "%b", &_centerImage); + break; + + case TOKEN_PRESSED: + parser.scanStr((char *)params, "%b", &_stayPressed); + break; + + case TOKEN_PIXEL_PERFECT: + parser.scanStr((char *)params, "%b", &_pixelPerfect); + break; + + case TOKEN_EDITOR_PROPERTY: + parseEditorProperty(params, false); + break; + } + } + if (cmd == PARSERR_TOKENNOTFOUND) { + _gameRef->LOG(0, "Syntax error in BUTTON definition"); + return STATUS_FAILED; + } + if (cmd == PARSERR_GENERIC) { + _gameRef->LOG(0, "Error loading BUTTON definition"); + return STATUS_FAILED; + } + + correctSize(); + + return STATUS_OK; +} + +////////////////////////////////////////////////////////////////////////// +bool UIButton::saveAsText(BaseDynamicBuffer *buffer, int indent) { + buffer->putTextIndent(indent, "BUTTON\n"); + buffer->putTextIndent(indent, "{\n"); + + buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", getName()); + buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption()); + + buffer->putTextIndent(indent + 2, "\n"); + + if (_back && _back->getFilename()) { + buffer->putTextIndent(indent + 2, "BACK=\"%s\"\n", _back->getFilename()); + } + if (_backHover && _backHover->getFilename()) { + buffer->putTextIndent(indent + 2, "BACK_HOVER=\"%s\"\n", _backHover->getFilename()); + } + if (_backPress && _backPress->getFilename()) { + buffer->putTextIndent(indent + 2, "BACK_PRESS=\"%s\"\n", _backPress->getFilename()); + } + if (_backDisable && _backDisable->getFilename()) { + buffer->putTextIndent(indent + 2, "BACK_DISABLE=\"%s\"\n", _backDisable->getFilename()); + } + if (_backFocus && _backFocus->getFilename()) { + buffer->putTextIndent(indent + 2, "BACK_FOCUS=\"%s\"\n", _backFocus->getFilename()); + } + + if (_image && _image->getFilename()) { + buffer->putTextIndent(indent + 2, "IMAGE=\"%s\"\n", _image->getFilename()); + } + if (_imageHover && _imageHover->getFilename()) { + buffer->putTextIndent(indent + 2, "IMAGE_HOVER=\"%s\"\n", _imageHover->getFilename()); + } + if (_imagePress && _imagePress->getFilename()) { + buffer->putTextIndent(indent + 2, "IMAGE_PRESS=\"%s\"\n", _imagePress->getFilename()); + } + if (_imageDisable && _imageDisable->getFilename()) { + buffer->putTextIndent(indent + 2, "IMAGE_DISABLE=\"%s\"\n", _imageDisable->getFilename()); + } + if (_imageFocus && _imageFocus->getFilename()) { + buffer->putTextIndent(indent + 2, "IMAGE_FOCUS=\"%s\"\n", _imageFocus->getFilename()); + } + + if (_font && _font->getFilename()) { + buffer->putTextIndent(indent + 2, "FONT=\"%s\"\n", _font->getFilename()); + } + if (_fontHover && _fontHover->getFilename()) { + buffer->putTextIndent(indent + 2, "FONT_HOVER=\"%s\"\n", _fontHover->getFilename()); + } + if (_fontPress && _fontPress->getFilename()) { + buffer->putTextIndent(indent + 2, "FONT_PRESS=\"%s\"\n", _fontPress->getFilename()); + } + if (_fontDisable && _fontDisable->getFilename()) { + buffer->putTextIndent(indent + 2, "FONT_DISABLE=\"%s\"\n", _fontDisable->getFilename()); + } + if (_fontFocus && _fontFocus->getFilename()) { + buffer->putTextIndent(indent + 2, "FONT_FOCUS=\"%s\"\n", _fontFocus->getFilename()); + } + + if (_cursor && _cursor->getFilename()) { + buffer->putTextIndent(indent + 2, "CURSOR=\"%s\"\n", _cursor->getFilename()); + } + + + buffer->putTextIndent(indent + 2, "\n"); + + if (_text) { + buffer->putTextIndent(indent + 2, "TEXT=\"%s\"\n", _text); + } + + switch (_align) { + 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: + warning("UIButton::SaveAsText - unhandled enum"); + 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, "FOCUSABLE=%s\n", _canFocus ? "TRUE" : "FALSE"); + buffer->putTextIndent(indent + 2, "CENTER_IMAGE=%s\n", _centerImage ? "TRUE" : "FALSE"); + buffer->putTextIndent(indent + 2, "PRESSED=%s\n", _stayPressed ? "TRUE" : "FALSE"); + buffer->putTextIndent(indent + 2, "PIXEL_PERFECT=%s\n", _pixelPerfect ? "TRUE" : "FALSE"); + + buffer->putTextIndent(indent + 2, "\n"); + + // scripts + for (uint32 i = 0; i < _scripts.size(); 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; +} + +////////////////////////////////////////////////////////////////////////// +void UIButton::correctSize() { + Rect32 rect; + + BaseSprite *img = NULL; + if (_image) { + img = _image; + } else if (_imageDisable) { + img = _imageDisable; + } else if (_imageHover) { + img = _imageHover; + } else if (_imagePress) { + img = _imagePress; + } else if (_imageFocus) { + img = _imageFocus; + } + + if (_width <= 0) { + if (img) { + img->getBoundingRect(&rect, 0, 0); + _width = rect.right - rect.left; + } else { + _width = 100; + } + } + + if (_height <= 0) { + if (img) { + img->getBoundingRect(&rect, 0, 0); + _height = rect.bottom - rect.top; + } + } + + if (_text) { + int text_height; + if (_font) { + text_height = _font->getTextHeight((byte *)_text, _width); + } else { + text_height = _gameRef->_systemFont->getTextHeight((byte *)_text, _width); + } + + if (text_height > _height) { + _height = text_height; + } + } + + if (_height <= 0) { + _height = 100; + } + + if (_back) { + _back->correctSize(&_width, &_height); + } +} + + +////////////////////////////////////////////////////////////////////////// +bool UIButton::display(int offsetX, int offsetY) { + if (!_visible) { + return STATUS_OK; + } + + UITiledImage *back = NULL; + BaseSprite *image = NULL; + BaseFont *font = 0; + + //RECT rect; + //BasePlatform::setRect(&rect, OffsetX + _posX, OffsetY + _posY, OffsetX+_posX+_width, OffsetY+_posY+_height); + //_hover = (!_disable && BasePlatform::ptInRect(&rect, _gameRef->_mousePos)!=FALSE); + _hover = (!_disable && _gameRef->_activeObject == this && (_gameRef->_interactive || _gameRef->_state == GAME_SEMI_FROZEN)); + + if ((_press && _hover && !_gameRef->_mouseLeftDown) || + (_oneTimePress && g_system->getMillis() - _oneTimePressTime >= 100)) { + press(); + } + + + if (_disable) { + if (_backDisable) { + back = _backDisable; + } + if (_imageDisable) { + image = _imageDisable; + } + if (_text && _fontDisable) { + font = _fontDisable; + } + } else if (_press || _oneTimePress || _stayPressed) { + if (_backPress) { + back = _backPress; + } + if (_imagePress) { + image = _imagePress; + } + if (_text && _fontPress) { + font = _fontPress; + } + } else if (_hover) { + if (_backHover) { + back = _backHover; + } + if (_imageHover) { + image = _imageHover; + } + if (_text && _fontHover) { + font = _fontHover; + } + } else if (_canFocus && isFocused()) { + if (_backFocus) { + back = _backFocus; + } + if (_imageFocus) { + image = _imageFocus; + } + if (_text && _fontFocus) { + font = _fontFocus; + } + } + + if (!back && _back) { + back = _back; + } + if (!image && _image) { + image = _image; + } + if (_text && !font) { + if (_font) { + font = _font; + } else { + font = _gameRef->_systemFont; + } + } + + int imageX = offsetX + _posX; + int imageY = offsetY + _posY; + + if (image && _centerImage) { + Rect32 rc; + image->getBoundingRect(&rc, 0, 0); + imageX += (_width - (rc.right - rc.left)) / 2; + imageY += (_height - (rc.bottom - rc.top)) / 2; + } + + if (back) { + back->display(offsetX + _posX, offsetY + _posY, _width, _height); + } + //if (image) image->Draw(ImageX +((_press||_oneTimePress)&&back?1:0), ImageY +((_press||_oneTimePress)&&back?1:0), NULL); + if (image) { + image->draw(imageX + ((_press || _oneTimePress) && back ? 1 : 0), imageY + ((_press || _oneTimePress) && back ? 1 : 0), _pixelPerfect ? this : NULL); + } + + if (font && _text) { + int text_offset = (_height - font->getTextHeight((byte *)_text, _width)) / 2; + font->drawText((byte *)_text, offsetX + _posX + ((_press || _oneTimePress) ? 1 : 0), offsetY + _posY + text_offset + ((_press || _oneTimePress) ? 1 : 0), _width, _align); + } + + if (!_pixelPerfect || !_image) { + _gameRef->_renderer->addRectToList(new BaseActiveRect(_gameRef, this, NULL, offsetX + _posX, offsetY + _posY, _width, _height, 100, 100, false)); + } + + // reset unused sprites + if (_image && _image != image) { + _image->reset(); + } + if (_imageDisable && _imageDisable != image) { + _imageDisable->reset(); + } + if (_imageFocus && _imageFocus != image) { + _imageFocus->reset(); + } + if (_imagePress && _imagePress != image) { + _imagePress->reset(); + } + if (_imageHover && _imageHover != image) { + _imageHover->reset(); + } + + _press = _hover && _gameRef->_mouseLeftDown && _gameRef->_capturedObject == this; + + return STATUS_OK; +} + + +////////////////////////////////////////////////////////////////////////// +void UIButton::press() { + applyEvent("Press"); + if (_listenerObject) { + _listenerObject->listen(_listenerParamObject, _listenerParamDWORD); + } + if (_parentNotify && _parent) { + _parent->applyEvent(getName()); + } + + _oneTimePress = false; +} + + +////////////////////////////////////////////////////////////////////////// +// high level scripting interface +////////////////////////////////////////////////////////////////////////// +bool UIButton::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) { + ////////////////////////////////////////////////////////////////////////// + // SetDisabledFont + ////////////////////////////////////////////////////////////////////////// + if (strcmp(name, "SetDisabledFont") == 0) { + stack->correctParams(1); + ScValue *val = stack->pop(); + + if (_fontDisable) { + _gameRef->_fontStorage->removeFont(_fontDisable); + } + if (val->isNULL()) { + _fontDisable = NULL; + stack->pushBool(true); + } else { + _fontDisable = _gameRef->_fontStorage->addFont(val->getString()); + stack->pushBool(_fontDisable != NULL); + } + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // SetHoverFont + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "SetHoverFont") == 0) { + stack->correctParams(1); + ScValue *val = stack->pop(); + + if (_fontHover) { + _gameRef->_fontStorage->removeFont(_fontHover); + } + if (val->isNULL()) { + _fontHover = NULL; + stack->pushBool(true); + } else { + _fontHover = _gameRef->_fontStorage->addFont(val->getString()); + stack->pushBool(_fontHover != NULL); + } + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // SetPressedFont + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "SetPressedFont") == 0) { + stack->correctParams(1); + ScValue *val = stack->pop(); + + if (_fontPress) { + _gameRef->_fontStorage->removeFont(_fontPress); + } + if (val->isNULL()) { + _fontPress = NULL; + stack->pushBool(true); + } else { + _fontPress = _gameRef->_fontStorage->addFont(val->getString()); + stack->pushBool(_fontPress != NULL); + } + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // SetFocusedFont + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "SetFocusedFont") == 0) { + stack->correctParams(1); + ScValue *val = stack->pop(); + + if (_fontFocus) { + _gameRef->_fontStorage->removeFont(_fontFocus); + } + if (val->isNULL()) { + _fontFocus = NULL; + stack->pushBool(true); + } else { + _fontFocus = _gameRef->_fontStorage->addFont(val->getString()); + stack->pushBool(_fontFocus != NULL); + } + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // SetDisabledImage + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "SetDisabledImage") == 0) { + stack->correctParams(1); + + delete _imageDisable; + _imageDisable = new BaseSprite(_gameRef); + const char *filename = stack->pop()->getString(); + if (!_imageDisable || DID_FAIL(_imageDisable->loadFile(filename))) { + delete _imageDisable; + _imageDisable = NULL; + stack->pushBool(false); + } else { + stack->pushBool(true); + } + + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // GetDisabledImage + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "GetDisabledImage") == 0) { + stack->correctParams(0); + if (!_imageDisable || !_imageDisable->getFilename()) { + stack->pushNULL(); + } else { + stack->pushString(_imageDisable->getFilename()); + } + + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // GetDisabledImageObject + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "GetDisabledImageObject") == 0) { + stack->correctParams(0); + if (!_imageDisable) { + stack->pushNULL(); + } else { + stack->pushNative(_imageDisable, true); + } + + return STATUS_OK; + } + + + ////////////////////////////////////////////////////////////////////////// + // SetHoverImage + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "SetHoverImage") == 0) { + stack->correctParams(1); + + delete _imageHover; + _imageHover = new BaseSprite(_gameRef); + const char *filename = stack->pop()->getString(); + if (!_imageHover || DID_FAIL(_imageHover->loadFile(filename))) { + delete _imageHover; + _imageHover = NULL; + stack->pushBool(false); + } else { + stack->pushBool(true); + } + + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // GetHoverImage + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "GetHoverImage") == 0) { + stack->correctParams(0); + if (!_imageHover || !_imageHover->getFilename()) { + stack->pushNULL(); + } else { + stack->pushString(_imageHover->getFilename()); + } + + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // GetHoverImageObject + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "GetHoverImageObject") == 0) { + stack->correctParams(0); + if (!_imageHover) { + stack->pushNULL(); + } else { + stack->pushNative(_imageHover, true); + } + + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // SetPressedImage + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "SetPressedImage") == 0) { + stack->correctParams(1); + + delete _imagePress; + _imagePress = new BaseSprite(_gameRef); + const char *filename = stack->pop()->getString(); + if (!_imagePress || DID_FAIL(_imagePress->loadFile(filename))) { + delete _imagePress; + _imagePress = NULL; + stack->pushBool(false); + } else { + stack->pushBool(true); + } + + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // GetPressedImage + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "GetPressedImage") == 0) { + stack->correctParams(0); + if (!_imagePress || !_imagePress->getFilename()) { + stack->pushNULL(); + } else { + stack->pushString(_imagePress->getFilename()); + } + + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // GetPressedImageObject + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "GetPressedImageObject") == 0) { + stack->correctParams(0); + if (!_imagePress) { + stack->pushNULL(); + } else { + stack->pushNative(_imagePress, true); + } + + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // SetFocusedImage + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "SetFocusedImage") == 0) { + stack->correctParams(1); + + delete _imageFocus; + _imageFocus = new BaseSprite(_gameRef); + const char *filename = stack->pop()->getString(); + if (!_imageFocus || DID_FAIL(_imageFocus->loadFile(filename))) { + delete _imageFocus; + _imageFocus = NULL; + stack->pushBool(false); + } else { + stack->pushBool(true); + } + + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // GetFocusedImage + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "GetFocusedImage") == 0) { + stack->correctParams(0); + if (!_imageFocus || !_imageFocus->getFilename()) { + stack->pushNULL(); + } else { + stack->pushString(_imageFocus->getFilename()); + } + + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // GetFocusedImageObject + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "GetFocusedImageObject") == 0) { + stack->correctParams(0); + if (!_imageFocus) { + stack->pushNULL(); + } else { + stack->pushNative(_imageFocus, true); + } + + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // Press + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "Press") == 0) { + stack->correctParams(0); + + if (_visible && !_disable) { + _oneTimePress = true; + _oneTimePressTime = g_system->getMillis(); + } + stack->pushNULL(); + + return STATUS_OK; + } else { + return UIObject::scCallMethod(script, stack, thisStack, name); + } +} + + +////////////////////////////////////////////////////////////////////////// +ScValue *UIButton::scGetProperty(const char *name) { + _scValue->setNULL(); + + ////////////////////////////////////////////////////////////////////////// + // Type + ////////////////////////////////////////////////////////////////////////// + if (strcmp(name, "Type") == 0) { + _scValue->setString("button"); + return _scValue; + } + + ////////////////////////////////////////////////////////////////////////// + // TextAlign + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "TextAlign") == 0) { + _scValue->setInt(_align); + return _scValue; + } + + ////////////////////////////////////////////////////////////////////////// + // Focusable + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "Focusable") == 0) { + _scValue->setBool(_canFocus); + return _scValue; + } + ////////////////////////////////////////////////////////////////////////// + // Pressed + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "Pressed") == 0) { + _scValue->setBool(_stayPressed); + return _scValue; + } + ////////////////////////////////////////////////////////////////////////// + // PixelPerfect + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "PixelPerfect") == 0) { + _scValue->setBool(_pixelPerfect); + return _scValue; + } else { + return UIObject::scGetProperty(name); + } +} + + +////////////////////////////////////////////////////////////////////////// +bool UIButton::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; + } + _align = (TTextAlign)i; + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // Focusable + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "Focusable") == 0) { + _canFocus = value->getBool(); + return STATUS_OK; + } + ////////////////////////////////////////////////////////////////////////// + // Pressed + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "Pressed") == 0) { + _stayPressed = value->getBool(); + return STATUS_OK; + } + ////////////////////////////////////////////////////////////////////////// + // PixelPerfect + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "PixelPerfect") == 0) { + _pixelPerfect = value->getBool(); + return STATUS_OK; + } else { + return UIObject::scSetProperty(name, value); + } +} + + +////////////////////////////////////////////////////////////////////////// +const char *UIButton::scToString() { + return "[button]"; +} + + +////////////////////////////////////////////////////////////////////////// +bool UIButton::persist(BasePersistenceManager *persistMgr) { + + UIObject::persist(persistMgr); + + persistMgr->transfer(TMEMBER_INT(_align)); + persistMgr->transfer(TMEMBER(_backDisable)); + persistMgr->transfer(TMEMBER(_backFocus)); + persistMgr->transfer(TMEMBER(_backHover)); + persistMgr->transfer(TMEMBER(_backPress)); + persistMgr->transfer(TMEMBER(_centerImage)); + persistMgr->transfer(TMEMBER(_fontDisable)); + persistMgr->transfer(TMEMBER(_fontFocus)); + persistMgr->transfer(TMEMBER(_fontHover)); + persistMgr->transfer(TMEMBER(_fontPress)); + persistMgr->transfer(TMEMBER(_hover)); + persistMgr->transfer(TMEMBER(_image)); + persistMgr->transfer(TMEMBER(_imageDisable)); + persistMgr->transfer(TMEMBER(_imageFocus)); + persistMgr->transfer(TMEMBER(_imageHover)); + persistMgr->transfer(TMEMBER(_imagePress)); + persistMgr->transfer(TMEMBER(_pixelPerfect)); + persistMgr->transfer(TMEMBER(_press)); + persistMgr->transfer(TMEMBER(_stayPressed)); + + if (!persistMgr->getIsSaving()) { + _oneTimePress = false; + _oneTimePressTime = 0; + } + + return STATUS_OK; +} + +} // end of namespace Wintermute diff --git a/engines/wintermute/ui/ui_button.h b/engines/wintermute/ui/ui_button.h index 88ba8dafc7..9342f766cc 100644 --- a/engines/wintermute/ui/ui_button.h +++ b/engines/wintermute/ui/ui_button.h @@ -1,80 +1,80 @@ -/* 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 2 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -/* - * 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(); - virtual bool display() { return display(0, 0); } - virtual bool display(int offsetX, int offsetY); - bool _press; - bool _hover; - void correctSize(); - 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 = NULL); - virtual ~UIButton(); - bool loadFile(const char *filename); - bool loadBuffer(byte *buffer, bool complete = true); - virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent); - - // scripting interface - virtual ScValue *scGetProperty(const char *name); - virtual bool scSetProperty(const char *name, ScValue *value); - virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name); - virtual const char *scToString(); -}; - -} // end of namespace Wintermute - -#endif +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + * 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(); + virtual bool display() { return display(0, 0); } + virtual bool display(int offsetX, int offsetY); + bool _press; + bool _hover; + void correctSize(); + 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 = NULL); + virtual ~UIButton(); + bool loadFile(const char *filename); + bool loadBuffer(byte *buffer, bool complete = true); + virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent); + + // scripting interface + virtual ScValue *scGetProperty(const char *name); + virtual bool scSetProperty(const char *name, ScValue *value); + virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name); + virtual const char *scToString(); +}; + +} // end of namespace Wintermute + +#endif diff --git a/engines/wintermute/ui/ui_edit.cpp b/engines/wintermute/ui/ui_edit.cpp index 2ea44cd64c..94d11255ce 100644 --- a/engines/wintermute/ui/ui_edit.cpp +++ b/engines/wintermute/ui/ui_edit.cpp @@ -1,951 +1,951 @@ -/* 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 2 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -/* - * 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/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 "common/util.h" -#include "common/keyboard.h" - -namespace Wintermute { - -IMPLEMENT_PERSISTENT(UIEdit, false) - -////////////////////////////////////////////////////////////////////////// -UIEdit::UIEdit(BaseGame *inGame) : UIObject(inGame) { - _type = UI_EDIT; - - _fontSelected = NULL; - - _selStart = _selEnd = 10000; - _scrollOffset = 0; - - _cursorChar = NULL; - setCursorChar("|"); - - _cursorBlinkRate = 600; - - _frameWidth = 0; - - setText(""); - - _lastBlinkTime = 0; - _cursorVisible = true; - - _maxLength = -1; - - _canFocus = true; -} - - -////////////////////////////////////////////////////////////////////////// -UIEdit::~UIEdit() { - if (!_sharedFonts) { - if (_fontSelected) { - _gameRef->_fontStorage->removeFont(_fontSelected); - } - } - - delete[] _cursorChar; - _cursorChar = NULL; -} - - -////////////////////////////////////////////////////////////////////////// -bool UIEdit::loadFile(const char *filename) { - byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename); - if (buffer == NULL) { - _gameRef->LOG(0, "UIEdit::LoadFile failed for file '%s'", filename); - return STATUS_FAILED; - } - - bool ret; - - setFilename(filename); - - if (DID_FAIL(ret = loadBuffer(buffer, true))) { - _gameRef->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(byte *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 - - byte *params; - int cmd = 2; - BaseParser parser; - - if (complete) { - if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_EDIT) { - _gameRef->LOG(0, "'EDIT' keyword expected."); - return STATUS_FAILED; - } - buffer = params; - } - - while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { - switch (cmd) { - case TOKEN_TEMPLATE: - if (DID_FAIL(loadFile((char *)params))) { - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_NAME: - setName((char *)params); - break; - - case TOKEN_BACK: - delete _back; - _back = new UITiledImage(_gameRef); - if (!_back || DID_FAIL(_back->loadFile((char *)params))) { - delete _back; - _back = NULL; - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_IMAGE: - delete _image; - _image = new BaseSprite(_gameRef); - if (!_image || DID_FAIL(_image->loadFile((char *)params))) { - delete _image; - _image = NULL; - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_FONT: - if (_font) { - _gameRef->_fontStorage->removeFont(_font); - } - _font = _gameRef->_fontStorage->addFont((char *)params); - if (!_font) { - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_FONT_SELECTED: - if (_fontSelected) { - _gameRef->_fontStorage->removeFont(_fontSelected); - } - _fontSelected = _gameRef->_fontStorage->addFont((char *)params); - if (!_fontSelected) { - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_TEXT: - setText((char *)params); - _gameRef->_stringTable->expand(&_text); - break; - - case TOKEN_X: - parser.scanStr((char *)params, "%d", &_posX); - break; - - case TOKEN_Y: - parser.scanStr((char *)params, "%d", &_posY); - break; - - case TOKEN_WIDTH: - parser.scanStr((char *)params, "%d", &_width); - break; - - case TOKEN_HEIGHT: - parser.scanStr((char *)params, "%d", &_height); - break; - - case TOKEN_MAX_LENGTH: - parser.scanStr((char *)params, "%d", &_maxLength); - break; - - case TOKEN_CAPTION: - setCaption((char *)params); - break; - - case TOKEN_CURSOR: - delete _cursor; - _cursor = new BaseSprite(_gameRef); - if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) { - delete _cursor; - _cursor = NULL; - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_CURSOR_BLINK_RATE: - parser.scanStr((char *)params, "%d", &_cursorBlinkRate); - break; - - case TOKEN_FRAME_WIDTH: - parser.scanStr((char *)params, "%d", &_frameWidth); - break; - - case TOKEN_SCRIPT: - addScript((char *)params); - break; - - case TOKEN_PARENT_NOTIFY: - parser.scanStr((char *)params, "%b", &_parentNotify); - break; - - case TOKEN_DISABLED: - parser.scanStr((char *)params, "%b", &_disable); - break; - - case TOKEN_VISIBLE: - parser.scanStr((char *)params, "%b", &_visible); - break; - - case TOKEN_EDITOR_PROPERTY: - parseEditorProperty(params, false); - break; - } - } - if (cmd == PARSERR_TOKENNOTFOUND) { - _gameRef->LOG(0, "Syntax error in EDIT definition"); - return STATUS_FAILED; - } - if (cmd == PARSERR_GENERIC) { - _gameRef->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", getName()); - buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption()); - - buffer->putTextIndent(indent + 2, "\n"); - - if (_back && _back->getFilename()) { - buffer->putTextIndent(indent + 2, "BACK=\"%s\"\n", _back->getFilename()); - } - - if (_image && _image->getFilename()) { - buffer->putTextIndent(indent + 2, "IMAGE=\"%s\"\n", _image->getFilename()); - } - - if (_font && _font->getFilename()) { - buffer->putTextIndent(indent + 2, "FONT=\"%s\"\n", _font->getFilename()); - } - if (_fontSelected && _fontSelected->getFilename()) { - buffer->putTextIndent(indent + 2, "FONT_SELECTED=\"%s\"\n", _fontSelected->getFilename()); - } - - if (_cursor && _cursor->getFilename()) { - buffer->putTextIndent(indent + 2, "CURSOR=\"%s\"\n", _cursor->getFilename()); - } - - buffer->putTextIndent(indent + 2, "\n"); - - if (_text) { - 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 (uint32 i = 0; i < _scripts.size(); 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) { - _gameRef->_fontStorage->removeFont(_fontSelected); - } - _fontSelected = _gameRef->_fontStorage->addFont(stack->pop()->getString()); - stack->pushBool(_fontSelected != NULL); - - 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 (_gameRef->_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(_selStart, 0); - _selStart = (int)MIN((size_t)_selStart, strlen(_text)); - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // SelEnd - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "SelEnd") == 0) { - _selEnd = value->getInt(); - _selEnd = MAX(_selEnd, 0); - _selEnd = (int)MIN((size_t)_selEnd, 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 (_gameRef->_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; - } - delete[] _cursorChar; - _cursorChar = new char [strlen(character) + 1]; - if (_cursorChar) { - strcpy(_cursorChar, character); - } -} - - -////////////////////////////////////////////////////////////////////////// -bool UIEdit::display(int offsetX, int offsetY) { - if (!_visible) { - return STATUS_OK; - } - - - // hack! - TTextEncoding OrigEncoding = _gameRef->_textEncoding; - _gameRef->_textEncoding = TEXT_ANSI; - - if (_back) { - _back->display(offsetX + _posX, offsetY + _posY, _width, _height); - } - if (_image) { - _image->draw(offsetX + _posX, offsetY + _posY, NULL); - } - - // prepare fonts - BaseFont *font; - BaseFont *sfont; - - if (_font) { - font = _font; - } else { - font = _gameRef->_systemFont; - } - - if (_fontSelected) { - sfont = _fontSelected; - } else { - sfont = font; - } - - bool focused = isFocused(); - - _selStart = MAX(_selStart, 0); - _selEnd = MAX(_selEnd, 0); - - _selStart = (int)MIN((size_t)_selStart, strlen(_text)); - _selEnd = (int)MIN((size_t)_selEnd, strlen(_text)); - - //int CursorWidth = font->GetCharWidth(_cursorChar[0]); - int cursorWidth = font->getTextWidth((byte *)_cursorChar); - - int s1, s2; - bool curFirst; - // modify scroll offset - if (_selStart >= _selEnd) { - while (font->getTextWidth((byte *)_text + _scrollOffset, MAX(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(0, _selStart - _scrollOffset)) + - sfont->getTextWidth((byte *)(_text + MAX(_scrollOffset, _selStart)), _selEnd - MAX(_scrollOffset, _selStart)) - - > _width - cursorWidth - 2 * _frameWidth) { - _scrollOffset++; - if (_scrollOffset >= (int)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 (_gameRef->_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 (g_system->getMillis() - _lastBlinkTime >= _cursorBlinkRate) { - _lastBlinkTime = g_system->getMillis(); - _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 (g_system->getMillis() - _lastBlinkTime >= _cursorBlinkRate) { - _lastBlinkTime = g_system->getMillis(); - _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; - } - } - - - _gameRef->_renderer->addRectToList(new BaseActiveRect(_gameRef, this, NULL, offsetX + _posX, offsetY + _posY, _width, _height, 100, 100, false)); - - - _gameRef->_textEncoding = OrigEncoding; - - return STATUS_OK; -} - - -////////////////////////////////////////////////////////////////////////// -bool UIEdit::handleKeypress(Common::Event *event, bool printable) { - bool handled = false; - - if (event->type == Common::EVENT_KEYDOWN && !printable) { - switch (event->kbd.keycode) { - case Common::KEYCODE_ESCAPE: - case Common::KEYCODE_TAB: - case Common::KEYCODE_RETURN: - return false; - - // ctrl+A - case Common::KEYCODE_a: - if (BaseKeyboardState::isControlDown()) { - _selStart = 0; - _selEnd = strlen(_text); - handled = true; - } - break; - - case Common::KEYCODE_BACKSPACE: - if (_selStart == _selEnd) { - if (_gameRef->_textRTL) { - deleteChars(_selStart, _selStart + 1); - } else { - deleteChars(_selStart - 1, _selStart); - } - } else { - deleteChars(_selStart, _selEnd); - } - if (_selEnd >= _selStart) { - _selEnd -= MAX(1, _selEnd - _selStart); - } - _selStart = _selEnd; - - handled = true; - break; - - case Common::KEYCODE_LEFT: - case Common::KEYCODE_UP: - _selEnd--; - if (!BaseKeyboardState::isShiftDown()) { - _selStart = _selEnd; - } - handled = true; - break; - - case Common::KEYCODE_RIGHT: - case Common::KEYCODE_DOWN: - _selEnd++; - if (!BaseKeyboardState::isShiftDown()) { - _selStart = _selEnd; - } - handled = true; - break; - - case Common::KEYCODE_HOME: - if (_gameRef->_textRTL) { - _selEnd = strlen(_text); - if (!BaseKeyboardState::isShiftDown()) { - _selStart = _selEnd; - } - } else { - _selEnd = 0; - if (!BaseKeyboardState::isShiftDown()) { - _selStart = _selEnd; - } - } - handled = true; - break; - - case Common::KEYCODE_END: - if (_gameRef->_textRTL) { - _selEnd = 0; - if (!BaseKeyboardState::isShiftDown()) { - _selStart = _selEnd; - } - } else { - _selEnd = strlen(_text); - if (!BaseKeyboardState::isShiftDown()) { - _selStart = _selEnd; - } - } - handled = true; - break; - - case Common::KEYCODE_DELETE: - if (_selStart == _selEnd) { - if (_gameRef->_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; - handled = true; - break; - default: - break; - } - return handled; - } else if (event->type == Common::EVENT_KEYDOWN && 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 (_gameRef->_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((size_t)end, 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); - - delete[] _text; - _text = str; - } - if (_parentNotify && _parent) { - _parent->applyEvent(getName()); - } - - return end - start; -} - - -////////////////////////////////////////////////////////////////////////// -int UIEdit::insertChars(int pos, const byte *chars, int num) { - if ((int)strlen(_text) + num > _maxLength) { - num -= (strlen(_text) + num - _maxLength); - } - - pos = MAX(pos, (int)0); - pos = MIN((size_t)pos, 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); - - delete[] _text; - _text = str; - } - if (_parentNotify && _parent) { - _parent->applyEvent(getName()); - } - - return num; -} - - - -////////////////////////////////////////////////////////////////////////// -bool UIEdit::persist(BasePersistenceManager *persistMgr) { - - UIObject::persist(persistMgr); - - persistMgr->transfer(TMEMBER(_cursorBlinkRate)); - persistMgr->transfer(TMEMBER(_cursorChar)); - persistMgr->transfer(TMEMBER(_fontSelected)); - persistMgr->transfer(TMEMBER(_frameWidth)); - persistMgr->transfer(TMEMBER(_maxLength)); - persistMgr->transfer(TMEMBER(_scrollOffset)); - persistMgr->transfer(TMEMBER(_selEnd)); - persistMgr->transfer(TMEMBER(_selStart)); - - if (!persistMgr->getIsSaving()) { - _cursorVisible = false; - _lastBlinkTime = 0; - } - - return STATUS_OK; -} - -} // end of namespace Wintermute +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + * 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/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 "common/util.h" +#include "common/keyboard.h" + +namespace Wintermute { + +IMPLEMENT_PERSISTENT(UIEdit, false) + +////////////////////////////////////////////////////////////////////////// +UIEdit::UIEdit(BaseGame *inGame) : UIObject(inGame) { + _type = UI_EDIT; + + _fontSelected = NULL; + + _selStart = _selEnd = 10000; + _scrollOffset = 0; + + _cursorChar = NULL; + setCursorChar("|"); + + _cursorBlinkRate = 600; + + _frameWidth = 0; + + setText(""); + + _lastBlinkTime = 0; + _cursorVisible = true; + + _maxLength = -1; + + _canFocus = true; +} + + +////////////////////////////////////////////////////////////////////////// +UIEdit::~UIEdit() { + if (!_sharedFonts) { + if (_fontSelected) { + _gameRef->_fontStorage->removeFont(_fontSelected); + } + } + + delete[] _cursorChar; + _cursorChar = NULL; +} + + +////////////////////////////////////////////////////////////////////////// +bool UIEdit::loadFile(const char *filename) { + byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename); + if (buffer == NULL) { + _gameRef->LOG(0, "UIEdit::LoadFile failed for file '%s'", filename); + return STATUS_FAILED; + } + + bool ret; + + setFilename(filename); + + if (DID_FAIL(ret = loadBuffer(buffer, true))) { + _gameRef->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(byte *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 + + byte *params; + int cmd = 2; + BaseParser parser; + + if (complete) { + if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_EDIT) { + _gameRef->LOG(0, "'EDIT' keyword expected."); + return STATUS_FAILED; + } + buffer = params; + } + + while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { + switch (cmd) { + case TOKEN_TEMPLATE: + if (DID_FAIL(loadFile((char *)params))) { + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_NAME: + setName((char *)params); + break; + + case TOKEN_BACK: + delete _back; + _back = new UITiledImage(_gameRef); + if (!_back || DID_FAIL(_back->loadFile((char *)params))) { + delete _back; + _back = NULL; + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_IMAGE: + delete _image; + _image = new BaseSprite(_gameRef); + if (!_image || DID_FAIL(_image->loadFile((char *)params))) { + delete _image; + _image = NULL; + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_FONT: + if (_font) { + _gameRef->_fontStorage->removeFont(_font); + } + _font = _gameRef->_fontStorage->addFont((char *)params); + if (!_font) { + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_FONT_SELECTED: + if (_fontSelected) { + _gameRef->_fontStorage->removeFont(_fontSelected); + } + _fontSelected = _gameRef->_fontStorage->addFont((char *)params); + if (!_fontSelected) { + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_TEXT: + setText((char *)params); + _gameRef->_stringTable->expand(&_text); + break; + + case TOKEN_X: + parser.scanStr((char *)params, "%d", &_posX); + break; + + case TOKEN_Y: + parser.scanStr((char *)params, "%d", &_posY); + break; + + case TOKEN_WIDTH: + parser.scanStr((char *)params, "%d", &_width); + break; + + case TOKEN_HEIGHT: + parser.scanStr((char *)params, "%d", &_height); + break; + + case TOKEN_MAX_LENGTH: + parser.scanStr((char *)params, "%d", &_maxLength); + break; + + case TOKEN_CAPTION: + setCaption((char *)params); + break; + + case TOKEN_CURSOR: + delete _cursor; + _cursor = new BaseSprite(_gameRef); + if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) { + delete _cursor; + _cursor = NULL; + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_CURSOR_BLINK_RATE: + parser.scanStr((char *)params, "%d", &_cursorBlinkRate); + break; + + case TOKEN_FRAME_WIDTH: + parser.scanStr((char *)params, "%d", &_frameWidth); + break; + + case TOKEN_SCRIPT: + addScript((char *)params); + break; + + case TOKEN_PARENT_NOTIFY: + parser.scanStr((char *)params, "%b", &_parentNotify); + break; + + case TOKEN_DISABLED: + parser.scanStr((char *)params, "%b", &_disable); + break; + + case TOKEN_VISIBLE: + parser.scanStr((char *)params, "%b", &_visible); + break; + + case TOKEN_EDITOR_PROPERTY: + parseEditorProperty(params, false); + break; + } + } + if (cmd == PARSERR_TOKENNOTFOUND) { + _gameRef->LOG(0, "Syntax error in EDIT definition"); + return STATUS_FAILED; + } + if (cmd == PARSERR_GENERIC) { + _gameRef->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", getName()); + buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption()); + + buffer->putTextIndent(indent + 2, "\n"); + + if (_back && _back->getFilename()) { + buffer->putTextIndent(indent + 2, "BACK=\"%s\"\n", _back->getFilename()); + } + + if (_image && _image->getFilename()) { + buffer->putTextIndent(indent + 2, "IMAGE=\"%s\"\n", _image->getFilename()); + } + + if (_font && _font->getFilename()) { + buffer->putTextIndent(indent + 2, "FONT=\"%s\"\n", _font->getFilename()); + } + if (_fontSelected && _fontSelected->getFilename()) { + buffer->putTextIndent(indent + 2, "FONT_SELECTED=\"%s\"\n", _fontSelected->getFilename()); + } + + if (_cursor && _cursor->getFilename()) { + buffer->putTextIndent(indent + 2, "CURSOR=\"%s\"\n", _cursor->getFilename()); + } + + buffer->putTextIndent(indent + 2, "\n"); + + if (_text) { + 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 (uint32 i = 0; i < _scripts.size(); 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) { + _gameRef->_fontStorage->removeFont(_fontSelected); + } + _fontSelected = _gameRef->_fontStorage->addFont(stack->pop()->getString()); + stack->pushBool(_fontSelected != NULL); + + 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 (_gameRef->_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(_selStart, 0); + _selStart = (int)MIN((size_t)_selStart, strlen(_text)); + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // SelEnd + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "SelEnd") == 0) { + _selEnd = value->getInt(); + _selEnd = MAX(_selEnd, 0); + _selEnd = (int)MIN((size_t)_selEnd, 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 (_gameRef->_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; + } + delete[] _cursorChar; + _cursorChar = new char [strlen(character) + 1]; + if (_cursorChar) { + strcpy(_cursorChar, character); + } +} + + +////////////////////////////////////////////////////////////////////////// +bool UIEdit::display(int offsetX, int offsetY) { + if (!_visible) { + return STATUS_OK; + } + + + // hack! + TTextEncoding OrigEncoding = _gameRef->_textEncoding; + _gameRef->_textEncoding = TEXT_ANSI; + + if (_back) { + _back->display(offsetX + _posX, offsetY + _posY, _width, _height); + } + if (_image) { + _image->draw(offsetX + _posX, offsetY + _posY, NULL); + } + + // prepare fonts + BaseFont *font; + BaseFont *sfont; + + if (_font) { + font = _font; + } else { + font = _gameRef->_systemFont; + } + + if (_fontSelected) { + sfont = _fontSelected; + } else { + sfont = font; + } + + bool focused = isFocused(); + + _selStart = MAX(_selStart, 0); + _selEnd = MAX(_selEnd, 0); + + _selStart = (int)MIN((size_t)_selStart, strlen(_text)); + _selEnd = (int)MIN((size_t)_selEnd, strlen(_text)); + + //int CursorWidth = font->GetCharWidth(_cursorChar[0]); + int cursorWidth = font->getTextWidth((byte *)_cursorChar); + + int s1, s2; + bool curFirst; + // modify scroll offset + if (_selStart >= _selEnd) { + while (font->getTextWidth((byte *)_text + _scrollOffset, MAX(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(0, _selStart - _scrollOffset)) + + sfont->getTextWidth((byte *)(_text + MAX(_scrollOffset, _selStart)), _selEnd - MAX(_scrollOffset, _selStart)) + + > _width - cursorWidth - 2 * _frameWidth) { + _scrollOffset++; + if (_scrollOffset >= (int)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 (_gameRef->_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 (g_system->getMillis() - _lastBlinkTime >= _cursorBlinkRate) { + _lastBlinkTime = g_system->getMillis(); + _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 (g_system->getMillis() - _lastBlinkTime >= _cursorBlinkRate) { + _lastBlinkTime = g_system->getMillis(); + _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; + } + } + + + _gameRef->_renderer->addRectToList(new BaseActiveRect(_gameRef, this, NULL, offsetX + _posX, offsetY + _posY, _width, _height, 100, 100, false)); + + + _gameRef->_textEncoding = OrigEncoding; + + return STATUS_OK; +} + + +////////////////////////////////////////////////////////////////////////// +bool UIEdit::handleKeypress(Common::Event *event, bool printable) { + bool handled = false; + + if (event->type == Common::EVENT_KEYDOWN && !printable) { + switch (event->kbd.keycode) { + case Common::KEYCODE_ESCAPE: + case Common::KEYCODE_TAB: + case Common::KEYCODE_RETURN: + return false; + + // ctrl+A + case Common::KEYCODE_a: + if (BaseKeyboardState::isControlDown()) { + _selStart = 0; + _selEnd = strlen(_text); + handled = true; + } + break; + + case Common::KEYCODE_BACKSPACE: + if (_selStart == _selEnd) { + if (_gameRef->_textRTL) { + deleteChars(_selStart, _selStart + 1); + } else { + deleteChars(_selStart - 1, _selStart); + } + } else { + deleteChars(_selStart, _selEnd); + } + if (_selEnd >= _selStart) { + _selEnd -= MAX(1, _selEnd - _selStart); + } + _selStart = _selEnd; + + handled = true; + break; + + case Common::KEYCODE_LEFT: + case Common::KEYCODE_UP: + _selEnd--; + if (!BaseKeyboardState::isShiftDown()) { + _selStart = _selEnd; + } + handled = true; + break; + + case Common::KEYCODE_RIGHT: + case Common::KEYCODE_DOWN: + _selEnd++; + if (!BaseKeyboardState::isShiftDown()) { + _selStart = _selEnd; + } + handled = true; + break; + + case Common::KEYCODE_HOME: + if (_gameRef->_textRTL) { + _selEnd = strlen(_text); + if (!BaseKeyboardState::isShiftDown()) { + _selStart = _selEnd; + } + } else { + _selEnd = 0; + if (!BaseKeyboardState::isShiftDown()) { + _selStart = _selEnd; + } + } + handled = true; + break; + + case Common::KEYCODE_END: + if (_gameRef->_textRTL) { + _selEnd = 0; + if (!BaseKeyboardState::isShiftDown()) { + _selStart = _selEnd; + } + } else { + _selEnd = strlen(_text); + if (!BaseKeyboardState::isShiftDown()) { + _selStart = _selEnd; + } + } + handled = true; + break; + + case Common::KEYCODE_DELETE: + if (_selStart == _selEnd) { + if (_gameRef->_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; + handled = true; + break; + default: + break; + } + return handled; + } else if (event->type == Common::EVENT_KEYDOWN && 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 (_gameRef->_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((size_t)end, 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); + + delete[] _text; + _text = str; + } + if (_parentNotify && _parent) { + _parent->applyEvent(getName()); + } + + return end - start; +} + + +////////////////////////////////////////////////////////////////////////// +int UIEdit::insertChars(int pos, const byte *chars, int num) { + if ((int)strlen(_text) + num > _maxLength) { + num -= (strlen(_text) + num - _maxLength); + } + + pos = MAX(pos, (int)0); + pos = MIN((size_t)pos, 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); + + delete[] _text; + _text = str; + } + if (_parentNotify && _parent) { + _parent->applyEvent(getName()); + } + + return num; +} + + + +////////////////////////////////////////////////////////////////////////// +bool UIEdit::persist(BasePersistenceManager *persistMgr) { + + UIObject::persist(persistMgr); + + persistMgr->transfer(TMEMBER(_cursorBlinkRate)); + persistMgr->transfer(TMEMBER(_cursorChar)); + persistMgr->transfer(TMEMBER(_fontSelected)); + persistMgr->transfer(TMEMBER(_frameWidth)); + persistMgr->transfer(TMEMBER(_maxLength)); + persistMgr->transfer(TMEMBER(_scrollOffset)); + persistMgr->transfer(TMEMBER(_selEnd)); + persistMgr->transfer(TMEMBER(_selStart)); + + if (!persistMgr->getIsSaving()) { + _cursorVisible = false; + _lastBlinkTime = 0; + } + + return STATUS_OK; +} + +} // end of namespace Wintermute diff --git a/engines/wintermute/ui/ui_edit.h b/engines/wintermute/ui/ui_edit.h index fa760951b0..610629afb3 100644 --- a/engines/wintermute/ui/ui_edit.h +++ b/engines/wintermute/ui/ui_edit.h @@ -1,72 +1,72 @@ -/* 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 2 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -/* - * 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) - int _maxLength; - int insertChars(int pos, const byte *chars, int num); - int deleteChars(int start, int end); - bool _cursorVisible; - uint32 _lastBlinkTime; - virtual bool display(int offsetX, int offsetY); - virtual bool handleKeypress(Common::Event *event, bool printable = false); - int _scrollOffset; - int _frameWidth; - uint32 _cursorBlinkRate; - void setCursorChar(const char *character); - char *_cursorChar; - int _selEnd; - int _selStart; - BaseFont *_fontSelected; - UIEdit(BaseGame *inGame); - virtual ~UIEdit(); - - bool loadFile(const char *filename); - bool loadBuffer(byte *buffer, bool complete = true); - virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent); - - // scripting interface - virtual ScValue *scGetProperty(const char *name); - virtual bool scSetProperty(const char *name, ScValue *value); - virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name); - virtual const char *scToString(); -}; - -} // end of namespace Wintermute - -#endif +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + * 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) + int _maxLength; + int insertChars(int pos, const byte *chars, int num); + int deleteChars(int start, int end); + bool _cursorVisible; + uint32 _lastBlinkTime; + virtual bool display(int offsetX, int offsetY); + virtual bool handleKeypress(Common::Event *event, bool printable = false); + int _scrollOffset; + int _frameWidth; + uint32 _cursorBlinkRate; + void setCursorChar(const char *character); + char *_cursorChar; + int _selEnd; + int _selStart; + BaseFont *_fontSelected; + UIEdit(BaseGame *inGame); + virtual ~UIEdit(); + + bool loadFile(const char *filename); + bool loadBuffer(byte *buffer, bool complete = true); + virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent); + + // scripting interface + virtual ScValue *scGetProperty(const char *name); + virtual bool scSetProperty(const char *name, ScValue *value); + virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name); + virtual const char *scToString(); +}; + +} // end of namespace Wintermute + +#endif diff --git a/engines/wintermute/ui/ui_entity.cpp b/engines/wintermute/ui/ui_entity.cpp index 18a4db124a..c49cb5a240 100644 --- a/engines/wintermute/ui/ui_entity.cpp +++ b/engines/wintermute/ui/ui_entity.cpp @@ -1,366 +1,366 @@ -/* 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 2 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -/* - * 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" - -namespace Wintermute { - -IMPLEMENT_PERSISTENT(UIEntity, false) - -////////////////////////////////////////////////////////////////////////// -UIEntity::UIEntity(BaseGame *inGame) : UIObject(inGame) { - _type = UI_CUSTOM; - _entity = NULL; -} - - -////////////////////////////////////////////////////////////////////////// -UIEntity::~UIEntity() { - if (_entity) { - _gameRef->unregisterObject(_entity); - } - _entity = NULL; -} - - -////////////////////////////////////////////////////////////////////////// -bool UIEntity::loadFile(const char *filename) { - byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename); - if (buffer == NULL) { - _gameRef->LOG(0, "UIEntity::LoadFile failed for file '%s'", filename); - return STATUS_FAILED; - } - - bool ret; - - setFilename(filename); - - if (DID_FAIL(ret = loadBuffer(buffer, true))) { - _gameRef->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(byte *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 - - byte *params; - int cmd = 2; - BaseParser parser; - - if (complete) { - if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_ENTITY_CONTAINER) { - _gameRef->LOG(0, "'ENTITY_CONTAINER' keyword expected."); - return STATUS_FAILED; - } - buffer = params; - } - - while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { - switch (cmd) { - case TOKEN_TEMPLATE: - if (DID_FAIL(loadFile((char *)params))) { - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_NAME: - setName((char *)params); - break; - - case TOKEN_X: - parser.scanStr((char *)params, "%d", &_posX); - break; - - case TOKEN_Y: - parser.scanStr((char *)params, "%d", &_posY); - break; - - case TOKEN_DISABLED: - parser.scanStr((char *)params, "%b", &_disable); - break; - - case TOKEN_VISIBLE: - parser.scanStr((char *)params, "%b", &_visible); - break; - - case TOKEN_ENTITY: - if (DID_FAIL(setEntity((char *)params))) { - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_SCRIPT: - addScript((char *)params); - break; - - case TOKEN_EDITOR_PROPERTY: - parseEditorProperty(params, false); - break; - } - } - if (cmd == PARSERR_TOKENNOTFOUND) { - _gameRef->LOG(0, "Syntax error in ENTITY_CONTAINER definition"); - return STATUS_FAILED; - } - if (cmd == PARSERR_GENERIC) { - _gameRef->LOG(0, "Error loading ENTITY_CONTAINER definition"); - return STATUS_FAILED; - } - - correctSize(); - - if (_gameRef->_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", getName()); - - 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->getFilename()) { - buffer->putTextIndent(indent + 2, "ENTITY=\"%s\"\n", _entity->getFilename()); - } - - buffer->putTextIndent(indent + 2, "\n"); - - // scripts - for (uint32 i = 0; i < _scripts.size(); 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) { - _gameRef->unregisterObject(_entity); - } - _entity = new AdEntity(_gameRef); - if (!_entity || DID_FAIL(_entity->loadFile(filename))) { - delete _entity; - _entity = NULL; - return STATUS_FAILED; - } else { - _entity->_nonIntMouseEvents = true; - _entity->_sceneIndependent = true; - _entity->makeFreezable(false); - _gameRef->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->transfer(TMEMBER(_entity)); - return STATUS_OK; -} - -} // end of namespace Wintermute +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + * 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" + +namespace Wintermute { + +IMPLEMENT_PERSISTENT(UIEntity, false) + +////////////////////////////////////////////////////////////////////////// +UIEntity::UIEntity(BaseGame *inGame) : UIObject(inGame) { + _type = UI_CUSTOM; + _entity = NULL; +} + + +////////////////////////////////////////////////////////////////////////// +UIEntity::~UIEntity() { + if (_entity) { + _gameRef->unregisterObject(_entity); + } + _entity = NULL; +} + + +////////////////////////////////////////////////////////////////////////// +bool UIEntity::loadFile(const char *filename) { + byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename); + if (buffer == NULL) { + _gameRef->LOG(0, "UIEntity::LoadFile failed for file '%s'", filename); + return STATUS_FAILED; + } + + bool ret; + + setFilename(filename); + + if (DID_FAIL(ret = loadBuffer(buffer, true))) { + _gameRef->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(byte *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 + + byte *params; + int cmd = 2; + BaseParser parser; + + if (complete) { + if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_ENTITY_CONTAINER) { + _gameRef->LOG(0, "'ENTITY_CONTAINER' keyword expected."); + return STATUS_FAILED; + } + buffer = params; + } + + while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { + switch (cmd) { + case TOKEN_TEMPLATE: + if (DID_FAIL(loadFile((char *)params))) { + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_NAME: + setName((char *)params); + break; + + case TOKEN_X: + parser.scanStr((char *)params, "%d", &_posX); + break; + + case TOKEN_Y: + parser.scanStr((char *)params, "%d", &_posY); + break; + + case TOKEN_DISABLED: + parser.scanStr((char *)params, "%b", &_disable); + break; + + case TOKEN_VISIBLE: + parser.scanStr((char *)params, "%b", &_visible); + break; + + case TOKEN_ENTITY: + if (DID_FAIL(setEntity((char *)params))) { + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_SCRIPT: + addScript((char *)params); + break; + + case TOKEN_EDITOR_PROPERTY: + parseEditorProperty(params, false); + break; + } + } + if (cmd == PARSERR_TOKENNOTFOUND) { + _gameRef->LOG(0, "Syntax error in ENTITY_CONTAINER definition"); + return STATUS_FAILED; + } + if (cmd == PARSERR_GENERIC) { + _gameRef->LOG(0, "Error loading ENTITY_CONTAINER definition"); + return STATUS_FAILED; + } + + correctSize(); + + if (_gameRef->_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", getName()); + + 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->getFilename()) { + buffer->putTextIndent(indent + 2, "ENTITY=\"%s\"\n", _entity->getFilename()); + } + + buffer->putTextIndent(indent + 2, "\n"); + + // scripts + for (uint32 i = 0; i < _scripts.size(); 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) { + _gameRef->unregisterObject(_entity); + } + _entity = new AdEntity(_gameRef); + if (!_entity || DID_FAIL(_entity->loadFile(filename))) { + delete _entity; + _entity = NULL; + return STATUS_FAILED; + } else { + _entity->_nonIntMouseEvents = true; + _entity->_sceneIndependent = true; + _entity->makeFreezable(false); + _gameRef->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->transfer(TMEMBER(_entity)); + return STATUS_OK; +} + +} // end of namespace Wintermute diff --git a/engines/wintermute/ui/ui_entity.h b/engines/wintermute/ui/ui_entity.h index aeb32a6ffb..3bf8068fd5 100644 --- a/engines/wintermute/ui/ui_entity.h +++ b/engines/wintermute/ui/ui_entity.h @@ -1,59 +1,59 @@ -/* 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 2 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -/* - * 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); - virtual ~UIEntity(); - bool loadFile(const char *filename); - bool loadBuffer(byte *buffer, bool complete); - virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent); - - virtual bool display() { return display(0, 0); } - virtual bool display(int offsetX, int offsetY); - AdEntity *_entity; - bool setEntity(const char *filename); - - // scripting interface - virtual ScValue *scGetProperty(const char *name); - virtual bool scSetProperty(const char *name, ScValue *value); - virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name); - virtual const char *scToString(); -}; - -} // end of namespace Wintermute - -#endif +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + * 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); + virtual ~UIEntity(); + bool loadFile(const char *filename); + bool loadBuffer(byte *buffer, bool complete); + virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent); + + virtual bool display() { return display(0, 0); } + virtual bool display(int offsetX, int offsetY); + AdEntity *_entity; + bool setEntity(const char *filename); + + // scripting interface + virtual ScValue *scGetProperty(const char *name); + virtual bool scSetProperty(const char *name, ScValue *value); + virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name); + virtual const char *scToString(); +}; + +} // end of namespace Wintermute + +#endif diff --git a/engines/wintermute/ui/ui_object.cpp b/engines/wintermute/ui/ui_object.cpp index 716570fd67..85e381c55b 100644 --- a/engines/wintermute/ui/ui_object.cpp +++ b/engines/wintermute/ui/ui_object.cpp @@ -1,650 +1,650 @@ -/* 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 2 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -/* - * 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/scriptables/script_value.h" -#include "engines/wintermute/base/scriptables/script_stack.h" -#include "engines/wintermute/base/font/base_font_storage.h" - -namespace Wintermute { - -IMPLEMENT_PERSISTENT(UIObject, false) - -////////////////////////////////////////////////////////////////////////// -UIObject::UIObject(BaseGame *inGame) : BaseObject(inGame) { - _back = NULL; - _image = NULL; - _font = NULL; - _text = NULL; - _sharedFonts = _sharedImages = false; - - _width = _height = 0; - - _listenerObject = NULL; - _listenerParamObject = NULL; - _listenerParamDWORD = 0; - - _disable = false; - _visible = true; - - _type = UI_UNKNOWN; - _parent = NULL; - - _parentNotify = false; - - _focusedWidget = NULL; - - _canFocus = false; - _nonIntMouseEvents = true; -} - - -////////////////////////////////////////////////////////////////////////// -UIObject::~UIObject() { - if (!_gameRef->_loadInProgress) { - SystemClassRegistry::getInstance()->enumInstances(BaseGame::invalidateValues, "ScValue", (void *)this); - } - - if (_back) { - delete _back; - } - if (_font && !_sharedFonts) { - _gameRef->_fontStorage->removeFont(_font); - } - - if (_image && !_sharedImages) { - delete _image; - } - - if (_text) { - delete[] _text; - } - - _focusedWidget = NULL; // ref only -} - - -////////////////////////////////////////////////////////////////////////// -void UIObject::setText(const char *text) { - if (_text) { - delete[] _text; - } - _text = new char [strlen(text) + 1]; - if (_text) { - strcpy(_text, 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() { - 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) { - _gameRef->_fontStorage->removeFont(_font); - } - if (val->isNULL()) { - _font = NULL; - stack->pushBool(true); - } else { - _font = _gameRef->_fontStorage->addFont(val->getString()); - stack->pushBool(_font != NULL); - } - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // SetImage - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "SetImage") == 0) { - stack->correctParams(1); - ScValue *val = stack->pop(); - - /* const char *filename = */ val->getString(); - - delete _image; - _image = NULL; - if (val->isNULL()) { - stack->pushBool(true); - return STATUS_OK; - } - - _image = new BaseSprite(_gameRef); - if (!_image || DID_FAIL(_image->loadFile(val->getString()))) { - delete _image; - _image = NULL; - stack->pushBool(false); - } else { - stack->pushBool(true); - } - - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // GetImage - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "GetImage") == 0) { - stack->correctParams(0); - if (!_image || !_image->getFilename()) { - stack->pushNULL(); - } else { - stack->pushString(_image->getFilename()); - } - - 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; - - uint32 i; - bool found = false; - ScValue *val = stack->pop(); - // find directly - if (val->isNative()) { - UIObject *widget = (UIObject *)val->getNative(); - for (i = 0; i < win->_widgets.size(); i++) { - if (win->_widgets[i] == widget) { - found = true; - break; - } - } - } - // find by name - else { - const char *findName = val->getString(); - for (i = 0; i < win->_widgets.size(); i++) { - if (scumm_stricmp(win->_widgets[i]->getName(), findName) == 0) { - found = true; - break; - } - } - } - - if (found) { - bool done = false; - for (uint32 j = 0; j < win->_widgets.size(); j++) { - if (win->_widgets[j] == this) { - if (strcmp(name, "MoveAfter") == 0) { - i++; - } - if (j >= i) { - j++; - } - - win->_widgets.insert_at(i, this); - win->_widgets.remove_at(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 (uint32 i = 0; i < win->_widgets.size(); i++) { - if (win->_widgets[i] == this) { - win->_widgets.remove_at(i); - win->_widgets.insert_at(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 (uint32 i = 0; i < win->_widgets.size(); i++) { - if (win->_widgets[i] == this) { - win->_widgets.remove_at(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(getName()); - 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 (uint32 i = 0; i < win->_widgets.size(); i++) { - if (win->_widgets[i] == this) { - if (strcmp(name, "NextSibling") == 0) { - if (i < win->_widgets.size() - 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 (!_gameRef->_focusedWindow) { - return false; - } - if (_gameRef->_focusedWindow == this) { - return true; - } - - UIObject *obj = _gameRef->_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) { - _gameRef->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->transfer(TMEMBER(_back)); - persistMgr->transfer(TMEMBER(_canFocus)); - persistMgr->transfer(TMEMBER(_disable)); - persistMgr->transfer(TMEMBER(_focusedWidget)); - persistMgr->transfer(TMEMBER(_font)); - persistMgr->transfer(TMEMBER(_height)); - persistMgr->transfer(TMEMBER(_image)); - persistMgr->transfer(TMEMBER(_listenerObject)); - persistMgr->transfer(TMEMBER(_listenerParamObject)); - persistMgr->transfer(TMEMBER(_listenerParamDWORD)); - persistMgr->transfer(TMEMBER(_parent)); - persistMgr->transfer(TMEMBER(_parentNotify)); - persistMgr->transfer(TMEMBER(_sharedFonts)); - persistMgr->transfer(TMEMBER(_sharedImages)); - persistMgr->transfer(TMEMBER(_text)); - persistMgr->transfer(TMEMBER_INT(_type)); - persistMgr->transfer(TMEMBER(_visible)); - persistMgr->transfer(TMEMBER(_width)); - - return STATUS_OK; -} - -////////////////////////////////////////////////////////////////////////// -bool UIObject::saveAsText(BaseDynamicBuffer *buffer, int indent) { - return STATUS_FAILED; -} - -} // end of namespace Wintermute +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + * 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/scriptables/script_value.h" +#include "engines/wintermute/base/scriptables/script_stack.h" +#include "engines/wintermute/base/font/base_font_storage.h" + +namespace Wintermute { + +IMPLEMENT_PERSISTENT(UIObject, false) + +////////////////////////////////////////////////////////////////////////// +UIObject::UIObject(BaseGame *inGame) : BaseObject(inGame) { + _back = NULL; + _image = NULL; + _font = NULL; + _text = NULL; + _sharedFonts = _sharedImages = false; + + _width = _height = 0; + + _listenerObject = NULL; + _listenerParamObject = NULL; + _listenerParamDWORD = 0; + + _disable = false; + _visible = true; + + _type = UI_UNKNOWN; + _parent = NULL; + + _parentNotify = false; + + _focusedWidget = NULL; + + _canFocus = false; + _nonIntMouseEvents = true; +} + + +////////////////////////////////////////////////////////////////////////// +UIObject::~UIObject() { + if (!_gameRef->_loadInProgress) { + SystemClassRegistry::getInstance()->enumInstances(BaseGame::invalidateValues, "ScValue", (void *)this); + } + + if (_back) { + delete _back; + } + if (_font && !_sharedFonts) { + _gameRef->_fontStorage->removeFont(_font); + } + + if (_image && !_sharedImages) { + delete _image; + } + + if (_text) { + delete[] _text; + } + + _focusedWidget = NULL; // ref only +} + + +////////////////////////////////////////////////////////////////////////// +void UIObject::setText(const char *text) { + if (_text) { + delete[] _text; + } + _text = new char [strlen(text) + 1]; + if (_text) { + strcpy(_text, 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() { + 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) { + _gameRef->_fontStorage->removeFont(_font); + } + if (val->isNULL()) { + _font = NULL; + stack->pushBool(true); + } else { + _font = _gameRef->_fontStorage->addFont(val->getString()); + stack->pushBool(_font != NULL); + } + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // SetImage + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "SetImage") == 0) { + stack->correctParams(1); + ScValue *val = stack->pop(); + + /* const char *filename = */ val->getString(); + + delete _image; + _image = NULL; + if (val->isNULL()) { + stack->pushBool(true); + return STATUS_OK; + } + + _image = new BaseSprite(_gameRef); + if (!_image || DID_FAIL(_image->loadFile(val->getString()))) { + delete _image; + _image = NULL; + stack->pushBool(false); + } else { + stack->pushBool(true); + } + + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // GetImage + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "GetImage") == 0) { + stack->correctParams(0); + if (!_image || !_image->getFilename()) { + stack->pushNULL(); + } else { + stack->pushString(_image->getFilename()); + } + + 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; + + uint32 i; + bool found = false; + ScValue *val = stack->pop(); + // find directly + if (val->isNative()) { + UIObject *widget = (UIObject *)val->getNative(); + for (i = 0; i < win->_widgets.size(); i++) { + if (win->_widgets[i] == widget) { + found = true; + break; + } + } + } + // find by name + else { + const char *findName = val->getString(); + for (i = 0; i < win->_widgets.size(); i++) { + if (scumm_stricmp(win->_widgets[i]->getName(), findName) == 0) { + found = true; + break; + } + } + } + + if (found) { + bool done = false; + for (uint32 j = 0; j < win->_widgets.size(); j++) { + if (win->_widgets[j] == this) { + if (strcmp(name, "MoveAfter") == 0) { + i++; + } + if (j >= i) { + j++; + } + + win->_widgets.insert_at(i, this); + win->_widgets.remove_at(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 (uint32 i = 0; i < win->_widgets.size(); i++) { + if (win->_widgets[i] == this) { + win->_widgets.remove_at(i); + win->_widgets.insert_at(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 (uint32 i = 0; i < win->_widgets.size(); i++) { + if (win->_widgets[i] == this) { + win->_widgets.remove_at(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(getName()); + 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 (uint32 i = 0; i < win->_widgets.size(); i++) { + if (win->_widgets[i] == this) { + if (strcmp(name, "NextSibling") == 0) { + if (i < win->_widgets.size() - 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 (!_gameRef->_focusedWindow) { + return false; + } + if (_gameRef->_focusedWindow == this) { + return true; + } + + UIObject *obj = _gameRef->_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) { + _gameRef->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->transfer(TMEMBER(_back)); + persistMgr->transfer(TMEMBER(_canFocus)); + persistMgr->transfer(TMEMBER(_disable)); + persistMgr->transfer(TMEMBER(_focusedWidget)); + persistMgr->transfer(TMEMBER(_font)); + persistMgr->transfer(TMEMBER(_height)); + persistMgr->transfer(TMEMBER(_image)); + persistMgr->transfer(TMEMBER(_listenerObject)); + persistMgr->transfer(TMEMBER(_listenerParamObject)); + persistMgr->transfer(TMEMBER(_listenerParamDWORD)); + persistMgr->transfer(TMEMBER(_parent)); + persistMgr->transfer(TMEMBER(_parentNotify)); + persistMgr->transfer(TMEMBER(_sharedFonts)); + persistMgr->transfer(TMEMBER(_sharedImages)); + persistMgr->transfer(TMEMBER(_text)); + persistMgr->transfer(TMEMBER_INT(_type)); + persistMgr->transfer(TMEMBER(_visible)); + persistMgr->transfer(TMEMBER(_width)); + + return STATUS_OK; +} + +////////////////////////////////////////////////////////////////////////// +bool UIObject::saveAsText(BaseDynamicBuffer *buffer, int indent) { + return STATUS_FAILED; +} + +} // end of namespace Wintermute diff --git a/engines/wintermute/ui/ui_object.h b/engines/wintermute/ui/ui_object.h index b0a34fe61e..81c025d33b 100644 --- a/engines/wintermute/ui/ui_object.h +++ b/engines/wintermute/ui/ui_object.h @@ -1,85 +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 2 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -/* - * 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: - - bool getTotalOffset(int *offsetX, int *offsetY); - bool _canFocus; - bool focus(); - virtual bool handleMouse(TMouseEvent event, TMouseButton button); - bool isFocused(); - bool _parentNotify; - DECLARE_PERSISTENT(UIObject, BaseObject) - UIObject *_parent; - virtual bool display() { 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 = NULL); - virtual ~UIObject(); - int _width; - int _height; - TUIObjectType _type; - BaseSprite *_image; - void setListener(BaseScriptHolder *object, BaseScriptHolder *listenerObject, uint32 listenerParam); - BaseScriptHolder *_listenerParamObject; - uint32 _listenerParamDWORD; - BaseScriptHolder *_listenerObject; - UIObject *_focusedWidget; - virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent); - - // scripting interface - virtual ScValue *scGetProperty(const char *name); - virtual bool scSetProperty(const char *name, ScValue *value); - virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name); - virtual const char *scToString(); -}; - -} // end of namespace Wintermute - -#endif +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + * 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: + + bool getTotalOffset(int *offsetX, int *offsetY); + bool _canFocus; + bool focus(); + virtual bool handleMouse(TMouseEvent event, TMouseButton button); + bool isFocused(); + bool _parentNotify; + DECLARE_PERSISTENT(UIObject, BaseObject) + UIObject *_parent; + virtual bool display() { 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 = NULL); + virtual ~UIObject(); + int _width; + int _height; + TUIObjectType _type; + BaseSprite *_image; + void setListener(BaseScriptHolder *object, BaseScriptHolder *listenerObject, uint32 listenerParam); + BaseScriptHolder *_listenerParamObject; + uint32 _listenerParamDWORD; + BaseScriptHolder *_listenerObject; + UIObject *_focusedWidget; + virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent); + + // scripting interface + virtual ScValue *scGetProperty(const char *name); + virtual bool scSetProperty(const char *name, ScValue *value); + virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name); + virtual const char *scToString(); +}; + +} // end of namespace Wintermute + +#endif diff --git a/engines/wintermute/ui/ui_text.cpp b/engines/wintermute/ui/ui_text.cpp index 86d5c754f1..1844b640d0 100644 --- a/engines/wintermute/ui/ui_text.cpp +++ b/engines/wintermute/ui/ui_text.cpp @@ -1,522 +1,522 @@ -/* 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 2 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -/* - * 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" - -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 = _gameRef->_systemFont; - } - - if (_back) { - _back->display(offsetX + _posX, offsetY + _posY, _width, _height); - } - if (_image) { - _image->draw(offsetX + _posX, offsetY + _posY, NULL); - } - - if (font && _text) { - 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); - } - - //_gameRef->_renderer->_rectList.add(new BaseActiveRect(_gameRef, this, NULL, OffsetX + _posX, OffsetY + _posY, _width, _height, 100, 100, false)); - - return STATUS_OK; -} - - - -////////////////////////////////////////////////////////////////////////// -bool UIText::loadFile(const char *filename) { - byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename); - if (buffer == NULL) { - _gameRef->LOG(0, "UIText::LoadFile failed for file '%s'", filename); - return STATUS_FAILED; - } - - bool ret; - - setFilename(filename); - - if (DID_FAIL(ret = loadBuffer(buffer, true))) { - _gameRef->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(byte *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 - - byte *params; - int cmd = 2; - BaseParser parser; - - if (complete) { - if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_STATIC) { - _gameRef->LOG(0, "'STATIC' keyword expected."); - return STATUS_FAILED; - } - buffer = params; - } - - while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { - switch (cmd) { - case TOKEN_TEMPLATE: - if (DID_FAIL(loadFile((char *)params))) { - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_NAME: - setName((char *)params); - break; - - case TOKEN_CAPTION: - setCaption((char *)params); - break; - - case TOKEN_BACK: - delete _back; - _back = new UITiledImage(_gameRef); - if (!_back || DID_FAIL(_back->loadFile((char *)params))) { - delete _back; - _back = NULL; - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_IMAGE: - delete _image; - _image = new BaseSprite(_gameRef); - if (!_image || DID_FAIL(_image->loadFile((char *)params))) { - delete _image; - _image = NULL; - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_FONT: - if (_font) { - _gameRef->_fontStorage->removeFont(_font); - } - _font = _gameRef->_fontStorage->addFont((char *)params); - if (!_font) { - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_TEXT: - setText((char *)params); - _gameRef->_stringTable->expand(&_text); - break; - - case TOKEN_TEXT_ALIGN: - if (scumm_stricmp((char *)params, "left") == 0) { - _textAlign = TAL_LEFT; - } else if (scumm_stricmp((char *)params, "right") == 0) { - _textAlign = TAL_RIGHT; - } else { - _textAlign = TAL_CENTER; - } - break; - - case TOKEN_VERTICAL_ALIGN: - if (scumm_stricmp((char *)params, "top") == 0) { - _verticalAlign = VAL_TOP; - } else if (scumm_stricmp((char *)params, "bottom") == 0) { - _verticalAlign = VAL_BOTTOM; - } else { - _verticalAlign = VAL_CENTER; - } - break; - - case TOKEN_X: - parser.scanStr((char *)params, "%d", &_posX); - break; - - case TOKEN_Y: - parser.scanStr((char *)params, "%d", &_posY); - break; - - case TOKEN_WIDTH: - parser.scanStr((char *)params, "%d", &_width); - break; - - case TOKEN_HEIGHT: - parser.scanStr((char *)params, "%d", &_height); - break; - - case TOKEN_CURSOR: - delete _cursor; - _cursor = new BaseSprite(_gameRef); - if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) { - delete _cursor; - _cursor = NULL; - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_SCRIPT: - addScript((char *)params); - break; - - case TOKEN_PARENT_NOTIFY: - parser.scanStr((char *)params, "%b", &_parentNotify); - break; - - case TOKEN_DISABLED: - parser.scanStr((char *)params, "%b", &_disable); - break; - - case TOKEN_VISIBLE: - parser.scanStr((char *)params, "%b", &_visible); - break; - - case TOKEN_EDITOR_PROPERTY: - parseEditorProperty(params, false); - break; - } - } - if (cmd == PARSERR_TOKENNOTFOUND) { - _gameRef->LOG(0, "Syntax error in STATIC definition"); - return STATUS_FAILED; - } - if (cmd == PARSERR_GENERIC) { - _gameRef->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", getName()); - buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption()); - - buffer->putTextIndent(indent + 2, "\n"); - - if (_back && _back->getFilename()) { - buffer->putTextIndent(indent + 2, "BACK=\"%s\"\n", _back->getFilename()); - } - - if (_image && _image->getFilename()) { - buffer->putTextIndent(indent + 2, "IMAGE=\"%s\"\n", _image->getFilename()); - } - - if (_font && _font->getFilename()) { - buffer->putTextIndent(indent + 2, "FONT=\"%s\"\n", _font->getFilename()); - } - - if (_cursor && _cursor->getFilename()) { - buffer->putTextIndent(indent + 2, "CURSOR=\"%s\"\n", _cursor->getFilename()); - } - - if (_text) { - 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: - error("UIText::SaveAsText - Unhandled enum"); - 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: - error("UIText::SaveAsText - Unhandled enum value: NUM_VERTICAL_ALIGN"); - } - - 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 (uint32 i = 0; i < _scripts.size(); 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->transfer(TMEMBER_INT(_textAlign)); - persistMgr->transfer(TMEMBER_INT(_verticalAlign)); - - return STATUS_OK; -} - - -////////////////////////////////////////////////////////////////////////// -bool UIText::sizeToFit() { - if (_font && _text) { - _width = _font->getTextWidth((byte *)_text); - _height = _font->getTextHeight((byte *)_text, _width); - } - return STATUS_OK; -} - -} // end of namespace Wintermute +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + * 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" + +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 = _gameRef->_systemFont; + } + + if (_back) { + _back->display(offsetX + _posX, offsetY + _posY, _width, _height); + } + if (_image) { + _image->draw(offsetX + _posX, offsetY + _posY, NULL); + } + + if (font && _text) { + 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); + } + + //_gameRef->_renderer->_rectList.add(new BaseActiveRect(_gameRef, this, NULL, OffsetX + _posX, OffsetY + _posY, _width, _height, 100, 100, false)); + + return STATUS_OK; +} + + + +////////////////////////////////////////////////////////////////////////// +bool UIText::loadFile(const char *filename) { + byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename); + if (buffer == NULL) { + _gameRef->LOG(0, "UIText::LoadFile failed for file '%s'", filename); + return STATUS_FAILED; + } + + bool ret; + + setFilename(filename); + + if (DID_FAIL(ret = loadBuffer(buffer, true))) { + _gameRef->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(byte *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 + + byte *params; + int cmd = 2; + BaseParser parser; + + if (complete) { + if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_STATIC) { + _gameRef->LOG(0, "'STATIC' keyword expected."); + return STATUS_FAILED; + } + buffer = params; + } + + while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { + switch (cmd) { + case TOKEN_TEMPLATE: + if (DID_FAIL(loadFile((char *)params))) { + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_NAME: + setName((char *)params); + break; + + case TOKEN_CAPTION: + setCaption((char *)params); + break; + + case TOKEN_BACK: + delete _back; + _back = new UITiledImage(_gameRef); + if (!_back || DID_FAIL(_back->loadFile((char *)params))) { + delete _back; + _back = NULL; + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_IMAGE: + delete _image; + _image = new BaseSprite(_gameRef); + if (!_image || DID_FAIL(_image->loadFile((char *)params))) { + delete _image; + _image = NULL; + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_FONT: + if (_font) { + _gameRef->_fontStorage->removeFont(_font); + } + _font = _gameRef->_fontStorage->addFont((char *)params); + if (!_font) { + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_TEXT: + setText((char *)params); + _gameRef->_stringTable->expand(&_text); + break; + + case TOKEN_TEXT_ALIGN: + if (scumm_stricmp((char *)params, "left") == 0) { + _textAlign = TAL_LEFT; + } else if (scumm_stricmp((char *)params, "right") == 0) { + _textAlign = TAL_RIGHT; + } else { + _textAlign = TAL_CENTER; + } + break; + + case TOKEN_VERTICAL_ALIGN: + if (scumm_stricmp((char *)params, "top") == 0) { + _verticalAlign = VAL_TOP; + } else if (scumm_stricmp((char *)params, "bottom") == 0) { + _verticalAlign = VAL_BOTTOM; + } else { + _verticalAlign = VAL_CENTER; + } + break; + + case TOKEN_X: + parser.scanStr((char *)params, "%d", &_posX); + break; + + case TOKEN_Y: + parser.scanStr((char *)params, "%d", &_posY); + break; + + case TOKEN_WIDTH: + parser.scanStr((char *)params, "%d", &_width); + break; + + case TOKEN_HEIGHT: + parser.scanStr((char *)params, "%d", &_height); + break; + + case TOKEN_CURSOR: + delete _cursor; + _cursor = new BaseSprite(_gameRef); + if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) { + delete _cursor; + _cursor = NULL; + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_SCRIPT: + addScript((char *)params); + break; + + case TOKEN_PARENT_NOTIFY: + parser.scanStr((char *)params, "%b", &_parentNotify); + break; + + case TOKEN_DISABLED: + parser.scanStr((char *)params, "%b", &_disable); + break; + + case TOKEN_VISIBLE: + parser.scanStr((char *)params, "%b", &_visible); + break; + + case TOKEN_EDITOR_PROPERTY: + parseEditorProperty(params, false); + break; + } + } + if (cmd == PARSERR_TOKENNOTFOUND) { + _gameRef->LOG(0, "Syntax error in STATIC definition"); + return STATUS_FAILED; + } + if (cmd == PARSERR_GENERIC) { + _gameRef->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", getName()); + buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption()); + + buffer->putTextIndent(indent + 2, "\n"); + + if (_back && _back->getFilename()) { + buffer->putTextIndent(indent + 2, "BACK=\"%s\"\n", _back->getFilename()); + } + + if (_image && _image->getFilename()) { + buffer->putTextIndent(indent + 2, "IMAGE=\"%s\"\n", _image->getFilename()); + } + + if (_font && _font->getFilename()) { + buffer->putTextIndent(indent + 2, "FONT=\"%s\"\n", _font->getFilename()); + } + + if (_cursor && _cursor->getFilename()) { + buffer->putTextIndent(indent + 2, "CURSOR=\"%s\"\n", _cursor->getFilename()); + } + + if (_text) { + 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: + error("UIText::SaveAsText - Unhandled enum"); + 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: + error("UIText::SaveAsText - Unhandled enum value: NUM_VERTICAL_ALIGN"); + } + + 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 (uint32 i = 0; i < _scripts.size(); 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->transfer(TMEMBER_INT(_textAlign)); + persistMgr->transfer(TMEMBER_INT(_verticalAlign)); + + return STATUS_OK; +} + + +////////////////////////////////////////////////////////////////////////// +bool UIText::sizeToFit() { + if (_font && _text) { + _width = _font->getTextWidth((byte *)_text); + _height = _font->getTextHeight((byte *)_text, _width); + } + return STATUS_OK; +} + +} // end of namespace Wintermute diff --git a/engines/wintermute/ui/ui_text.h b/engines/wintermute/ui/ui_text.h index 54817ccf52..d2f116b44b 100644 --- a/engines/wintermute/ui/ui_text.h +++ b/engines/wintermute/ui/ui_text.h @@ -1,60 +1,60 @@ -/* 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 2 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -/* - * 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 { -private: - bool sizeToFit(); -public: - virtual bool display(int offsetX, int offsetY); - DECLARE_PERSISTENT(UIText, UIObject) - UIText(BaseGame *inGame = NULL); - virtual ~UIText(); - TTextAlign _textAlign; - TVerticalAlign _verticalAlign; - bool loadFile(const char *filename); - bool loadBuffer(byte *buffer, bool complete = true); - virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent); - - // scripting interface - virtual ScValue *scGetProperty(const char *name); - virtual bool scSetProperty(const char *name, ScValue *value); - virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name); - virtual const char *scToString(); -}; - -} // end of namespace Wintermute - -#endif +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + * 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 { +private: + bool sizeToFit(); +public: + virtual bool display(int offsetX, int offsetY); + DECLARE_PERSISTENT(UIText, UIObject) + UIText(BaseGame *inGame = NULL); + virtual ~UIText(); + TTextAlign _textAlign; + TVerticalAlign _verticalAlign; + bool loadFile(const char *filename); + bool loadBuffer(byte *buffer, bool complete = true); + virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent); + + // scripting interface + virtual ScValue *scGetProperty(const char *name); + virtual bool scSetProperty(const char *name, ScValue *value); + virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name); + virtual const char *scToString(); +}; + +} // end of namespace Wintermute + +#endif diff --git a/engines/wintermute/ui/ui_tiled_image.cpp b/engines/wintermute/ui/ui_tiled_image.cpp index 0cf28b81f5..cec23cf67e 100644 --- a/engines/wintermute/ui/ui_tiled_image.cpp +++ b/engines/wintermute/ui/ui_tiled_image.cpp @@ -1,393 +1,393 @@ -/* 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 2 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -/* - * 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/platform_osystem.h" - -namespace Wintermute { - -IMPLEMENT_PERSISTENT(UITiledImage, false) - -////////////////////////////////////////////////////////////////////////// -UITiledImage::UITiledImage(BaseGame *inGame) : BaseObject(inGame) { - _image = NULL; - - 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() { - delete _image; - _image = NULL; -} - - -////////////////////////////////////////////////////////////////////////// -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 nuColumns = (width - (_middleLeft.right - _middleLeft.left) - (_middleRight.right - _middleRight.left)) / tileWidth; - int nuRows = (height - (_upMiddle.bottom - _upMiddle.top) - (_downMiddle.bottom - _downMiddle.top)) / tileHeight; - - int col, row; - - _gameRef->_renderer->startSpriteBatch(); - - // top left/right - _image->_surface->displayTrans(x, y, _upLeft); - _image->_surface->displayTrans(x + (_upLeft.right - _upLeft.left) + nuColumns * tileWidth, y, _upRight); - - // bottom left/right - _image->_surface->displayTrans(x, y + (_upMiddle.bottom - _upMiddle.top) + nuRows * tileHeight, _downLeft); - _image->_surface->displayTrans(x + (_upLeft.right - _upLeft.left) + nuColumns * tileWidth, y + (_upMiddle.bottom - _upMiddle.top) + nuRows * tileHeight, _downRight); - - // left/right - int yyy = y + (_upMiddle.bottom - _upMiddle.top); - for (row = 0; row < nuRows; row++) { - _image->_surface->displayTrans(x, yyy, _middleLeft); - _image->_surface->displayTrans(x + (_middleLeft.right - _middleLeft.left) + nuColumns * tileWidth, yyy, _middleRight); - yyy += tileWidth; - } - - // top/bottom - int xxx = x + (_upLeft.right - _upLeft.left); - for (col = 0; col < nuColumns; col++) { - _image->_surface->displayTrans(xxx, y, _upMiddle); - _image->_surface->displayTrans(xxx, y + (_upMiddle.bottom - _upMiddle.top) + nuRows * tileHeight, _downMiddle); - xxx += tileWidth; - } - - // tiles - yyy = y + (_upMiddle.bottom - _upMiddle.top); - for (row = 0; row < nuRows; row++) { - xxx = x + (_upLeft.right - _upLeft.left); - for (col = 0; col < nuColumns; col++) { - _image->_surface->displayTrans(xxx, yyy, _middleMiddle); - xxx += tileWidth; - } - yyy += tileWidth; - } - - _gameRef->_renderer->endSpriteBatch(); - - return STATUS_OK; -} - - -////////////////////////////////////////////////////////////////////////// -bool UITiledImage::loadFile(const char *filename) { - byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename); - if (buffer == NULL) { - _gameRef->LOG(0, "UITiledImage::LoadFile failed for file '%s'", filename); - return STATUS_FAILED; - } - - bool ret; - - setFilename(filename); - - if (DID_FAIL(ret = loadBuffer(buffer, true))) { - _gameRef->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(byte *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 - - byte *params; - int cmd; - BaseParser parser; - bool hTiles = false, vTiles = false; - int h1 = 0, h2 = 0, h3 = 0; - int v1 = 0, v2 = 0, v3 = 0; - - if (complete) { - if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_TILED_IMAGE) { - _gameRef->LOG(0, "'TILED_IMAGE' keyword expected."); - return STATUS_FAILED; - } - buffer = params; - } - - while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { - switch (cmd) { - case TOKEN_TEMPLATE: - if (DID_FAIL(loadFile((char *)params))) { - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_IMAGE: - delete _image; - _image = new BaseSubFrame(_gameRef); - if (!_image || DID_FAIL(_image->setSurface((char *)params))) { - delete _image; - _image = NULL; - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_UP_LEFT: - parser.scanStr((char *)params, "%d,%d,%d,%d", &_upLeft.left, &_upLeft.top, &_upLeft.right, &_upLeft.bottom); - break; - - case TOKEN_UP_RIGHT: - parser.scanStr((char *)params, "%d,%d,%d,%d", &_upRight.left, &_upRight.top, &_upRight.right, &_upRight.bottom); - break; - - case TOKEN_UP_MIDDLE: - parser.scanStr((char *)params, "%d,%d,%d,%d", &_upMiddle.left, &_upMiddle.top, &_upMiddle.right, &_upMiddle.bottom); - break; - - case TOKEN_DOWN_LEFT: - parser.scanStr((char *)params, "%d,%d,%d,%d", &_downLeft.left, &_downLeft.top, &_downLeft.right, &_downLeft.bottom); - break; - - case TOKEN_DOWN_RIGHT: - parser.scanStr((char *)params, "%d,%d,%d,%d", &_downRight.left, &_downRight.top, &_downRight.right, &_downRight.bottom); - break; - - case TOKEN_DOWN_MIDDLE: - parser.scanStr((char *)params, "%d,%d,%d,%d", &_downMiddle.left, &_downMiddle.top, &_downMiddle.right, &_downMiddle.bottom); - break; - - case TOKEN_MIDDLE_LEFT: - parser.scanStr((char *)params, "%d,%d,%d,%d", &_middleLeft.left, &_middleLeft.top, &_middleLeft.right, &_middleLeft.bottom); - break; - - case TOKEN_MIDDLE_RIGHT: - parser.scanStr((char *)params, "%d,%d,%d,%d", &_middleRight.left, &_middleRight.top, &_middleRight.right, &_middleRight.bottom); - break; - - case TOKEN_MIDDLE_MIDDLE: - parser.scanStr((char *)params, "%d,%d,%d,%d", &_middleMiddle.left, &_middleMiddle.top, &_middleMiddle.right, &_middleMiddle.bottom); - break; - - case TOKEN_HORIZONTAL_TILES: - parser.scanStr((char *)params, "%d,%d,%d", &h1, &h2, &h3); - hTiles = true; - break; - - case TOKEN_VERTICAL_TILES: - parser.scanStr((char *)params, "%d,%d,%d", &v1, &v2, &v3); - vTiles = true; - break; - - case TOKEN_EDITOR_PROPERTY: - parseEditorProperty(params, false); - break; - } - } - if (cmd == PARSERR_TOKENNOTFOUND) { - _gameRef->LOG(0, "Syntax error in TILED_IMAGE definition"); - return STATUS_FAILED; - } - if (cmd == PARSERR_GENERIC) { - _gameRef->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) { - 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(int *width, int *height) { - int tileWidth = _middleMiddle.right - _middleMiddle.left; - int tileHeight = _middleMiddle.bottom - _middleMiddle.top; - - int nuColumns = (*width - (_middleLeft.right - _middleLeft.left) - (_middleRight.right - _middleRight.left)) / tileWidth; - int nuRows = (*height - (_upMiddle.bottom - _upMiddle.top) - (_downMiddle.bottom - _downMiddle.top)) / tileHeight; - - *width = (_middleLeft.right - _middleLeft.left) + (_middleRight.right - _middleRight.left) + nuColumns * tileWidth; - *height = (_upMiddle.bottom - _upMiddle.top) + (_downMiddle.bottom - _downMiddle.top) + nuRows * tileHeight; -} - - -////////////////////////////////////////////////////////////////////////// -bool UITiledImage::persist(BasePersistenceManager *persistMgr) { - BaseObject::persist(persistMgr); - - persistMgr->transfer(TMEMBER(_downLeft)); - persistMgr->transfer(TMEMBER(_downMiddle)); - persistMgr->transfer(TMEMBER(_downRight)); - persistMgr->transfer(TMEMBER(_image)); - persistMgr->transfer(TMEMBER(_middleLeft)); - persistMgr->transfer(TMEMBER(_middleMiddle)); - persistMgr->transfer(TMEMBER(_middleRight)); - persistMgr->transfer(TMEMBER(_upLeft)); - persistMgr->transfer(TMEMBER(_upMiddle)); - persistMgr->transfer(TMEMBER(_upRight)); - - return STATUS_OK; -} - -} // end of namespace Wintermute +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + * 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/platform_osystem.h" + +namespace Wintermute { + +IMPLEMENT_PERSISTENT(UITiledImage, false) + +////////////////////////////////////////////////////////////////////////// +UITiledImage::UITiledImage(BaseGame *inGame) : BaseObject(inGame) { + _image = NULL; + + 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() { + delete _image; + _image = NULL; +} + + +////////////////////////////////////////////////////////////////////////// +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 nuColumns = (width - (_middleLeft.right - _middleLeft.left) - (_middleRight.right - _middleRight.left)) / tileWidth; + int nuRows = (height - (_upMiddle.bottom - _upMiddle.top) - (_downMiddle.bottom - _downMiddle.top)) / tileHeight; + + int col, row; + + _gameRef->_renderer->startSpriteBatch(); + + // top left/right + _image->_surface->displayTrans(x, y, _upLeft); + _image->_surface->displayTrans(x + (_upLeft.right - _upLeft.left) + nuColumns * tileWidth, y, _upRight); + + // bottom left/right + _image->_surface->displayTrans(x, y + (_upMiddle.bottom - _upMiddle.top) + nuRows * tileHeight, _downLeft); + _image->_surface->displayTrans(x + (_upLeft.right - _upLeft.left) + nuColumns * tileWidth, y + (_upMiddle.bottom - _upMiddle.top) + nuRows * tileHeight, _downRight); + + // left/right + int yyy = y + (_upMiddle.bottom - _upMiddle.top); + for (row = 0; row < nuRows; row++) { + _image->_surface->displayTrans(x, yyy, _middleLeft); + _image->_surface->displayTrans(x + (_middleLeft.right - _middleLeft.left) + nuColumns * tileWidth, yyy, _middleRight); + yyy += tileWidth; + } + + // top/bottom + int xxx = x + (_upLeft.right - _upLeft.left); + for (col = 0; col < nuColumns; col++) { + _image->_surface->displayTrans(xxx, y, _upMiddle); + _image->_surface->displayTrans(xxx, y + (_upMiddle.bottom - _upMiddle.top) + nuRows * tileHeight, _downMiddle); + xxx += tileWidth; + } + + // tiles + yyy = y + (_upMiddle.bottom - _upMiddle.top); + for (row = 0; row < nuRows; row++) { + xxx = x + (_upLeft.right - _upLeft.left); + for (col = 0; col < nuColumns; col++) { + _image->_surface->displayTrans(xxx, yyy, _middleMiddle); + xxx += tileWidth; + } + yyy += tileWidth; + } + + _gameRef->_renderer->endSpriteBatch(); + + return STATUS_OK; +} + + +////////////////////////////////////////////////////////////////////////// +bool UITiledImage::loadFile(const char *filename) { + byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename); + if (buffer == NULL) { + _gameRef->LOG(0, "UITiledImage::LoadFile failed for file '%s'", filename); + return STATUS_FAILED; + } + + bool ret; + + setFilename(filename); + + if (DID_FAIL(ret = loadBuffer(buffer, true))) { + _gameRef->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(byte *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 + + byte *params; + int cmd; + BaseParser parser; + bool hTiles = false, vTiles = false; + int h1 = 0, h2 = 0, h3 = 0; + int v1 = 0, v2 = 0, v3 = 0; + + if (complete) { + if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_TILED_IMAGE) { + _gameRef->LOG(0, "'TILED_IMAGE' keyword expected."); + return STATUS_FAILED; + } + buffer = params; + } + + while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) > 0) { + switch (cmd) { + case TOKEN_TEMPLATE: + if (DID_FAIL(loadFile((char *)params))) { + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_IMAGE: + delete _image; + _image = new BaseSubFrame(_gameRef); + if (!_image || DID_FAIL(_image->setSurface((char *)params))) { + delete _image; + _image = NULL; + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_UP_LEFT: + parser.scanStr((char *)params, "%d,%d,%d,%d", &_upLeft.left, &_upLeft.top, &_upLeft.right, &_upLeft.bottom); + break; + + case TOKEN_UP_RIGHT: + parser.scanStr((char *)params, "%d,%d,%d,%d", &_upRight.left, &_upRight.top, &_upRight.right, &_upRight.bottom); + break; + + case TOKEN_UP_MIDDLE: + parser.scanStr((char *)params, "%d,%d,%d,%d", &_upMiddle.left, &_upMiddle.top, &_upMiddle.right, &_upMiddle.bottom); + break; + + case TOKEN_DOWN_LEFT: + parser.scanStr((char *)params, "%d,%d,%d,%d", &_downLeft.left, &_downLeft.top, &_downLeft.right, &_downLeft.bottom); + break; + + case TOKEN_DOWN_RIGHT: + parser.scanStr((char *)params, "%d,%d,%d,%d", &_downRight.left, &_downRight.top, &_downRight.right, &_downRight.bottom); + break; + + case TOKEN_DOWN_MIDDLE: + parser.scanStr((char *)params, "%d,%d,%d,%d", &_downMiddle.left, &_downMiddle.top, &_downMiddle.right, &_downMiddle.bottom); + break; + + case TOKEN_MIDDLE_LEFT: + parser.scanStr((char *)params, "%d,%d,%d,%d", &_middleLeft.left, &_middleLeft.top, &_middleLeft.right, &_middleLeft.bottom); + break; + + case TOKEN_MIDDLE_RIGHT: + parser.scanStr((char *)params, "%d,%d,%d,%d", &_middleRight.left, &_middleRight.top, &_middleRight.right, &_middleRight.bottom); + break; + + case TOKEN_MIDDLE_MIDDLE: + parser.scanStr((char *)params, "%d,%d,%d,%d", &_middleMiddle.left, &_middleMiddle.top, &_middleMiddle.right, &_middleMiddle.bottom); + break; + + case TOKEN_HORIZONTAL_TILES: + parser.scanStr((char *)params, "%d,%d,%d", &h1, &h2, &h3); + hTiles = true; + break; + + case TOKEN_VERTICAL_TILES: + parser.scanStr((char *)params, "%d,%d,%d", &v1, &v2, &v3); + vTiles = true; + break; + + case TOKEN_EDITOR_PROPERTY: + parseEditorProperty(params, false); + break; + } + } + if (cmd == PARSERR_TOKENNOTFOUND) { + _gameRef->LOG(0, "Syntax error in TILED_IMAGE definition"); + return STATUS_FAILED; + } + if (cmd == PARSERR_GENERIC) { + _gameRef->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) { + 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(int *width, int *height) { + int tileWidth = _middleMiddle.right - _middleMiddle.left; + int tileHeight = _middleMiddle.bottom - _middleMiddle.top; + + int nuColumns = (*width - (_middleLeft.right - _middleLeft.left) - (_middleRight.right - _middleRight.left)) / tileWidth; + int nuRows = (*height - (_upMiddle.bottom - _upMiddle.top) - (_downMiddle.bottom - _downMiddle.top)) / tileHeight; + + *width = (_middleLeft.right - _middleLeft.left) + (_middleRight.right - _middleRight.left) + nuColumns * tileWidth; + *height = (_upMiddle.bottom - _upMiddle.top) + (_downMiddle.bottom - _downMiddle.top) + nuRows * tileHeight; +} + + +////////////////////////////////////////////////////////////////////////// +bool UITiledImage::persist(BasePersistenceManager *persistMgr) { + BaseObject::persist(persistMgr); + + persistMgr->transfer(TMEMBER(_downLeft)); + persistMgr->transfer(TMEMBER(_downMiddle)); + persistMgr->transfer(TMEMBER(_downRight)); + persistMgr->transfer(TMEMBER(_image)); + persistMgr->transfer(TMEMBER(_middleLeft)); + persistMgr->transfer(TMEMBER(_middleMiddle)); + persistMgr->transfer(TMEMBER(_middleRight)); + persistMgr->transfer(TMEMBER(_upLeft)); + persistMgr->transfer(TMEMBER(_upMiddle)); + persistMgr->transfer(TMEMBER(_upRight)); + + return STATUS_OK; +} + +} // end of namespace Wintermute diff --git a/engines/wintermute/ui/ui_tiled_image.h b/engines/wintermute/ui/ui_tiled_image.h index 863bf7d1ea..c413e7f129 100644 --- a/engines/wintermute/ui/ui_tiled_image.h +++ b/engines/wintermute/ui/ui_tiled_image.h @@ -1,63 +1,63 @@ -/* 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 2 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -/* - * 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 { -public: - DECLARE_PERSISTENT(UITiledImage, BaseObject) - void correctSize(int *width, int *height); - bool loadFile(const char *filename); - bool loadBuffer(byte *buffer, bool complete = true); - virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent); - - bool display(int x, int y, int width, int height); - UITiledImage(BaseGame *inGame = NULL); - virtual ~UITiledImage(); - BaseSubFrame *_image; - Rect32 _upLeft; - Rect32 _upMiddle; - Rect32 _upRight; - Rect32 _middleLeft; - Rect32 _middleMiddle; - Rect32 _middleRight; - Rect32 _downLeft; - Rect32 _downMiddle; - Rect32 _downRight; -}; - -} // end of namespace Wintermute - -#endif +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + * 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 { +public: + DECLARE_PERSISTENT(UITiledImage, BaseObject) + void correctSize(int *width, int *height); + bool loadFile(const char *filename); + bool loadBuffer(byte *buffer, bool complete = true); + virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent); + + bool display(int x, int y, int width, int height); + UITiledImage(BaseGame *inGame = NULL); + virtual ~UITiledImage(); + BaseSubFrame *_image; + Rect32 _upLeft; + Rect32 _upMiddle; + Rect32 _upRight; + Rect32 _middleLeft; + Rect32 _middleMiddle; + Rect32 _middleRight; + Rect32 _downLeft; + Rect32 _downMiddle; + Rect32 _downRight; +}; + +} // end of namespace Wintermute + +#endif diff --git a/engines/wintermute/ui/ui_window.cpp b/engines/wintermute/ui/ui_window.cpp index ffb7e4dbf8..65af62141d 100644 --- a/engines/wintermute/ui/ui_window.cpp +++ b/engines/wintermute/ui/ui_window.cpp @@ -1,1444 +1,1444 @@ -/* 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 2 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -/* - * 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_parser.h" -#include "engines/wintermute/base/base_active_rect.h" -#include "engines/wintermute/base/base_dynamic_buffer.h" -#include "engines/wintermute/base/base_keyboard_state.h" -#include "engines/wintermute/base/scriptables/script_value.h" -#include "engines/wintermute/ui/ui_button.h" -#include "engines/wintermute/ui/ui_edit.h" -#include "engines/wintermute/ui/ui_text.h" -#include "engines/wintermute/ui/ui_tiled_image.h" -#include "engines/wintermute/ui/ui_window.h" -#include "engines/wintermute/base/base_viewport.h" -#include "engines/wintermute/base/font/base_font_storage.h" -#include "engines/wintermute/base/font/base_font.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" - -namespace Wintermute { - -IMPLEMENT_PERSISTENT(UIWindow, false) - -////////////////////////////////////////////////////////////////////////// -UIWindow::UIWindow(BaseGame *inGame) : UIObject(inGame) { - BasePlatform::setRectEmpty(&_titleRect); - BasePlatform::setRectEmpty(&_dragRect); - _titleAlign = TAL_LEFT; - _transparent = false; - - _backInactive = NULL; - _fontInactive = NULL; - _imageInactive = NULL; - - _type = UI_WINDOW; - _canFocus = true; - - _dragging = false; - _dragFrom.x = _dragFrom.y = 0; - - _mode = WINDOW_NORMAL; - _shieldWindow = NULL; - _shieldButton = NULL; - - _fadeColor = 0x00000000; - _fadeBackground = false; - - _ready = true; - _isMenu = false; - _inGame = false; - - _clipContents = false; - _viewport = NULL; - - _pauseMusic = true; -} - - -////////////////////////////////////////////////////////////////////////// -UIWindow::~UIWindow() { - close(); - cleanup(); -} - - -////////////////////////////////////////////////////////////////////////// -void UIWindow::cleanup() { - delete _shieldWindow; - delete _shieldButton; - delete _viewport; - _shieldWindow = NULL; - _shieldButton = NULL; - _viewport = NULL; - - delete _backInactive; - if (!_sharedFonts && _fontInactive) { - _gameRef->_fontStorage->removeFont(_fontInactive); - } - if (!_sharedImages && _imageInactive) { - delete _imageInactive; - } - - for (uint32 i = 0; i < _widgets.size(); i++) { - delete _widgets[i]; - } - _widgets.clear(); -} - - -////////////////////////////////////////////////////////////////////////// -bool UIWindow::display(int offsetX, int offsetY) { - // go exclusive - if (_mode == WINDOW_EXCLUSIVE || _mode == WINDOW_SYSTEM_EXCLUSIVE) { - if (!_shieldWindow) { - _shieldWindow = new UIWindow(_gameRef); - } - if (_shieldWindow) { - _shieldWindow->_posX = _shieldWindow->_posY = 0; - _shieldWindow->_width = _gameRef->_renderer->_width; - _shieldWindow->_height = _gameRef->_renderer->_height; - - _shieldWindow->display(); - } - } else if (_isMenu) { - if (!_shieldButton) { - _shieldButton = new UIButton(_gameRef); - _shieldButton->setName("close"); - _shieldButton->setListener(this, _shieldButton, 0); - _shieldButton->_parent = this; - } - if (_shieldButton) { - _shieldButton->_posX = _shieldButton->_posY = 0; - _shieldButton->_width = _gameRef->_renderer->_width; - _shieldButton->_height = _gameRef->_renderer->_height; - - _shieldButton->display(); - } - } - - if (!_visible) { - return STATUS_OK; - } - - if (_fadeBackground) { - Graphics::PixelFormat format = _gameRef->_renderer->getPixelFormat(); - byte fadeR, fadeG, fadeB, fadeA; - // First convert from the internal format to the screen-format - uint32 fadeColor = format.ARGBToColor(RGBCOLGetA(_fadeColor), RGBCOLGetR(_fadeColor), RGBCOLGetG(_fadeColor), RGBCOLGetB(_fadeColor)); - // Then get components - format.colorToARGB(fadeColor, fadeA, fadeR, fadeG, fadeB); - _gameRef->_renderer->fadeToColor(fadeR, fadeG, fadeB, fadeA); - } - - if (_dragging) { - _posX += (_gameRef->_mousePos.x - _dragFrom.x); - _posY += (_gameRef->_mousePos.y - _dragFrom.y); - - _dragFrom.x = _gameRef->_mousePos.x; - _dragFrom.y = _gameRef->_mousePos.y; - } - - if (!_focusedWidget || (!_focusedWidget->_canFocus || _focusedWidget->_disable || !_focusedWidget->_visible)) { - moveFocus(); - } - - bool popViewport = false; - if (_clipContents) { - if (!_viewport) { - _viewport = new BaseViewport(_gameRef); - } - if (_viewport) { - _viewport->setRect(_posX + offsetX, _posY + offsetY, _posX + _width + offsetX, _posY + _height + offsetY); - _gameRef->pushViewport(_viewport); - popViewport = true; - } - } - - - UITiledImage *back = _back; - BaseSprite *image = _image; - BaseFont *font = _font; - - if (!isFocused()) { - if (_backInactive) { - back = _backInactive; - } - if (_imageInactive) { - image = _imageInactive; - } - if (_fontInactive) { - font = _fontInactive; - } - } - - if (_alphaColor != 0) { - _gameRef->_renderer->_forceAlphaColor = _alphaColor; - } - if (back) { - back->display(_posX + offsetX, _posY + offsetY, _width, _height); - } - if (image) { - image->draw(_posX + offsetX, _posY + offsetY, _transparent ? NULL : this); - } - - if (!BasePlatform::isRectEmpty(&_titleRect) && font && _text) { - font->drawText((byte *)_text, _posX + offsetX + _titleRect.left, _posY + offsetY + _titleRect.top, _titleRect.right - _titleRect.left, _titleAlign, _titleRect.bottom - _titleRect.top); - } - - if (!_transparent && !image) { - _gameRef->_renderer->addRectToList(new BaseActiveRect(_gameRef, this, NULL, _posX + offsetX, _posY + offsetY, _width, _height, 100, 100, false)); - } - - for (uint32 i = 0; i < _widgets.size(); i++) { - _widgets[i]->display(_posX + offsetX, _posY + offsetY); - } - - if (_alphaColor != 0) { - _gameRef->_renderer->_forceAlphaColor = 0; - } - - if (popViewport) { - _gameRef->popViewport(); - } - - return STATUS_OK; -} - - -////////////////////////////////////////////////////////////////////////// -bool UIWindow::loadFile(const char *filename) { - byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename); - if (buffer == NULL) { - _gameRef->LOG(0, "UIWindow::LoadFile failed for file '%s'", filename); - return STATUS_FAILED; - } - - bool ret; - - setFilename(filename); - - if (DID_FAIL(ret = loadBuffer(buffer, true))) { - _gameRef->LOG(0, "Error parsing WINDOW file '%s'", filename); - } - - delete[] buffer; - - return ret; -} - - -TOKEN_DEF_START -TOKEN_DEF(WINDOW) -TOKEN_DEF(ALPHA_COLOR) -TOKEN_DEF(ALPHA) -TOKEN_DEF(TEMPLATE) -TOKEN_DEF(DISABLED) -TOKEN_DEF(VISIBLE) -TOKEN_DEF(BACK_INACTIVE) -TOKEN_DEF(BACK) -TOKEN_DEF(IMAGE_INACTIVE) -TOKEN_DEF(IMAGE) -TOKEN_DEF(FONT_INACTIVE) -TOKEN_DEF(FONT) -TOKEN_DEF(TITLE_ALIGN) -TOKEN_DEF(TITLE_RECT) -TOKEN_DEF(TITLE) -TOKEN_DEF(DRAG_RECT) -TOKEN_DEF(X) -TOKEN_DEF(Y) -TOKEN_DEF(WIDTH) -TOKEN_DEF(HEIGHT) -TOKEN_DEF(FADE_ALPHA) -TOKEN_DEF(FADE_COLOR) -TOKEN_DEF(CURSOR) -TOKEN_DEF(NAME) -TOKEN_DEF(BUTTON) -TOKEN_DEF(STATIC) -TOKEN_DEF(TRANSPARENT) -TOKEN_DEF(SCRIPT) -TOKEN_DEF(CAPTION) -TOKEN_DEF(PARENT_NOTIFY) -TOKEN_DEF(MENU) -TOKEN_DEF(IN_GAME) -TOKEN_DEF(CLIP_CONTENTS) -TOKEN_DEF(PAUSE_MUSIC) -TOKEN_DEF(EDITOR_PROPERTY) -TOKEN_DEF(EDIT) -TOKEN_DEF_END -////////////////////////////////////////////////////////////////////////// -bool UIWindow::loadBuffer(byte *buffer, bool complete) { - TOKEN_TABLE_START(commands) - TOKEN_TABLE(WINDOW) - TOKEN_TABLE(ALPHA_COLOR) - TOKEN_TABLE(ALPHA) - TOKEN_TABLE(TEMPLATE) - TOKEN_TABLE(DISABLED) - TOKEN_TABLE(VISIBLE) - TOKEN_TABLE(BACK_INACTIVE) - TOKEN_TABLE(BACK) - TOKEN_TABLE(IMAGE_INACTIVE) - TOKEN_TABLE(IMAGE) - TOKEN_TABLE(FONT_INACTIVE) - TOKEN_TABLE(FONT) - TOKEN_TABLE(TITLE_ALIGN) - TOKEN_TABLE(TITLE_RECT) - TOKEN_TABLE(TITLE) - TOKEN_TABLE(DRAG_RECT) - TOKEN_TABLE(X) - TOKEN_TABLE(Y) - TOKEN_TABLE(WIDTH) - TOKEN_TABLE(HEIGHT) - TOKEN_TABLE(FADE_ALPHA) - TOKEN_TABLE(FADE_COLOR) - TOKEN_TABLE(CURSOR) - TOKEN_TABLE(NAME) - TOKEN_TABLE(BUTTON) - TOKEN_TABLE(STATIC) - TOKEN_TABLE(TRANSPARENT) - TOKEN_TABLE(SCRIPT) - TOKEN_TABLE(CAPTION) - TOKEN_TABLE(PARENT_NOTIFY) - TOKEN_TABLE(MENU) - TOKEN_TABLE(IN_GAME) - TOKEN_TABLE(CLIP_CONTENTS) - TOKEN_TABLE(PAUSE_MUSIC) - TOKEN_TABLE(EDITOR_PROPERTY) - TOKEN_TABLE(EDIT) - TOKEN_TABLE_END - - byte *params; - int cmd = 2; - BaseParser parser; - - int fadeR = 0, fadeG = 0, fadeB = 0, fadeA = 0; - int ar = 0, ag = 0, ab = 0, alpha = 0; - - if (complete) { - if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_WINDOW) { - _gameRef->LOG(0, "'WINDOW' keyword expected."); - return STATUS_FAILED; - } - buffer = params; - } - - while (cmd >= PARSERR_TOKENNOTFOUND && (cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) >= PARSERR_TOKENNOTFOUND) { - switch (cmd) { - case TOKEN_TEMPLATE: - if (DID_FAIL(loadFile((char *)params))) { - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_NAME: - setName((char *)params); - break; - - case TOKEN_CAPTION: - setCaption((char *)params); - break; - - case TOKEN_BACK: - delete _back; - _back = new UITiledImage(_gameRef); - if (!_back || DID_FAIL(_back->loadFile((char *)params))) { - delete _back; - _back = NULL; - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_BACK_INACTIVE: - delete _backInactive; - _backInactive = new UITiledImage(_gameRef); - if (!_backInactive || DID_FAIL(_backInactive->loadFile((char *)params))) { - delete _backInactive; - _backInactive = NULL; - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_IMAGE: - delete _image; - _image = new BaseSprite(_gameRef); - if (!_image || DID_FAIL(_image->loadFile((char *)params))) { - delete _image; - _image = NULL; - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_IMAGE_INACTIVE: - delete _imageInactive, - _imageInactive = new BaseSprite(_gameRef); - if (!_imageInactive || DID_FAIL(_imageInactive->loadFile((char *)params))) { - delete _imageInactive; - _imageInactive = NULL; - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_FONT: - if (_font) { - _gameRef->_fontStorage->removeFont(_font); - } - _font = _gameRef->_fontStorage->addFont((char *)params); - if (!_font) { - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_FONT_INACTIVE: - if (_fontInactive) { - _gameRef->_fontStorage->removeFont(_fontInactive); - } - _fontInactive = _gameRef->_fontStorage->addFont((char *)params); - if (!_fontInactive) { - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_TITLE: - setText((char *)params); - _gameRef->_stringTable->expand(&_text); - break; - - case TOKEN_TITLE_ALIGN: - if (scumm_stricmp((char *)params, "left") == 0) { - _titleAlign = TAL_LEFT; - } else if (scumm_stricmp((char *)params, "right") == 0) { - _titleAlign = TAL_RIGHT; - } else { - _titleAlign = TAL_CENTER; - } - break; - - case TOKEN_TITLE_RECT: - parser.scanStr((char *)params, "%d,%d,%d,%d", &_titleRect.left, &_titleRect.top, &_titleRect.right, &_titleRect.bottom); - break; - - case TOKEN_DRAG_RECT: - parser.scanStr((char *)params, "%d,%d,%d,%d", &_dragRect.left, &_dragRect.top, &_dragRect.right, &_dragRect.bottom); - break; - - case TOKEN_X: - parser.scanStr((char *)params, "%d", &_posX); - break; - - case TOKEN_Y: - parser.scanStr((char *)params, "%d", &_posY); - break; - - case TOKEN_WIDTH: - parser.scanStr((char *)params, "%d", &_width); - break; - - case TOKEN_HEIGHT: - parser.scanStr((char *)params, "%d", &_height); - break; - - case TOKEN_CURSOR: - delete _cursor; - _cursor = new BaseSprite(_gameRef); - if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) { - delete _cursor; - _cursor = NULL; - cmd = PARSERR_GENERIC; - } - break; - - case TOKEN_BUTTON: { - UIButton *btn = new UIButton(_gameRef); - if (!btn || DID_FAIL(btn->loadBuffer(params, false))) { - delete btn; - btn = NULL; - cmd = PARSERR_GENERIC; - } else { - btn->_parent = this; - _widgets.add(btn); - } - } - break; - - case TOKEN_STATIC: { - UIText *text = new UIText(_gameRef); - if (!text || DID_FAIL(text->loadBuffer(params, false))) { - delete text; - text = NULL; - cmd = PARSERR_GENERIC; - } else { - text->_parent = this; - _widgets.add(text); - } - } - break; - - case TOKEN_EDIT: { - UIEdit *edit = new UIEdit(_gameRef); - if (!edit || DID_FAIL(edit->loadBuffer(params, false))) { - delete edit; - edit = NULL; - cmd = PARSERR_GENERIC; - } else { - edit->_parent = this; - _widgets.add(edit); - } - } - break; - - case TOKEN_WINDOW: { - UIWindow *win = new UIWindow(_gameRef); - if (!win || DID_FAIL(win->loadBuffer(params, false))) { - delete win; - win = NULL; - cmd = PARSERR_GENERIC; - } else { - win->_parent = this; - _widgets.add(win); - } - } - break; - - - case TOKEN_TRANSPARENT: - parser.scanStr((char *)params, "%b", &_transparent); - break; - - case TOKEN_SCRIPT: - addScript((char *)params); - break; - - case TOKEN_PARENT_NOTIFY: - parser.scanStr((char *)params, "%b", &_parentNotify); - break; - - case TOKEN_PAUSE_MUSIC: - parser.scanStr((char *)params, "%b", &_pauseMusic); - break; - - case TOKEN_DISABLED: - parser.scanStr((char *)params, "%b", &_disable); - break; - - case TOKEN_VISIBLE: - parser.scanStr((char *)params, "%b", &_visible); - break; - - case TOKEN_MENU: - parser.scanStr((char *)params, "%b", &_isMenu); - break; - - case TOKEN_IN_GAME: - parser.scanStr((char *)params, "%b", &_inGame); - break; - - case TOKEN_CLIP_CONTENTS: - parser.scanStr((char *)params, "%b", &_clipContents); - break; - - case TOKEN_FADE_COLOR: - parser.scanStr((char *)params, "%d,%d,%d", &fadeR, &fadeG, &fadeB); - _fadeBackground = true; - break; - - case TOKEN_FADE_ALPHA: - parser.scanStr((char *)params, "%d", &fadeA); - _fadeBackground = true; - break; - - case TOKEN_EDITOR_PROPERTY: - parseEditorProperty(params, false); - break; - - case TOKEN_ALPHA_COLOR: - parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab); - break; - - case TOKEN_ALPHA: - parser.scanStr((char *)params, "%d", &alpha); - break; - - - default: - if (DID_FAIL(_gameRef->windowLoadHook(this, (char **)&buffer, (char **)params))) { - cmd = PARSERR_GENERIC; - } - } - } - if (cmd == PARSERR_TOKENNOTFOUND) { - _gameRef->LOG(0, "Syntax error in WINDOW definition"); - return STATUS_FAILED; - } - if (cmd == PARSERR_GENERIC) { - _gameRef->LOG(0, "Error loading WINDOW definition"); - return STATUS_FAILED; - } - - correctSize(); - - if (alpha != 0 && ar == 0 && ag == 0 && ab == 0) { - ar = ag = ab = 255; - } - _alphaColor = BYTETORGBA(ar, ag, ab, alpha); - - if (_fadeBackground) { - _fadeColor = BYTETORGBA(fadeR, fadeG, fadeB, fadeA); - } - - _focusedWidget = NULL; - - return STATUS_OK; -} - -////////////////////////////////////////////////////////////////////////// -bool UIWindow::saveAsText(BaseDynamicBuffer *buffer, int indent) { - buffer->putTextIndent(indent, "WINDOW\n"); - buffer->putTextIndent(indent, "{\n"); - - buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", getName()); - buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption()); - - buffer->putTextIndent(indent + 2, "\n"); - - if (_back && _back->getFilename()) { - buffer->putTextIndent(indent + 2, "BACK=\"%s\"\n", _back->getFilename()); - } - if (_backInactive && _backInactive->getFilename()) { - buffer->putTextIndent(indent + 2, "BACK_INACTIVE=\"%s\"\n", _backInactive->getFilename()); - } - - if (_image && _image->getFilename()) { - buffer->putTextIndent(indent + 2, "IMAGE=\"%s\"\n", _image->getFilename()); - } - if (_imageInactive && _imageInactive->getFilename()) { - buffer->putTextIndent(indent + 2, "IMAGE_INACTIVE=\"%s\"\n", _imageInactive->getFilename()); - } - - if (_font && _font->getFilename()) { - buffer->putTextIndent(indent + 2, "FONT=\"%s\"\n", _font->getFilename()); - } - if (_fontInactive && _fontInactive->getFilename()) { - buffer->putTextIndent(indent + 2, "FONT_INACTIVE=\"%s\"\n", _fontInactive->getFilename()); - } - - if (_cursor && _cursor->getFilename()) { - buffer->putTextIndent(indent + 2, "CURSOR=\"%s\"\n", _cursor->getFilename()); - } - - buffer->putTextIndent(indent + 2, "\n"); - - if (_text) { - buffer->putTextIndent(indent + 2, "TITLE=\"%s\"\n", _text); - } - - switch (_titleAlign) { - case TAL_LEFT: - buffer->putTextIndent(indent + 2, "TITLE_ALIGN=\"%s\"\n", "left"); - break; - case TAL_RIGHT: - buffer->putTextIndent(indent + 2, "TITLE_ALIGN=\"%s\"\n", "right"); - break; - case TAL_CENTER: - buffer->putTextIndent(indent + 2, "TITLE_ALIGN=\"%s\"\n", "center"); - break; - default: - error("UIWindow::SaveAsText - Unhandled enum-value NUM_TEXT_ALIGN"); - } - - if (!BasePlatform::isRectEmpty(&_titleRect)) { - buffer->putTextIndent(indent + 2, "TITLE_RECT { %d, %d, %d, %d }\n", _titleRect.left, _titleRect.top, _titleRect.right, _titleRect.bottom); - } - - if (!BasePlatform::isRectEmpty(&_dragRect)) { - buffer->putTextIndent(indent + 2, "DRAG_RECT { %d, %d, %d, %d }\n", _dragRect.left, _dragRect.top, _dragRect.right, _dragRect.bottom); - } - - 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, "TRANSPARENT=%s\n", _transparent ? "TRUE" : "FALSE"); - buffer->putTextIndent(indent + 2, "PAUSE_MUSIC=%s\n", _pauseMusic ? "TRUE" : "FALSE"); - buffer->putTextIndent(indent + 2, "MENU=%s\n", _isMenu ? "TRUE" : "FALSE"); - buffer->putTextIndent(indent + 2, "IN_GAME=%s\n", _inGame ? "TRUE" : "FALSE"); - buffer->putTextIndent(indent + 2, "CLIP_CONTENTS=%s\n", _clipContents ? "TRUE" : "FALSE"); - - buffer->putTextIndent(indent + 2, "\n"); - - if (_fadeBackground) { - buffer->putTextIndent(indent + 2, "FADE_COLOR { %d, %d, %d }\n", RGBCOLGetR(_fadeColor), RGBCOLGetG(_fadeColor), RGBCOLGetB(_fadeColor)); - buffer->putTextIndent(indent + 2, "FADE_ALPHA=%d\n", RGBCOLGetA(_fadeColor)); - } - - buffer->putTextIndent(indent + 2, "ALPHA_COLOR { %d, %d, %d }\n", RGBCOLGetR(_alphaColor), RGBCOLGetG(_alphaColor), RGBCOLGetB(_alphaColor)); - buffer->putTextIndent(indent + 2, "ALPHA=%d\n", RGBCOLGetA(_alphaColor)); - - buffer->putTextIndent(indent + 2, "\n"); - - // scripts - for (uint32 i = 0; i < _scripts.size(); i++) { - buffer->putTextIndent(indent + 2, "SCRIPT=\"%s\"\n", _scripts[i]->_filename); - } - - buffer->putTextIndent(indent + 2, "\n"); - - // editor properties - BaseClass::saveAsText(buffer, indent + 2); - - // controls - for (uint32 i = 0; i < _widgets.size(); i++) { - _widgets[i]->saveAsText(buffer, indent + 2); - } - - - buffer->putTextIndent(indent, "}\n"); - return STATUS_OK; -} - -////////////////////////////////////////////////////////////////////////// -bool UIWindow::enableWidget(const char *name, bool enable) { - for (uint32 i = 0; i < _widgets.size(); i++) { - if (scumm_stricmp(_widgets[i]->getName(), name) == 0) { - _widgets[i]->_disable = !enable; - } - } - return STATUS_OK; -} - - -////////////////////////////////////////////////////////////////////////// -bool UIWindow::showWidget(const char *name, bool visible) { - for (uint32 i = 0; i < _widgets.size(); i++) { - if (scumm_stricmp(_widgets[i]->getName(), name) == 0) { - _widgets[i]->_visible = visible; - } - } - return STATUS_OK; -} - - -////////////////////////////////////////////////////////////////////////// -// high level scripting interface -////////////////////////////////////////////////////////////////////////// -bool UIWindow::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) { - ////////////////////////////////////////////////////////////////////////// - // GetWidget / GetControl - ////////////////////////////////////////////////////////////////////////// - if (strcmp(name, "GetWidget") == 0 || strcmp(name, "GetControl") == 0) { - stack->correctParams(1); - ScValue *val = stack->pop(); - if (val->getType() == VAL_INT) { - int widget = val->getInt(); - if (widget < 0 || widget >= (int32)_widgets.size()) { - stack->pushNULL(); - } else { - stack->pushNative(_widgets[widget], true); - } - } else { - for (uint32 i = 0; i < _widgets.size(); i++) { - if (scumm_stricmp(_widgets[i]->getName(), val->getString()) == 0) { - stack->pushNative(_widgets[i], true); - return STATUS_OK; - } - } - stack->pushNULL(); - } - - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // SetInactiveFont - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "SetInactiveFont") == 0) { - stack->correctParams(1); - - if (_fontInactive) { - _gameRef->_fontStorage->removeFont(_fontInactive); - } - _fontInactive = _gameRef->_fontStorage->addFont(stack->pop()->getString()); - stack->pushBool(_fontInactive != NULL); - - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // SetInactiveImage - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "SetInactiveImage") == 0) { - stack->correctParams(1); - - delete _imageInactive; - _imageInactive = new BaseSprite(_gameRef); - const char *filename = stack->pop()->getString(); - if (!_imageInactive || DID_FAIL(_imageInactive->loadFile(filename))) { - delete _imageInactive; - _imageInactive = NULL; - stack->pushBool(false); - } else { - stack->pushBool(true); - } - - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // GetInactiveImage - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "GetInactiveImage") == 0) { - stack->correctParams(0); - if (!_imageInactive || !_imageInactive->getFilename()) { - stack->pushNULL(); - } else { - stack->pushString(_imageInactive->getFilename()); - } - - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // GetInactiveImageObject - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "GetInactiveImageObject") == 0) { - stack->correctParams(0); - if (!_imageInactive) { - stack->pushNULL(); - } else { - stack->pushNative(_imageInactive, true); - } - - return STATUS_OK; - } - - - ////////////////////////////////////////////////////////////////////////// - // Close - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "Close") == 0) { - stack->correctParams(0); - stack->pushBool(DID_SUCCEED(close())); - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // GoExclusive - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "GoExclusive") == 0) { - stack->correctParams(0); - goExclusive(); - script->waitFor(this); - stack->pushNULL(); - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // GoSystemExclusive - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "GoSystemExclusive") == 0) { - stack->correctParams(0); - goSystemExclusive(); - script->waitFor(this); - stack->pushNULL(); - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // Center - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "Center") == 0) { - stack->correctParams(0); - _posX = (_gameRef->_renderer->_width - _width) / 2; - _posY = (_gameRef->_renderer->_height - _height) / 2; - stack->pushNULL(); - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // LoadFromFile - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "LoadFromFile") == 0) { - stack->correctParams(1); - - ScValue *val = stack->pop(); - cleanup(); - if (!val->isNULL()) { - stack->pushBool(DID_SUCCEED(loadFile(val->getString()))); - } else { - stack->pushBool(true); - } - - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // CreateButton - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "CreateButton") == 0) { - stack->correctParams(1); - ScValue *val = stack->pop(); - - UIButton *btn = new UIButton(_gameRef); - if (!val->isNULL()) { - btn->setName(val->getString()); - } - stack->pushNative(btn, true); - - btn->_parent = this; - _widgets.add(btn); - - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // CreateStatic - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "CreateStatic") == 0) { - stack->correctParams(1); - ScValue *val = stack->pop(); - - UIText *sta = new UIText(_gameRef); - if (!val->isNULL()) { - sta->setName(val->getString()); - } - stack->pushNative(sta, true); - - sta->_parent = this; - _widgets.add(sta); - - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // CreateEditor - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "CreateEditor") == 0) { - stack->correctParams(1); - ScValue *val = stack->pop(); - - UIEdit *edi = new UIEdit(_gameRef); - if (!val->isNULL()) { - edi->setName(val->getString()); - } - stack->pushNative(edi, true); - - edi->_parent = this; - _widgets.add(edi); - - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // CreateWindow - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "CreateWindow") == 0) { - stack->correctParams(1); - ScValue *val = stack->pop(); - - UIWindow *win = new UIWindow(_gameRef); - if (!val->isNULL()) { - win->setName(val->getString()); - } - stack->pushNative(win, true); - - win->_parent = this; - _widgets.add(win); - - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // DeleteControl / DeleteButton / DeleteStatic / DeleteEditor / DeleteWindow - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "DeleteControl") == 0 || strcmp(name, "DeleteButton") == 0 || strcmp(name, "DeleteStatic") == 0 || strcmp(name, "DeleteEditor") == 0 || strcmp(name, "DeleteWindow") == 0) { - stack->correctParams(1); - ScValue *val = stack->pop(); - UIObject *obj = (UIObject *)val->getNative(); - - for (uint32 i = 0; i < _widgets.size(); i++) { - if (_widgets[i] == obj) { - delete _widgets[i]; - _widgets.remove_at(i); - if (val->getType() == VAL_VARIABLE_REF) { - val->setNULL(); - } - } - } - stack->pushNULL(); - return STATUS_OK; - } else if DID_SUCCEED(_gameRef->windowScriptMethodHook(this, script, stack, name)) { - return STATUS_OK; - } - - else { - return UIObject::scCallMethod(script, stack, thisStack, name); - } -} - - -////////////////////////////////////////////////////////////////////////// -ScValue *UIWindow::scGetProperty(const char *name) { - _scValue->setNULL(); - - ////////////////////////////////////////////////////////////////////////// - // Type - ////////////////////////////////////////////////////////////////////////// - if (strcmp(name, "Type") == 0) { - _scValue->setString("window"); - return _scValue; - } - - ////////////////////////////////////////////////////////////////////////// - // NumWidgets / NumControls (RO) - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "NumWidgets") == 0 || strcmp(name, "NumControls") == 0) { - _scValue->setInt(_widgets.size()); - return _scValue; - } - - ////////////////////////////////////////////////////////////////////////// - // Exclusive - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "Exclusive") == 0) { - _scValue->setBool(_mode == WINDOW_EXCLUSIVE); - return _scValue; - } - - ////////////////////////////////////////////////////////////////////////// - // SystemExclusive - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "SystemExclusive") == 0) { - _scValue->setBool(_mode == WINDOW_SYSTEM_EXCLUSIVE); - return _scValue; - } - - ////////////////////////////////////////////////////////////////////////// - // Menu - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "Menu") == 0) { - _scValue->setBool(_isMenu); - return _scValue; - } - - ////////////////////////////////////////////////////////////////////////// - // InGame - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "InGame") == 0) { - _scValue->setBool(_inGame); - return _scValue; - } - - ////////////////////////////////////////////////////////////////////////// - // PauseMusic - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "PauseMusic") == 0) { - _scValue->setBool(_pauseMusic); - return _scValue; - } - - ////////////////////////////////////////////////////////////////////////// - // ClipContents - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "ClipContents") == 0) { - _scValue->setBool(_clipContents); - return _scValue; - } - - ////////////////////////////////////////////////////////////////////////// - // Transparent - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "Transparent") == 0) { - _scValue->setBool(_transparent); - return _scValue; - } - - ////////////////////////////////////////////////////////////////////////// - // FadeColor - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "FadeColor") == 0) { - _scValue->setInt((int)_fadeColor); - return _scValue; - } else { - return UIObject::scGetProperty(name); - } -} - - -////////////////////////////////////////////////////////////////////////// -bool UIWindow::scSetProperty(const char *name, ScValue *value) { - ////////////////////////////////////////////////////////////////////////// - // Name - ////////////////////////////////////////////////////////////////////////// - if (strcmp(name, "Name") == 0) { - setName(value->getString()); - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // Menu - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "Menu") == 0) { - _isMenu = value->getBool(); - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // InGame - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "InGame") == 0) { - _inGame = value->getBool(); - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // PauseMusic - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "PauseMusic") == 0) { - _pauseMusic = value->getBool(); - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // ClipContents - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "ClipContents") == 0) { - _clipContents = value->getBool(); - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // Transparent - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "Transparent") == 0) { - _transparent = value->getBool(); - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // FadeColor - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "FadeColor") == 0) { - _fadeColor = (uint32)value->getInt(); - _fadeBackground = (_fadeColor != 0); - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // Exclusive - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "Exclusive") == 0) { - if (value->getBool()) { - goExclusive(); - } else { - close(); - _visible = true; - } - return STATUS_OK; - } - - ////////////////////////////////////////////////////////////////////////// - // SystemExclusive - ////////////////////////////////////////////////////////////////////////// - else if (strcmp(name, "SystemExclusive") == 0) { - if (value->getBool()) { - goSystemExclusive(); - } else { - close(); - _visible = true; - } - return STATUS_OK; - } else { - return UIObject::scSetProperty(name, value); - } -} - - -////////////////////////////////////////////////////////////////////////// -const char *UIWindow::scToString() { - return "[window]"; -} - - -////////////////////////////////////////////////////////////////////////// -bool UIWindow::handleKeypress(Common::Event *event, bool printable) { -//TODO - if (event->type == Common::EVENT_KEYDOWN && event->kbd.keycode == Common::KEYCODE_TAB) { - return DID_SUCCEED(moveFocus(!BaseKeyboardState::isShiftDown())); - } else { - if (_focusedWidget) { - return _focusedWidget->handleKeypress(event, printable); - } else { - return false; - } - } - return false; -} - - -////////////////////////////////////////////////////////////////////////// -bool UIWindow::handleMouseWheel(int Delta) { - if (_focusedWidget) { - return _focusedWidget->handleMouseWheel(Delta); - } else { - return false; - } -} - - -////////////////////////////////////////////////////////////////////////// -bool UIWindow::handleMouse(TMouseEvent event, TMouseButton button) { - bool res = UIObject::handleMouse(event, button); - - // handle window dragging - if (!BasePlatform::isRectEmpty(&_dragRect)) { - // start drag - if (event == MOUSE_CLICK && button == MOUSE_BUTTON_LEFT) { - Rect32 dragRect = _dragRect; - int offsetX, offsetY; - getTotalOffset(&offsetX, &offsetY); - dragRect.offsetRect(_posX + offsetX, _posY + offsetY); - - if (BasePlatform::ptInRect(&dragRect, _gameRef->_mousePos)) { - _dragFrom.x = _gameRef->_mousePos.x; - _dragFrom.y = _gameRef->_mousePos.y; - _dragging = true; - } - } - // end drag - else if (_dragging && event == MOUSE_RELEASE && button == MOUSE_BUTTON_LEFT) { - _dragging = false; - } - } - - return res; -} - - - -////////////////////////////////////////////////////////////////////////// -bool UIWindow::persist(BasePersistenceManager *persistMgr) { - - UIObject::persist(persistMgr); - - persistMgr->transfer(TMEMBER(_backInactive)); - persistMgr->transfer(TMEMBER(_clipContents)); - persistMgr->transfer(TMEMBER(_dragFrom)); - persistMgr->transfer(TMEMBER(_dragging)); - persistMgr->transfer(TMEMBER(_dragRect)); - persistMgr->transfer(TMEMBER(_fadeBackground)); - persistMgr->transfer(TMEMBER(_fadeColor)); - persistMgr->transfer(TMEMBER(_fontInactive)); - persistMgr->transfer(TMEMBER(_imageInactive)); - persistMgr->transfer(TMEMBER(_inGame)); - persistMgr->transfer(TMEMBER(_isMenu)); - persistMgr->transfer(TMEMBER_INT(_mode)); - persistMgr->transfer(TMEMBER(_shieldButton)); - persistMgr->transfer(TMEMBER(_shieldWindow)); - persistMgr->transfer(TMEMBER_INT(_titleAlign)); - persistMgr->transfer(TMEMBER(_titleRect)); - persistMgr->transfer(TMEMBER(_transparent)); - persistMgr->transfer(TMEMBER(_viewport)); - persistMgr->transfer(TMEMBER(_pauseMusic)); - - _widgets.persist(persistMgr); - - return STATUS_OK; -} - - -////////////////////////////////////////////////////////////////////////// -bool UIWindow::moveFocus(bool forward) { - int i; - bool found = false; - for (i = 0; i < (int32)_widgets.size(); i++) { - if (_widgets[i] == _focusedWidget) { - found = true; - break; - } - } - if (!found) { - _focusedWidget = NULL; - } - - if (!_focusedWidget) { - if (_widgets.size() > 0) { - i = 0; - } else { - return STATUS_OK; - } - } - - int numTries = 0; - bool done = false; - - while (numTries <= (int32)_widgets.size()) { - if (_widgets[i] != _focusedWidget && _widgets[i]->_canFocus && _widgets[i]->_visible && !_widgets[i]->_disable) { - _focusedWidget = _widgets[i]; - done = true; - break; - } - - if (forward) { - i++; - if (i >= (int32)_widgets.size()) { - i = 0; - } - } else { - i--; - if (i < 0) { - i = _widgets.size() - 1; - } - } - numTries++; - } - - return done ? STATUS_OK : STATUS_FAILED; -} - - -////////////////////////////////////////////////////////////////////////// -bool UIWindow::goExclusive() { - if (_mode == WINDOW_EXCLUSIVE) { - return STATUS_OK; - } - - if (_mode == WINDOW_NORMAL) { - _ready = false; - _mode = WINDOW_EXCLUSIVE; - _visible = true; - _disable = false; - _gameRef->focusWindow(this); - return STATUS_OK; - } else { - return STATUS_FAILED; - } -} - - -////////////////////////////////////////////////////////////////////////// -bool UIWindow::goSystemExclusive() { - if (_mode == WINDOW_SYSTEM_EXCLUSIVE) { - return STATUS_OK; - } - - makeFreezable(false); - - _mode = WINDOW_SYSTEM_EXCLUSIVE; - _ready = false; - _visible = true; - _disable = false; - _gameRef->focusWindow(this); - - _gameRef->freeze(_pauseMusic); - return STATUS_OK; -} - - -////////////////////////////////////////////////////////////////////////// -bool UIWindow::close() { - if (_mode == WINDOW_SYSTEM_EXCLUSIVE) { - _gameRef->unfreeze(); - } - - _mode = WINDOW_NORMAL; - _visible = false; - _ready = true; - - return STATUS_OK; -} - - -////////////////////////////////////////////////////////////////////////// -bool UIWindow::listen(BaseScriptHolder *param1, uint32 param2) { - UIObject *obj = (UIObject *)param1; - - switch (obj->_type) { - case UI_BUTTON: - if (scumm_stricmp(obj->getName(), "close") == 0) { - close(); - } else { - return BaseObject::listen(param1, param2); - } - break; - default: - return BaseObject::listen(param1, param2); - } - - return STATUS_OK; -} - - -////////////////////////////////////////////////////////////////////////// -void UIWindow::makeFreezable(bool freezable) { - for (uint32 i = 0; i < _widgets.size(); i++) { - _widgets[i]->makeFreezable(freezable); - } - - BaseObject::makeFreezable(freezable); -} - - -////////////////////////////////////////////////////////////////////////// -bool UIWindow::getWindowObjects(BaseArray &objects, bool interactiveOnly) { - for (uint32 i = 0; i < _widgets.size(); i++) { - UIObject *control = _widgets[i]; - if (control->_disable && interactiveOnly) { - continue; - } - - switch (control->_type) { - case UI_WINDOW: - ((UIWindow *)control)->getWindowObjects(objects, interactiveOnly); - break; - - case UI_BUTTON: - case UI_EDIT: - objects.add(control); - break; - - default: - if (!interactiveOnly) { - objects.add(control); - } - } - } - return STATUS_OK; -} - -} // end of namespace Wintermute +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + * 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_parser.h" +#include "engines/wintermute/base/base_active_rect.h" +#include "engines/wintermute/base/base_dynamic_buffer.h" +#include "engines/wintermute/base/base_keyboard_state.h" +#include "engines/wintermute/base/scriptables/script_value.h" +#include "engines/wintermute/ui/ui_button.h" +#include "engines/wintermute/ui/ui_edit.h" +#include "engines/wintermute/ui/ui_text.h" +#include "engines/wintermute/ui/ui_tiled_image.h" +#include "engines/wintermute/ui/ui_window.h" +#include "engines/wintermute/base/base_viewport.h" +#include "engines/wintermute/base/font/base_font_storage.h" +#include "engines/wintermute/base/font/base_font.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" + +namespace Wintermute { + +IMPLEMENT_PERSISTENT(UIWindow, false) + +////////////////////////////////////////////////////////////////////////// +UIWindow::UIWindow(BaseGame *inGame) : UIObject(inGame) { + BasePlatform::setRectEmpty(&_titleRect); + BasePlatform::setRectEmpty(&_dragRect); + _titleAlign = TAL_LEFT; + _transparent = false; + + _backInactive = NULL; + _fontInactive = NULL; + _imageInactive = NULL; + + _type = UI_WINDOW; + _canFocus = true; + + _dragging = false; + _dragFrom.x = _dragFrom.y = 0; + + _mode = WINDOW_NORMAL; + _shieldWindow = NULL; + _shieldButton = NULL; + + _fadeColor = 0x00000000; + _fadeBackground = false; + + _ready = true; + _isMenu = false; + _inGame = false; + + _clipContents = false; + _viewport = NULL; + + _pauseMusic = true; +} + + +////////////////////////////////////////////////////////////////////////// +UIWindow::~UIWindow() { + close(); + cleanup(); +} + + +////////////////////////////////////////////////////////////////////////// +void UIWindow::cleanup() { + delete _shieldWindow; + delete _shieldButton; + delete _viewport; + _shieldWindow = NULL; + _shieldButton = NULL; + _viewport = NULL; + + delete _backInactive; + if (!_sharedFonts && _fontInactive) { + _gameRef->_fontStorage->removeFont(_fontInactive); + } + if (!_sharedImages && _imageInactive) { + delete _imageInactive; + } + + for (uint32 i = 0; i < _widgets.size(); i++) { + delete _widgets[i]; + } + _widgets.clear(); +} + + +////////////////////////////////////////////////////////////////////////// +bool UIWindow::display(int offsetX, int offsetY) { + // go exclusive + if (_mode == WINDOW_EXCLUSIVE || _mode == WINDOW_SYSTEM_EXCLUSIVE) { + if (!_shieldWindow) { + _shieldWindow = new UIWindow(_gameRef); + } + if (_shieldWindow) { + _shieldWindow->_posX = _shieldWindow->_posY = 0; + _shieldWindow->_width = _gameRef->_renderer->_width; + _shieldWindow->_height = _gameRef->_renderer->_height; + + _shieldWindow->display(); + } + } else if (_isMenu) { + if (!_shieldButton) { + _shieldButton = new UIButton(_gameRef); + _shieldButton->setName("close"); + _shieldButton->setListener(this, _shieldButton, 0); + _shieldButton->_parent = this; + } + if (_shieldButton) { + _shieldButton->_posX = _shieldButton->_posY = 0; + _shieldButton->_width = _gameRef->_renderer->_width; + _shieldButton->_height = _gameRef->_renderer->_height; + + _shieldButton->display(); + } + } + + if (!_visible) { + return STATUS_OK; + } + + if (_fadeBackground) { + Graphics::PixelFormat format = _gameRef->_renderer->getPixelFormat(); + byte fadeR, fadeG, fadeB, fadeA; + // First convert from the internal format to the screen-format + uint32 fadeColor = format.ARGBToColor(RGBCOLGetA(_fadeColor), RGBCOLGetR(_fadeColor), RGBCOLGetG(_fadeColor), RGBCOLGetB(_fadeColor)); + // Then get components + format.colorToARGB(fadeColor, fadeA, fadeR, fadeG, fadeB); + _gameRef->_renderer->fadeToColor(fadeR, fadeG, fadeB, fadeA); + } + + if (_dragging) { + _posX += (_gameRef->_mousePos.x - _dragFrom.x); + _posY += (_gameRef->_mousePos.y - _dragFrom.y); + + _dragFrom.x = _gameRef->_mousePos.x; + _dragFrom.y = _gameRef->_mousePos.y; + } + + if (!_focusedWidget || (!_focusedWidget->_canFocus || _focusedWidget->_disable || !_focusedWidget->_visible)) { + moveFocus(); + } + + bool popViewport = false; + if (_clipContents) { + if (!_viewport) { + _viewport = new BaseViewport(_gameRef); + } + if (_viewport) { + _viewport->setRect(_posX + offsetX, _posY + offsetY, _posX + _width + offsetX, _posY + _height + offsetY); + _gameRef->pushViewport(_viewport); + popViewport = true; + } + } + + + UITiledImage *back = _back; + BaseSprite *image = _image; + BaseFont *font = _font; + + if (!isFocused()) { + if (_backInactive) { + back = _backInactive; + } + if (_imageInactive) { + image = _imageInactive; + } + if (_fontInactive) { + font = _fontInactive; + } + } + + if (_alphaColor != 0) { + _gameRef->_renderer->_forceAlphaColor = _alphaColor; + } + if (back) { + back->display(_posX + offsetX, _posY + offsetY, _width, _height); + } + if (image) { + image->draw(_posX + offsetX, _posY + offsetY, _transparent ? NULL : this); + } + + if (!BasePlatform::isRectEmpty(&_titleRect) && font && _text) { + font->drawText((byte *)_text, _posX + offsetX + _titleRect.left, _posY + offsetY + _titleRect.top, _titleRect.right - _titleRect.left, _titleAlign, _titleRect.bottom - _titleRect.top); + } + + if (!_transparent && !image) { + _gameRef->_renderer->addRectToList(new BaseActiveRect(_gameRef, this, NULL, _posX + offsetX, _posY + offsetY, _width, _height, 100, 100, false)); + } + + for (uint32 i = 0; i < _widgets.size(); i++) { + _widgets[i]->display(_posX + offsetX, _posY + offsetY); + } + + if (_alphaColor != 0) { + _gameRef->_renderer->_forceAlphaColor = 0; + } + + if (popViewport) { + _gameRef->popViewport(); + } + + return STATUS_OK; +} + + +////////////////////////////////////////////////////////////////////////// +bool UIWindow::loadFile(const char *filename) { + byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename); + if (buffer == NULL) { + _gameRef->LOG(0, "UIWindow::LoadFile failed for file '%s'", filename); + return STATUS_FAILED; + } + + bool ret; + + setFilename(filename); + + if (DID_FAIL(ret = loadBuffer(buffer, true))) { + _gameRef->LOG(0, "Error parsing WINDOW file '%s'", filename); + } + + delete[] buffer; + + return ret; +} + + +TOKEN_DEF_START +TOKEN_DEF(WINDOW) +TOKEN_DEF(ALPHA_COLOR) +TOKEN_DEF(ALPHA) +TOKEN_DEF(TEMPLATE) +TOKEN_DEF(DISABLED) +TOKEN_DEF(VISIBLE) +TOKEN_DEF(BACK_INACTIVE) +TOKEN_DEF(BACK) +TOKEN_DEF(IMAGE_INACTIVE) +TOKEN_DEF(IMAGE) +TOKEN_DEF(FONT_INACTIVE) +TOKEN_DEF(FONT) +TOKEN_DEF(TITLE_ALIGN) +TOKEN_DEF(TITLE_RECT) +TOKEN_DEF(TITLE) +TOKEN_DEF(DRAG_RECT) +TOKEN_DEF(X) +TOKEN_DEF(Y) +TOKEN_DEF(WIDTH) +TOKEN_DEF(HEIGHT) +TOKEN_DEF(FADE_ALPHA) +TOKEN_DEF(FADE_COLOR) +TOKEN_DEF(CURSOR) +TOKEN_DEF(NAME) +TOKEN_DEF(BUTTON) +TOKEN_DEF(STATIC) +TOKEN_DEF(TRANSPARENT) +TOKEN_DEF(SCRIPT) +TOKEN_DEF(CAPTION) +TOKEN_DEF(PARENT_NOTIFY) +TOKEN_DEF(MENU) +TOKEN_DEF(IN_GAME) +TOKEN_DEF(CLIP_CONTENTS) +TOKEN_DEF(PAUSE_MUSIC) +TOKEN_DEF(EDITOR_PROPERTY) +TOKEN_DEF(EDIT) +TOKEN_DEF_END +////////////////////////////////////////////////////////////////////////// +bool UIWindow::loadBuffer(byte *buffer, bool complete) { + TOKEN_TABLE_START(commands) + TOKEN_TABLE(WINDOW) + TOKEN_TABLE(ALPHA_COLOR) + TOKEN_TABLE(ALPHA) + TOKEN_TABLE(TEMPLATE) + TOKEN_TABLE(DISABLED) + TOKEN_TABLE(VISIBLE) + TOKEN_TABLE(BACK_INACTIVE) + TOKEN_TABLE(BACK) + TOKEN_TABLE(IMAGE_INACTIVE) + TOKEN_TABLE(IMAGE) + TOKEN_TABLE(FONT_INACTIVE) + TOKEN_TABLE(FONT) + TOKEN_TABLE(TITLE_ALIGN) + TOKEN_TABLE(TITLE_RECT) + TOKEN_TABLE(TITLE) + TOKEN_TABLE(DRAG_RECT) + TOKEN_TABLE(X) + TOKEN_TABLE(Y) + TOKEN_TABLE(WIDTH) + TOKEN_TABLE(HEIGHT) + TOKEN_TABLE(FADE_ALPHA) + TOKEN_TABLE(FADE_COLOR) + TOKEN_TABLE(CURSOR) + TOKEN_TABLE(NAME) + TOKEN_TABLE(BUTTON) + TOKEN_TABLE(STATIC) + TOKEN_TABLE(TRANSPARENT) + TOKEN_TABLE(SCRIPT) + TOKEN_TABLE(CAPTION) + TOKEN_TABLE(PARENT_NOTIFY) + TOKEN_TABLE(MENU) + TOKEN_TABLE(IN_GAME) + TOKEN_TABLE(CLIP_CONTENTS) + TOKEN_TABLE(PAUSE_MUSIC) + TOKEN_TABLE(EDITOR_PROPERTY) + TOKEN_TABLE(EDIT) + TOKEN_TABLE_END + + byte *params; + int cmd = 2; + BaseParser parser; + + int fadeR = 0, fadeG = 0, fadeB = 0, fadeA = 0; + int ar = 0, ag = 0, ab = 0, alpha = 0; + + if (complete) { + if (parser.getCommand((char **)&buffer, commands, (char **)¶ms) != TOKEN_WINDOW) { + _gameRef->LOG(0, "'WINDOW' keyword expected."); + return STATUS_FAILED; + } + buffer = params; + } + + while (cmd >= PARSERR_TOKENNOTFOUND && (cmd = parser.getCommand((char **)&buffer, commands, (char **)¶ms)) >= PARSERR_TOKENNOTFOUND) { + switch (cmd) { + case TOKEN_TEMPLATE: + if (DID_FAIL(loadFile((char *)params))) { + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_NAME: + setName((char *)params); + break; + + case TOKEN_CAPTION: + setCaption((char *)params); + break; + + case TOKEN_BACK: + delete _back; + _back = new UITiledImage(_gameRef); + if (!_back || DID_FAIL(_back->loadFile((char *)params))) { + delete _back; + _back = NULL; + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_BACK_INACTIVE: + delete _backInactive; + _backInactive = new UITiledImage(_gameRef); + if (!_backInactive || DID_FAIL(_backInactive->loadFile((char *)params))) { + delete _backInactive; + _backInactive = NULL; + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_IMAGE: + delete _image; + _image = new BaseSprite(_gameRef); + if (!_image || DID_FAIL(_image->loadFile((char *)params))) { + delete _image; + _image = NULL; + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_IMAGE_INACTIVE: + delete _imageInactive, + _imageInactive = new BaseSprite(_gameRef); + if (!_imageInactive || DID_FAIL(_imageInactive->loadFile((char *)params))) { + delete _imageInactive; + _imageInactive = NULL; + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_FONT: + if (_font) { + _gameRef->_fontStorage->removeFont(_font); + } + _font = _gameRef->_fontStorage->addFont((char *)params); + if (!_font) { + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_FONT_INACTIVE: + if (_fontInactive) { + _gameRef->_fontStorage->removeFont(_fontInactive); + } + _fontInactive = _gameRef->_fontStorage->addFont((char *)params); + if (!_fontInactive) { + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_TITLE: + setText((char *)params); + _gameRef->_stringTable->expand(&_text); + break; + + case TOKEN_TITLE_ALIGN: + if (scumm_stricmp((char *)params, "left") == 0) { + _titleAlign = TAL_LEFT; + } else if (scumm_stricmp((char *)params, "right") == 0) { + _titleAlign = TAL_RIGHT; + } else { + _titleAlign = TAL_CENTER; + } + break; + + case TOKEN_TITLE_RECT: + parser.scanStr((char *)params, "%d,%d,%d,%d", &_titleRect.left, &_titleRect.top, &_titleRect.right, &_titleRect.bottom); + break; + + case TOKEN_DRAG_RECT: + parser.scanStr((char *)params, "%d,%d,%d,%d", &_dragRect.left, &_dragRect.top, &_dragRect.right, &_dragRect.bottom); + break; + + case TOKEN_X: + parser.scanStr((char *)params, "%d", &_posX); + break; + + case TOKEN_Y: + parser.scanStr((char *)params, "%d", &_posY); + break; + + case TOKEN_WIDTH: + parser.scanStr((char *)params, "%d", &_width); + break; + + case TOKEN_HEIGHT: + parser.scanStr((char *)params, "%d", &_height); + break; + + case TOKEN_CURSOR: + delete _cursor; + _cursor = new BaseSprite(_gameRef); + if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) { + delete _cursor; + _cursor = NULL; + cmd = PARSERR_GENERIC; + } + break; + + case TOKEN_BUTTON: { + UIButton *btn = new UIButton(_gameRef); + if (!btn || DID_FAIL(btn->loadBuffer(params, false))) { + delete btn; + btn = NULL; + cmd = PARSERR_GENERIC; + } else { + btn->_parent = this; + _widgets.add(btn); + } + } + break; + + case TOKEN_STATIC: { + UIText *text = new UIText(_gameRef); + if (!text || DID_FAIL(text->loadBuffer(params, false))) { + delete text; + text = NULL; + cmd = PARSERR_GENERIC; + } else { + text->_parent = this; + _widgets.add(text); + } + } + break; + + case TOKEN_EDIT: { + UIEdit *edit = new UIEdit(_gameRef); + if (!edit || DID_FAIL(edit->loadBuffer(params, false))) { + delete edit; + edit = NULL; + cmd = PARSERR_GENERIC; + } else { + edit->_parent = this; + _widgets.add(edit); + } + } + break; + + case TOKEN_WINDOW: { + UIWindow *win = new UIWindow(_gameRef); + if (!win || DID_FAIL(win->loadBuffer(params, false))) { + delete win; + win = NULL; + cmd = PARSERR_GENERIC; + } else { + win->_parent = this; + _widgets.add(win); + } + } + break; + + + case TOKEN_TRANSPARENT: + parser.scanStr((char *)params, "%b", &_transparent); + break; + + case TOKEN_SCRIPT: + addScript((char *)params); + break; + + case TOKEN_PARENT_NOTIFY: + parser.scanStr((char *)params, "%b", &_parentNotify); + break; + + case TOKEN_PAUSE_MUSIC: + parser.scanStr((char *)params, "%b", &_pauseMusic); + break; + + case TOKEN_DISABLED: + parser.scanStr((char *)params, "%b", &_disable); + break; + + case TOKEN_VISIBLE: + parser.scanStr((char *)params, "%b", &_visible); + break; + + case TOKEN_MENU: + parser.scanStr((char *)params, "%b", &_isMenu); + break; + + case TOKEN_IN_GAME: + parser.scanStr((char *)params, "%b", &_inGame); + break; + + case TOKEN_CLIP_CONTENTS: + parser.scanStr((char *)params, "%b", &_clipContents); + break; + + case TOKEN_FADE_COLOR: + parser.scanStr((char *)params, "%d,%d,%d", &fadeR, &fadeG, &fadeB); + _fadeBackground = true; + break; + + case TOKEN_FADE_ALPHA: + parser.scanStr((char *)params, "%d", &fadeA); + _fadeBackground = true; + break; + + case TOKEN_EDITOR_PROPERTY: + parseEditorProperty(params, false); + break; + + case TOKEN_ALPHA_COLOR: + parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab); + break; + + case TOKEN_ALPHA: + parser.scanStr((char *)params, "%d", &alpha); + break; + + + default: + if (DID_FAIL(_gameRef->windowLoadHook(this, (char **)&buffer, (char **)params))) { + cmd = PARSERR_GENERIC; + } + } + } + if (cmd == PARSERR_TOKENNOTFOUND) { + _gameRef->LOG(0, "Syntax error in WINDOW definition"); + return STATUS_FAILED; + } + if (cmd == PARSERR_GENERIC) { + _gameRef->LOG(0, "Error loading WINDOW definition"); + return STATUS_FAILED; + } + + correctSize(); + + if (alpha != 0 && ar == 0 && ag == 0 && ab == 0) { + ar = ag = ab = 255; + } + _alphaColor = BYTETORGBA(ar, ag, ab, alpha); + + if (_fadeBackground) { + _fadeColor = BYTETORGBA(fadeR, fadeG, fadeB, fadeA); + } + + _focusedWidget = NULL; + + return STATUS_OK; +} + +////////////////////////////////////////////////////////////////////////// +bool UIWindow::saveAsText(BaseDynamicBuffer *buffer, int indent) { + buffer->putTextIndent(indent, "WINDOW\n"); + buffer->putTextIndent(indent, "{\n"); + + buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", getName()); + buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption()); + + buffer->putTextIndent(indent + 2, "\n"); + + if (_back && _back->getFilename()) { + buffer->putTextIndent(indent + 2, "BACK=\"%s\"\n", _back->getFilename()); + } + if (_backInactive && _backInactive->getFilename()) { + buffer->putTextIndent(indent + 2, "BACK_INACTIVE=\"%s\"\n", _backInactive->getFilename()); + } + + if (_image && _image->getFilename()) { + buffer->putTextIndent(indent + 2, "IMAGE=\"%s\"\n", _image->getFilename()); + } + if (_imageInactive && _imageInactive->getFilename()) { + buffer->putTextIndent(indent + 2, "IMAGE_INACTIVE=\"%s\"\n", _imageInactive->getFilename()); + } + + if (_font && _font->getFilename()) { + buffer->putTextIndent(indent + 2, "FONT=\"%s\"\n", _font->getFilename()); + } + if (_fontInactive && _fontInactive->getFilename()) { + buffer->putTextIndent(indent + 2, "FONT_INACTIVE=\"%s\"\n", _fontInactive->getFilename()); + } + + if (_cursor && _cursor->getFilename()) { + buffer->putTextIndent(indent + 2, "CURSOR=\"%s\"\n", _cursor->getFilename()); + } + + buffer->putTextIndent(indent + 2, "\n"); + + if (_text) { + buffer->putTextIndent(indent + 2, "TITLE=\"%s\"\n", _text); + } + + switch (_titleAlign) { + case TAL_LEFT: + buffer->putTextIndent(indent + 2, "TITLE_ALIGN=\"%s\"\n", "left"); + break; + case TAL_RIGHT: + buffer->putTextIndent(indent + 2, "TITLE_ALIGN=\"%s\"\n", "right"); + break; + case TAL_CENTER: + buffer->putTextIndent(indent + 2, "TITLE_ALIGN=\"%s\"\n", "center"); + break; + default: + error("UIWindow::SaveAsText - Unhandled enum-value NUM_TEXT_ALIGN"); + } + + if (!BasePlatform::isRectEmpty(&_titleRect)) { + buffer->putTextIndent(indent + 2, "TITLE_RECT { %d, %d, %d, %d }\n", _titleRect.left, _titleRect.top, _titleRect.right, _titleRect.bottom); + } + + if (!BasePlatform::isRectEmpty(&_dragRect)) { + buffer->putTextIndent(indent + 2, "DRAG_RECT { %d, %d, %d, %d }\n", _dragRect.left, _dragRect.top, _dragRect.right, _dragRect.bottom); + } + + 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, "TRANSPARENT=%s\n", _transparent ? "TRUE" : "FALSE"); + buffer->putTextIndent(indent + 2, "PAUSE_MUSIC=%s\n", _pauseMusic ? "TRUE" : "FALSE"); + buffer->putTextIndent(indent + 2, "MENU=%s\n", _isMenu ? "TRUE" : "FALSE"); + buffer->putTextIndent(indent + 2, "IN_GAME=%s\n", _inGame ? "TRUE" : "FALSE"); + buffer->putTextIndent(indent + 2, "CLIP_CONTENTS=%s\n", _clipContents ? "TRUE" : "FALSE"); + + buffer->putTextIndent(indent + 2, "\n"); + + if (_fadeBackground) { + buffer->putTextIndent(indent + 2, "FADE_COLOR { %d, %d, %d }\n", RGBCOLGetR(_fadeColor), RGBCOLGetG(_fadeColor), RGBCOLGetB(_fadeColor)); + buffer->putTextIndent(indent + 2, "FADE_ALPHA=%d\n", RGBCOLGetA(_fadeColor)); + } + + buffer->putTextIndent(indent + 2, "ALPHA_COLOR { %d, %d, %d }\n", RGBCOLGetR(_alphaColor), RGBCOLGetG(_alphaColor), RGBCOLGetB(_alphaColor)); + buffer->putTextIndent(indent + 2, "ALPHA=%d\n", RGBCOLGetA(_alphaColor)); + + buffer->putTextIndent(indent + 2, "\n"); + + // scripts + for (uint32 i = 0; i < _scripts.size(); i++) { + buffer->putTextIndent(indent + 2, "SCRIPT=\"%s\"\n", _scripts[i]->_filename); + } + + buffer->putTextIndent(indent + 2, "\n"); + + // editor properties + BaseClass::saveAsText(buffer, indent + 2); + + // controls + for (uint32 i = 0; i < _widgets.size(); i++) { + _widgets[i]->saveAsText(buffer, indent + 2); + } + + + buffer->putTextIndent(indent, "}\n"); + return STATUS_OK; +} + +////////////////////////////////////////////////////////////////////////// +bool UIWindow::enableWidget(const char *name, bool enable) { + for (uint32 i = 0; i < _widgets.size(); i++) { + if (scumm_stricmp(_widgets[i]->getName(), name) == 0) { + _widgets[i]->_disable = !enable; + } + } + return STATUS_OK; +} + + +////////////////////////////////////////////////////////////////////////// +bool UIWindow::showWidget(const char *name, bool visible) { + for (uint32 i = 0; i < _widgets.size(); i++) { + if (scumm_stricmp(_widgets[i]->getName(), name) == 0) { + _widgets[i]->_visible = visible; + } + } + return STATUS_OK; +} + + +////////////////////////////////////////////////////////////////////////// +// high level scripting interface +////////////////////////////////////////////////////////////////////////// +bool UIWindow::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) { + ////////////////////////////////////////////////////////////////////////// + // GetWidget / GetControl + ////////////////////////////////////////////////////////////////////////// + if (strcmp(name, "GetWidget") == 0 || strcmp(name, "GetControl") == 0) { + stack->correctParams(1); + ScValue *val = stack->pop(); + if (val->getType() == VAL_INT) { + int widget = val->getInt(); + if (widget < 0 || widget >= (int32)_widgets.size()) { + stack->pushNULL(); + } else { + stack->pushNative(_widgets[widget], true); + } + } else { + for (uint32 i = 0; i < _widgets.size(); i++) { + if (scumm_stricmp(_widgets[i]->getName(), val->getString()) == 0) { + stack->pushNative(_widgets[i], true); + return STATUS_OK; + } + } + stack->pushNULL(); + } + + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // SetInactiveFont + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "SetInactiveFont") == 0) { + stack->correctParams(1); + + if (_fontInactive) { + _gameRef->_fontStorage->removeFont(_fontInactive); + } + _fontInactive = _gameRef->_fontStorage->addFont(stack->pop()->getString()); + stack->pushBool(_fontInactive != NULL); + + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // SetInactiveImage + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "SetInactiveImage") == 0) { + stack->correctParams(1); + + delete _imageInactive; + _imageInactive = new BaseSprite(_gameRef); + const char *filename = stack->pop()->getString(); + if (!_imageInactive || DID_FAIL(_imageInactive->loadFile(filename))) { + delete _imageInactive; + _imageInactive = NULL; + stack->pushBool(false); + } else { + stack->pushBool(true); + } + + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // GetInactiveImage + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "GetInactiveImage") == 0) { + stack->correctParams(0); + if (!_imageInactive || !_imageInactive->getFilename()) { + stack->pushNULL(); + } else { + stack->pushString(_imageInactive->getFilename()); + } + + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // GetInactiveImageObject + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "GetInactiveImageObject") == 0) { + stack->correctParams(0); + if (!_imageInactive) { + stack->pushNULL(); + } else { + stack->pushNative(_imageInactive, true); + } + + return STATUS_OK; + } + + + ////////////////////////////////////////////////////////////////////////// + // Close + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "Close") == 0) { + stack->correctParams(0); + stack->pushBool(DID_SUCCEED(close())); + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // GoExclusive + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "GoExclusive") == 0) { + stack->correctParams(0); + goExclusive(); + script->waitFor(this); + stack->pushNULL(); + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // GoSystemExclusive + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "GoSystemExclusive") == 0) { + stack->correctParams(0); + goSystemExclusive(); + script->waitFor(this); + stack->pushNULL(); + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // Center + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "Center") == 0) { + stack->correctParams(0); + _posX = (_gameRef->_renderer->_width - _width) / 2; + _posY = (_gameRef->_renderer->_height - _height) / 2; + stack->pushNULL(); + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // LoadFromFile + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "LoadFromFile") == 0) { + stack->correctParams(1); + + ScValue *val = stack->pop(); + cleanup(); + if (!val->isNULL()) { + stack->pushBool(DID_SUCCEED(loadFile(val->getString()))); + } else { + stack->pushBool(true); + } + + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // CreateButton + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "CreateButton") == 0) { + stack->correctParams(1); + ScValue *val = stack->pop(); + + UIButton *btn = new UIButton(_gameRef); + if (!val->isNULL()) { + btn->setName(val->getString()); + } + stack->pushNative(btn, true); + + btn->_parent = this; + _widgets.add(btn); + + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // CreateStatic + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "CreateStatic") == 0) { + stack->correctParams(1); + ScValue *val = stack->pop(); + + UIText *sta = new UIText(_gameRef); + if (!val->isNULL()) { + sta->setName(val->getString()); + } + stack->pushNative(sta, true); + + sta->_parent = this; + _widgets.add(sta); + + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // CreateEditor + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "CreateEditor") == 0) { + stack->correctParams(1); + ScValue *val = stack->pop(); + + UIEdit *edi = new UIEdit(_gameRef); + if (!val->isNULL()) { + edi->setName(val->getString()); + } + stack->pushNative(edi, true); + + edi->_parent = this; + _widgets.add(edi); + + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // CreateWindow + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "CreateWindow") == 0) { + stack->correctParams(1); + ScValue *val = stack->pop(); + + UIWindow *win = new UIWindow(_gameRef); + if (!val->isNULL()) { + win->setName(val->getString()); + } + stack->pushNative(win, true); + + win->_parent = this; + _widgets.add(win); + + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // DeleteControl / DeleteButton / DeleteStatic / DeleteEditor / DeleteWindow + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "DeleteControl") == 0 || strcmp(name, "DeleteButton") == 0 || strcmp(name, "DeleteStatic") == 0 || strcmp(name, "DeleteEditor") == 0 || strcmp(name, "DeleteWindow") == 0) { + stack->correctParams(1); + ScValue *val = stack->pop(); + UIObject *obj = (UIObject *)val->getNative(); + + for (uint32 i = 0; i < _widgets.size(); i++) { + if (_widgets[i] == obj) { + delete _widgets[i]; + _widgets.remove_at(i); + if (val->getType() == VAL_VARIABLE_REF) { + val->setNULL(); + } + } + } + stack->pushNULL(); + return STATUS_OK; + } else if DID_SUCCEED(_gameRef->windowScriptMethodHook(this, script, stack, name)) { + return STATUS_OK; + } + + else { + return UIObject::scCallMethod(script, stack, thisStack, name); + } +} + + +////////////////////////////////////////////////////////////////////////// +ScValue *UIWindow::scGetProperty(const char *name) { + _scValue->setNULL(); + + ////////////////////////////////////////////////////////////////////////// + // Type + ////////////////////////////////////////////////////////////////////////// + if (strcmp(name, "Type") == 0) { + _scValue->setString("window"); + return _scValue; + } + + ////////////////////////////////////////////////////////////////////////// + // NumWidgets / NumControls (RO) + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "NumWidgets") == 0 || strcmp(name, "NumControls") == 0) { + _scValue->setInt(_widgets.size()); + return _scValue; + } + + ////////////////////////////////////////////////////////////////////////// + // Exclusive + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "Exclusive") == 0) { + _scValue->setBool(_mode == WINDOW_EXCLUSIVE); + return _scValue; + } + + ////////////////////////////////////////////////////////////////////////// + // SystemExclusive + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "SystemExclusive") == 0) { + _scValue->setBool(_mode == WINDOW_SYSTEM_EXCLUSIVE); + return _scValue; + } + + ////////////////////////////////////////////////////////////////////////// + // Menu + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "Menu") == 0) { + _scValue->setBool(_isMenu); + return _scValue; + } + + ////////////////////////////////////////////////////////////////////////// + // InGame + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "InGame") == 0) { + _scValue->setBool(_inGame); + return _scValue; + } + + ////////////////////////////////////////////////////////////////////////// + // PauseMusic + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "PauseMusic") == 0) { + _scValue->setBool(_pauseMusic); + return _scValue; + } + + ////////////////////////////////////////////////////////////////////////// + // ClipContents + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "ClipContents") == 0) { + _scValue->setBool(_clipContents); + return _scValue; + } + + ////////////////////////////////////////////////////////////////////////// + // Transparent + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "Transparent") == 0) { + _scValue->setBool(_transparent); + return _scValue; + } + + ////////////////////////////////////////////////////////////////////////// + // FadeColor + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "FadeColor") == 0) { + _scValue->setInt((int)_fadeColor); + return _scValue; + } else { + return UIObject::scGetProperty(name); + } +} + + +////////////////////////////////////////////////////////////////////////// +bool UIWindow::scSetProperty(const char *name, ScValue *value) { + ////////////////////////////////////////////////////////////////////////// + // Name + ////////////////////////////////////////////////////////////////////////// + if (strcmp(name, "Name") == 0) { + setName(value->getString()); + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // Menu + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "Menu") == 0) { + _isMenu = value->getBool(); + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // InGame + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "InGame") == 0) { + _inGame = value->getBool(); + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // PauseMusic + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "PauseMusic") == 0) { + _pauseMusic = value->getBool(); + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // ClipContents + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "ClipContents") == 0) { + _clipContents = value->getBool(); + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // Transparent + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "Transparent") == 0) { + _transparent = value->getBool(); + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // FadeColor + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "FadeColor") == 0) { + _fadeColor = (uint32)value->getInt(); + _fadeBackground = (_fadeColor != 0); + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // Exclusive + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "Exclusive") == 0) { + if (value->getBool()) { + goExclusive(); + } else { + close(); + _visible = true; + } + return STATUS_OK; + } + + ////////////////////////////////////////////////////////////////////////// + // SystemExclusive + ////////////////////////////////////////////////////////////////////////// + else if (strcmp(name, "SystemExclusive") == 0) { + if (value->getBool()) { + goSystemExclusive(); + } else { + close(); + _visible = true; + } + return STATUS_OK; + } else { + return UIObject::scSetProperty(name, value); + } +} + + +////////////////////////////////////////////////////////////////////////// +const char *UIWindow::scToString() { + return "[window]"; +} + + +////////////////////////////////////////////////////////////////////////// +bool UIWindow::handleKeypress(Common::Event *event, bool printable) { +//TODO + if (event->type == Common::EVENT_KEYDOWN && event->kbd.keycode == Common::KEYCODE_TAB) { + return DID_SUCCEED(moveFocus(!BaseKeyboardState::isShiftDown())); + } else { + if (_focusedWidget) { + return _focusedWidget->handleKeypress(event, printable); + } else { + return false; + } + } + return false; +} + + +////////////////////////////////////////////////////////////////////////// +bool UIWindow::handleMouseWheel(int Delta) { + if (_focusedWidget) { + return _focusedWidget->handleMouseWheel(Delta); + } else { + return false; + } +} + + +////////////////////////////////////////////////////////////////////////// +bool UIWindow::handleMouse(TMouseEvent event, TMouseButton button) { + bool res = UIObject::handleMouse(event, button); + + // handle window dragging + if (!BasePlatform::isRectEmpty(&_dragRect)) { + // start drag + if (event == MOUSE_CLICK && button == MOUSE_BUTTON_LEFT) { + Rect32 dragRect = _dragRect; + int offsetX, offsetY; + getTotalOffset(&offsetX, &offsetY); + dragRect.offsetRect(_posX + offsetX, _posY + offsetY); + + if (BasePlatform::ptInRect(&dragRect, _gameRef->_mousePos)) { + _dragFrom.x = _gameRef->_mousePos.x; + _dragFrom.y = _gameRef->_mousePos.y; + _dragging = true; + } + } + // end drag + else if (_dragging && event == MOUSE_RELEASE && button == MOUSE_BUTTON_LEFT) { + _dragging = false; + } + } + + return res; +} + + + +////////////////////////////////////////////////////////////////////////// +bool UIWindow::persist(BasePersistenceManager *persistMgr) { + + UIObject::persist(persistMgr); + + persistMgr->transfer(TMEMBER(_backInactive)); + persistMgr->transfer(TMEMBER(_clipContents)); + persistMgr->transfer(TMEMBER(_dragFrom)); + persistMgr->transfer(TMEMBER(_dragging)); + persistMgr->transfer(TMEMBER(_dragRect)); + persistMgr->transfer(TMEMBER(_fadeBackground)); + persistMgr->transfer(TMEMBER(_fadeColor)); + persistMgr->transfer(TMEMBER(_fontInactive)); + persistMgr->transfer(TMEMBER(_imageInactive)); + persistMgr->transfer(TMEMBER(_inGame)); + persistMgr->transfer(TMEMBER(_isMenu)); + persistMgr->transfer(TMEMBER_INT(_mode)); + persistMgr->transfer(TMEMBER(_shieldButton)); + persistMgr->transfer(TMEMBER(_shieldWindow)); + persistMgr->transfer(TMEMBER_INT(_titleAlign)); + persistMgr->transfer(TMEMBER(_titleRect)); + persistMgr->transfer(TMEMBER(_transparent)); + persistMgr->transfer(TMEMBER(_viewport)); + persistMgr->transfer(TMEMBER(_pauseMusic)); + + _widgets.persist(persistMgr); + + return STATUS_OK; +} + + +////////////////////////////////////////////////////////////////////////// +bool UIWindow::moveFocus(bool forward) { + int i; + bool found = false; + for (i = 0; i < (int32)_widgets.size(); i++) { + if (_widgets[i] == _focusedWidget) { + found = true; + break; + } + } + if (!found) { + _focusedWidget = NULL; + } + + if (!_focusedWidget) { + if (_widgets.size() > 0) { + i = 0; + } else { + return STATUS_OK; + } + } + + int numTries = 0; + bool done = false; + + while (numTries <= (int32)_widgets.size()) { + if (_widgets[i] != _focusedWidget && _widgets[i]->_canFocus && _widgets[i]->_visible && !_widgets[i]->_disable) { + _focusedWidget = _widgets[i]; + done = true; + break; + } + + if (forward) { + i++; + if (i >= (int32)_widgets.size()) { + i = 0; + } + } else { + i--; + if (i < 0) { + i = _widgets.size() - 1; + } + } + numTries++; + } + + return done ? STATUS_OK : STATUS_FAILED; +} + + +////////////////////////////////////////////////////////////////////////// +bool UIWindow::goExclusive() { + if (_mode == WINDOW_EXCLUSIVE) { + return STATUS_OK; + } + + if (_mode == WINDOW_NORMAL) { + _ready = false; + _mode = WINDOW_EXCLUSIVE; + _visible = true; + _disable = false; + _gameRef->focusWindow(this); + return STATUS_OK; + } else { + return STATUS_FAILED; + } +} + + +////////////////////////////////////////////////////////////////////////// +bool UIWindow::goSystemExclusive() { + if (_mode == WINDOW_SYSTEM_EXCLUSIVE) { + return STATUS_OK; + } + + makeFreezable(false); + + _mode = WINDOW_SYSTEM_EXCLUSIVE; + _ready = false; + _visible = true; + _disable = false; + _gameRef->focusWindow(this); + + _gameRef->freeze(_pauseMusic); + return STATUS_OK; +} + + +////////////////////////////////////////////////////////////////////////// +bool UIWindow::close() { + if (_mode == WINDOW_SYSTEM_EXCLUSIVE) { + _gameRef->unfreeze(); + } + + _mode = WINDOW_NORMAL; + _visible = false; + _ready = true; + + return STATUS_OK; +} + + +////////////////////////////////////////////////////////////////////////// +bool UIWindow::listen(BaseScriptHolder *param1, uint32 param2) { + UIObject *obj = (UIObject *)param1; + + switch (obj->_type) { + case UI_BUTTON: + if (scumm_stricmp(obj->getName(), "close") == 0) { + close(); + } else { + return BaseObject::listen(param1, param2); + } + break; + default: + return BaseObject::listen(param1, param2); + } + + return STATUS_OK; +} + + +////////////////////////////////////////////////////////////////////////// +void UIWindow::makeFreezable(bool freezable) { + for (uint32 i = 0; i < _widgets.size(); i++) { + _widgets[i]->makeFreezable(freezable); + } + + BaseObject::makeFreezable(freezable); +} + + +////////////////////////////////////////////////////////////////////////// +bool UIWindow::getWindowObjects(BaseArray &objects, bool interactiveOnly) { + for (uint32 i = 0; i < _widgets.size(); i++) { + UIObject *control = _widgets[i]; + if (control->_disable && interactiveOnly) { + continue; + } + + switch (control->_type) { + case UI_WINDOW: + ((UIWindow *)control)->getWindowObjects(objects, interactiveOnly); + break; + + case UI_BUTTON: + case UI_EDIT: + objects.add(control); + break; + + default: + if (!interactiveOnly) { + objects.add(control); + } + } + } + return STATUS_OK; +} + +} // end of namespace Wintermute diff --git a/engines/wintermute/ui/ui_window.h b/engines/wintermute/ui/ui_window.h index 8093e2b8f4..cbd417a7d9 100644 --- a/engines/wintermute/ui/ui_window.h +++ b/engines/wintermute/ui/ui_window.h @@ -1,94 +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 2 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -/* - * 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 { - uint32 _fadeColor; -public: - bool getWindowObjects(BaseArray &Objects, bool InteractiveOnly); - - bool _pauseMusic; - void cleanup(); - virtual void makeFreezable(bool freezable); - BaseViewport *_viewport; - bool _clipContents; - bool _inGame; - bool _isMenu; - bool _fadeBackground; - - virtual bool handleMouseWheel(int delta); - UIWindow *_shieldWindow; - UIButton *_shieldButton; - bool close(); - bool goSystemExclusive(); - bool goExclusive(); - TWindowMode _mode; - bool moveFocus(bool forward = true); - virtual bool handleMouse(TMouseEvent Event, TMouseButton Button); - 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); - Rect32 _titleRect; - Rect32 _dragRect; - virtual bool display(int offsetX = 0, int offsetY = 0); - UIWindow(BaseGame *inGame); - virtual ~UIWindow(); - virtual bool handleKeypress(Common::Event *event, bool printable = false); - BaseArray _widgets; - TTextAlign _titleAlign; - bool loadFile(const char *filename); - bool loadBuffer(byte *buffer, bool complete = true); - UITiledImage *_backInactive; - BaseFont *_fontInactive; - BaseSprite *_imageInactive; - virtual bool listen(BaseScriptHolder *param1, uint32 param2); - virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent); - - // scripting interface - virtual ScValue *scGetProperty(const char *name); - virtual bool scSetProperty(const char *name, ScValue *value); - virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name); - virtual const char *scToString(); -}; - -} // end of namespace Wintermute - -#endif +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + * 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 { + uint32 _fadeColor; +public: + bool getWindowObjects(BaseArray &Objects, bool InteractiveOnly); + + bool _pauseMusic; + void cleanup(); + virtual void makeFreezable(bool freezable); + BaseViewport *_viewport; + bool _clipContents; + bool _inGame; + bool _isMenu; + bool _fadeBackground; + + virtual bool handleMouseWheel(int delta); + UIWindow *_shieldWindow; + UIButton *_shieldButton; + bool close(); + bool goSystemExclusive(); + bool goExclusive(); + TWindowMode _mode; + bool moveFocus(bool forward = true); + virtual bool handleMouse(TMouseEvent Event, TMouseButton Button); + 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); + Rect32 _titleRect; + Rect32 _dragRect; + virtual bool display(int offsetX = 0, int offsetY = 0); + UIWindow(BaseGame *inGame); + virtual ~UIWindow(); + virtual bool handleKeypress(Common::Event *event, bool printable = false); + BaseArray _widgets; + TTextAlign _titleAlign; + bool loadFile(const char *filename); + bool loadBuffer(byte *buffer, bool complete = true); + UITiledImage *_backInactive; + BaseFont *_fontInactive; + BaseSprite *_imageInactive; + virtual bool listen(BaseScriptHolder *param1, uint32 param2); + virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent); + + // scripting interface + virtual ScValue *scGetProperty(const char *name); + virtual bool scSetProperty(const char *name, ScValue *value); + virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name); + virtual const char *scToString(); +}; + +} // end of namespace Wintermute + +#endif -- cgit v1.2.3