scummvm/engines/ultima/shared/gfx/info.cpp

158 lines
4.3 KiB
C++

/* 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 "ultima/shared/gfx/info.h"
#include "ultima/shared/early/game.h"
#include "ultima/shared/gfx/text_cursor.h"
#include "ultima/shared/core/str.h"
namespace Ultima {
namespace Shared {
#define PROMPT_CHAR '\x1'
#define SUGGESTED_CR '\r'
BEGIN_MESSAGE_MAP(Info, Shared::Gfx::VisualItem)
ON_MESSAGE(InfoMsg)
ON_MESSAGE(InfoGetCommandKeypress)
ON_MESSAGE(InfoGetKeypress)
ON_MESSAGE(InfoGetInput)
ON_MESSAGE(KeypressMsg)
END_MESSAGE_MAP()
Info::Info(TreeItem *parent, const Rect &bounds) : Gfx::VisualItem("Info", bounds, parent),
_commandRespondTo(nullptr) {
_characterInput = new Gfx::CharacterInput(getGame());
_textInput = new Gfx::TextInput(getGame());
}
Info::~Info() {
delete _characterInput;
delete _textInput;
}
bool Info::InfoMsg(CInfoMsg &msg) {
// Iterate through text, dealing with lines one at a time
StringArray lines = String(msg._text).split("\r\n");
if (!_lines.empty() && msg._replaceLine)
_lines.back() = _lines.back().firstChar();
for (uint idx = 0; idx < lines.size(); ++idx) {
if (_lines.empty() || idx > 0)
_lines.push_back(" ");
_lines.back() += lines[idx];
}
// Add newline if necessary
if (msg._newLine)
_lines.push_back(" ");
setDirty();
// Adding any text hides any visible cursor
_commandRespondTo = nullptr;
Gfx::TextCursor *textCursor = getGame()->_textCursor;
textCursor->setVisible(false);
return true;
}
bool Info::InfoGetCommandKeypress(CInfoGetCommandKeypress &msg) {
if (_lines.empty() || _lines.back() != " ")
_lines.push_back("");
_lines.back() = PROMPT_CHAR;
Gfx::TextCursor *textCursor = getGame()->_textCursor;
textCursor->setVisible(true);
textCursor->setPosition(Point(8, _bounds.bottom - 8));
_commandRespondTo = msg._responder;
return true;
}
bool Info::InfoGetKeypress(CInfoGetKeypress &msg) {
Game *game = getGame();
Point pt(_bounds.left + _lines.back().size() * 8, _bounds.bottom - 8);
_characterInput->show(pt, game->_textColor, msg._responder);
return true;
}
bool Info::InfoGetInput(CInfoGetInput &msg) {
Game *game = getGame();
Point pt(_bounds.left + _lines.back().size() * 8, _bounds.bottom - 8);
_textInput->show(pt, msg._isNumeric, msg._maxCharacters, game->_textColor, msg._responder);
return true;
}
bool Info::KeypressMsg(CKeypressMsg &msg) {
// If waiting for a command, dispatch the key to the respond, and hide the cursor
if (_commandRespondTo) {
TreeItem *target = _commandRespondTo;
_commandRespondTo = nullptr;
getGame()->_textCursor->setVisible(false);
CCharacterInputMsg cMsg(msg._keyState);
cMsg.execute(target);
return true;
}
return true;
}
void Info::draw() {
// Clear the background
Gfx::VisualSurface s = getSurface();
s.clear();
// Get the number og lines to display
uint lineHeight = s.fontHeight();
uint numLines = (s.h + lineHeight - 1) / lineHeight;
// Discard any stored lines beyond the top of the display
while (_lines.size() > numLines)
_lines.remove_at(0);
// Display the lines
int x = 0, y = s.h - _lines.size() * lineHeight;
for (uint idx = 0; idx < _lines.size(); ++idx, x = 0, y += lineHeight) {
// Handle drawing the prompt character at the start of lines if necessary
Common::String line = _lines[idx];
if (!line.empty() && line[0] == PROMPT_CHAR) {
drawPrompt(s, Point(0, y));
x = 8;
line.deleteChar(0);
}
// Write the remainder of the line
s.writeString(line, Point(x, y));
}
_isDirty = false;
}
} // End of namespace Shared
} // End of namespace Ultima