SCI: More work on kEditText

This commit is contained in:
Filippos Karapetis 2011-10-30 12:12:40 +02:00
parent acebd6d0be
commit 9caacac724
5 changed files with 147 additions and 103 deletions

View file

@ -20,6 +20,8 @@
*
*/
#include "common/system.h"
#include "sci/sci.h"
#include "sci/event.h"
#include "sci/engine/kernel.h"
@ -33,8 +35,8 @@
namespace Sci {
GfxControls32::GfxControls32(SegManager *segMan, GfxCache *cache, GfxScreen *screen)
: _segMan(segMan), _cache(cache), _screen(screen) {
GfxControls32::GfxControls32(SegManager *segMan, GfxCache *cache, GfxScreen *screen, GfxText32 *text)
: _segMan(segMan), _cache(cache), _screen(screen), _text(text) {
}
GfxControls32::~GfxControls32() {
@ -42,7 +44,7 @@ GfxControls32::~GfxControls32() {
void GfxControls32::kernelTexteditChange(reg_t controlObject) {
SciEvent curEvent;
uint16 maxChars = readSelectorValue(_segMan, controlObject, SELECTOR(max));
uint16 maxChars = 40; //readSelectorValue(_segMan, controlObject, SELECTOR(max)); // TODO
reg_t textReference = readSelector(_segMan, controlObject, SELECTOR(text));
GfxFont *font = _cache->getFont(readSelectorValue(_segMan, controlObject, SELECTOR(font)));
Common::String text;
@ -55,118 +57,148 @@ void GfxControls32::kernelTexteditChange(reg_t controlObject) {
error("kEditControl called on object that doesnt have a text reference");
text = _segMan->getString(textReference);
// TODO: Finish this, add a loop etc
// TODO: Finish this
warning("kEditText ('%s')", text.c_str());
return;
uint16 cursorPos = 0;
//uint16 oldCursorPos = cursorPos;
bool captureEvents = true;
EventManager* eventMan = g_sci->getEventManager();
curEvent = g_sci->getEventManager()->getSciEvent(SCI_EVENT_KEYBOARD);
if (curEvent.type != SCI_EVENT_NONE) {
textSize = text.size();
while (captureEvents) {
curEvent = g_sci->getEventManager()->getSciEvent(SCI_EVENT_KEYBOARD | SCI_EVENT_PEEK);
if (curEvent.type == SCI_EVENT_NONE) {
eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
} else {
textSize = text.size();
switch (curEvent.type) {
case SCI_EVENT_MOUSE_PRESS:
// TODO: Implement mouse support for cursor change
break;
case SCI_EVENT_KEYBOARD:
switch (curEvent.data) {
case SCI_KEY_BACKSPACE:
if (cursorPos > 0) {
cursorPos--; text.deleteChar(cursorPos);
textChanged = true;
}
switch (curEvent.type) {
case SCI_EVENT_MOUSE_PRESS:
// TODO: Implement mouse support for cursor change
break;
case SCI_KEY_DELETE:
if (cursorPos < textSize) {
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;
case 3: // returned in SCI1 late and newer when Control - C is pressed
if (curEvent.modifiers & SCI_KEYMOD_CTRL) {
// Control-C erases the whole line
cursorPos = 0; text.clear();
textChanged = true;
}
break;
default:
if ((curEvent.modifiers & SCI_KEYMOD_CTRL) && curEvent.data == 99) {
// Control-C in earlier SCI games (SCI0 - SCI1 middle)
// Control-C erases the whole line
cursorPos = 0; text.clear();
textChanged = true;
} else if (curEvent.data > 31 && curEvent.data < 256 && textSize < maxChars) {
// insert pressed character
textAddChar = true;
textChanged = true;
case SCI_EVENT_KEYBOARD:
switch (curEvent.data) {
case SCI_KEY_BACKSPACE:
if (cursorPos > 0) {
cursorPos--; text.deleteChar(cursorPos);
textChanged = true;
}
eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
break;
case SCI_KEY_DELETE:
if (cursorPos < textSize) {
text.deleteChar(cursorPos);
textChanged = true;
}
eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
break;
case SCI_KEY_HOME: // HOME
cursorPos = 0; textChanged = true;
eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
break;
case SCI_KEY_END: // END
cursorPos = textSize; textChanged = true;
eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
break;
case SCI_KEY_LEFT: // LEFT
if (cursorPos > 0) {
cursorPos--; textChanged = true;
}
eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
break;
case SCI_KEY_RIGHT: // RIGHT
if (cursorPos + 1 <= textSize) {
cursorPos++; textChanged = true;
}
eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
break;
case 3: // returned in SCI1 late and newer when Control - C is pressed
if (curEvent.modifiers & SCI_KEYMOD_CTRL) {
// Control-C erases the whole line
cursorPos = 0; text.clear();
textChanged = true;
}
eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
break;
case SCI_KEY_UP:
case SCI_KEY_DOWN:
case SCI_KEY_ENTER:
case SCI_KEY_ESC:
case SCI_KEY_TAB:
case SCI_KEY_SHIFT_TAB:
captureEvents = false;
break;
default:
if ((curEvent.modifiers & SCI_KEYMOD_CTRL) && curEvent.data == 99) {
// Control-C in earlier SCI games (SCI0 - SCI1 middle)
// Control-C erases the whole line
cursorPos = 0; text.clear();
textChanged = true;
} else if (curEvent.data > 31 && curEvent.data < 256 && textSize < maxChars) {
// insert pressed character
textAddChar = true;
textChanged = true;
}
eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
break;
}
break;
}
break;
}
}
if (textChanged) {
rect = g_sci->_gfxCompare->getNSRect(controlObject);
if (textChanged) {
rect = g_sci->_gfxCompare->getNSRect(controlObject);
if (textAddChar) {
const char *textPtr = text.c_str();
if (textAddChar) {
const char *textPtr = text.c_str();
// We check if we are really able to add the new char
uint16 textWidth = 0;
while (*textPtr)
textWidth += font->getCharWidth((byte)*textPtr++);
textWidth += font->getCharWidth(curEvent.data);
// We check if we are really able to add the new char
uint16 textWidth = 0;
while (*textPtr)
textWidth += font->getCharWidth((byte)*textPtr++);
textWidth += font->getCharWidth(curEvent.data);
// Does it fit?
if (textWidth >= rect.width()) {
return;
// Does it fit?
if (textWidth >= rect.width()) {
return;
}
text.insertChar(curEvent.data, cursorPos++);
// Note: the following checkAltInput call might make the text
// too wide to fit, but SSCI fails to check that too.
}
reg_t hunkId = readSelector(_segMan, controlObject, SELECTOR(bitmap));
Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(controlObject);
//texteditCursorErase(); // TODO: Cursor
// Write back string
_segMan->strcpy(textReference, text.c_str());
// Modify the buffer and show it
_text->createTextBitmap(controlObject, 0, 0, hunkId);
text.insertChar(curEvent.data, cursorPos++);
_text->drawTextBitmap(0, 0, nsRect, controlObject);
//texteditCursorDraw(rect, text.c_str(), cursorPos); // TODO: Cursor
g_system->updateScreen();
} else {
// TODO: Cursor
/*
if (g_system->getMillis() >= _texteditBlinkTime) {
_paint16->invertRect(_texteditCursorRect);
_paint16->bitsShow(_texteditCursorRect);
_texteditCursorVisible = !_texteditCursorVisible;
texteditSetBlinkTime();
}
*/
}
// Note: the following checkAltInput call might make the text
// too wide to fit, but SSCI fails to check that too.
}
// TODO: Cursor
/*
texteditCursorErase();
_paint16->eraseRect(rect);
_text16->Box(text.c_str(), false, rect, SCI_TEXT16_ALIGNMENT_LEFT, -1);
_paint16->bitsShow(rect);
texteditCursorDraw(rect, text.c_str(), cursorPos);
*/
// Write back string
_segMan->strcpy(textReference, text.c_str());
} else {
// TODO: Cursor
/*
if (g_system->getMillis() >= _texteditBlinkTime) {
_paint16->invertRect(_texteditCursorRect);
_paint16->bitsShow(_texteditCursorRect);
_texteditCursorVisible = !_texteditCursorVisible;
texteditSetBlinkTime();
}
*/
}
textAddChar = false;
textChanged = false;
g_sci->sleep(10);
} // while
}
} // End of namespace Sci