/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "mm/mm1/views_enh/interactions/interaction.h" #include "mm/mm1/globals.h" #include "mm/mm1/mm1.h" #include "mm/mm1/sound.h" #include "mm/shared/utils/strings.h" namespace MM { namespace MM1 { namespace ViewsEnh { namespace Interactions { #define BTN_SIZE 10 Interaction::Interaction(const Common::String &name, int portrait) : PartyView(name) { _bounds = Common::Rect(8, 8, 224, 140); if (portrait != -1) { _frame.load("frame.fac"); _portrait.load(Common::Path(Common::String::format("face%02d.fac", portrait))); } } void Interaction::addText(const Common::String &str) { setReduced(false); _lines = splitLines(searchAndReplace(str, "\n", " ")); } bool Interaction::msgGame(const GameMessage &msg) { if (msg._name == "DISPLAY") { addView(this); return true; } return PartyView::msgGame(msg); } bool Interaction::msgUnfocus(const UnfocusMessage &msg) { PartyView::msgUnfocus(msg); return true; } void Interaction::draw() { PartyView::draw(); Graphics::ManagedSurface s = getSurface(); if (!_frame.empty()) { _frame.draw(&s, 0, Common::Point(8, 8)); _portrait.draw(&s, _portraitFrameNum, Common::Point(15, 14)); } setReduced(false); if (!_title.empty()) { size_t strWidth = getStringWidth(_title); writeString(125 - strWidth / 2, 20, _title); } // Write any text lines for (uint i = 0; i < _lines.size(); ++i) { writeString(0, (6 + i) * 9 - 5, _lines[i], ALIGN_MIDDLE); } // Write out any buttons if (!_buttons.empty()) { _textPos = Common::Point(0, (6 + _lines.size()) * 9); setReduced(true); // Create a blank button Graphics::ManagedSurface btnSmall(BTN_SIZE, BTN_SIZE); btnSmall.blitFrom(g_globals->_blankButton, Common::Rect(0, 0, 20, 20), Common::Rect(0, 0, BTN_SIZE, BTN_SIZE)); for (uint i = 0; i < _buttons.size(); ++i, _textPos.x += 10) { InteractionButton &btn = _buttons[i]; int itemWidth = BTN_SIZE + 5 + getStringWidth(_buttons[i]._text); if ((_textPos.x + itemWidth) > _innerBounds.width()) { _textPos.x = 0; _textPos.y += BTN_SIZE + 2; } Common::Point pt = _textPos; // Display button and write character in the middle s.blitFrom(btnSmall, Common::Point(pt.x + _bounds.borderSize(), pt.y + _bounds.borderSize())); writeString(pt.x + (BTN_SIZE / 2) + 1, pt.y, Common::String::format("%c", _buttons[i]._c), ALIGN_MIDDLE); // Write text to the right of the button writeString(pt.x + BTN_SIZE + 5, pt.y, _buttons[i]._text); // Set up bounds for the area covered by the button & text btn._bounds = Common::Rect(pt.x, pt.y, pt.x + BTN_SIZE + 5 + itemWidth, pt.y + BTN_SIZE); btn._bounds.translate(_innerBounds.left, _innerBounds.top); } } } bool Interaction::tick() { if (_animated && ++_tickCtr >= 10) { _tickCtr = 0; _portraitFrameNum = g_engine->getRandomNumber(0, 2); redraw(); } return PartyView::tick(); } void Interaction::leave() { if (g_events->focusedView() == this) close(); g_maps->turnAround(); g_events->redraw(); } bool Interaction::msgKeypress(const KeypressMessage &msg) { viewAction(); return true; } bool Interaction::msgAction(const ActionMessage &msg) { if (msg._action == KEYBIND_ESCAPE) { leave(); } else if (!PartyView::msgAction(msg)) { viewAction(); } return true; } bool Interaction::msgMouseDown(const MouseDownMessage &msg) { if (!PartyView::msgMouseDown(msg)) { // Check if a button was pressed for (uint i = 0; i < _buttons.size(); ++i) { const auto &btn = _buttons[i]; if (_buttons[i]._bounds.contains(msg._pos)) { msgKeypress(KeypressMessage(Common::KeyState( (Common::KeyCode)(Common::KEYCODE_a + btn._c - 'A'), btn._c ))); return true; } } // Fall back on treating click as a standard acknowledgement viewAction(); } return true; } } // namespace Interactions } // namespace ViewsEnh } // namespace MM1 } // namespace MM