ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

actionmenu.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the AUTHORS
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "engines/stark/ui/world/actionmenu.h"
00024 
00025 #include "engines/stark/ui/cursor.h"
00026 #include "engines/stark/ui/world/gamewindow.h"
00027 #include "engines/stark/ui/world/inventorywindow.h"
00028 
00029 #include "engines/stark/gfx/driver.h"
00030 
00031 #include "engines/stark/resources/anim.h"
00032 #include "engines/stark/resources/item.h"
00033 #include "engines/stark/resources/knowledgeset.h"
00034 #include "engines/stark/resources/level.h"
00035 #include "engines/stark/resources/pattable.h"
00036 
00037 #include "engines/stark/services/services.h"
00038 #include "engines/stark/services/gameinterface.h"
00039 #include "engines/stark/services/staticprovider.h"
00040 #include "engines/stark/services/global.h"
00041 
00042 #include "engines/stark/scene.h"
00043 
00044 #include "engines/stark/visual/image.h"
00045 #include "engines/stark/visual/text.h"
00046 
00047 
00048 namespace Stark {
00049 
00050 static const int kAutoCloseSuspended = -1;
00051 static const int kAutoCloseDisabled  = -2;
00052 static const int kAutoCloseDelay     = 200;
00053 
00054 ActionMenu::ActionMenu(Gfx::Driver *gfx, Cursor *cursor) :
00055         Window(gfx, cursor),
00056         _inventory(nullptr),
00057         _item(nullptr),
00058         _itemDescription(nullptr),
00059         _fromInventory(false),
00060         _autoCloseTimeRemaining(kAutoCloseDisabled) {
00061 
00062     _background = StarkStaticProvider->getUIElement(StaticProvider::kActionMenuBg);
00063 
00064     _itemDescription = new VisualText(gfx);
00065     _itemDescription->setColor(Color(0xFF, 0xFF, 0xFF));
00066     _itemDescription->setBackgroundColor(Color(0x00, 0x00, 0x00, 0x80));
00067     _itemDescription->setFont(FontProvider::kSmallFont);
00068     _itemDescription->setTargetWidth(96);
00069 
00070     _buttons[kActionHand].action = Resources::PATTable::kActionUse;
00071     _buttons[kActionHand].rect = Common::Rect(90, 15, 126, 63);
00072     _buttons[kActionEye].action = Resources::PATTable::kActionLook;
00073     _buttons[kActionEye].rect = Common::Rect(5, 77, 51, 110);
00074     _buttons[kActionMouth].action = Resources::PATTable::kActionTalk;
00075     _buttons[kActionMouth].rect = Common::Rect(42, 35, 83, 74);
00076 
00077     clearActions();
00078 }
00079 
00080 ActionMenu::~ActionMenu() {
00081     delete _itemDescription;
00082 }
00083 
00084 void ActionMenu::open(Resources::ItemVisual *item, const Common::Point &itemRelativePos) {
00085     _visible = true;
00086 
00087     Common::Point mousePos = _cursor->getMousePosition();
00088 
00089     _position = computePosition(mousePos);
00090 
00091     _itemRelativePos = itemRelativePos;
00092     _item = item;
00093     _fromInventory = item->getSubType() == Resources::Item::kItemInventory;
00094     _itemDescription->setText(StarkGameInterface->getItemTitleAt(item, itemRelativePos));
00095 
00096     _cursor->setMouseHint("");
00097 
00098     clearActions();
00099 
00100     Resources::ActionArray possible;
00101     if (_fromInventory) {
00102         possible = StarkGameInterface->listActionsPossibleForObject(_item);
00103     } else {
00104         possible = StarkGameInterface->listActionsPossibleForObjectAt(_item, _itemRelativePos);
00105     }
00106 
00107     for (uint i = 0; i < possible.size(); i++) {
00108         enableAction(possible[i]);
00109     }
00110 
00111     if (_fromInventory) {
00112         // All inventory items can be picked up
00113         enableAction(Resources::PATTable::kActionUse);
00114     }
00115 }
00116 
00117 void ActionMenu::close() {
00118     _visible = false;
00119     _item = nullptr;
00120 }
00121 
00122 Common::Rect ActionMenu::computePosition(const Common::Point &mouse) const {
00123     Common::Rect position = Common::Rect::center(mouse.x, mouse.y, 160, 111);
00124 
00125     Common::Rect gameWindowRect(Gfx::Driver::kGameViewportWidth, Gfx::Driver::kGameViewportHeight);
00126     gameWindowRect.translate(0, Gfx::Driver::kTopBorderHeight);
00127 
00128     if (position.top < gameWindowRect.top)       position.translate(0, gameWindowRect.top - position.top);
00129     if (position.left < gameWindowRect.left)     position.translate(gameWindowRect.left - position.left, 0);
00130     if (position.bottom > gameWindowRect.bottom) position.translate(0, gameWindowRect.bottom - position.bottom);
00131     if (position.right > gameWindowRect.right)   position.translate(gameWindowRect.right - position.right, 0);
00132 
00133     return position;
00134 }
00135 
00136 void ActionMenu::onRender() {
00137     Common::Point mousePos = getRelativeMousePosition();
00138 
00139     _background->render(Common::Point(0, 0), false);
00140 
00141     for (uint i = 0; i < ARRAYSIZE(_buttons); i++) {
00142         if (_buttons[i].enabled) {
00143             bool active = _buttons[i].rect.contains(mousePos);
00144             VisualImageXMG *visual = StarkGameInterface->getActionImage(_buttons[i].action, active);
00145             visual->render(Common::Point(_buttons[i].rect.left, _buttons[i].rect.top), false);
00146         }
00147     }
00148 
00149     Common::Rect descriptionSize = _itemDescription->getRect();
00150     int descriptionX = 60 + (_itemDescription->getTargetWidth() - descriptionSize.width()) / 2;
00151     int descriptionY = _position.height() - descriptionSize.height();
00152 
00153     _itemDescription->render(Common::Point(descriptionX, descriptionY));
00154 }
00155 
00156 void ActionMenu::clearActions() {
00157     for (uint i = 0; i < ARRAYSIZE(_buttons); i++) {
00158         _buttons[i].enabled = false;
00159     }
00160 }
00161 
00162 void ActionMenu::enableAction(uint32 action) {
00163     for (uint j = 0; j < ARRAYSIZE(_buttons); j++) {
00164         if (_buttons[j].action == action) {
00165             _buttons[j].enabled = true;
00166             break;
00167         }
00168     }
00169 }
00170 
00171 void ActionMenu::onMouseMove(const Common::Point &pos) {
00172     bool hoveringAction = false;
00173     for (uint i = 0; i < ARRAYSIZE(_buttons); i++) {
00174         if (_buttons[i].enabled && _buttons[i].rect.contains(pos)) {
00175             hoveringAction = true;
00176         }
00177     }
00178 
00179     if (hoveringAction) {
00180         _cursor->setCursorType(Cursor::kActive);
00181     } else {
00182         _cursor->setCursorType(Cursor::kDefault);
00183     }
00184 
00185     _autoCloseTimeRemaining = kAutoCloseSuspended;
00186 }
00187 
00188 void ActionMenu::onClick(const Common::Point &pos) {
00189     assert(_item);
00190 
00191     for (uint i = 0; i < ARRAYSIZE(_buttons); i++) {
00192         if (_buttons[i].enabled && _buttons[i].rect.contains(pos)) {
00193 
00194             if (_fromInventory && i == kActionHand) {
00195                 _inventory->setSelectedInventoryItem(_item->getIndex());
00196             } else {
00197                 if (_fromInventory) {
00198                     StarkGameInterface->itemDoAction(_item, _buttons[i].action);
00199                 } else {
00200                     StarkGameInterface->itemDoActionAt(_item, _buttons[i].action, _itemRelativePos);
00201                 }
00202             }
00203 
00204             close();
00205             break;
00206         }
00207     }
00208 }
00209 
00210 void ActionMenu::setInventory(InventoryWindow *inventory) {
00211     _inventory = inventory;
00212 }
00213 
00214 void ActionMenu::onGameLoop() {
00215     if (!isMouseInside() && _autoCloseTimeRemaining == kAutoCloseSuspended) {
00216         _autoCloseTimeRemaining = kAutoCloseDelay;
00217     } else if (_autoCloseTimeRemaining >= 0) {
00218         _autoCloseTimeRemaining -= StarkGlobal->getMillisecondsPerGameloop();
00219 
00220         if (_autoCloseTimeRemaining <= 0) {
00221             _autoCloseTimeRemaining = kAutoCloseSuspended;
00222             close();
00223         }
00224     }
00225 }
00226 
00227 void ActionMenu::onScreenChanged() {
00228     _itemDescription->resetTexture();
00229 }
00230 
00231 } // End of namespace Stark


Generated on Sat May 18 2019 05:00:54 for ResidualVM by doxygen 1.7.1
curved edge   curved edge