diff options
-rw-r--r-- | engines/sci/gui/gui.cpp | 22 | ||||
-rw-r--r-- | engines/sci/gui/gui_gfx.cpp | 130 | ||||
-rw-r--r-- | engines/sci/gui/gui_gfx.h | 10 |
3 files changed, 159 insertions, 3 deletions
diff --git a/engines/sci/gui/gui.cpp b/engines/sci/gui/gui.cpp index 78eaa0c1e2..2e70447929 100644 --- a/engines/sci/gui/gui.cpp +++ b/engines/sci/gui/gui.cpp @@ -357,6 +357,21 @@ void SciGui::drawControlText(Common::Rect rect, reg_t obj, const char *text, int } void SciGui::drawControlTextEdit(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 mode, int16 style, int16 cursorPos, int16 maxChars, bool hilite) { + Common::Rect textRect = rect; + uint16 oldFontId = _gfx->GetFontId(); + + textRect.translate(0, 1); + rect.grow(1); + _gfx->TexteditCursorErase(); + _gfx->EraseRect(rect); + _gfx->TextBox(text, 0, textRect, 0, fontId); + _gfx->FrameRect(rect); + if (style & 8) { + _gfx->SetFont(fontId); + rect.grow(-1); + _gfx->TexteditCursorDraw(rect, text, cursorPos); + _gfx->SetFont(oldFontId); + } } void SciGui::drawControlIcon(Common::Rect rect, reg_t obj, GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, int16 style, bool hilite) { @@ -384,6 +399,13 @@ void SciGui::drawControlList(Common::Rect rect, reg_t obj, int16 maxChars, int16 } void SciGui::editControl(reg_t controlObject, reg_t eventObject) { + SegManager *segMan = _s->_segMan; + int16 controlType = GET_SEL32V(controlObject, type); + + if (controlType == 3) { + // Only process textedit controls in here + _gfx->TexteditChange(controlObject, eventObject); + } } void SciGui::graphFillBoxForeground(Common::Rect rect) { diff --git a/engines/sci/gui/gui_gfx.cpp b/engines/sci/gui/gui_gfx.cpp index e950757e21..49ed3b4b5b 100644 --- a/engines/sci/gui/gui_gfx.cpp +++ b/engines/sci/gui/gui_gfx.cpp @@ -54,6 +54,8 @@ void SciGuiGfx::init() { _textFonts = NULL; _textFontsCount = 0; _textColors = NULL; _textColorsCount = 0; + _texteditCursorVisible = false; + _animateListData = NULL; _animateListSize = 0; @@ -693,8 +695,6 @@ void SciGuiGfx::drawLine(int16 left, int16 top, int16 right, int16 bottom, byte _screen->putPixel(left, top, drawMask, color, priority, control); } } - //g_sci->eventMgr->waitUntil(5); - //ShowBits(&_rThePort->rect,6); } void SciGuiGfx::Draw_String(const char *text) { @@ -747,6 +747,7 @@ const char controlListUpArrow[2] = { 0x18, 0 }; const char controlListDownArrow[2] = { 0x19, 0 }; void SciGuiGfx::drawListControl(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 upperPos, int16 cursorPos, bool isAlias) { + SegManager *segMan = _s->_segMan; Common::Rect workerRect = rect; GuiResourceId oldFontId = GetFontId(); int16 oldPenColor = _curPort->penClr; @@ -757,7 +758,10 @@ void SciGuiGfx::drawListControl(Common::Rect rect, reg_t obj, int16 maxChars, in // draw basic window EraseRect(workerRect); - workerRect.grow(1); FrameRect(workerRect); + workerRect.grow(1); + FrameRect(workerRect); + PUT_SEL32V(obj, nsLeft, workerRect.left); PUT_SEL32V(obj, nsTop, workerRect.top); + PUT_SEL32V(obj, nsRight, workerRect.right); PUT_SEL32V(obj, nsBottom, workerRect.bottom); // draw UP/DOWN arrows workerRect = rect; TextBox(controlListUpArrow, 0, workerRect, 1, 0); @@ -794,6 +798,126 @@ void SciGuiGfx::drawListControl(Common::Rect rect, reg_t obj, int16 maxChars, in SetFont(oldFontId); } +void SciGuiGfx::TexteditCursorDraw (Common::Rect rect, const char *text, uint16 curPos) { + int16 textWidth, i; + if (!_texteditCursorVisible) { + textWidth = 0; + for (i = 0; i < curPos; i++) { + textWidth += _font->getCharWidth(text[i]); + } + _texteditCursorRect.left = rect.left + textWidth; + _texteditCursorRect.top = rect.top; + _texteditCursorRect.bottom = _texteditCursorRect.top + _font->getHeight(); + _texteditCursorRect.right = _texteditCursorRect.left + (text[curPos] == 0 ? 1 : CharWidth(text[curPos])); + InvertRect(_texteditCursorRect); + BitsShow(_texteditCursorRect, SCI_SCREEN_MASK_VISUAL); + _texteditCursorVisible = true; + TexteditSetBlinkTime(); + } +} + +void SciGuiGfx::TexteditCursorErase() { + if (_texteditCursorVisible) { + InvertRect(_texteditCursorRect); + BitsShow(_texteditCursorRect, SCI_SCREEN_MASK_VISUAL); + _texteditCursorVisible = false; + } + TexteditSetBlinkTime(); +} + +void SciGuiGfx::TexteditSetBlinkTime() { + _texteditBlinkTime = g_system->getMillis() + (30 * 1000 / 60); +} + +void SciGuiGfx::TexteditChange(reg_t controlObject, reg_t eventObject) { + SegManager *segMan = _s->_segMan; + uint16 cursorPos = GET_SEL32V(controlObject, cursor); + uint16 maxChars = GET_SEL32V(controlObject, max); + uint16 oldCursor = cursorPos; + reg_t textReference = GET_SEL32(controlObject, text); + Common::String text; + uint16 textSize, eventType, eventKey; + bool textChanged = false; + + 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(eventObject, type); + + switch (eventType) { + case SCI_EVT_MOUSE_PRESS: + // TODO: Implement mouse support for cursor change + break; + case SCI_EVT_KEYBOARD: + eventKey = GET_SEL32V(eventObject, message); + switch (eventKey) { + case SCI_K_BACKSPACE: + cursorPos--; text.deleteChar(cursorPos); + textChanged = true; + break; + case SCI_K_DELETE: + text.deleteChar(cursorPos); + textChanged = true; + break; + case SCI_K_HOME: // HOME + cursorPos = 0; textChanged = true; + break; + case SCI_K_END: // END + cursorPos = textSize; textChanged = true; + break; + case SCI_K_LEFT: // LEFT + if (cursorPos > 0) { + cursorPos--; textChanged = true; + } + case SCI_K_RIGHT: // RIGHT + if (cursorPos + 1 <= textSize) { + cursorPos++; textChanged = true; + } + break; + default: + if (eventKey > 31 && eventKey < 256 && textSize < maxChars) { + // insert pressed character + text.insertChar(eventKey, cursorPos++); + textChanged = true; + } + break; + } + break; + } + } + + if (textChanged) { + GuiResourceId oldFontId = GetFontId(); + GuiResourceId fontId = GET_SEL32V(controlObject, font); + Common::Rect rect; + rect = Common::Rect (GET_SEL32V(controlObject, nsLeft), GET_SEL32V(controlObject, nsTop), + GET_SEL32V(controlObject, nsRight), GET_SEL32V(controlObject, nsBottom)); + rect.top++; + TexteditCursorErase(); + EraseRect(rect); + TextBox(text.c_str(), 0, rect, 0, fontId); + BitsShow(rect, SCI_SCREEN_MASK_VISUAL); + SetFont(fontId); + rect.top--; + TexteditCursorDraw(rect, text.c_str(), cursorPos); + SetFont(oldFontId); + // Write back string + segMan->strcpy(textReference, text.c_str()); + } else { + if (g_system->getMillis() >= _texteditBlinkTime) { + InvertRect(_texteditCursorRect); + BitsShow(_texteditCursorRect, SCI_SCREEN_MASK_VISUAL); + _texteditCursorVisible = !_texteditCursorVisible; + TexteditSetBlinkTime(); + } + } + + PUT_SEL32V(controlObject, cursor, cursorPos); +} + uint16 SciGuiGfx::onControl(uint16 screenMask, Common::Rect rect) { Common::Rect outRect(rect.left, rect.top, rect.right, rect.bottom); int16 x, y; diff --git a/engines/sci/gui/gui_gfx.h b/engines/sci/gui/gui_gfx.h index 019b5d3299..096137374f 100644 --- a/engines/sci/gui/gui_gfx.h +++ b/engines/sci/gui/gui_gfx.h @@ -112,6 +112,9 @@ public: void drawPicture(GuiResourceId pictureId, int16 animationNr, bool mirroredFlag, bool addToFlag, GuiResourceId paletteId); void drawCel(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, uint16 leftPos, uint16 topPos, byte priority, uint16 paletteNo); void drawListControl(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 upperPos, int16 cursorPos, bool isAlias); + void TexteditCursorDraw (Common::Rect rect, const char *text, uint16 curPos); + void TexteditCursorErase(); + void TexteditChange(reg_t controlObject, reg_t eventObject); uint16 onControl(uint16 screenMask, Common::Rect rect); @@ -144,6 +147,8 @@ private: void DrawText(const char *str, int16 from, int16 len, GuiResourceId orgFontId, int16 orgPenColor); void ShowText(const char *str, int16 from, int16 len, GuiResourceId orgFontId, int16 orgPenColor); + void TexteditSetBlinkTime(); + EngineState *_s; SciGuiScreen *_screen; SciGuiPalette *_palette; @@ -161,6 +166,11 @@ private: int16 _priorityTop, _priorityBottom, _priorityBandCount; byte _priorityBands[200]; + // Textedit-Control related + Common::Rect _texteditCursorRect; + bool _texteditCursorVisible; + uint32 _texteditBlinkTime; + // Animate* related variables uint16 _animateListSize; GuiAnimateEntry *_animateListData; |