Script v1_7_1_0
- AI
- Animals
- Collections
- Contracts
- Debug
- Economy
- Elements
- EnvironmentalScore
- Errors
- Events
- GUI
- AnimalScreen
- AnimationElement
- BitmapElement
- BoxLayoutElement
- BreadcrumbsElement
- ButtonElement
- ButtonOverlay
- ChatWindow
- CheckedOptionElement
- ClearElement
- ColorPickButtonElement
- ConstructionScreen
- ContextActionDisplay
- ControlBarDisplay
- DialogElement
- DynamicFadedBitmapElement
- FillLevelsDisplay
- FlowLayoutElement
- FocusManager
- FrameElement
- FrameReferenceElement
- GameInfoDisplay
- GameInfoDisplayMobile
- GamePausedDisplay
- Gui
- GuiDataSource
- GuiElement
- GuiMixin
- GuiOverlay
- GuiProfile
- GuiSoundPlayer
- GuiTopDownCamera
- GuiTopDownCursor
- GuiUtils
- HUDDisplayElement
- HUDElement
- HUDFrameElement
- HUDPopupMessage
- HUDSliderElement
- HUDTextDisplay
- IndexChangeSubjectMixin
- IndexStateElement
- InfoDisplay
- InfoHUDBox
- InGameIcon
- IngameMap
- IngameMapElement
- InputGlyphElement
- InputGlyphElementUI
- InputHelpDisplay
- KeyValueInfoHUDBox
- ListElement
- ListItemElement
- MapOverlayGenerator
- MixerWagonHUDExtension
- MultiTextOptionElement
- MultiValueTween
- Overlay
- PagingElement
- PictureElement
- PlatformIconElement
- PlayerControlPadDisplay
- PlaySampleMixin
- RenderElement
- RoundStatusBar
- ScreenElement
- ScrollingLayoutElement
- SettingsModel
- SideNotification
- SideNotificationMobile
- SliderElement
- SpeakerDisplay
- SpeedMeterDisplay
- SpeedSliderDisplay
- StatusBar
- SteeringSliderDisplay
- TabbedMenu
- TabbedMenuFrameElement
- TabbedMenuWithDetails
- TableElement
- TableHeaderElement
- TerrainLayerElement
- TextBackdropElement
- TextElement
- TextInputElement
- ThreePartBitmapElement
- TimerElement
- ToggleButtonElement
- TopNotification
- Tween
- TweenSequence
- VariableWorkWidthHUDExten...
- VehicleHUDExtension
- VehicleSchemaDisplay
- VideoElement
- WardrobeScreen
- Handtools
- Hud
- I3d
- Input
- Jobs
- Maps
- Materials
- Misc
- Objects
- Parameters
- Placeables
- Placement
- Player
- Shop
- Sounds
- Specialization
- Specializations
- StateMachine
- Statistics
- Tasks
- Triggers
- Utils
- Vehicles
Engine v1_7_1_0
- AI
- Animation
- Camera
- Entity
- Fillplanes
- general
- General
- I3D
- Input
- Lighting
- Math
- Network
- Node
- NoteNode
- Overlays
- Particle System
- Physics
- Rendering
- Scenegraph
- Shape
- Sound
- Spline
- String
- Terrain Detail
- Text Rendering
- Tire Track
- VoiceChat
- XML
Foundation Reference
TextInputElement
DescriptionText input element which captures strings from player input. Used layers: "cursor" for a text input cursor icon. TODO: IME property docsParent
ButtonElementXML Configuration Parameters
GuiElement#imeKeyboardType | string [optional] Input method editor keyboard type, defaults to "normal". TODO: add valid types based on engine code |
GuiElement#imeTitle | string |
GuiElement#imeDescription | string |
GuiElement#imePlaceholder | string |
GuiElement#maxCharacters | int [optional] Maximum number of characters to allow as input, defaults to 512. |
GuiElement#maxInputTextWidth | string [optional] Maximum pixel width of input text in reference resolution. Must be defined when text alignment is not "left". Format: "[width]px" |
GuiElement#cursorOffset | string [optional] Pixel offset of input cursor icon in text element in reference resolution, defaults to [0, 0]. Format: "[x]px y[px]" |
GuiElement#cursorSize | string [optional] Pixel size of input cursor icon in text element in reference resolution. Format: "[width]px [height]px" |
GuiElement#isPassword | bool [optional] If true, will behave as password input and mask characters, defaults to false. |
Functions
- abortIme
- applyScreenAlignment
- applyTextInputAspectScale
- copyAttributes
- delete
- deleteText
- draw
- drawCursor
- drawTextPart
- finalize
- getAvailableTextWidth
- getDoRenderText
- getIsActive
- getIsUnicodeAllowed
- getNeededTextWidth
- getText
- inputEvent
- keyEvent
- limitTextToAvailableWidth
- loadFromXML
- loadProfile
- mouseEvent
- moveCursorLeft
- moveCursorRight
- new
- onClose
- onFocusActivate
- onFocusLeave
- openIme
- reset
- setAlpha
- setCaptureInput
- setCursorPosition
- setForcePressed
- setText
- shouldFocusChange
- stopSpecialKeyRepeating
- translate
- update
- updateVisibleTextElements
abortIme
DescriptionDefinitionabortIme()Code
505 | function TextInputElement:abortIme() |
506 | if self.useIme and self.imeActive then |
507 | self.imeActive = false |
508 | self.preImeText = "" |
509 | imeAbort() |
510 | end |
511 | end |
applyScreenAlignment
DescriptionDefinitionapplyScreenAlignment()Code
206 | function TextInputElement:applyScreenAlignment() |
207 | self:applyTextInputAspectScale() |
208 | |
209 | TextInputElement:superClass().applyScreenAlignment(self) |
210 | end |
applyTextInputAspectScale
DescriptionDefinitionapplyTextInputAspectScale()Code
193 | function TextInputElement:applyTextInputAspectScale() |
194 | local xScale, yScale = self:getAspectScale() |
195 | |
196 | self.cursorOffset[1] = self.cursorOffset[1] * xScale |
197 | self.cursorSize[1] = self.cursorSize[1] * xScale |
198 | self.maxInputTextWidth = self.maxInputTextWidth * xScale |
199 | |
200 | self.cursorOffset[2] = self.cursorOffset[2] * yScale |
201 | self.cursorSize[2] = self.cursorSize[2] * yScale |
202 | end |
copyAttributes
DescriptionDefinitioncopyAttributes()Code
164 | function TextInputElement:copyAttributes(src) |
165 | TextInputElement:superClass().copyAttributes(self, src) |
166 | |
167 | self.imeKeyboardType = src.imeKeyboardType |
168 | self.imeTitle = src.imeTitle |
169 | self.imeDescription = src.imeDescription |
170 | self.imePlaceholder = src.imePlaceholder |
171 | |
172 | self.maxCharacters = src.maxCharacters |
173 | self.maxInputTextWidth = src.maxInputTextWidth |
174 | |
175 | GuiOverlay.copyOverlay(self.cursor, src.cursor) |
176 | self.cursorOffset = table.copy(src.cursorOffset) |
177 | self.cursorSize = table.copy(src.cursorSize) |
178 | self.isPassword = src.isPassword |
179 | |
180 | self.onEnterCallback = src.onEnterCallback |
181 | self.onTextChangedCallback = src.onTextChangedCallback |
182 | self.onEnterPressedCallback = src.onEnterPressedCallback |
183 | self.onEscPressedCallback = src.onEscPressedCallback |
184 | self.onIsUnicodeAllowedCallback = src.onIsUnicodeAllowedCallback |
185 | |
186 | self.enterWhenClickOutside = src.enterWhenClickOutside |
187 | |
188 | self:finalize() |
189 | end |
delete
DescriptionDefinitiondelete()Code
88 | function TextInputElement:delete() |
89 | self:abortIme() |
90 | GuiOverlay.deleteOverlay(self.cursor) |
91 | TextInputElement:superClass().delete(self) |
92 | end |
deleteText
DescriptionDefinitiondeleteText()Code
445 | function TextInputElement:deleteText(deleteRightCharacterFromCursor) |
446 | local textLength = utf8Strlen(self.text) |
447 | |
448 | if textLength > 0 then |
449 | local canDelete = false |
450 | local deleteOffset |
451 | |
452 | if deleteRightCharacterFromCursor then |
453 | if self.cursorPosition <= textLength then |
454 | canDelete = true |
455 | deleteOffset = 0 |
456 | end |
457 | else |
458 | if self.cursorPosition > 1 then |
459 | canDelete = true |
460 | deleteOffset = -1 |
461 | end |
462 | end |
463 | |
464 | if canDelete then |
465 | --[[ |
466 | print(string.format( |
467 | "self.cursorPosition %d, deleteOffset %d, textLength %d, prestring : %s, poststring : %s", |
468 | self.cursorPosition, deleteOffset, textLength, |
469 | tostring(utf8Substr(self.text, 0, self.cursorPosition + deleteOffset - 1)), |
470 | tostring(utf8Substr(self.text, self.cursorPosition + deleteOffset, -1)))) |
471 | --]] |
472 | self.text = |
473 | (((self.cursorPosition + deleteOffset) > 1) and utf8Substr(self.text, 0, self.cursorPosition + deleteOffset - 1) or "") .. |
474 | (((self.cursorPosition + deleteOffset) < textLength) and utf8Substr(self.text, self.cursorPosition + deleteOffset, -1) or "") |
475 | self.cursorPosition = self.cursorPosition + deleteOffset |
476 | --print("final text : " .. self.text) |
477 | |
478 | self:raiseCallback("onTextChangedCallback", self, self.text) |
479 | end |
480 | end |
481 | end |
draw
DescriptionDefinitiondraw()Code
693 | function TextInputElement:draw(clipX1, clipY1, clipX2, clipY2) |
694 | -- call ancestor drawing functions with empty text: |
695 | local text = self.text |
696 | self.text = "" |
697 | TextInputElement:superClass().draw(self, clipX1, clipY1, clipX2, clipY2) |
698 | self.text = text |
699 | |
700 | setTextAlignment(self.textAlignment) |
701 | local neededWidth = self:getNeededTextWidth() |
702 | |
703 | local textXPos = self.absPosition[1] + self.textOffset[1] |
704 | if self.textAlignment == RenderText.ALIGN_CENTER then |
705 | textXPos = textXPos + (self.maxInputTextWidth * 0.5) - (neededWidth * 0.5) |
706 | elseif self.textAlignment == RenderText.ALIGN_RIGHT then |
707 | textXPos = textXPos + self.maxInputTextWidth - neededWidth |
708 | end |
709 | textXPos = textXPos + (self.size[1]-self.maxInputTextWidth) / 2 |
710 | |
711 | local _, yOffset = self:getTextOffset() |
712 | local _, yPos = self:getTextPosition(self.text) |
713 | local textYPos = yPos + yOffset |
714 | |
715 | if clipX1 ~= nil then |
716 | setTextClipArea(clipX1, clipY1, clipX2, clipY2) |
717 | end |
718 | |
719 | local displacementX = 0 |
720 | if self.areFrontDotsVisible then |
721 | local additionalDisplacement = self:drawTextPart(self.frontDotsText, textXPos, displacementX, textYPos) |
722 | displacementX = displacementX + additionalDisplacement |
723 | end |
724 | if self.isVisibleTextPart1Visible then |
725 | local additionalDisplacement = self:drawTextPart(self.visibleTextPart1, textXPos, displacementX, textYPos) |
726 | displacementX = displacementX + additionalDisplacement |
727 | end |
728 | if self.isCursorVisible then |
729 | local additionalDisplacement = self:drawCursor(textXPos, displacementX, textYPos) |
730 | displacementX = displacementX + additionalDisplacement |
731 | end |
732 | if self.isVisibleTextPart2Visible then |
733 | local additionalDisplacement = self:drawTextPart(self.visibleTextPart2, textXPos, displacementX, textYPos) |
734 | displacementX = displacementX + additionalDisplacement |
735 | end |
736 | |
737 | if self.areBackDotsVisible then |
738 | self:drawTextPart(self.backDotsText, textXPos, displacementX, textYPos) |
739 | end |
740 | |
741 | setTextBold(false) |
742 | setTextAlignment(RenderText.ALIGN_LEFT) |
743 | setTextColor(1, 1, 1, 1) |
744 | |
745 | if clipX1 ~= nil then |
746 | setTextClipArea(0, 0, 1, 1) |
747 | end |
748 | end |
drawCursor
DescriptionDefinitiondrawCursor()Code
823 | function TextInputElement:drawCursor(textXPos, displacementX, textYPos) |
824 | if self.cursorBlinkTime < self.cursorBlinkInterval then |
825 | local x = textXPos + displacementX + self.cursorOffset[1] |
826 | x = math.floor(x * g_screenWidth) * (1 / g_screenWidth) |
827 | GuiOverlay.renderOverlay(self.cursor, x, textYPos + self.cursorOffset[2], self.cursorSize[1], self.cursorSize[2]) |
828 | end |
829 | |
830 | return self.cursorNeededSize[1] |
831 | end |
drawTextPart
DescriptionDefinitiondrawTextPart()Code
796 | function TextInputElement:drawTextPart(text, textXPos, displacementX, textYPos) |
797 | local textWidth = 0 |
798 | if text ~= "" then |
799 | setTextBold(self.textBold) |
800 | textWidth = getTextWidth(self.textSize, text) |
801 | local alignmentDisplacement = 0 |
802 | if self.textAlignment == RenderText.ALIGN_CENTER then |
803 | alignmentDisplacement = textWidth * 0.5 |
804 | elseif self.textAlignment == RenderText.ALIGN_RIGHT then |
805 | alignmentDisplacement = textWidth |
806 | end |
807 | |
808 | if self.text2Size > 0 then |
809 | setTextBold(self.text2Bold) |
810 | setTextColor(unpack(self:getText2Color())) |
811 | renderText(textXPos + alignmentDisplacement + displacementX + (self.text2Offset[1] - self.textOffset[1]), textYPos + (self.text2Offset[2] - self.textOffset[2]), self.text2Size, text) |
812 | end |
813 | |
814 | setTextBold(self.textBold) |
815 | setTextColor(unpack(self:getTextColor())) |
816 | renderText(textXPos + alignmentDisplacement + displacementX, textYPos, self.textSize, text) |
817 | end |
818 | return textWidth |
819 | end |
finalize
DescriptionDefinitionfinalize()Code
214 | function TextInputElement:finalize() |
215 | self.cursorNeededSize = { |
216 | self.cursorOffset[1] + self.cursorSize[1], |
217 | self.cursorOffset[2] + self.cursorSize[2] |
218 | } |
219 | |
220 | if not self.maxInputTextWidth and (self.textAlignment == RenderText.ALIGN_CENTER or self.textAlignment == RenderText.ALIGN_RIGHT) then |
221 | Logging.error('TextInputElement loading using "center" or "right" alignment requires specification of "maxInputTextWidth"') |
222 | end |
223 | |
224 | if self.maxInputTextWidth and self.maxInputTextWidth <= (getTextWidth(self.textSize, self.frontDotsText) + self.cursorNeededSize[1] + getTextWidth(self.textSize, self.backDotsText)) then |
225 | Logging.warning('TextInputElement loading specified "maxInputTextWidth" is too small (%.4f) to display needed data', self.maxInputTextWidth) |
226 | end |
227 | end |
getAvailableTextWidth
DescriptionDefinitiongetAvailableTextWidth()Code
1008 | function TextInputElement:getAvailableTextWidth() |
1009 | if not self.maxInputTextWidth then |
1010 | return nil |
1011 | end |
1012 | |
1013 | local availableTextWidth = self.maxInputTextWidth |
1014 | |
1015 | if self.areFrontDotsVisible then |
1016 | availableTextWidth = availableTextWidth - getTextWidth(self.textSize, self.frontDotsText) |
1017 | end |
1018 | |
1019 | if self.isCursorVisible then |
1020 | availableTextWidth = availableTextWidth - self.cursorNeededSize[1] |
1021 | end |
1022 | |
1023 | if self.areBackDotsVisible then |
1024 | availableTextWidth = availableTextWidth - getTextWidth(self.textSize, self.backDotsText) |
1025 | end |
1026 | |
1027 | return availableTextWidth |
1028 | end |
getDoRenderText
DescriptionDefinitiongetDoRenderText()Code
290 | function TextInputElement:getDoRenderText() |
291 | return false |
292 | end |
getIsActive
DescriptionDefinitiongetIsActive()Code
231 | function TextInputElement:getIsActive() |
232 | return GuiElement.getIsActive(self) -- parent type ButtonElement behaves incompatibly, use the base method |
233 | end |
getIsUnicodeAllowed
DescriptionDefinitiongetIsUnicodeAllowed()Code
352 | function TextInputElement:getIsUnicodeAllowed(unicode) |
353 | if unicode == 13 or unicode == 10 then |
354 | return false |
355 | end |
356 | if not getCanRenderUnicode(unicode) then |
357 | return false |
358 | end |
359 | |
360 | return Utils.getNoNil(self:raiseCallback("onIsUnicodeAllowedCallback", unicode), true) |
361 | end |
getNeededTextWidth
DescriptionDefinitiongetNeededTextWidth()Code
1032 | function TextInputElement:getNeededTextWidth() |
1033 | local neededWidth = 0 |
1034 | if self.areFrontDotsVisible then |
1035 | neededWidth = neededWidth + getTextWidth(self.textSize, self.frontDotsText) |
1036 | end |
1037 | |
1038 | if self.isVisibleTextPart1Visible then |
1039 | neededWidth = neededWidth + getTextWidth(self.textSize, self.visibleTextPart1) |
1040 | end |
1041 | |
1042 | if self.isCursorVisible then |
1043 | neededWidth = neededWidth + self.cursorNeededSize[1] |
1044 | end |
1045 | |
1046 | if self.isVisibleTextPart2Visible then |
1047 | neededWidth = neededWidth + getTextWidth(self.textSize, self.visibleTextPart2) |
1048 | end |
1049 | |
1050 | if self.areBackDotsVisible then |
1051 | neededWidth = neededWidth + getTextWidth(self.textSize, self.backDotsText) |
1052 | end |
1053 | |
1054 | return neededWidth |
1055 | end |
getText
DescriptionGet textDefinition
getText()Code
1059 | function TextInputElement:getText() |
1060 | return self.text |
1061 | end |
inputEvent
DescriptionHandle GUI input events. Reacts to confirmation and cancel actions. Also see GuiElement.inputEvent().Definition
inputEvent()Code
609 | function TextInputElement:inputEvent(action, value, eventUsed) |
610 | -- break inheritance from ButtonElement, text input needs custom logic |
611 | if self.blockTime <= 0 then |
612 | if not self.imeActive and self:getIsActive() and self:getOverlayState() == GuiOverlay.STATE_PRESSED then |
613 | if action == InputAction.MENU_ACCEPT then |
614 | if self.forcePressed then |
615 | self:setForcePressed(false) |
616 | else |
617 | self:setForcePressed(true) |
618 | end |
619 | self:raiseCallback("onEnterPressedCallback", self) |
620 | eventUsed = true |
621 | elseif action == InputAction.MENU_CANCEL or action == InputAction.MENU_BACK then |
622 | if self.forcePressed then |
623 | self:setForcePressed(false) |
624 | else |
625 | self:setForcePressed(true) |
626 | end |
627 | self:raiseCallback("onEscPressedCallback", self) |
628 | eventUsed = true |
629 | end |
630 | end |
631 | end |
632 | |
633 | return eventUsed |
634 | end |
keyEvent
DescriptionDefinitionkeyEvent()Code
515 | function TextInputElement:keyEvent(unicode, sym, modifier, isDown, eventUsed) |
516 | if TextInputElement:superClass().keyEvent(self, unicode, sym, modifier, isDown, eventUsed) then |
517 | eventUsed = true |
518 | end |
519 | |
520 | if self.isRepeatingSpecialKeyDown and not isDown and self.repeatingSpecialKeySym == sym then |
521 | self:stopSpecialKeyRepeating() |
522 | end |
523 | |
524 | if self.blockTime <= 0 and self:getIsActive() and self:getOverlayState() == GuiOverlay.STATE_PRESSED then |
525 | local wasSpecialKey = false |
526 | |
527 | if not isDown then |
528 | -- react to input state-changing keys on key "up" to avoid double inputs in the menu |
529 | if sym == Input.KEY_return and self.isReturnDown then |
530 | self.isReturnDown = false |
531 | self:setForcePressed(not self.forcePressed) |
532 | self:raiseCallback("onEnterPressedCallback", self) |
533 | elseif sym == Input.KEY_esc then |
534 | self.isEscDown = false |
535 | self:setForcePressed(not self.forcePressed) |
536 | self:raiseCallback("onEscPressedCallback", self) |
537 | end |
538 | else |
539 | local startSpecialKeyRepeating = false |
540 | if sym == Input.KEY_left then |
541 | --self.cursorPosition = math.max(1, self.cursorPosition - 1) |
542 | -- is now handled by Focus system |
543 | self:moveCursorLeft() |
544 | startSpecialKeyRepeating = true |
545 | wasSpecialKey = true |
546 | elseif sym == Input.KEY_right then |
547 | --self.cursorPosition = math.min(utf8Strlen(self.text) + 1, self.cursorPosition + 1) |
548 | -- is now handled by focus system |
549 | self:moveCursorRight() |
550 | startSpecialKeyRepeating = true |
551 | wasSpecialKey = true |
552 | elseif sym == Input.KEY_home then |
553 | self.cursorPosition = 1 |
554 | wasSpecialKey = true |
555 | elseif sym == Input.KEY_end then |
556 | self.cursorPosition = utf8Strlen(self.text) + 1 |
557 | wasSpecialKey = true |
558 | elseif sym == Input.KEY_delete then |
559 | self:deleteText(true) |
560 | startSpecialKeyRepeating = true |
561 | wasSpecialKey = true |
562 | elseif sym == Input.KEY_backspace then |
563 | self:deleteText(false) |
564 | startSpecialKeyRepeating = true |
565 | wasSpecialKey = true |
566 | elseif sym == Input.KEY_esc then |
567 | self.isEscDown = true |
568 | wasSpecialKey = true |
569 | elseif sym == Input.KEY_return then |
570 | self.isReturnDown = true |
571 | wasSpecialKey = true |
572 | end |
573 | |
574 | if startSpecialKeyRepeating then |
575 | self.isRepeatingSpecialKeyDown = true |
576 | self.repeatingSpecialKeySym = sym |
577 | self.repeatingSpecialKeyDelayTime = TextInputElement.INITIAL_REPEAT_DELAY |
578 | self.repeatingSpecialKeyRemainingDelayTime = self.repeatingSpecialKeyDelayTime |
579 | end |
580 | |
581 | if not wasSpecialKey then |
582 | if self:getIsUnicodeAllowed(unicode) then |
583 | local textLength = utf8Strlen(self.text) |
584 | if self.maxCharacters == nil or textLength < self.maxCharacters then |
585 | self.text = |
586 | ((self.cursorPosition > 1) and utf8Substr(self.text, 0, self.cursorPosition - 1) or "") .. |
587 | unicodeToUtf8(unicode) .. |
588 | ((self.cursorPosition <= textLength) and utf8Substr(self.text, self.cursorPosition - 1) or "") |
589 | |
590 | self.cursorPosition = self.cursorPosition + 1 |
591 | |
592 | self:raiseCallback("onTextChangedCallback", self, self.text) |
593 | end |
594 | end |
595 | end |
596 | |
597 | self:updateVisibleTextElements() |
598 | |
599 | eventUsed = true |
600 | end |
601 | end |
602 | |
603 | return eventUsed |
604 | end |
limitTextToAvailableWidth
DescriptionDefinitionlimitTextToAvailableWidth()Code
978 | function TextInputElement.limitTextToAvailableWidth(text, textSize, availableWidth, trimFront) |
979 | local resultingText = text |
980 | local indexOfFirstCharacter = 0 |
981 | local indexOfLastCharacter = utf8Strlen(text) |
982 | |
983 | if availableWidth then |
984 | if trimFront then |
985 | while getTextWidth(textSize, resultingText) > availableWidth do |
986 | --print("1a limiting text : " .. resultingText) |
987 | resultingText = utf8Substr(resultingText, 1) |
988 | indexOfFirstCharacter = indexOfFirstCharacter + 1 |
989 | --print("1b limiting text : " .. resultingText) |
990 | end |
991 | else |
992 | local textLength = utf8Strlen(resultingText) |
993 | while getTextWidth(textSize, resultingText) > availableWidth do |
994 | --print("2a limiting text : " .. resultingText) |
995 | textLength = textLength - 1 |
996 | resultingText = utf8Substr(resultingText, 0, textLength) |
997 | indexOfLastCharacter = indexOfLastCharacter - 1 |
998 | --print("2b limiting text : " .. resultingText) |
999 | end |
1000 | end |
1001 | end |
1002 | |
1003 | return resultingText, indexOfFirstCharacter, indexOfLastCharacter |
1004 | end |
loadFromXML
DescriptionDefinitionloadFromXML()Code
105 | function TextInputElement:loadFromXML(xmlFile, key) |
106 | TextInputElement:superClass().loadFromXML(self, xmlFile, key) |
107 | |
108 | self:addCallback(xmlFile, key.."#onEnter", "onEnterCallback") |
109 | self:addCallback(xmlFile, key.."#onTextChanged", "onTextChangedCallback") |
110 | self:addCallback(xmlFile, key.."#onEnterPressed", "onEnterPressedCallback") |
111 | self:addCallback(xmlFile, key.."#onEscPressed", "onEscPressedCallback") |
112 | self:addCallback(xmlFile, key.."#onIsUnicodeAllowed", "onIsUnicodeAllowedCallback") |
113 | |
114 | self.imeKeyboardType = Utils.getNoNil(getXMLString(xmlFile, key.."#imeKeyboardType"), self.imeKeyboardType) |
115 | self.imeTitle = self:translate(getXMLString(xmlFile, key.."#imeTitle")) |
116 | self.imeDescription = self:translate(getXMLString(xmlFile, key.."#imeDescription")) |
117 | self.imePlaceholder = self:translate(getXMLString(xmlFile, key.."#imePlaceholder")) |
118 | |
119 | self.maxCharacters = Utils.getNoNil(getXMLInt(xmlFile, key.."#maxCharacters"), self.maxCharacters) |
120 | self.maxInputTextWidth = unpack(GuiUtils.getNormalizedValues(getXMLString(xmlFile, key.."#maxInputTextWidth"), {self.outputSize[1]}, {self.maxInputTextWidth})) |
121 | self.cursorOffset = GuiUtils.getNormalizedValues(getXMLString(xmlFile, key.."#cursorOffset"), self.outputSize, self.cursorOffset) |
122 | self.cursorSize = GuiUtils.getNormalizedValues(getXMLString(xmlFile, key.."#cursorSize"), self.outputSize, self.cursorSize) |
123 | |
124 | if g_screenWidth > 1 then |
125 | self.cursorSize[1] = math.max(self.cursorSize[1], 1 / g_screenWidth) |
126 | end |
127 | |
128 | self.enterWhenClickOutside = Utils.getNoNil(getXMLBool(xmlFile, key .. "#enterWhenClickOutside"), self.enterWhenClickOutside) |
129 | |
130 | GuiOverlay.loadOverlay(self, self.cursor, "cursor", self.imageSize, nil, xmlFile, key) |
131 | GuiOverlay.createOverlay(self.cursor) |
132 | |
133 | self.isPassword = Utils.getNoNil(getXMLBool(xmlFile, key .. "#isPassword"), self.isPassword) |
134 | |
135 | self:finalize() |
136 | end |
loadProfile
DescriptionDefinitionloadProfile()Code
140 | function TextInputElement:loadProfile(profile, applyProfile) |
141 | TextInputElement:superClass().loadProfile(self, profile, applyProfile) |
142 | |
143 | self.maxCharacters = profile:getNumber("maxCharacters", self.maxCharacters) |
144 | self.maxInputTextWidth = unpack(GuiUtils.getNormalizedValues(profile:getValue("maxInputTextWidth"), {self.outputSize[1]}, {self.maxInputTextWidth})) |
145 | self.cursorOffset = GuiUtils.getNormalizedValues(profile:getValue("cursorOffset"), self.outputSize, self.cursorOffset) |
146 | self.cursorSize = GuiUtils.getNormalizedValues(profile:getValue("cursorSize"), self.outputSize, self.cursorSize) |
147 | self.isPassword = profile:getBool("isPassword", self.isPassword) |
148 | |
149 | GuiOverlay.loadOverlay(self, self.cursor, "cursor", self.imageSize, profile, nil, nil) |
150 | |
151 | if g_screenWidth > 1 then |
152 | self.cursorSize[1] = math.max(self.cursorSize[1], 1 / g_screenWidth) |
153 | end |
154 | |
155 | if applyProfile then |
156 | self:applyTextInputAspectScale() |
157 | end |
158 | |
159 | self:finalize() |
160 | end |
mouseEvent
DescriptionDefinitionmouseEvent()Code
365 | function TextInputElement:mouseEvent(posX, posY, isDown, isUp, button, eventUsed) |
366 | if self:getIsActive() then |
367 | local isCursorInside = GuiUtils.checkOverlayOverlap(posX, posY, self.absPosition[1], self.absPosition[2], self.size[1], self.size[2]) |
368 | |
369 | if not self.forcePressed then |
370 | if eventUsed then |
371 | self:setOverlayState(GuiOverlay.STATE_NORMAL) |
372 | end |
373 | |
374 | if not eventUsed and isCursorInside and not FocusManager:isLocked() then |
375 | FocusManager:setHighlight(self) |
376 | |
377 | eventUsed = true |
378 | if self:getOverlayState() == GuiOverlay.STATE_NORMAL then |
379 | self:setOverlayState(GuiOverlay.STATE_FOCUSED) |
380 | end |
381 | |
382 | if isDown and button == Input.MOUSE_BUTTON_LEFT then |
383 | self.textInputMouseDown = true |
384 | |
385 | if not self.useIme then |
386 | self:setOverlayState(GuiOverlay.STATE_PRESSED) |
387 | end |
388 | end |
389 | |
390 | if isUp and button == Input.MOUSE_BUTTON_LEFT and self.textInputMouseDown then |
391 | self.textInputMouseDown = false |
392 | |
393 | self:setOverlayState(GuiOverlay.STATE_PRESSED) |
394 | self:setForcePressed(true) |
395 | if self.useIme then |
396 | self:openIme() |
397 | end |
398 | end |
399 | else |
400 | if (isDown and button == Input.MOUSE_BUTTON_LEFT) or self.textInputMouseDown or self:getOverlayState() ~= GuiOverlay.STATE_PRESSED then |
401 | FocusManager:unsetHighlight(self) |
402 | end |
403 | |
404 | self.textInputMouseDown = false |
405 | end |
406 | elseif self.enterWhenClickOutside then |
407 | if not isCursorInside and isUp and button == Input.MOUSE_BUTTON_LEFT then |
408 | -- Dismiss when clicking outside of the box |
409 | self:abortIme() |
410 | self:setForcePressed(false) |
411 | |
412 | |
413 | self:raiseCallback("onEnterPressedCallback", self, true) |
414 | end |
415 | end |
416 | |
417 | if not eventUsed then |
418 | eventUsed = TextInputElement:superClass().mouseEvent(self, posX, posY, isDown, isUp, button, eventUsed) |
419 | end |
420 | end |
421 | |
422 | return eventUsed |
423 | end |
moveCursorLeft
DescriptionDefinitionmoveCursorLeft()Code
427 | function TextInputElement:moveCursorLeft() |
428 | self:setCursorPosition(self.cursorPosition - 1) |
429 | end |
moveCursorRight
DescriptionDefinitionmoveCursorRight()Code
433 | function TextInputElement:moveCursorRight() |
434 | self:setCursorPosition(self.cursorPosition + 1) |
435 | end |
new
DescriptionDefinitionnew()Code
38 | function TextInputElement.new(target, custom_mt) |
39 | local self = ButtonElement.new(target, custom_mt or TextInputElement_mt) |
40 | |
41 | self.textInputMouseDown = false |
42 | self.forcePressed = false |
43 | self.isPassword = false |
44 | self.displayText = "" -- actually displayed text, masked if this is a password input field |
45 | self.cursor = {} |
46 | self.cursorBlinkTime = 0 |
47 | self.cursorBlinkInterval = 400 |
48 | self.cursorOffset = {0,0} |
49 | self.cursorSize = {0.0016, 0.018} |
50 | self.cursorNeededSize = { |
51 | self.cursorOffset[1] + self.cursorSize[1], |
52 | self.cursorOffset[2] + self.cursorSize[2] |
53 | } |
54 | self.cursorPosition = 1 |
55 | self.firstVisibleCharacterPosition = 1 |
56 | self.lastVisibleCharacterPosition = 1 |
57 | self.maxCharacters = nil |
58 | self.maxInputTextWidth = nil |
59 | self.frontDotsText = "..." |
60 | self.backDotsText = "..." |
61 | self.text = "" |
62 | self.useIme = imeIsSupported() |
63 | self.preImeText = "" |
64 | self.imeActive = false |
65 | self.blockTime = 0 |
66 | |
67 | self.isReturnDown = false |
68 | self.isEscDown = false |
69 | self.isCapturingInput = false |
70 | self.hadFocusOnCapture = false |
71 | self.enterWhenClickOutside = true |
72 | |
73 | -- Handle hightlight on focused elements differently: if highlight is removed, |
74 | -- do not change focus. |
75 | self.disallowFocusedHighlight = true |
76 | |
77 | self.imeKeyboardType = "normal" |
78 | |
79 | self.forceFocus = true |
80 | |
81 | self.customFocusSample = GuiSoundPlayer.SOUND_SAMPLES.TEXTBOX |
82 | |
83 | return self |
84 | end |
onClose
DescriptionDefinitiononClose()Code
787 | function TextInputElement:onClose() |
788 | TextInputElement:superClass().onClose(self) |
789 | -- makes sure that the input mode is disabled when clicking directly on a "back" button while text input is active |
790 | self:abortIme() |
791 | self:setForcePressed(false) |
792 | end |
onFocusActivate
DescriptionDefinitiononFocusActivate()Code
767 | function TextInputElement:onFocusActivate() |
768 | if self.blockTime <= 0 then |
769 | TextInputElement:superClass().onFocusActivate(self) |
770 | self:raiseCallback("onEnterCallback", self) |
771 | |
772 | if self.forcePressed then |
773 | self:abortIme() |
774 | -- deactivate input |
775 | self:setForcePressed(false) |
776 | self:setOverlayState(TextInputElement.STATE_FOCUSED) |
777 | self:raiseCallback("onEnterPressedCallback", self) |
778 | else |
779 | self:openIme() |
780 | self:setForcePressed(true) |
781 | end |
782 | end |
783 | end |
onFocusLeave
DescriptionDefinitiononFocusLeave()Code
759 | function TextInputElement:onFocusLeave() |
760 | self:abortIme() |
761 | self:setForcePressed(false) |
762 | TextInputElement:superClass().onFocusLeave(self) |
763 | end |
openIme
DescriptionDefinitionopenIme()Code
494 | function TextInputElement:openIme() |
495 | if self.useIme and imeOpen(self.text, self.imeTitle or "", self.imeDescription or "", self.imePlaceholder or "", self.imeKeyboardType or "normal", Utils.getNoNil(self.maxCharacters, 512), self.absPosition[1], self.absPosition[2], self.size[1], self.size[2]) then |
496 | self.imeActive = true |
497 | self.preImeText = self.text |
498 | return true |
499 | end |
500 | return false |
501 | end |
reset
DescriptionDefinitionreset()Code
296 | function TextInputElement:reset() |
297 | TextInputElement:superClass().reset(self) |
298 | |
299 | if self.isRepeatingSpecialKeyDown then |
300 | self:stopSpecialKeyRepeating() |
301 | end |
302 | end |
setAlpha
DescriptionDefinitionsetAlpha()Code
281 | function TextInputElement:setAlpha(alpha) |
282 | TextInputElement:superClass().setAlpha(self, alpha) |
283 | if self.cursor ~= nil then |
284 | self.cursor.alpha = self.alpha |
285 | end |
286 | end |
setCaptureInput
DescriptionSet input capturing state. When capturing, the standard input bindings are disabled (input context switch).Definition
setCaptureInput()Code
238 | function TextInputElement:setCaptureInput(isCapturing) |
239 | self.blockTime = 200 |
240 | if not self.isCapturingInput and isCapturing then |
241 | -- reset control key flags to avoid immediately returning out of edit mode: |
242 | self.isReturnDown = false |
243 | self.isEscDown = false |
244 | |
245 | self.target:disableInputForDuration(0) |
246 | |
247 | if TextInputElement.inputContextActive then |
248 | -- Special case handling for mouse click activation of text input elements. Because of the call order, |
249 | -- another text element may previously have been active when this one has been activated by click. Avoid |
250 | -- corrupting the input context by reverting here first. |
251 | g_inputBinding:revertContext(true) |
252 | end |
253 | |
254 | g_inputBinding:setContext(TextInputElement.INPUT_CONTEXT_NAME, true, false) |
255 | TextInputElement.inputContextActive = true |
256 | |
257 | if not GS_IS_CONSOLE_VERSION then |
258 | -- Special case handling for gaming stations which do not have keyboards available for players: |
259 | -- Register menu back and accept actions so players can exit text boxes with gamepads using either input, |
260 | -- by default bound to buttons "A" for accept and "B" for back. |
261 | g_inputBinding:registerActionEvent(InputAction.MENU_BACK, self, self.inputEvent, false, true, false, true) |
262 | g_inputBinding:registerActionEvent(InputAction.MENU_ACCEPT, self, self.inputEvent, false, true, false, true) |
263 | end |
264 | |
265 | self.isCapturingInput = true |
266 | elseif self.isCapturingInput and not isCapturing then |
267 | if TextInputElement.inputContextActive then |
268 | -- Special case handling for mouse click activation of text input elements. Ensure to avoid double reverts |
269 | -- when switching from one text input to another. |
270 | g_inputBinding:revertContext(true) -- revert and clear text input context |
271 | TextInputElement.inputContextActive = false |
272 | end |
273 | |
274 | self.target:disableInputForDuration(200) |
275 | self.isCapturingInput = false |
276 | end |
277 | end |
setCursorPosition
DescriptionDefinitionsetCursorPosition()Code
439 | function TextInputElement:setCursorPosition(position) |
440 | self.cursorPosition = math.max(1, math.min(utf8Strlen(self.text) + 1, position)) |
441 | end |
setForcePressed
DescriptionDefinitionsetForcePressed()Code
321 | function TextInputElement:setForcePressed(force) |
322 | if force then |
323 | self.hadFocusOnCapture = self:getOverlayState() == GuiOverlay.STATE_FOCUSED |
324 | self:setCaptureInput(true) |
325 | else |
326 | self:setCaptureInput(false) |
327 | end |
328 | |
329 | self.forcePressed = force |
330 | if self.forcePressed then |
331 | FocusManager:setFocus(self) |
332 | self:setOverlayState(GuiOverlay.STATE_PRESSED) |
333 | else |
334 | local newState = GuiOverlay.STATE_NORMAL |
335 | if self.hadFocusOnCapture then |
336 | newState = GuiOverlay.STATE_FOCUSED |
337 | self.hadFocusOnCapture = false |
338 | end |
339 | |
340 | self:setOverlayState(newState) |
341 | end |
342 | |
343 | if self.isRepeatingSpecialKeyDown then |
344 | self:stopSpecialKeyRepeating() |
345 | end |
346 | |
347 | self:updateVisibleTextElements() |
348 | end |
setText
DescriptionDefinitionsetText()Code
306 | function TextInputElement:setText(text) |
307 | local textLength = utf8Strlen(text) |
308 | if self.maxCharacters and textLength > self.maxCharacters then |
309 | text = utf8Substr(text, 0, self.maxCharacters) |
310 | textLength = utf8Strlen(text) |
311 | end |
312 | |
313 | TextInputElement:superClass().setText(self, text) |
314 | |
315 | self.cursorPosition = textLength + 1 |
316 | self:updateVisibleTextElements() |
317 | end |
shouldFocusChange
DescriptionFocus methodsDefinition
shouldFocusChange()Code
753 | function TextInputElement:shouldFocusChange(direction) |
754 | return not self.forcePressed |
755 | end |
stopSpecialKeyRepeating
DescriptionDefinitionstopSpecialKeyRepeating()Code
485 | function TextInputElement:stopSpecialKeyRepeating() |
486 | self.isRepeatingSpecialKeyDown = false |
487 | self.repeatingSpecialKeySym = nil |
488 | self.repeatingSpecialKeyDelayTime = nil |
489 | self.repeatingSpecialKeyRemainingDelayTime = nil |
490 | end |
translate
DescriptionDefinitiontranslate()Code
96 | function TextInputElement:translate(str) |
97 | if str then |
98 | str = g_i18n:convertText(str) |
99 | end |
100 | return str |
101 | end |
update
DescriptionDefinitionupdate()Code
638 | function TextInputElement:update(dt) |
639 | TextInputElement:superClass().update(self, dt) |
640 | |
641 | self.cursorBlinkTime = self.cursorBlinkTime+dt |
642 | while self.cursorBlinkTime > 2*self.cursorBlinkInterval do |
643 | self.cursorBlinkTime = self.cursorBlinkTime - 2*self.cursorBlinkInterval |
644 | end |
645 | |
646 | if self.isRepeatingSpecialKeyDown then |
647 | self.repeatingSpecialKeyRemainingDelayTime = self.repeatingSpecialKeyRemainingDelayTime - dt |
648 | if self.repeatingSpecialKeyRemainingDelayTime <= 0 then |
649 | if self.repeatingSpecialKeySym == Input.KEY_left then |
650 | self:moveCursorLeft() |
651 | elseif self.repeatingSpecialKeySym == Input.KEY_right then |
652 | self:moveCursorRight() |
653 | elseif self.repeatingSpecialKeySym == Input.KEY_delete then |
654 | self:deleteText(true) |
655 | elseif self.repeatingSpecialKeySym == Input.KEY_backspace then |
656 | self:deleteText(false) |
657 | end |
658 | self:updateVisibleTextElements() |
659 | |
660 | -- reduce key delay each frame down to the minimum to accelerate input when holding control keys |
661 | self.repeatingSpecialKeyDelayTime = math.max(TextInputElement.MIN_REPEAT_DELAY, (self.repeatingSpecialKeyDelayTime or TextInputElement.INITIAL_REPEAT_DELAY) * (0.1^(dt/100))) |
662 | self.repeatingSpecialKeyRemainingDelayTime = self.repeatingSpecialKeyDelayTime |
663 | end |
664 | end |
665 | if self.useIme and self.imeActive then |
666 | local done,cancel = imeIsComplete() |
667 | if done then |
668 | self.imeActive = false |
669 | |
670 | self:setForcePressed(false) |
671 | if not cancel then |
672 | self:setText(imeGetLastString()) |
673 | self:raiseCallback("onEnterPressedCallback", self) |
674 | else |
675 | self:setText(self.preImeText) |
676 | self.preImeText = "" |
677 | self:raiseCallback("onEscPressedCallback", self) |
678 | end |
679 | else |
680 | self:setText(imeGetLastString()) |
681 | self:setCursorPosition(imeGetCursorPos()+1) |
682 | self:updateVisibleTextElements() |
683 | end |
684 | end |
685 | |
686 | if self.blockTime > 0 then |
687 | self.blockTime = self.blockTime - dt |
688 | end |
689 | end |
updateVisibleTextElements
DescriptionDefinitionupdateVisibleTextElements()Code
835 | function TextInputElement:updateVisibleTextElements() |
836 | self.isCursorVisible = false |
837 | self.isVisibleTextPart1Visible = false |
838 | self.visibleTextPart1 = "" |
839 | self.isVisibleTextPart2Visible = false |
840 | self.visibleTextPart2 = "" |
841 | |
842 | self.areFrontDotsVisible = false |
843 | self.areBackDotsVisible = false |
844 | |
845 | self.firstVisibleCharacterPosition = 1 |
846 | |
847 | setTextBold(self.textBold) |
848 | |
849 | local displayText = self.text |
850 | if self.isPassword then |
851 | displayText = string.rep("*", utf8Strlen(self.text)) |
852 | end |
853 | |
854 | local textLength = utf8Strlen(displayText) |
855 | local availableTextWidth = self:getAvailableTextWidth() |
856 | |
857 | if self:getIsActive() and self:getOverlayState() == GuiOverlay.STATE_PRESSED then |
858 | -- input is gathered, cursor is shown, |
859 | -- text is displayed at an arbitrary position, both additonal text markers may be displayed |
860 | |
861 | self.isCursorVisible = true |
862 | |
863 | if self.cursorPosition < self.firstVisibleCharacterPosition then |
864 | -- cursor was moved to the left to display additional text |
865 | self.firstVisibleCharacterPosition = self.cursorPosition |
866 | end |
867 | |
868 | if self.firstVisibleCharacterPosition > 1 then |
869 | self.areFrontDotsVisible = true |
870 | end |
871 | |
872 | local textInvisibleFrontTrimmed = utf8Substr(displayText, self.firstVisibleCharacterPosition-1) |
873 | local textWidthInvisibleFrontTrimmed = getTextWidth(self.textSize, textInvisibleFrontTrimmed) |
874 | availableTextWidth = self:getAvailableTextWidth() |
875 | |
876 | if availableTextWidth and textWidthInvisibleFrontTrimmed > availableTextWidth then |
877 | -- not all text fits into the visible area |
878 | if self.cursorPosition <= textLength then |
879 | -- the cursor is not at the last position of the text |
880 | --self.isBackAdditionalTextMarkerVisible = true |
881 | self.areBackDotsVisible = true |
882 | availableTextWidth = self:getAvailableTextWidth() |
883 | end |
884 | end |
885 | |
886 | |
887 | local visibleText = TextInputElement.limitTextToAvailableWidth(textInvisibleFrontTrimmed, self.textSize, availableTextWidth) |
888 | local visibleTextWidth = getTextWidth(self.textSize, visibleText) |
889 | local visibleTextLength = utf8Strlen(visibleText) |
890 | |
891 | if availableTextWidth and self.cursorPosition > self.firstVisibleCharacterPosition + visibleTextLength then |
892 | -- the cursor is on the right side and not visible anymore |
893 | -- text has to be shifted for the cursor to become visible again |
894 | --self.isFrontAdditionalTextMarkerVisible = true |
895 | self.areFrontDotsVisible = true |
896 | availableTextWidth = self:getAvailableTextWidth() |
897 | |
898 | local textTrimmedAtCursor = utf8Substr(textInvisibleFrontTrimmed, 0, self.cursorPosition - self.firstVisibleCharacterPosition) |
899 | visibleText = TextInputElement.limitTextToAvailableWidth( |
900 | textTrimmedAtCursor, self.textSize, availableTextWidth, true) |
901 | visibleTextWidth = getTextWidth(self.textSize, visibleText) |
902 | visibleTextLength = utf8Strlen(visibleText) |
903 | self.firstVisibleCharacterPosition = self.cursorPosition - visibleTextLength |
904 | end |
905 | |
906 | if availableTextWidth and not self.areBackDotsVisible and self.firstVisibleCharacterPosition > 1 then |
907 | -- check if there is still room for additonal characters (can happen if text gets deleted) |
908 | local lastCharacterPosition = visibleTextLength + self.firstVisibleCharacterPosition |
909 | local nextCharacter = utf8Substr(displayText, self.firstVisibleCharacterPosition - 1, 1) |
910 | local additionalCharacterWidth = getTextWidth(self.textSize, nextCharacter) |
911 | if visibleTextWidth + additionalCharacterWidth <= availableTextWidth and self.firstVisibleCharacterPosition > 1 then |
912 | while visibleTextWidth + additionalCharacterWidth <= availableTextWidth and self.firstVisibleCharacterPosition > 1 do |
913 | -- there is still room for additonal characters |
914 | self.firstVisibleCharacterPosition = self.firstVisibleCharacterPosition - 1 |
915 | visibleTextWidth = visibleTextWidth + additionalCharacterWidth |
916 | nextCharacter = utf8Substr(displayText, self.firstVisibleCharacterPosition - 1, 1) |
917 | additionalCharacterWidth = getTextWidth(self.textSize, nextCharacter) |
918 | end |
919 | |
920 | if self.firstVisibleCharacterPosition > 1 then |
921 | self.areFrontDotsVisible = false |
922 | local availableWidthWithoutFrontDots = self:getAvailableTextWidth() |
923 | self.areFrontDotsVisible = true |
924 | local neededWidthForCompleteText = getTextWidth(self.textSize, displayText) |
925 | if neededWidthForCompleteText <= availableWidthWithoutFrontDots then |
926 | self.areFrontDotsVisible = false |
927 | self.firstVisibleCharacterPosition = 1 |
928 | end |
929 | else |
930 | -- all characters are visible |
931 | self.areFrontDotsVisible = false |
932 | end |
933 | |
934 | visibleText = utf8Substr(displayText, self.firstVisibleCharacterPosition - 1, lastCharacterPosition) |
935 | end |
936 | end |
937 | |
938 | |
939 | self.isVisibleTextPart1Visible = true |
940 | self.visibleTextPart1 = utf8Substr(visibleText, 0, self.cursorPosition - self.firstVisibleCharacterPosition) |
941 | if visibleTextLength > self.cursorPosition - self.firstVisibleCharacterPosition then |
942 | self.isVisibleTextPart2Visible = true |
943 | self.visibleTextPart2 = utf8Substr(visibleText, self.cursorPosition - self.firstVisibleCharacterPosition) |
944 | end |
945 | |
946 | else |
947 | -- input is not gathered, cursor is not shown, |
948 | -- text is displayed from its beginning, only back additonal text marker may be displayed if text is too long |
949 | local textWidth = getTextWidth(self.textSize, displayText) |
950 | -- check if additional text marker has to be displayed |
951 | if availableTextWidth and textWidth > availableTextWidth then |
952 | --self.isBackAdditionalTextMarkerVisible = true |
953 | self.areBackDotsVisible = true |
954 | availableTextWidth = self:getAvailableTextWidth() |
955 | end |
956 | |
957 | -- set visible text |
958 | if availableTextWidth and textWidth > availableTextWidth then |
959 | -- not all text fits into the visible area |
960 | self.visibleTextPart1 = TextInputElement.limitTextToAvailableWidth(displayText, self.textSize, availableTextWidth) |
961 | self.isVisibleTextPart1Visible = true |
962 | else |
963 | -- all text fits into the visible area |
964 | self.visibleTextPart1 = displayText |
965 | self.isVisibleTextPart1Visible = true |
966 | end |
967 | end |
968 | setTextBold(false) |
969 | |
970 | -- print(string.format("updateVisibleTextElements finished :")) |
971 | -- print(string.format( |
972 | -- "text: %s - cursorPosition: %d - firstVisibleCharacterPosition: %d - areFrontDotsVisible: %s - isVisibleTextPart1Visible: %s - visibleTextPart1: %s - isCursorVisible: %s - isVisibleTextPart2Visible: %s - visibleTextPart2: %s - areBackDotsVisible: %s", |
973 | -- self.text, self.cursorPosition, self.firstVisibleCharacterPosition, tostring(self.areFrontDotsVisible), tostring(self.isVisibleTextPart1Visible), self.visibleTextPart1, tostring(self.isCursorVisible), tostring(self.isVisibleTextPart2Visible), self.visibleTextPart2, tostring(self.areBackDotsVisible))) |
974 | end |