aboutsummaryrefslogtreecommitdiff
path: root/engines/m4/gui.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/m4/gui.cpp')
-rw-r--r--engines/m4/gui.cpp1215
1 files changed, 0 insertions, 1215 deletions
diff --git a/engines/m4/gui.cpp b/engines/m4/gui.cpp
deleted file mode 100644
index 6bedfa7e9b..0000000000
--- a/engines/m4/gui.cpp
+++ /dev/null
@@ -1,1215 +0,0 @@
-/* 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.
- *
- */
-
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/textconsole.h"
-
-#include "m4/globals.h"
-#include "m4/events.h"
-#include "m4/font.h"
-#include "m4/graphics.h"
-#include "m4/viewmgr.h"
-#include "m4/gui.h"
-#include "m4/midi.h"
-#include "m4/scene.h"
-#include "m4/m4.h"
-
-namespace M4 {
-
-//--------------------------------------------------------------------------
-// DialogView class
-//
-// Defines a generic base class for dialogs, that some of the classes
-// in the object hierharchy require as a parent
-//--------------------------------------------------------------------------
-
-void DialogView::close() {
- // Default to simply destroying the given dialog
- _vm->_viewManager->deleteView(this);
-}
-
-//--------------------------------------------------------------------------
-// GUIObject class
-//
-// Defines a generic object that appears in a view
-//--------------------------------------------------------------------------
-
-GUIObject::GUIObject(View *owner, const Common::Rect &bounds) {
- _parent = owner;
- _bounds = bounds;
-}
-
-//--------------------------------------------------------------------------
-// MenuObject class
-//
-// Defines a specialised GUI object that appears in a dialog
-//--------------------------------------------------------------------------
-
-MenuObject::MenuObject(DialogView *owner, int objectId, int xs, int ys, int width, int height,
- bool greyed, bool transparent):
- GUIObject(owner, Common::Rect(xs, ys, xs + width, ys + height)) {
-
- _objectId = objectId;
- _bounds.top = ys;
- _bounds.bottom = ys + height - 1;
- _bounds.left = xs;
- _bounds.right = xs + width - 1;
- _transparent = transparent;
- _objectState = greyed ? OS_GREYED : OS_NORMAL;
- _callback = NULL;
-
- if (transparent) {
- _background = new M4Surface(width, height);
- Common::Rect srcBounds(xs, ys, xs + width - 1, ys + height - 1);
- _background->copyFrom(owner, srcBounds, 0, 0);
- } else {
- _background = NULL;
- }
-}
-
-MenuObject::~MenuObject() {
- delete _background;
-}
-
-void MenuObject::onExecute() {
- // If a callback function has been specified, then execute it
- if (_callback)
- _callback(parent(), this);
-}
-
-//--------------------------------------------------------------------------
-// MenuButton class
-//
-// Defines a button object
-//--------------------------------------------------------------------------
-
-MenuButton::MenuButton(DialogView *owner, int buttonId, int xs, int ys, int width, int height,
- MenuButton::Callback callbackFn, bool greyed, bool transparent,
- ObjectType buttonType):
- MenuObject(owner, buttonId, xs, ys, width, height, greyed, transparent) {
-
- _objectType = buttonType;
- _callback = callbackFn;
-}
-
-bool MenuButton::onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem) {
- bool redrawFlag = false;
- bool callbackFlag = false;
- bool handledFlag = true;
-
- if (_objectState == OS_GREYED)
- return false;
-
- switch (event) {
- case MEVENT_LEFT_CLICK:
- case MEVENT_DOUBLECLICK:
- if (isInside(x, y)) {
- _objectState = OS_PRESSED;
- if (currentItem != NULL)
- currentItem = this;
- redrawFlag = true;
- } else {
- currentItem = NULL;
- if (_objectState != OS_NORMAL) {
- _objectState = OS_PRESSED;
- redrawFlag = true;
- }
- }
- break;
-
- case MEVENT_LEFT_DRAG:
- case MEVENT_DOUBLECLICK_DRAG:
- if (!currentItem) {
- return true;
- }
- if (isInside(x, y)) {
- if (_objectState != OS_PRESSED) {
- _objectState = OS_PRESSED;
- redrawFlag = true;
- }
- }
- else {
- if (_objectState != OS_MOUSEOVER) {
- _objectState = OS_MOUSEOVER;
- redrawFlag = true;
- }
- }
- break;
-
- case MEVENT_LEFT_RELEASE:
- case MEVENT_DOUBLECLICK_RELEASE:
- if (isInside(x, y)) {
- if (currentItem) {
- callbackFlag = true;
- if (_objectType == OBJTYPE_OM_SWITCH_ON)
- _objectType = OBJTYPE_OM_SWITCH_OFF;
- else if (_objectType == OBJTYPE_OM_SWITCH_OFF)
- _objectType = OBJTYPE_OM_SWITCH_ON;
- }
- else {
- currentItem = this;
- }
-
- _objectState = OS_MOUSEOVER;
- redrawFlag = true;
-
- } else {
- currentItem = NULL;
- _objectState = OS_MOUSEOVER;
- redrawFlag = true;
- handledFlag = false;
- }
- break;
-
- case MEVENT_MOVE:
- if (isInside(x, y)) {
- currentItem = this;
- if (_objectState != OS_MOUSEOVER) {
- _objectState = OS_MOUSEOVER;
- redrawFlag = true;
- }
- }
- else {
- currentItem = NULL;
- if (_objectState != OS_NORMAL) {
- _objectState = OS_NORMAL;
- redrawFlag = true;
- handledFlag = false;
- }
- }
- break;
-
- case MEVENT_LEFT_HOLD:
- case MEVENT_DOUBLECLICK_HOLD:
- break;
-
- default:
- break;
- }
-
- //see if we need to redraw the button
- if (redrawFlag) {
- onRefresh();
-
- // TODO: There may be a more efficient mechanism than refreshing the entire screen
- // when a menu object refreshes itself
- if (parent()->screenFlags().visible)
- _vm->_viewManager->refreshAll();
- }
-
- // If a callback is flagged, then handle it
-
- if (callbackFlag)
- onExecute();
-
- return handledFlag;
-}
-
-void MenuButton::onRefresh() {
- M4Sprite *sprite = NULL;
- SpriteAsset &sprites = *parent()->sprites();
-
- // Switch handling for the various button types
- switch (_objectType) {
- case OBJTYPE_BUTTON:
- sprite = sprites[GM_BUTTON_GREYED + _objectState];
- break;
-
- case OBJTYPE_OM_SWITCH_ON:
- switch (_objectState) {
- case OS_MOUSEOVER:
- sprite = sprites[MENU_SS_SWITCH_ON_MOUSEOVER];
- break;
- case OS_PRESSED:
- sprite = sprites[MENU_SS_SWITCH_ON_PRESSED];
- break;
- default:
- sprite = sprites[MENU_SS_SWITCH_ON_NORMAL];
- break;
- }
- break;
-
- case OBJTYPE_OM_SWITCH_OFF:
- switch (_objectState) {
- case OS_MOUSEOVER:
- sprite = sprites[MENU_SS_SWITCH_OFF_MOUSEOVER];
- break;
- case OS_PRESSED:
- sprite = sprites[MENU_SS_SWITCH_OFF_PRESSED];
- break;
- default:
- sprite = sprites[MENU_SS_SWITCH_OFF_NORMAL];
- break;
- }
- break;
-
- case OBJTYPE_OM_DONE:
- sprite = sprites[OM_DONE_BTN_GREYED + _objectState];
- break;
-
- case OBJTYPE_OM_CANCEL:
- sprite = (_objectState == OS_GREYED) ? sprites[OM_CANCEL_BTN_NORMAL] :
- sprites[OM_CANCEL_BTN_NORMAL + _objectState - 1];
- break;
-
- case OBJTYPE_SL_SAVE:
- sprite = sprites[SL_SAVE_BTN_GREYED + _objectState];
- break;
-
- case OBJTYPE_SL_LOAD:
- sprite = sprites[SL_LOAD_BTN_GREYED + _objectState];
- break;
-
- case OBJTYPE_SL_CANCEL:
- sprite = (_objectState == OS_GREYED) ? sprites[SL_CANCEL_BTN_NORMAL] :
- sprites[SL_CANCEL_BTN_NORMAL + _objectState - 1];
- break;
-
- case OBJTYPE_SL_TEXT:
- switch (_objectState) {
- case OS_MOUSEOVER:
- _vm->_font->current()->setColors(TEXT_COLOR_MOUSEOVER_SHADOW, TEXT_COLOR_MOUSEOVER_FOREGROUND,
- TEXT_COLOR_MOUSEOVER_HILIGHT);
- sprite = sprites[SL_LINE_MOUSEOVER];
- break;
-
- case OS_PRESSED:
- _vm->_font->current()->setColors(TEXT_COLOR_PRESSED_SHADOW, TEXT_COLOR_PRESSED_FOREGROUND,
- TEXT_COLOR_PRESSED_HILIGHT);
- sprite = sprites[SL_LINE_PRESSED];
- break;
-
- case OS_GREYED:
- _vm->_font->current()->setColors(TEXT_COLOR_GREYED_SHADOW, TEXT_COLOR_GREYED_FOREGROUND,
- TEXT_COLOR_GREYED_HILIGHT);
- sprite = sprites[SL_LINE_NORMAL];
- break;
-
- default:
- case OS_NORMAL:
- _vm->_font->current()->setColors(TEXT_COLOR_NORMAL_SHADOW, TEXT_COLOR_NORMAL_FOREGROUND,
- TEXT_COLOR_NORMAL_HILIGHT);
- sprite = sprites[SL_LINE_NORMAL];
- break;
- }
- break;
-
- default:
- error("Unknown object type");
- break;
- }
-
- // If no sprite object was set, then exit without doing anything
- if (!sprite)
- return;
-
- // Draw the button
- if (_transparent) {
- // Transparent button, so restore original background
- if (!_background)
- return;
- else
- _background->copyTo(parent(), _bounds.left, _bounds.top);
- }
-
- sprite->copyTo(parent(), _bounds.left, _bounds.top, 0);
-}
-
-//--------------------------------------------------------------------------
-// MenuHorizSlider class
-//
-// Defines a horizontal slider that allows selection of a percentage
-//--------------------------------------------------------------------------
-
-MenuHorizSlider::MenuHorizSlider(DialogView *owner, int objectId, int xs, int ys,
- int width, int height, int initialPercentage, Callback callbackFn, bool transparent):
- MenuObject(owner, objectId, xs, ys, width, height, false, transparent) {
-
- _objectType = OBJTYPE_SLIDER;
- _callback = callbackFn;
-
- SpriteAsset &sprites = *owner->sprites();
- _sliderState = HSLIDER_THUMB_NORMAL;
- _thumbSize.x = sprites[OM_SLIDER_BTN_NORMAL]->width();
- _thumbSize.y = sprites[OM_SLIDER_BTN_NORMAL]->height();
- _maxThumbX = width - _thumbSize.x;
- _percent = MAX(MIN(initialPercentage, 100), 0);
- _thumbX = initialPercentage * _maxThumbX / 100;
-}
-
-void MenuHorizSlider::onRefresh() {
- // If the slider is transparent, first copy in the background
- if (_transparent) {
- // Transparent button
- if (!_background)
- return;
-
- _background->copyTo(parent(), _bounds.left, _bounds.top, 0);
- }
-
- // Get the thumb sprite for the slider
- SpriteAsset &sprites = *parent()->sprites();
- M4Sprite *sprite = sprites[OM_SLIDER_BTN_NORMAL + _sliderState];
- assert(sprite);
-
- // Fill in the area to the left of the thumbnail
- if (_thumbX > 2) {
- Common::Rect leftBounds(_bounds.left + 3, _bounds.top + 9, _bounds.left + _thumbX,
- _bounds.top + _thumbSize.y - 9);
- parent()->fillRect(leftBounds, SLIDER_BAR_COLOR);
- }
-
- // Draw the thumbnail
- sprite->copyTo(parent(), _bounds.left + _thumbX, _bounds.top, 0);
-}
-
-bool MenuHorizSlider::onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem) {
- static bool movingFlag = false;
- static int movingX = 0;
- bool redrawFlag = false, handledFlag = false, callbackFlag = false;
-
- if (event == KEVENT_KEY)
- return false;
-
- switch (event) {
- case MEVENT_LEFT_CLICK:
- case MEVENT_DOUBLECLICK:
- if (isInside(x, y) && (x - _bounds.left >= _thumbX) &&
- (x - _bounds.left <= _thumbX + _thumbSize.x - 1)) {
- // The thumbnail has been clicked
- _sliderState = HSLIDER_THUMB_PRESSED;
- movingFlag = true;
- movingX = x;
- currentItem = this;
- redrawFlag = true;
- } else {
- currentItem = NULL;
- _sliderState = HSLIDER_THUMB_NORMAL;
- redrawFlag = true;
- }
- redrawFlag = true;
- break;
-
- case MEVENT_LEFT_DRAG:
- case MEVENT_DOUBLECLICK_DRAG:
- if (!currentItem)
- return true;
-
- if (movingFlag) {
- if (x != movingX) {
- if (x < movingX)
- _thumbX -= MIN(_thumbX, movingX - x);
- else
- _thumbX += MIN(_maxThumbX - _thumbX, x - movingX);
- _percent = _thumbX * 100 / _maxThumbX;
- redrawFlag = callbackFlag = true;
- }
- movingX = CLIP(x, _bounds.left + _thumbX,
- _bounds.left + _thumbX + _thumbSize.x - 1);
- } else {
- currentItem = NULL;
- }
- break;
-
- case MEVENT_LEFT_RELEASE:
- case MEVENT_DOUBLECLICK_RELEASE:
- if (!currentItem)
- return true;
-
- movingFlag = false;
- if (isInside(x, y) && (x - _bounds.left >= _thumbX) &&
- (x - _bounds.left <= _thumbX + _thumbSize.x - 1)) {
- _sliderState = HSLIDER_THUMB_MOUSEOVER;
- currentItem = this;
- } else {
- _sliderState = HSLIDER_THUMB_NORMAL;
- currentItem = NULL;
- }
-
- redrawFlag = true;
- callbackFlag = true;
- break;
-
- case MEVENT_MOVE:
- if (isInside(x, y) && (x - _bounds.left >= _thumbX) &&
- (x - _bounds.left <= _thumbX + _thumbSize.x - 1)) {
- if (_sliderState != HSLIDER_THUMB_MOUSEOVER) {
- _sliderState = HSLIDER_THUMB_MOUSEOVER;
- currentItem = this;
- }
- } else {
- if (_sliderState != HSLIDER_THUMB_NORMAL) {
- _sliderState = HSLIDER_THUMB_NORMAL;
- currentItem = NULL;
- handledFlag = false;
- }
- }
- redrawFlag = true;
- break;
-
- default:
- break;
- }
-
- if (redrawFlag)
- onRefresh();
-
- if (callbackFlag)
- onExecute();
-
- return handledFlag;
-}
-
-//--------------------------------------------------------------------------
-// MenuVertSlider class
-//
-// Defines a vertical slider that's used in the save/load dialog
-//--------------------------------------------------------------------------
-
-MenuVertSlider::MenuVertSlider(DialogView *owner, int objectId, int xs, int ys,
- int width, int height, int initialPercentage, Callback callbackFn, bool transparent):
- MenuObject(owner, objectId, xs, ys, width, height, false, transparent) {
-
- _objectType = OBJTYPE_SLIDER;
- _callback = callbackFn;
-
- SpriteAsset &sprites = *owner->sprites();
- _sliderState = VSLIDER_NONE;
- _thumbSize.x = sprites[SL_SLIDER_BTN_NORMAL]->width();
- _thumbSize.y = sprites[SL_SLIDER_BTN_NORMAL]->height();
- _minThumbY = sprites[SL_UP_BTN_NORMAL]->height() + 1;
- _maxThumbY = sprites[SL_UP_BTN_NORMAL]->height() + sprites[SL_SCROLLBAR]->height() -
- sprites[SL_SLIDER_BTN_NORMAL]->height() - 1;
-
- _percent = MAX(MIN(initialPercentage, 100), 0);
- _thumbY = _minThumbY + ((_percent * (_maxThumbY - _minThumbY)) / 100);
-}
-
-MenuVertSliderState MenuVertSlider::getSliderArea(int y) {
- if (y < _minThumbY)
- return VSLIDER_UP;
- else if (y < _thumbY)
- return VSLIDER_PAGE_UP;
- else if (y < _thumbY + _thumbSize.y)
- return VSLIDER_THUMBNAIL;
- else if (y < _maxThumbY + _thumbSize.y)
- return VSLIDER_PAGE_DOWN;
- else
- return VSLIDER_DOWN;
-}
-
-void MenuVertSlider::onRefresh() {
- // If the slider is transparent, first copy in the background
- if (_transparent) {
- // Transparent button
- if (!_background)
- return;
-
- _background->copyTo(parent(), _bounds.left, _bounds.top, 0);
- }
-
- // Get the various needed sprites
- SpriteAsset &sprites = *parent()->sprites();
- M4Sprite *barSprite = sprites[SL_SCROLLBAR];
- M4Sprite *thumbSprite = sprites[SL_SLIDER_BTN_NORMAL];
- M4Sprite *upSprite = sprites[SL_UP_BTN_NORMAL];
- M4Sprite *downSprite = sprites[SL_DOWN_BTN_NORMAL];
-
- if (_objectState == OS_GREYED) {
- upSprite = sprites[SL_UP_BTN_GREYED];
- downSprite = sprites[SL_DOWN_BTN_GREYED];
- thumbSprite = NULL;
-
- } else if (_objectState == OS_MOUSEOVER) {
- if (_sliderState == VSLIDER_UP)
- upSprite = sprites[SL_UP_BTN_MOUSEOVER];
- else if (_sliderState == VSLIDER_THUMBNAIL)
- thumbSprite = sprites[SL_SLIDER_BTN_MOUSEOVER];
- else if (_sliderState == VSLIDER_DOWN)
- downSprite = sprites[SL_DOWN_BTN_MOUSEOVER];
- }
- else if (_objectState == OS_PRESSED) {
- if (_sliderState == VSLIDER_UP)
- upSprite = sprites[SL_UP_BTN_PRESSED];
- else if (_sliderState == VSLIDER_THUMBNAIL)
- thumbSprite = sprites[SL_SLIDER_BTN_PRESSED];
- else if (_sliderState == VSLIDER_DOWN)
- downSprite = sprites[SL_DOWN_BTN_PRESSED];
- }
-
- // Draw the sprites
- upSprite->copyTo(parent(), _bounds.left, _bounds.top, 0);
- barSprite->copyTo(parent(), _bounds.left, _bounds.top + upSprite->height(), 0);
- downSprite->copyTo(parent(), _bounds.left, _bounds.top + upSprite->height() + barSprite->height(), 0);
- if (thumbSprite)
- thumbSprite->copyTo(parent(), _bounds.left, _bounds.top + _thumbY, 0);
-}
-
-bool MenuVertSlider::onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem) {
- static bool movingFlag = false;
- static int movingY = 0;
- static uint32 callbackTime;
- MenuVertSliderState tempState;
- int delta;
- uint32 currentTime = g_system->getMillis();
- bool redrawFlag = false;
- bool handledFlag = true;
- bool callbackFlag = false;
-
- if (event == KEVENT_KEY)
- return false;
-
- if (_objectState == OS_GREYED) {
- currentItem = NULL;
- return false;
- }
-
- switch (event) {
- case MEVENT_LEFT_CLICK:
- case MEVENT_DOUBLECLICK:
- if (isInside(x, y)) {
- currentItem = this;
- tempState = getSliderArea(y - _bounds.top);
- if (tempState == VSLIDER_THUMBNAIL) {
- movingFlag = true;
- movingY = y;
- }
- if ((tempState == VSLIDER_PAGE_UP) || (tempState == VSLIDER_PAGE_DOWN)) {
- _sliderState = tempState;
- setState(OS_NORMAL);
- } else {
- _sliderState = tempState;
- setState(OS_PRESSED);
- redrawFlag = true;
- }
- callbackFlag = true;
- } else {
- currentItem = NULL;
- setState(OS_NORMAL);
- redrawFlag = true;
- }
- break;
-
- case MEVENT_LEFT_DRAG:
- case MEVENT_DOUBLECLICK_DRAG:
- if (!currentItem)
- return true;
-
- if (movingFlag) {
- if (y < movingY) {
- delta = MIN(_thumbY - _minThumbY, movingY - y);
- if (delta > 0) {
- _thumbY -= delta;
- _percent = ((_thumbY - _minThumbY) * 100) / (_maxThumbY - _minThumbY);
- redrawFlag = true;
- callbackFlag = true;
- }
- }
- else if (y > movingY) {
- delta = MIN(_maxThumbY - _thumbY, y - movingY);
- if (delta > 0) {
- _thumbY += delta;
- _percent = ((_thumbY - _minThumbY) * 100) / (_maxThumbY - _minThumbY);
- redrawFlag = true;
- callbackFlag = true;
- }
- }
- movingY = y;
-
- if (movingY < (_thumbY + _bounds.top))
- movingY = _thumbY + _bounds.top;
- else if (movingY > (_bounds.top + _thumbY + _thumbSize.y - 1))
- movingY = _bounds.top + _thumbY + _thumbSize.y - 1;
-
- } else {
- if (isInside(x, y)) {
- tempState = getSliderArea(y - _bounds.top);
- if (_sliderState == tempState) {
- if ((tempState != VSLIDER_PAGE_UP) && (tempState != VSLIDER_PAGE_DOWN) &&
- (_objectState != OS_PRESSED)) {
- _sliderState = tempState;
- setState(OS_PRESSED);
- redrawFlag = true;
- }
- if (currentTime - callbackTime > 100)
- callbackFlag = true;
-
- } else {
- if (_objectState != OS_MOUSEOVER)
- setState(OS_MOUSEOVER);
- redrawFlag = true;
- }
- callbackFlag = true;
-
- } else {
- if (_objectState != OS_MOUSEOVER) {
- setState(OS_MOUSEOVER);
- redrawFlag = true;
- }
- }
- }
- break;
-
- case MEVENT_LEFT_RELEASE:
- case MEVENT_DOUBLECLICK_RELEASE:
- movingFlag = false;
- if (isInside(x, y)) {
- tempState = getSliderArea(y - _bounds.top);
- if ((tempState == VSLIDER_PAGE_UP) || (tempState == VSLIDER_PAGE_DOWN))
- setState(OS_NORMAL);
- else {
- setState(OS_MOUSEOVER);
- currentItem = this;
- }
- } else {
- setState(OS_NORMAL);
- currentItem = NULL;
- }
-
- redrawFlag = true;
- if (parent()->getMenuType() == LOAD_MENU)
- updateThumbnails();
- break;
-
- case MEVENT_MOVE:
- if (isInside(x, y)) {
- currentItem = this;
- tempState = getSliderArea(y - _bounds.top);
- if (_sliderState != tempState) {
- if ((tempState == VSLIDER_PAGE_UP) || (tempState == VSLIDER_PAGE_DOWN))
- _objectState = OS_NORMAL;
- else {
- _sliderState = tempState;
- _objectState = OS_MOUSEOVER;
- }
- redrawFlag = true;
- }
- } else {
- currentItem = NULL;
-
- if (_objectState != OS_NORMAL) {
- _objectState = OS_NORMAL;
- redrawFlag = true;
- handledFlag = false;
- }
- }
- break;
-
- case MEVENT_LEFT_HOLD:
- case MEVENT_DOUBLECLICK_HOLD:
- if (!currentItem)
- return true;
-
- if (isInside(x, y)) {
- tempState = getSliderArea(y - _bounds.top);
-
- if (_sliderState == tempState) {
- if (currentTime - callbackTime > 100)
- callbackFlag = true;
- }
- }
- break;
-
- default:
- break;
- }
-
- if (redrawFlag)
- onRefresh();
-
- if (callbackFlag) {
- callbackTime = currentTime;
- onExecute();
- }
-
- return handledFlag;
-}
-
-void MenuVertSlider::setPercentage(int value) {
- _percent = value;
- _thumbY = _minThumbY + ((_percent * (_maxThumbY - _minThumbY)) / 100);
- onRefresh();
-}
-
-//--------------------------------------------------------------------------
-// MenuMessage class
-//
-// Defines a message menu object
-//--------------------------------------------------------------------------
-
-MenuMessage::MenuMessage(DialogView *owner, int objectId, int xs, int ys, int width, int height,
- bool transparent):
- MenuObject(owner, objectId, xs, ys, width, height, false, transparent) {
-}
-
-void MenuMessage::onRefresh() {
- SpriteAsset &sprites = *parent()->sprites();
- M4Surface *sprite = NULL;
-
- // Get the correct sprite to use
- switch (_objectId) {
- case SLTAG_SAVELOAD_LABEL:
- sprite = (parent()->getMenuType() == SAVE_MENU) ? sprites[SL_SAVE_LABEL] :
- sprites[SL_LOAD_LABEL];
- break;
- }
- assert(sprite);
-
- // Draw the sprite
- if (_transparent) {
- // Transparent button
- if (!_background)
- return;
-
- // Restore original background and then do a transparent copy of the sprite
- _background->copyTo(parent(), _bounds.left, _bounds.top);
- }
-
- sprite->copyTo(parent(), _bounds.left, _bounds.top, 0);
-}
-
-//--------------------------------------------------------------------------
-// MenuImage class
-//
-// Defines a menu item that displays a given surface
-//--------------------------------------------------------------------------
-
-MenuImage::MenuImage(DialogView *owner, int objectId, int xs, int ys, int width, int height,
- M4Surface *image, bool transparent):
- MenuObject(owner, objectId, xs, ys, width, height, false, transparent) {
-
- _sprite = image;
-}
-
-void MenuImage::onRefresh() {
- if (!_sprite)
- return;
-
- // Draw the sprite
- if (_transparent) {
- // Transparent button
- if (!_background)
- return;
-
- // Restore original background and then do a transparent copy of the sprite
- _background->copyTo(parent(), _bounds.left, _bounds.top);
- }
-
- _sprite->copyTo(parent(), _bounds.left + (_bounds.width() - _sprite->width()) / 2,
- _bounds.top + (_bounds.height() - _sprite->height()) / 2, 0);
-}
-
-//--------------------------------------------------------------------------
-// MenuSaveLoadText class
-//
-// Defines a save/load dialog text entry
-//--------------------------------------------------------------------------
-
-MenuSaveLoadText::MenuSaveLoadText(DialogView *owner, int textId, int xs, int ys,
- int width, int height, Callback callbackFn, bool greyed, bool transparent,
- bool loadFlag, const char *displayText, int displayValue):
- MenuButton(owner, textId, xs, ys, width, height, callbackFn, greyed, transparent, OBJTYPE_SL_TEXT) {
-
- _loadFlag = loadFlag;
- _displayText = displayText;
- _displayValue = displayValue;
- _index = textId - SLTAG_SLOTS_START;
- _visible = true;
-}
-
-void MenuSaveLoadText::onRefresh() {
- if (!_visible) return;
- _vm->_font->setFont(FONT_MENU);
- MenuButton::onRefresh();
-
- if ((_objectType == OBJTYPE_SL_TEXT) && (_displayText != NULL)) {
- int xp = _bounds.left + 4;
- if (_displayValue != 0) {
- char tempBuffer[5];
- sprintf(tempBuffer, "%02d", _displayValue);
- _vm->_font->current()->writeString(_parent, tempBuffer, xp, _bounds.top + 1, 0, -1);
- xp = _bounds.left + 26;
- }
-
- _vm->_font->current()->writeString(_parent, _displayText, xp, _bounds.top + 1, 0, -1);
- }
-}
-
-bool MenuSaveLoadText::onEvent(M4::M4EventType event, int32 param, int x, int y, M4::MenuObject *&currentItem) {
- if (!_visible) return false;
- bool handledFlag = MenuButton::onEvent(event, param, x, y, currentItem);
-
- // Further handling will only be done when in load mode and a slot hasn't been selected
- if (!_loadFlag || (parent()->_selectedSlot != -1))
- return handledFlag;
-
- // Only handling for certain event types
- if ((event != MEVENT_MOVE) && (event != MEVENT_LEFT_DRAG) &&
- (event != MEVENT_LEFT_RELEASE) && (event != MEVENT_DOUBLECLICK_DRAG) &&
- (event != MEVENT_DOUBLECLICK_RELEASE))
- return handledFlag;
-
- MenuImage *thumbnail = (MenuImage *) parent()->getItem(SLTAG_THUMBNAIL);
-
- // Check whether the cursor is over the button
- if ((_objectState == OS_MOUSEOVER) || (_objectState == OS_PRESSED)) {
- if (_index != parent()->_highlightedSlot) {
- // Selected slot has changed
- if (parent()->_savegameThumbnail != NULL)
- delete parent()->_savegameThumbnail;
-
- parent()->_highlightedSlot = _index;
- parent()->_savegameThumbnail = _vm->_saveLoad->getThumbnail(_index + 1);
- thumbnail->setSprite(parent()->_savegameThumbnail);
- }
-
- } else {
- // If the mouse has moved outside the area of all the save slots, then the
- // thumbnail needs to be removed
-
- Common::Rect slotArea(50, 256, 288, 377);
- if (isInside(x, y) || !slotArea.contains(x, y)) {
- if (parent()->_savegameThumbnail) {
- delete parent()->_savegameThumbnail;
- parent()->_savegameThumbnail = NULL;
- }
-
- thumbnail->setSprite(parent()->sprites()->getFrame(SL_EMPTY_THUMBNAIL));
- parent()->_highlightedSlot = -1;
- }
- }
-
- return handledFlag;
-}
-
-void MenuSaveLoadText::setVisible(bool value) {
- _visible = value;
- parent()->refresh(_bounds);
-}
-
-//--------------------------------------------------------------------------
-// MenuTextField class
-//
-// Defines a text entry field
-//--------------------------------------------------------------------------
-
-MenuTextField::MenuTextField(DialogView *owner, int fieldId, int xs, int ys, int width,
- int height, bool greyed, Callback callbackFn,
- const char *displayText, int displayValue, bool transparent):
- MenuObject(owner, fieldId, xs, ys, width, height, greyed, transparent) {
-
- _displayValue = displayValue;
- _callback = callbackFn;
- _pixelWidth = width - 27;
- if (displayText) {
- strcpy(_displayText, displayText);
- _promptEnd = &_displayText[strlen(_displayText)];
- } else {
- _displayText[0] = '\0';
- _promptEnd = &_displayText[0];
- }
- _cursor = _promptEnd;
-}
-
-void MenuTextField::onRefresh() {
- bool focused = _objectState != OS_GREYED;
-
- // Get the thumb sprite for the slider
- SpriteAsset &sprites = *parent()->sprites();
- M4Sprite *sprite = sprites[SL_LINE_NORMAL + OS_MOUSEOVER - 1];
-
- // If the slider is transparent, first copy in the background
- if (_transparent) {
- // Transparent button
- if (!_background)
- return;
-
- _background->copyTo(parent(), _bounds.left, _bounds.top, 0);
- }
-
- // Draw the sprite
- sprite->copyTo(parent(), _bounds.left, _bounds.top, 0);
-
- // Draw the text
-
- _vm->_font->setFont(FONT_MENU);
- _vm->_font->current()->setColors(TEXT_COLOR_NORMAL_SHADOW, TEXT_COLOR_NORMAL_FOREGROUND,
- TEXT_COLOR_NORMAL_HILIGHT);
- int xp = _bounds.left + 4;
-
- if (_displayValue != 0) {
- char tempBuffer[5];
- sprintf(tempBuffer, "%02d", _displayValue);
- _vm->_font->current()->writeString(_parent, tempBuffer, xp, _bounds.top + 1, 0, -1);
- xp = _bounds.left + 26;
- }
-
- _vm->_font->current()->writeString(_parent, _displayText, xp, _bounds.top + 1, 0, -1);
-
- if (focused) {
- // Draw in the cursor
-
- if (_cursor) {
- // Get the width of the string up to the cursor position
- char tempCh = *_cursor;
- *_cursor = '\0';
- int stringWidth = _vm->_font->current()->getWidth(_displayText);
- *_cursor = tempCh;
-
- parent()->setColor(TEXT_COLOR_MOUSEOVER_FOREGROUND);
- parent()->vLine(xp + stringWidth + 1, _bounds.top + 1, _bounds.top + 12);
- }
- }
-}
-
-bool MenuTextField::onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem) {
- char tempStr[MAX_SAVEGAME_NAME];
- int tempLen;
- char *tempP;
- bool handledFlag = false, redrawFlag = false, callbackFlag = false;
-
- if (_objectState == OS_GREYED)
- return false;
-
- switch (event) {
- case MEVENT_LEFT_CLICK:
- case MEVENT_DOUBLECLICK:
- parent()->_deleteSaveDesc = false;
- if (isInside(x, y))
- currentItem = this;
- break;
-
- case MEVENT_LEFT_RELEASE:
- case MEVENT_DOUBLECLICK_RELEASE:
- if (!currentItem)
- return true;
- currentItem = NULL;
-
- if (isInside(x, y)) {
- if (_objectState == OS_MOUSEOVER) {
- tempLen = strlen(_displayText);
- if (tempLen > 0) {
- strcpy(tempStr, _displayText);
- tempP = &tempStr[tempLen];
- _vm->_font->setFont(FONT_MENU);
-
- tempLen = _vm->_font->current()->getWidth(tempStr);
- while ((tempP != &tempStr[0]) && (tempLen > x - _bounds.left - 26)) {
- *--tempP = '\0';
- tempLen = _vm->_font->current()->getWidth(tempStr);
- }
-
- _cursor = &_displayText[tempP - &tempStr[0]];
- redrawFlag = true;
- }
- } else if (event == MEVENT_DOUBLECLICK_RELEASE) {
- callbackFlag = true;
- }
- }
- break;
-
- case KEVENT_KEY:
- switch (param) {
- case Common::KEYCODE_RETURN:
- case Common::KEYCODE_KP_ENTER:
- parent()->_deleteSaveDesc = false;
- callbackFlag = true;
- break;
- break;
-
- case Common::KEYCODE_HOME:
- parent()->_deleteSaveDesc = false;
- _cursor = &_displayText[0];
- redrawFlag = true;
- break;
-
- case Common::KEYCODE_END:
- parent()->_deleteSaveDesc = false;
- _cursor = _promptEnd;
- redrawFlag = true;
- break;
-
- case Common::KEYCODE_LEFT:
- case Common::KEYCODE_KP4:
- parent()->_deleteSaveDesc = false;
- if (_cursor > &_displayText[0]) {
- --_cursor;
- redrawFlag = true;
- }
- break;
-
- case Common::KEYCODE_RIGHT:
- case Common::KEYCODE_KP6:
- parent()->_deleteSaveDesc = false;
- if (_cursor < _promptEnd) {
- ++_cursor;
- redrawFlag = true;
- }
- break;
-
- case Common::KEYCODE_DELETE:
- if (parent()->_deleteSaveDesc) {
- _displayText[0] = '\0';
- _promptEnd = &_displayText[0];
- _cursor = _promptEnd;
- redrawFlag = true;
- } else if (_cursor < _promptEnd) {
- strcpy(tempStr, _cursor + 1);
- strcpy(_cursor, tempStr);
- --_promptEnd;
- redrawFlag = true;
- }
- break;
-
- case Common::KEYCODE_BACKSPACE:
- parent()->_deleteSaveDesc = false;
- if (_cursor > &_displayText[0]) {
- strcpy(tempStr, _cursor);
- --_promptEnd;
- --_cursor;
- strcpy(_cursor, tempStr);
- redrawFlag = true;
- }
- break;
-
- default:
- parent()->_deleteSaveDesc = false;
- _vm->_font->setFont(FONT_MENU);
-
- tempLen = _vm->_font->current()->getWidth(_displayText);
- if ((strlen(_displayText) < MAX_SAVEGAME_NAME - 1) &&
- (tempLen < _pixelWidth - 12) && (param >= 32) && (param <= 127)) {
-
- // Valid displayable character
- if (_cursor < _promptEnd) {
- strcpy(tempStr, _cursor);
- sprintf(_cursor, "%c%s", (char)param, tempStr);
- } else {
- *_cursor = (char)param;
- *(_cursor + 1) = '\0';
- }
- ++_cursor;
- ++_promptEnd;
-
- redrawFlag = true;
- }
- break;
- }
- break;
-
- default:
- break;
- }
-
- if (redrawFlag)
- onRefresh();
-
- if (callbackFlag)
- onExecute();
-
- return handledFlag;
-}
-
-//--------------------------------------------------------------------------
-
-
-GUITextField::GUITextField(View *owner, const Common::Rect &bounds): GUIRect(owner, bounds, 0) {
-}
-
-void GUITextField::onRefresh() {
- _parent->fillRect(_bounds, _vm->_palette->BLACK);
- _vm->_font->current()->setColors(3, 3, 3);
- _vm->_font->setFont(FONT_INTERFACE);
- _vm->_font->current()->writeString(_parent, _text.c_str(), _bounds.left, _bounds.top, 0, 1);
-}
-
-//--------------------------------------------------------------------------
-
-GUIButton::GUIButton(View *owner, const Common::Rect &bounds, int tag,
- M4Surface *normalSprite, M4Surface *mouseOverSprite, M4Surface *pressedSprite):
- GUIRect(owner, bounds, tag) {
-
- _normalSprite = normalSprite;
- _mouseOverSprite = mouseOverSprite;
- _pressedSprite = pressedSprite;
- _visible = true;
- _tracking = false;
-}
-
-void GUIButton::onRefresh() {
- _parent->fillRect(_bounds, _vm->_palette->BLACK);
-
- if (_visible) {
- switch (_buttonState) {
- case BUTTON_MOUSEOVER:
- _mouseOverSprite->copyTo(_parent, _bounds.left, _bounds.top, 0);
- break;
- case BUTTON_PRESSED:
- _pressedSprite->copyTo(_parent, _bounds.left, _bounds.top, 0);
- break;
- default:
- _normalSprite->copyTo(_parent, _bounds.left, _bounds.top, 0);
- break;
- }
- }
-}
-
-bool GUIButton::onEvent(M4EventType eventType, int32 param, int x, int y, GUIObject *&currentItem) {
- bool result = false;
- bool isPressed = (eventType == MEVENT_LEFT_CLICK) || (eventType == MEVENT_LEFT_HOLD) ||
- (eventType == MEVENT_LEFT_DRAG);
- bool isOver = isInside(x, y);
- GUIButtonState oldState = _buttonState;
-
- if (isOver) {
- if (isPressed) {
- // Button is pressed
- if (!_tracking) {
- _tracking = true;
- _buttonState = BUTTON_PRESSED;
- }
-
- if (_vm->isM4())
- _m4Vm->globals()->invSuppressClickSound = false;
- } else {
- // Button isn't pressed
- if (_tracking)
- result = true;
- else {
- result = false;
- _buttonState = BUTTON_MOUSEOVER;
- _tracking = false;
- }
- }
- } else {
- _tracking = false;
- _buttonState = BUTTON_NORMAL;
- }
-
- if (oldState != _buttonState)
- onRefresh();
-
- return result;
-}
-
-} // End of namespace M4