scummvm/engines/sci/graphics/controls.cpp
Filippos Karapetis d99aa0f126 More renaming
svn-id: r47009
2010-01-05 01:37:57 +00:00

232 lines
7.0 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.
*
* $URL$
* $Id$
*
*/
#include "common/util.h"
#include "common/stack.h"
#include "graphics/primitives.h"
#include "sci/sci.h"
#include "sci/event.h"
#include "sci/engine/state.h"
#include "sci/graphics/gfx.h"
#include "sci/graphics/font.h"
#include "sci/graphics/text.h"
#include "sci/graphics/controls.h"
namespace Sci {
SciGuiControls::SciGuiControls(SegManager *segMan, Gfx *gfx, Text *text)
: _segMan(segMan), _gfx(gfx), _text(text) {
init();
}
SciGuiControls::~SciGuiControls() {
}
void SciGuiControls::init() {
_texteditCursorVisible = false;
}
const char controlListUpArrow[2] = { 0x18, 0 };
const char controlListDownArrow[2] = { 0x19, 0 };
void SciGuiControls::drawListControl(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 upperPos, int16 cursorPos, bool isAlias) {
Common::Rect workerRect = rect;
GuiResourceId oldFontId = _text->GetFontId();
int16 oldPenColor = _gfx->_curPort->penClr;
uint16 fontSize = 0;
int16 i;
const char *listEntry;
int16 listEntryLen;
int16 lastYpos;
// draw basic window
_gfx->EraseRect(workerRect);
workerRect.grow(1);
_gfx->FrameRect(workerRect);
// draw UP/DOWN arrows
// we draw UP arrow one pixel lower than sierra did, because it looks nicer. Also the DOWN arrow has one pixel
// line inbetween as well
workerRect.top++;
_text->Box(controlListUpArrow, 0, workerRect, SCI_TEXT_ALIGNMENT_CENTER, 0);
workerRect.top = workerRect.bottom - 10;
_text->Box(controlListDownArrow, 0, workerRect, SCI_TEXT_ALIGNMENT_CENTER, 0);
// Draw inner lines
workerRect.top = rect.top + 9;
workerRect.bottom -= 10;
_gfx->FrameRect(workerRect);
workerRect.grow(-1);
_text->SetFont(fontId);
fontSize = _gfx->_curPort->fontHeight;
_gfx->PenColor(_gfx->_curPort->penClr); _gfx->BackColor(_gfx->_curPort->backClr);
workerRect.bottom = workerRect.top + 9;
lastYpos = rect.bottom - fontSize;
// Write actual text
for (i = upperPos; i < count; i++) {
_gfx->EraseRect(workerRect);
listEntry = entries[i];
if (listEntry[0]) {
_gfx->MoveTo(workerRect.left, workerRect.top);
listEntryLen = strlen(listEntry);
_text->Draw(listEntry, 0, MIN(maxChars, listEntryLen), oldFontId, oldPenColor);
if ((!isAlias) && (i == cursorPos)) {
_gfx->InvertRect(workerRect);
}
}
workerRect.translate(0, fontSize);
if (workerRect.bottom > lastYpos)
break;
}
_text->SetFont(oldFontId);
}
void SciGuiControls::TexteditCursorDraw(Common::Rect rect, const char *text, uint16 curPos) {
int16 textWidth, i;
if (!_texteditCursorVisible) {
textWidth = 0;
for (i = 0; i < curPos; i++) {
textWidth += _text->_font->getCharWidth(text[i]);
}
_texteditCursorRect.left = rect.left + textWidth;
_texteditCursorRect.top = rect.top;
_texteditCursorRect.bottom = _texteditCursorRect.top + _text->_font->getHeight();
_texteditCursorRect.right = _texteditCursorRect.left + (text[curPos] == 0 ? 1 : _text->_font->getCharWidth(text[curPos]));
_gfx->InvertRect(_texteditCursorRect);
_gfx->BitsShow(_texteditCursorRect);
_texteditCursorVisible = true;
TexteditSetBlinkTime();
}
}
void SciGuiControls::TexteditCursorErase() {
if (_texteditCursorVisible) {
_gfx->InvertRect(_texteditCursorRect);
_gfx->BitsShow(_texteditCursorRect);
_texteditCursorVisible = false;
}
TexteditSetBlinkTime();
}
void SciGuiControls::TexteditSetBlinkTime() {
_texteditBlinkTime = g_system->getMillis() + (30 * 1000 / 60);
}
void SciGuiControls::TexteditChange(reg_t controlObject, reg_t eventObject) {
uint16 cursorPos = GET_SEL32V(_segMan, controlObject, cursor);
uint16 maxChars = GET_SEL32V(_segMan, controlObject, max);
reg_t textReference = GET_SEL32(_segMan, controlObject, text);
Common::String text;
uint16 textSize, eventType, eventKey;
bool textChanged = false;
Common::Rect rect;
if (textReference.isNull())
error("kEditControl called on object that doesnt have a text reference");
text = _segMan->getString(textReference);
if (!eventObject.isNull()) {
textSize = text.size();
eventType = GET_SEL32V(_segMan, eventObject, type);
switch (eventType) {
case SCI_EVENT_MOUSE_PRESS:
// TODO: Implement mouse support for cursor change
break;
case SCI_EVENT_KEYBOARD:
eventKey = GET_SEL32V(_segMan, eventObject, message);
switch (eventKey) {
case SCI_KEY_BACKSPACE:
if (cursorPos > 0) {
cursorPos--; text.deleteChar(cursorPos);
textChanged = true;
}
break;
case SCI_KEY_DELETE:
text.deleteChar(cursorPos);
textChanged = true;
break;
case SCI_KEY_HOME: // HOME
cursorPos = 0; textChanged = true;
break;
case SCI_KEY_END: // END
cursorPos = textSize; textChanged = true;
break;
case SCI_KEY_LEFT: // LEFT
if (cursorPos > 0) {
cursorPos--; textChanged = true;
}
break;
case SCI_KEY_RIGHT: // RIGHT
if (cursorPos + 1 <= textSize) {
cursorPos++; textChanged = true;
}
break;
default:
if (eventKey > 31 && eventKey < 256 && textSize < maxChars) {
// insert pressed character
// we check, if there is space left for this character
text.insertChar(eventKey, cursorPos++);
textChanged = true;
}
break;
}
break;
}
}
if (textChanged) {
GuiResourceId oldFontId = _text->GetFontId();
GuiResourceId fontId = GET_SEL32V(_segMan, controlObject, font);
rect = Common::Rect(GET_SEL32V(_segMan, controlObject, nsLeft), GET_SEL32V(_segMan, controlObject, nsTop),
GET_SEL32V(_segMan, controlObject, nsRight), GET_SEL32V(_segMan, controlObject, nsBottom));
TexteditCursorErase();
_gfx->EraseRect(rect);
_text->Box(text.c_str(), 0, rect, SCI_TEXT_ALIGNMENT_LEFT, fontId);
_gfx->BitsShow(rect);
_text->SetFont(fontId);
TexteditCursorDraw(rect, text.c_str(), cursorPos);
_text->SetFont(oldFontId);
// Write back string
_segMan->strcpy(textReference, text.c_str());
} else {
if (g_system->getMillis() >= _texteditBlinkTime) {
_gfx->InvertRect(_texteditCursorRect);
_gfx->BitsShow(_texteditCursorRect);
_texteditCursorVisible = !_texteditCursorVisible;
TexteditSetBlinkTime();
}
}
PUT_SEL32V(_segMan, controlObject, cursor, cursorPos);
}
} // End of namespace Sci