static int breakTextC(JNIEnv* env, jobject jpaint, jcharArray jtext, int index, int count, float maxWidth, jfloatArray jmeasuredWidth) { NPE_CHECK_RETURN_ZERO(env, jpaint); NPE_CHECK_RETURN_ZERO(env, jtext); SkPaint::TextBufferDirection tbd; if (count < 0) { tbd = SkPaint::kBackward_TextBufferDirection; count = -count; } else { tbd = SkPaint::kForward_TextBufferDirection; } if ((index < 0) || (index + count > env->GetArrayLength(jtext))) { doThrow(env, "java/lang/ArrayIndexOutOfBoundsException"); return 0; } SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint); const jchar* text = env->GetCharArrayElements(jtext, NULL); count = breakText(env, *paint, text + index, count, maxWidth, jmeasuredWidth, tbd); env->ReleaseCharArrayElements(jtext, const_cast<jchar*>(text), JNI_ABORT); return count; }
void Label::setText( char const* s ) { strncpy( text, ( s ? s : "" ), 3000 ); text[2999] = '\0'; lines.clear(); if ( lineWidth > 1 && static_cast<int>( strlen( text ) ) >= lineWidth ) { breakText( text, lineWidth, &lines ); } }
//! Sets the new caption of this element. void CGUIEditBox::setText(const wchar_t* text) { Text = text; if (u32(CursorPos) > Text.size()) CursorPos = Text.size(); HScrollPos = 0; breakText(); }
void StaticText::setRightToLeft(bool rtl) { if (RightToLeft != rtl) { RightToLeft = rtl; breakText(); } }
void CGUIEditBox::updateAbsolutePosition() { core::rect<s32> oldAbsoluteRect(AbsoluteRect); IGUIElement::updateAbsolutePosition(); if ( oldAbsoluteRect != AbsoluteRect ) { breakText(); } }
//! Sets the new caption of this element. void StaticText::setText(const EnrichedString &text) { IGUIElement::setText(text.c_str()); cText = text; if (text.hasBackground()) { setBackgroundColor(text.getBackground()); } breakText(); }
void MSTableColumn::removeBreakText(const MSSymbol& tag_) { MSParagraph *printText=0; for (unsigned i=0;i<breakTextList().count();i++) if (tag_==breakText(i)->tag()) printText=breakText(i); if (printText!=0) { delete printText; _breakTextList.remove(printText); } }
//! Sets another skin independent font. void CGUIStaticText::setOverrideFont(IGUIFont* font) { if (OverrideFont) OverrideFont->drop(); OverrideFont = font; if (OverrideFont) OverrideFont->grab(); breakText(); }
void OguiCheckBox::setText( const std::string& text, TEXT_ALIGN align, int w, IOguiFont* font, OguiButton::TEXT_V_ALIGN valign ) { delete textButton; textButton = NULL; textW = w; textAlign = align; if( font != NULL ) { float foo = ( (float)font->getStringWidth( text.c_str() ) / (float)w ); foo++; textH = (int)foo * buttonH; } else { textH = textW; } { int buttonSpace = 0; int x, y, w, h; std::string foo_text; if( font != NULL ) foo_text = breakText( text, font ); if( textAlign == TEXT_ALIGN_LEFT ) x = buttonX - textW - buttonSpace; else if (textAlign == TEXT_ALIGN_RIGHT ) x = buttonX + buttonW + buttonSpace; y = buttonY; w = textW; h = textH; textButton = ogui->CreateSimpleTextButton( win, x, y, w, h, NULL, NULL, NULL, NULL, textId ); textButton->SetTextHAlign( OguiButton::TEXT_H_ALIGN_LEFT ); textButton->SetTextVAlign( valign ); textButton->SetLineBreaks( true ); textButton->SetListener( this ); textButton->SetEventMask( OguiButtonEvent::EVENT_TYPE_PRESS ); if( font ) textButton->SetFont( font ); textButton->SetText( foo_text.c_str() ); } }
//! Sets another skin independent font. void CGUIEditBox::setOverrideFont(IGUIFont* font) { if (OverrideFont == font) return; if (OverrideFont) OverrideFont->drop(); OverrideFont = font; if (OverrideFont) OverrideFont->grab(); breakText(); }
//! constructor CGUIEditBox::CGUIEditBox(const wchar_t* text, bool border, IGUIEnvironment* environment, IGUIElement* parent, s32 id, const core::rect<s32>& rectangle, bool is_rtl) : IGUIEditBox(environment, parent, id, rectangle), MouseMarking(false), Border(border), OverrideColorEnabled(false), MarkBegin(0), MarkEnd(0), OverrideColor(video::SColor(101,255,255,255)), OverrideFont(0), LastBreakFont(0), Operator(0), BlinkStartTime(0), CursorPos(0), HScrollPos(0), VScrollPos(0), Max(0), WordWrap(false), MultiLine(false), AutoScroll(true), PasswordBox(false), PasswordChar(L'*'), HAlign(EGUIA_UPPERLEFT), VAlign(EGUIA_CENTER), CurrentTextRect(0,0,1,1), FrameRect(rectangle) { //m_rtl = is_rtl; m_rtl = false; // FIXME quick hack to enable mark movement with keyboard and mouse for rtl language, // don't know why it's disabled in the first place, because STK fail // to input unicode characters before? #ifdef _DEBUG setDebugName("CGUIEditBox"); #endif Text = text; if (Environment) Operator = Environment->getOSOperator(); if (Operator) Operator->grab(); // this element can be tabbed to setTabStop(true); setTabOrder(-1); IGUISkin *skin = 0; if (Environment) skin = Environment->getSkin(); if (Border && skin) { FrameRect.UpperLeftCorner.X += skin->getSize(EGDS_TEXT_DISTANCE_X)+1; FrameRect.UpperLeftCorner.Y += skin->getSize(EGDS_TEXT_DISTANCE_Y)+1; FrameRect.LowerRightCorner.X -= skin->getSize(EGDS_TEXT_DISTANCE_X)+1; FrameRect.LowerRightCorner.Y -= skin->getSize(EGDS_TEXT_DISTANCE_Y)+1; } breakText(); calculateScrollPos(); }
static int breakTextS(JNIEnv* env, jobject jpaint, jstring jtext, bool forwards, float maxWidth, jfloatArray jmeasuredWidth) { NPE_CHECK_RETURN_ZERO(env, jpaint); NPE_CHECK_RETURN_ZERO(env, jtext); SkPaint::TextBufferDirection tbd = forwards ? SkPaint::kForward_TextBufferDirection : SkPaint::kBackward_TextBufferDirection; SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint); int count = env->GetStringLength(jtext); const jchar* text = env->GetStringChars(jtext, NULL); count = breakText(env, *paint, text, count, maxWidth, jmeasuredWidth, tbd); env->ReleaseStringChars(jtext, text); return count; }
void CGUIEditBox::inputChar(wchar_t c) { if (!isEnabled()) return; if (c != 0) { if (Text.size() < Max || Max == 0) { core::stringw s; if (MarkBegin != MarkEnd) { // replace marked text const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; s = Text.subString(0, realmbgn); s.append(c); s.append( Text.subString(realmend, Text.size()-realmend) ); Text = s; CursorPos = realmbgn+1; } else { // add new character s = Text.subString(0, CursorPos); s.append(c); s.append( Text.subString(CursorPos, Text.size()-CursorPos) ); Text = s; ++CursorPos; } BlinkStartTime = getTime(); setTextMarkers(0, 0); } } breakText(); sendGuiEvent(EGET_EDITBOX_CHANGED); calculateScrollPos(); }
MSTableColumn::~MSTableColumn(void) { for (unsigned i=0;i<breakTextList().count();i++) delete breakText(i); _fontStruct=0; _headingFontStruct=0; }
MSParagraph& MSTableColumn::breakText(const MSSymbol& tag_) { for (unsigned i=0;i<breakTextList().count();i++) if (tag_==breakText(i)->tag()) return *breakText(i); MSMessageLog::warningMessage("Warning: breakText \"%s\" not fount\n",tag_.symbolName()); return defaultText(); }
void MSTableColumn::removeAllBreakText(void) { for (unsigned i=0;i<breakTextList().count();i++) delete breakText(i); _breakTextList.removeAll(); }
//! draws the element and its children void CGUIEditBox::draw() { #ifndef SERVER_ONLY if (!IsVisible) return; const bool focus = Environment->hasFocus(this); IGUISkin* skin = Environment->getSkin(); if (!skin) return; FrameRect = AbsoluteRect; // draw the border if (Border) { EGUI_DEFAULT_COLOR col = EGDC_GRAY_EDITABLE; if ( isEnabled() ) col = focus ? EGDC_FOCUSED_EDITABLE : EGDC_EDITABLE; skin->draw3DSunkenPane(this, skin->getColor(col), false, true, FrameRect, &AbsoluteClippingRect); FrameRect.UpperLeftCorner.X += skin->getSize(EGDS_TEXT_DISTANCE_X)+1; FrameRect.UpperLeftCorner.Y += skin->getSize(EGDS_TEXT_DISTANCE_Y)+1; FrameRect.LowerRightCorner.X -= skin->getSize(EGDS_TEXT_DISTANCE_X)+1; FrameRect.LowerRightCorner.Y -= skin->getSize(EGDS_TEXT_DISTANCE_Y)+1; } core::rect<s32> localClipRect = FrameRect; localClipRect.clipAgainst(AbsoluteClippingRect); // draw the text IGUIFont* font = OverrideFont; if (!OverrideFont) font = skin->getFont(); s32 cursorLine = 0; s32 charcursorpos = 0; if (font) { if (LastBreakFont != font) { breakText(); } // calculate cursor pos core::stringw *txtLine = &Text; s32 startPos = 0; core::stringw s, s2; // get mark position const bool ml = (!PasswordBox && (WordWrap || MultiLine)); const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; const s32 hlineStart = ml ? getLineFromPos(realmbgn) : 0; const s32 hlineCount = ml ? getLineFromPos(realmend) - hlineStart + 1 : 1; const s32 lineCount = ml ? BrokenText.size() : 1; // Save the override color information. // Then, alter it if the edit box is disabled. const bool prevOver = OverrideColorEnabled; const video::SColor prevColor = OverrideColor; if (Text.size()) { if (!isEnabled() && !OverrideColorEnabled) { OverrideColorEnabled = true; OverrideColor = skin->getColor(EGDC_GRAY_TEXT); } for (s32 i=0; i < lineCount; ++i) { setTextRect(i); // clipping test - don't draw anything outside the visible area core::rect<s32> c = localClipRect; c.clipAgainst(CurrentTextRect); if (!c.isValid()) continue; // get current line if (PasswordBox) { if (BrokenText.size() != 1) { BrokenText.clear(); BrokenText.push_back(core::stringw()); } if (BrokenText[0].size() != Text.size()) { BrokenText[0] = Text; for (u32 q = 0; q < Text.size(); ++q) { BrokenText[0] [q] = PasswordChar; } } txtLine = &BrokenText[0]; startPos = 0; } else { txtLine = ml ? &BrokenText[i] : &Text; startPos = ml ? BrokenTextPositions[i] : 0; } font->draw(translations->fribidize(txtLine->c_str()), CurrentTextRect, OverrideColorEnabled ? OverrideColor : skin->getColor(EGDC_BUTTON_TEXT), false, true, &localClipRect); // draw with fribidize no matter what language, because in fribidize function, // it will return the input pointer if (this->isRTLLanguage()) from Translations::isRTLText // is false // draw mark and marked text if (focus && MarkBegin != MarkEnd && i >= hlineStart && i < hlineStart + hlineCount) { s32 mbegin = 0, mend = 0; s32 lineStartPos = 0, lineEndPos = txtLine->size(); if (i == hlineStart) { // highlight start is on this line s = txtLine->subString(0, realmbgn - startPos); mbegin = font->getDimension(s.c_str()).Width; // deal with kerning mbegin += font->getKerningWidth( &((*txtLine)[realmbgn - startPos]), realmbgn - startPos > 0 ? &((*txtLine)[realmbgn - startPos - 1]) : 0); lineStartPos = realmbgn - startPos; } if (i == hlineStart + hlineCount - 1) { // highlight end is on this line s2 = txtLine->subString(0, realmend - startPos); mend = font->getDimension(s2.c_str()).Width; lineEndPos = (s32)s2.size(); } else mend = font->getDimension(txtLine->c_str()).Width; CurrentTextRect.UpperLeftCorner.X += mbegin; CurrentTextRect.LowerRightCorner.X = CurrentTextRect.UpperLeftCorner.X + mend - mbegin; // draw mark skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), CurrentTextRect, &localClipRect); // draw marked text s = txtLine->subString(lineStartPos, lineEndPos - lineStartPos); if (s.size()) font->draw(s.c_str(), CurrentTextRect, OverrideColorEnabled ? OverrideColor : skin->getColor(EGDC_HIGH_LIGHT_TEXT), false, true, &localClipRect); } } // Return the override color information to its previous settings. OverrideColorEnabled = prevOver; OverrideColor = prevColor; } // draw cursor if (WordWrap || MultiLine) { cursorLine = getLineFromPos(CursorPos); txtLine = &BrokenText[cursorLine]; startPos = BrokenTextPositions[cursorLine]; } s = txtLine->subString(0,CursorPos-startPos); charcursorpos = font->getDimension(s.c_str()).Width ; // + font->getKerningWidth(L"_", CursorPos-startPos > 0 ? &((*txtLine)[CursorPos-startPos-1]) : 0); if (focus && (getTime() - BlinkStartTime) % 2 == 0 && !m_rtl) { //setTextRect(cursorLine); //CurrentTextRect.UpperLeftCorner.X += charcursorpos; setTextRect(0); core::rect< s32 > caret_rect = CurrentTextRect; caret_rect.UpperLeftCorner.X += charcursorpos - 1; caret_rect.LowerRightCorner.X = caret_rect.UpperLeftCorner.X + 2; GL32_draw2DRectangle( video::SColor(255,0,0,0), caret_rect ); /* font->draw(L"_", CurrentTextRect, OverrideColorEnabled ? OverrideColor : skin->getColor(EGDC_BUTTON_TEXT), false, true, &localClipRect); */ } } // draw children IGUIElement::draw(); #endif }
//! Sets the new caption of this element. void CGUIStaticText::setText(const wchar_t* text) { IGUIElement::setText(text); breakText(); }
//! Enables or disables word wrap void CGUIEditBox::setWordWrap(bool enable) { WordWrap = enable; breakText(); }
void CGUIStaticText::updateAbsolutePosition() { IGUIElement::updateAbsolutePosition(); breakText(); }
//! Enables or disables word wrap for using the static text as //! multiline text control. void CGUIStaticText::setWordWrap(bool enable) { WordWrap = enable; breakText(); }
//! draws the element and its children void CGUIStaticText::draw() { if (!IsVisible) return; IGUISkin* skin = Environment->getSkin(); if (!skin) return; video::IVideoDriver* driver = Environment->getVideoDriver(); core::rect<s32> frameRect(AbsoluteRect); // draw background if (Background) { driver->draw2DRectangle(BGColor, frameRect, &AbsoluteClippingRect); } // draw the border if (Border) { skin->draw3DSunkenPane(this, 0, true, false, frameRect, &AbsoluteClippingRect); frameRect.UpperLeftCorner.X += skin->getSize(EGDS_TEXT_DISTANCE_X); } // draw the text if (Text.size()) { IGUIFont* font = OverrideFont; if (!OverrideFont) font = skin->getFont(); if (font) { if (!WordWrap) { if (VAlign == EGUIA_LOWERRIGHT) { frameRect.UpperLeftCorner.Y = frameRect.LowerRightCorner.Y - font->getDimension(L"A").Height - font->getKerningHeight(); } if (HAlign == EGUIA_LOWERRIGHT) { frameRect.UpperLeftCorner.X = frameRect.LowerRightCorner.X - font->getDimension(Text.c_str()).Width; } font->draw(Text.c_str(), frameRect, OverrideColorEnabled ? OverrideColor : skin->getColor(IsEnabled ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT), HAlign == EGUIA_CENTER, VAlign == EGUIA_CENTER, &AbsoluteClippingRect); } else { if (font != LastBreakFont) breakText(); core::rect<s32> r = frameRect; s32 height = font->getDimension(L"A").Height + font->getKerningHeight(); s32 totalHeight = height * BrokenText.size(); if (VAlign == EGUIA_CENTER) { r.UpperLeftCorner.Y = r.getCenter().Y - (totalHeight / 2); } else if (VAlign == EGUIA_LOWERRIGHT) { r.UpperLeftCorner.Y = r.LowerRightCorner.Y - totalHeight; } for (u32 i=0; i<BrokenText.size(); ++i) { if (HAlign == EGUIA_LOWERRIGHT) { r.UpperLeftCorner.X = frameRect.LowerRightCorner.X - font->getDimension(BrokenText[i].c_str()).Width; } font->draw(BrokenText[i].c_str(), r, OverrideColorEnabled ? OverrideColor : skin->getColor(IsEnabled ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT), HAlign == EGUIA_CENTER, false, &AbsoluteClippingRect); r.LowerRightCorner.Y += height; r.UpperLeftCorner.Y += height; } } } } IGUIElement::draw(); }
//! draws the element and its children void CGUIStaticText::draw() { if (!IsVisible) return; IGUISkin* skin = Environment->getSkin(); irr::video::IVideoDriver* driver = Environment->getVideoDriver(); core::rect<s32> frameRect(AbsoluteRect); // draw background if (Background) { driver->draw2DRectangle( skin->getColor(gui::EGDC_3D_FACE), frameRect, &AbsoluteClippingRect); } // draw the border if (Border) { skin->draw3DSunkenPane(this, 0, true, false, frameRect, &AbsoluteClippingRect); frameRect.UpperLeftCorner.X += 3; } // draw the text if (Text.size()) { IGUIFont* font = OverrideFont; if (!OverrideFont) font = skin->getFont(); if (font) { if (!WordWrap) font->draw(Text.c_str(), frameRect, OverrideColorEnabled ? OverrideColor : skin->getColor(EGDC_BUTTON_TEXT), false, true, &AbsoluteClippingRect); else { if (font != LastBreakFont) breakText(); core::rect<s32> r = frameRect; s32 height = font->getDimension(L"A").Height; for (u32 i=0; i<BrokenText.size(); ++i) { font->draw(BrokenText[i].c_str(), r, OverrideColorEnabled ? OverrideColor : skin->getColor(EGDC_BUTTON_TEXT), false, false, &AbsoluteClippingRect); r.LowerRightCorner.Y += height; r.UpperLeftCorner.Y += height; } } } } IGUIElement::draw(); }
bool CGUIEditBox::processKey(const SEvent& event) { if (!event.KeyInput.PressedDown) return false; bool textChanged = false; s32 newMarkBegin = MarkBegin; s32 newMarkEnd = MarkEnd; // control shortcut handling if (event.KeyInput.Control) { // german backlash '\' entered with control + '?' if ( event.KeyInput.Char == '\\' ) { inputChar(event.KeyInput.Char); return true; } switch(event.KeyInput.Key) { case KEY_KEY_A: // select all newMarkBegin = 0; newMarkEnd = Text.size(); break; case KEY_KEY_C: // copy to clipboard if (!PasswordBox && Operator && MarkBegin != MarkEnd) { const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; core::stringw s; s = Text.subString(realmbgn, realmend - realmbgn).c_str(); #ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ Operator->copyToClipboard(s.c_str()); #else Operator->copyToClipboard(StringUtils::wideToUtf8(s).c_str()); #endif } break; case KEY_KEY_X: // cut to the clipboard if (!PasswordBox && Operator && MarkBegin != MarkEnd) { const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; // copy core::stringw sc; sc = Text.subString(realmbgn, realmend - realmbgn).c_str(); #ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ Operator->copyToClipboard(sc.c_str()); #else Operator->copyToClipboard(StringUtils::wideToUtf8(sc).c_str()); #endif if (isEnabled()) { // delete core::stringw s; s = Text.subString(0, realmbgn); s.append( Text.subString(realmend, Text.size()-realmend) ); Text = s; CursorPos = realmbgn; newMarkBegin = 0; newMarkEnd = 0; textChanged = true; } } break; case KEY_KEY_V: if ( !isEnabled() ) break; // paste from the clipboard if (Operator) { const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; // add new character #ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ const wchar_t* p = Operator->getTextFromClipboard(); #else const c8* p = Operator->getTextFromClipboard(); #endif if (p) { if (MarkBegin == MarkEnd) { // insert text core::stringw s = Text.subString(0, CursorPos); #ifndef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ s.append(StringUtils::utf8ToWide(p)); #else s.append(p); #endif s.append( Text.subString(CursorPos, Text.size()-CursorPos) ); if (!Max || s.size()<=Max) // thx to Fish FH for fix { Text = s; #ifndef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ s = StringUtils::utf8ToWide(p); #else s = p; #endif CursorPos += s.size(); } } else { // replace text core::stringw s = Text.subString(0, realmbgn); #ifndef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ s.append(StringUtils::utf8ToWide(p)); #else s.append(p); #endif s.append( Text.subString(realmend, Text.size()-realmend) ); if (!Max || s.size()<=Max) // thx to Fish FH for fix { Text = s; #ifndef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ s = StringUtils::utf8ToWide(p); #else s = p; #endif CursorPos = realmbgn + s.size(); } } } newMarkBegin = 0; newMarkEnd = 0; textChanged = true; } break; case KEY_HOME: if (!m_rtl) { // move/highlight to start of text if (event.KeyInput.Shift) { newMarkEnd = CursorPos; newMarkBegin = 0; CursorPos = 0; } else { CursorPos = 0; newMarkBegin = 0; newMarkEnd = 0; } } break; case KEY_END: if (!m_rtl) { // move/highlight to end of text if (event.KeyInput.Shift) { newMarkBegin = CursorPos; newMarkEnd = Text.size(); CursorPos = 0; } else { CursorPos = Text.size(); newMarkBegin = 0; newMarkEnd = 0; } } break; default: return false; } } // default keyboard handling else switch(event.KeyInput.Key) { /* case KEY_KEY_Q: inputChar(L'\u05DC'); textChanged = true; return true; case KEY_KEY_W: inputChar(L'\u05DB'); textChanged = true; return true; case KEY_KEY_E: inputChar(L'\u05DA'); textChanged = true; return true; case KEY_KEY_R: inputChar(L'\u05D9'); textChanged = true; return true; case KEY_KEY_T: inputChar(L'\u05D8'); textChanged = true; return true; case KEY_KEY_Y: inputChar(L'\u05D7'); textChanged = true; return true; */ case KEY_END: if (!m_rtl) { s32 p = Text.size(); if (WordWrap || MultiLine) { p = getLineFromPos(CursorPos); p = BrokenTextPositions[p] + (s32)BrokenText[p].size(); if (p > 0 && (Text[p-1] == L'\r' || Text[p-1] == L'\n' )) p-=1; } if (event.KeyInput.Shift) { if (MarkBegin == MarkEnd) newMarkBegin = CursorPos; newMarkEnd = p; } else { newMarkBegin = 0; newMarkEnd = 0; } CursorPos = p; BlinkStartTime = getTime(); } break; case KEY_HOME: if (!m_rtl) { s32 p = 0; if (WordWrap || MultiLine) { p = getLineFromPos(CursorPos); p = BrokenTextPositions[p]; } if (event.KeyInput.Shift) { if (MarkBegin == MarkEnd) newMarkBegin = CursorPos; newMarkEnd = p; } else { newMarkBegin = 0; newMarkEnd = 0; } CursorPos = p; BlinkStartTime = getTime(); } break; case KEY_RETURN: if (MultiLine) { inputChar(L'\n'); return true; } else { sendGuiEvent( EGET_EDITBOX_ENTER ); } break; case KEY_LEFT: if (!m_rtl) { if (event.KeyInput.Shift) { if (CursorPos > 0) { if (MarkBegin == MarkEnd) newMarkBegin = CursorPos; newMarkEnd = CursorPos-1; } } else { newMarkBegin = 0; newMarkEnd = 0; } if (CursorPos > 0) CursorPos--; BlinkStartTime = getTime(); } break; case KEY_RIGHT: if (!m_rtl) { if (event.KeyInput.Shift) { if (Text.size() > (u32)CursorPos) { if (MarkBegin == MarkEnd) newMarkBegin = CursorPos; newMarkEnd = CursorPos+1; } } else { newMarkBegin = 0; newMarkEnd = 0; } if (Text.size() > (u32)CursorPos) CursorPos++; BlinkStartTime = getTime(); } break; case KEY_UP: if (MultiLine || (WordWrap && BrokenText.size() > 1) ) { s32 lineNo = getLineFromPos(CursorPos); s32 mb = (MarkBegin == MarkEnd) ? CursorPos : (MarkBegin > MarkEnd ? MarkBegin : MarkEnd); if (lineNo > 0) { s32 cp = CursorPos - BrokenTextPositions[lineNo]; if ((s32)BrokenText[lineNo-1].size() < cp) CursorPos = BrokenTextPositions[lineNo-1] + (s32)BrokenText[lineNo-1].size()-1; else CursorPos = BrokenTextPositions[lineNo-1] + cp; } if (event.KeyInput.Shift) { newMarkBegin = mb; newMarkEnd = CursorPos; } else { newMarkBegin = 0; newMarkEnd = 0; } } else { return false; } break; case KEY_DOWN: if (MultiLine || (WordWrap && BrokenText.size() > 1) ) { s32 lineNo = getLineFromPos(CursorPos); s32 mb = (MarkBegin == MarkEnd) ? CursorPos : (MarkBegin < MarkEnd ? MarkBegin : MarkEnd); if (lineNo < (s32)BrokenText.size()-1) { s32 cp = CursorPos - BrokenTextPositions[lineNo]; if ((s32)BrokenText[lineNo+1].size() < cp) CursorPos = BrokenTextPositions[lineNo+1] + BrokenText[lineNo+1].size()-1; else CursorPos = BrokenTextPositions[lineNo+1] + cp; } if (event.KeyInput.Shift) { newMarkBegin = mb; newMarkEnd = CursorPos; } else { newMarkBegin = 0; newMarkEnd = 0; } } else { return false; } break; case KEY_BACK: if ( !isEnabled() ) break; if (Text.size()) { core::stringw s; if (MarkBegin != MarkEnd) { // delete marked text const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; s = Text.subString(0, realmbgn); s.append( Text.subString(realmend, Text.size()-realmend) ); Text = s; CursorPos = realmbgn; } else { // delete text behind cursor if (CursorPos>0) s = Text.subString(0, CursorPos-1); else s = L""; s.append( Text.subString(CursorPos, Text.size()-CursorPos) ); Text = s; --CursorPos; } if (CursorPos < 0) CursorPos = 0; BlinkStartTime = getTime(); newMarkBegin = 0; newMarkEnd = 0; textChanged = true; } break; case KEY_DELETE: if ( !isEnabled() ) break; if (Text.size() != 0) { core::stringw s; if (MarkBegin != MarkEnd) { // delete marked text const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; s = Text.subString(0, realmbgn); s.append( Text.subString(realmend, Text.size()-realmend) ); Text = s; CursorPos = realmbgn; } else { // delete text before cursor s = Text.subString(0, CursorPos); s.append( Text.subString(CursorPos+1, Text.size()-CursorPos-1) ); Text = s; } if (CursorPos > (s32)Text.size()) CursorPos = (s32)Text.size(); BlinkStartTime = getTime(); newMarkBegin = 0; newMarkEnd = 0; textChanged = true; } break; case KEY_ESCAPE: case KEY_TAB: case KEY_SHIFT: case KEY_F1: case KEY_F2: case KEY_F3: case KEY_F4: case KEY_F5: case KEY_F6: case KEY_F7: case KEY_F8: case KEY_F9: case KEY_F10: case KEY_F11: case KEY_F12: case KEY_F13: case KEY_F14: case KEY_F15: case KEY_F16: case KEY_F17: case KEY_F18: case KEY_F19: case KEY_F20: case KEY_F21: case KEY_F22: case KEY_F23: case KEY_F24: // ignore these keys return false; default: inputChar(event.KeyInput.Char); return true; } // Set new text markers setTextMarkers( newMarkBegin, newMarkEnd ); // break the text if it has changed if (textChanged) { breakText(); sendGuiEvent(EGET_EDITBOX_CHANGED); } calculateScrollPos(); #if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) switch(event.KeyInput.Key) { // If cursor points the surrogate low, send KEY_LEFT event. case KEY_UP: case KEY_DOWN: if (MultiLine || (WordWrap && BrokenText.size() > 1) ) { if (UTF16_IS_SURROGATE_LO(Text[CursorPos])) { SEvent leftEvent; leftEvent = event; leftEvent.KeyInput.Key = KEY_LEFT; Environment->postEventFromUser(leftEvent); } } break; // If cursor points the surrogate low, send a same event. case KEY_LEFT: case KEY_RIGHT: case KEY_DELETE: if (UTF16_IS_SURROGATE_LO(Text[CursorPos])) Environment->postEventFromUser(event); break; // If cursor points front of the surrogate high, send a same event. case KEY_BACK: if (CursorPos > 0) { if (UTF16_IS_SURROGATE_HI(Text[CursorPos-1])) Environment->postEventFromUser(event); } break; default: break; } #endif return true; }