diff options
Diffstat (limited to 'engines/m4/gui.cpp')
-rw-r--r-- | engines/m4/gui.cpp | 1215 |
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 *¤tItem) { - 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 *¤tItem) { - 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 *¤tItem) { - 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 *¤tItem) { - 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 *¤tItem) { - 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 *¤tItem) { - 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 |