LUADOC - Farming Simulator 19

Script v1.7.1.0

Engine v1.7.1.0

Foundation Reference

TextInputElement

Description
Text input element which captures strings from player input. Used layers: "cursor" for a text input cursor icon. TODO: IME property docs
Parent
ButtonElement
XML Configuration Parameters
GuiElement#imeKeyboardTypestring [optional] Input method editor keyboard type, defaults to "normal". TODO: add valid types based on engine code
GuiElement#imeTitlestring
GuiElement#imeDescriptionstring
GuiElement#imePlaceholderstring
GuiElement#maxCharactersint [optional] Maximum number of characters to allow as input, defaults to 512.
GuiElement#maxInputTextWidthstring [optional] Maximum pixel width of input text in reference resolution. Must be defined when text alignment is not "left". Format: "[width]px"
GuiElement#cursorOffsetstring [optional] Pixel offset of input cursor icon in text element in reference resolution, defaults to [0, 0]. Format: "[x]px y[px]"
GuiElement#cursorSizestring [optional] Pixel size of input cursor icon in text element in reference resolution. Format: "[width]px [height]px"
GuiElement#isPasswordbool [optional] If true, will behave as password input and mask characters, defaults to false.

Functions

abortIme

Description
Definition
abortIme()
Code
491function TextInputElement:abortIme()
492 if self.useIme and self.imeActive then
493 self.imeActive = false
494 self.preImeText = ""
495 imeAbort()
496 end
497end

applyScreenAlignment

Description
Definition
applyScreenAlignment()
Code
193function TextInputElement:applyScreenAlignment()
194 self:applyTextInputAspectScale()
195
196 TextInputElement:superClass().applyScreenAlignment(self)
197end

applyTextInputAspectScale

Description
Definition
applyTextInputAspectScale()
Code
180function TextInputElement:applyTextInputAspectScale()
181 local xScale, yScale = self:getAspectScale()
182
183 self.cursorOffset[1] = self.cursorOffset[1] * xScale
184 self.cursorSize[1] = self.cursorSize[1] * xScale
185 self.maxInputTextWidth = self.maxInputTextWidth * xScale
186
187 self.cursorOffset[2] = self.cursorOffset[2] * yScale
188 self.cursorSize[2] = self.cursorSize[2] * yScale
189end

copyAttributes

Description
Definition
copyAttributes()
Code
151function TextInputElement:copyAttributes(src)
152 TextInputElement:superClass().copyAttributes(self, src)
153
154 self.imeKeyboardType = src.imeKeyboardType
155 self.imeTitle = src.imeTitle
156 self.imeDescription = src.imeDescription
157 self.imePlaceholder = src.imePlaceholder
158
159 self.maxCharacters = src.maxCharacters
160 self.maxInputTextWidth = src.maxInputTextWidth
161
162 GuiOverlay.copyOverlay(self.cursor, src.cursor)
163 self.cursorOffset = ListUtil.copyTable(src.cursorOffset)
164 self.cursorSize = ListUtil.copyTable(src.cursorSize)
165 self.isPassword = src.isPassword
166
167 self.onEnterCallback = src.onEnterCallback
168 self.onTextChangedCallback = src.onTextChangedCallback
169 self.onEnterPressedCallback = src.onEnterPressedCallback
170 self.onEscPressedCallback = src.onEscPressedCallback
171 self.onIsUnicodeAllowedCallback = src.onIsUnicodeAllowedCallback
172
173 self.enterWhenClickOutside = src.enterWhenClickOutside
174
175 self:finalize()
176end

delete

Description
Definition
delete()
Code
83function TextInputElement:delete()
84 self:abortIme()
85 GuiOverlay.deleteOverlay(self.cursor)
86 TextInputElement:superClass().delete(self)
87end

deleteText

Description
Definition
deleteText()
Code
431function TextInputElement:deleteText(deleteRightCharacterFromCursor)
432 local textLength = utf8Strlen(self.text)
433
434 if textLength > 0 then
435 local canDelete = false
436 local deleteOffset
437
438 if deleteRightCharacterFromCursor then
439 if self.cursorPosition <= textLength then
440 canDelete = true
441 deleteOffset = 0
442 end
443 else
444 if self.cursorPosition > 1 then
445 canDelete = true
446 deleteOffset = -1
447 end
448 end
449
450 if canDelete then
451 --[[
452 print(string.format(
453 "self.cursorPosition %d, deleteOffset %d, textLength %d, prestring : %s, poststring : %s",
454 self.cursorPosition, deleteOffset, textLength,
455 tostring(utf8Substr(self.text, 0, self.cursorPosition + deleteOffset - 1)),
456 tostring(utf8Substr(self.text, self.cursorPosition + deleteOffset, -1))))
457 --]]
458 self.text =
459 (((self.cursorPosition + deleteOffset) > 1) and utf8Substr(self.text, 0, self.cursorPosition + deleteOffset - 1) or "") ..
460 (((self.cursorPosition + deleteOffset) < textLength) and utf8Substr(self.text, self.cursorPosition + deleteOffset, -1) or "")
461 self.cursorPosition = self.cursorPosition + deleteOffset
462 --print("final text : " .. self.text)
463
464 self:raiseCallback("onTextChangedCallback", self, self.text)
465 end
466 end
467end

draw

Description
Definition
draw()
Code
683function TextInputElement:draw()
684 -- call ancestor drawing functions with empty text:
685 local text = self.text
686 self.text = ""
687 TextInputElement:superClass().draw(self)
688 self.text = text
689
690 setTextAlignment(self.textAlignment)
691 local neededWidth = self:getNeededTextWidth()
692
693 local textXPos = self.absPosition[1] + self.textOffset[1]
694 if self.textAlignment == RenderText.ALIGN_CENTER then
695 textXPos = textXPos + (self.maxInputTextWidth * 0.5) - (neededWidth * 0.5)
696 elseif self.textAlignment == RenderText.ALIGN_RIGHT then
697 textXPos = textXPos + self.maxInputTextWidth - neededWidth
698 end
699 textXPos = textXPos + (self.size[1]-self.maxInputTextWidth) / 2
700
701 local _, yOffset = self:getTextOffset()
702 local _, yPos = self:getTextPosition(self.text)
703 local textYPos = yPos + yOffset
704
705 local displacementX = 0
706 if (self.areFrontDotsVisible) then
707 local additionalDisplacement = self:drawTextPart(self.frontDotsText, textXPos, displacementX, textYPos)
708 displacementX = displacementX + additionalDisplacement
709 end
710 if (self.isVisibleTextPart1Visible) then
711 local additionalDisplacement = self:drawTextPart(self.visibleTextPart1, textXPos, displacementX, textYPos)
712 displacementX = displacementX + additionalDisplacement
713 end
714 if (self.isCursorVisible) then
715 local additionalDisplacement = self:drawCursor(textXPos, displacementX, textYPos)
716 displacementX = displacementX + additionalDisplacement
717 end
718 if (self.isVisibleTextPart2Visible) then
719 local additionalDisplacement = self:drawTextPart(self.visibleTextPart2, textXPos, displacementX, textYPos)
720 displacementX = displacementX + additionalDisplacement
721 end
722
723 if (self.areBackDotsVisible) then
724 local additionalDisplacement = self:drawTextPart(self.backDotsText, textXPos, displacementX, textYPos)
725 displacementX = displacementX + additionalDisplacement
726 end
727
728 setTextBold(false)
729 setTextAlignment(RenderText.ALIGN_LEFT)
730 setTextColor(1, 1, 1, 1)
731end

drawCursor

Description
Definition
drawCursor()
Code
806function TextInputElement:drawCursor(textXPos, displacementX, textYPos)
807 if self.cursorBlinkTime < self.cursorBlinkInterval then
808 GuiOverlay.renderOverlay(self.cursor, textXPos + displacementX + self.cursorOffset[1], textYPos + self.cursorOffset[2], self.cursorSize[1], self.cursorSize[2])
809 end
810
811 return self.cursorNeededSize[1]
812end

drawTextPart

Description
Definition
drawTextPart()
Code
779function TextInputElement:drawTextPart(text, textXPos, displacementX, textYPos)
780 local textWidth = 0
781 if text ~= "" then
782 setTextBold(self.textBold)
783 textWidth = getTextWidth(self.textSize, text)
784 local alignmentDisplacement = 0
785 if self.textAlignment == RenderText.ALIGN_CENTER then
786 alignmentDisplacement = textWidth * 0.5
787 elseif self.textAlignment == RenderText.ALIGN_RIGHT then
788 alignmentDisplacement = textWidth
789 end
790
791 if self.text2Size > 0 then
792 setTextBold(self.text2Bold)
793 setTextColor(unpack(self:getText2Color()))
794 renderText(textXPos + alignmentDisplacement + displacementX + (self.text2Offset[1] - self.textOffset[1]), textYPos + (self.text2Offset[2] - self.textOffset[2]), self.text2Size, text)
795 end
796
797 setTextBold(self.textBold)
798 setTextColor(unpack(self:getTextColor()))
799 renderText(textXPos + alignmentDisplacement + displacementX, textYPos, self.textSize, text)
800 end
801 return textWidth
802end

finalize

Description
Definition
finalize()
Code
201function TextInputElement:finalize()
202 self.cursorNeededSize = {
203 self.cursorOffset[1] + self.cursorSize[1],
204 self.cursorOffset[2] + self.cursorSize[2]
205 }
206
207 if ((not self.maxInputTextWidth) and ((self.textAlignment == RenderText.ALIGN_CENTER) or (self.textAlignment == RenderText.ALIGN_RIGHT))) then
208 print("Error: TextInputElement loading using \"center\" or \"right\" alignment requires specification of \"maxInputTextWidth\"")
209 end
210
211 if ((self.maxInputTextWidth) and (self.maxInputTextWidth <= (getTextWidth(self.textSize, self.frontDotsText) + self.cursorNeededSize[1] + getTextWidth(self.textSize, self.backDotsText)))) then
212 print(string.format("Error: TextInputElement loading specified \"maxInputTextWidth\" is too small (%.4f) to display needed data", self.maxInputTextWidth))
213 end
214end

getAvailableTextWidth

Description
Definition
getAvailableTextWidth()
Code
989function TextInputElement:getAvailableTextWidth()
990 if not self.maxInputTextWidth then
991 return nil
992 end
993
994 local availableTextWidth = self.maxInputTextWidth
995 --if (self.isFrontAdditionalTextMarkerVisible) then
996 --end
997
998 if self.areFrontDotsVisible then
999 availableTextWidth = availableTextWidth - getTextWidth(self.textSize, self.frontDotsText)
1000 end
1001
1002 if self.isCursorVisible then
1003 availableTextWidth = availableTextWidth - self.cursorNeededSize[1]
1004 end
1005
1006 --if (self.isBackAdditionalTextMarkerVisible) then
1007 --end
1008
1009 if self.areBackDotsVisible then
1010 availableTextWidth = availableTextWidth - getTextWidth(self.textSize, self.backDotsText)
1011 end
1012
1013 return availableTextWidth
1014end

getDoRenderText

Description
Definition
getDoRenderText()
Code
277function TextInputElement:getDoRenderText()
278 return false
279end

getIsActive

Description
Definition
getIsActive()
Code
218function TextInputElement:getIsActive()
219 return GuiElement.getIsActive(self) -- parent type ButtonElement behaves incompatibly, use the base method
220end

getIsUnicodeAllowed

Description
Definition
getIsUnicodeAllowed()
Code
339function TextInputElement:getIsUnicodeAllowed(unicode)
340 if unicode == 13 or unicode == 10 then
341 return false
342 end
343 if not getCanRenderUnicode(unicode) then
344 return false
345 end
346
347 return Utils.getNoNil(self:raiseCallback("onIsUnicodeAllowedCallback", unicode), true)
348end

getNeededTextWidth

Description
Definition
getNeededTextWidth()
Code
1018function TextInputElement:getNeededTextWidth()
1019 local neededWidth = 0
1020 -- if (self.isFrontAdditionalTextMarkerVisible) then
1021 -- end
1022 if self.areFrontDotsVisible then
1023 neededWidth = neededWidth + getTextWidth(self.textSize, self.frontDotsText)
1024 end
1025
1026 if self.isVisibleTextPart1Visible then
1027 neededWidth = neededWidth + getTextWidth(self.textSize, self.visibleTextPart1)
1028 end
1029
1030 if self.isCursorVisible then
1031 neededWidth = neededWidth + self.cursorNeededSize[1]
1032 end
1033
1034 if self.isVisibleTextPart2Visible then
1035 neededWidth = neededWidth + getTextWidth(self.textSize, self.visibleTextPart2)
1036 end
1037 -- if (self.isBackAdditionalTextMarkerVisible) then
1038 -- end
1039 if self.areBackDotsVisible then
1040 neededWidth = neededWidth + getTextWidth(self.textSize, self.backDotsText)
1041 end
1042
1043 return neededWidth
1044end

keyEvent

Description
Definition
keyEvent()
Code
501function TextInputElement:keyEvent(unicode, sym, modifier, isDown, eventUsed)
502 if TextInputElement:superClass().keyEvent(self, unicode, sym, modifier, isDown, eventUsed) then
503 eventUsed = true
504 end
505
506 if self.isRepeatingSpecialKeyDown and not isDown and self.repeatingSpecialKeySym == sym then
507 self:stopSpecialKeyRepeating()
508 end
509
510 if self.blockTime <= 0 and self:getIsActive() and self:getOverlayState() == GuiOverlay.STATE_PRESSED then
511 local wasSpecialKey = false
512
513 if not isDown then
514 -- react to input state-changing keys on key "up" to avoid double inputs in the menu
515 if sym == Input.KEY_return and self.isReturnDown then
516 self.isReturnDown = false
517 self:setForcePressed(not self.forcePressed)
518 self:raiseCallback("onEnterPressedCallback", self)
519 wasSpecialKey = true
520 elseif sym == Input.KEY_esc then
521 self.isEscDown = false
522 self:setForcePressed(not self.forcePressed)
523 self:raiseCallback("onEscPressedCallback", self)
524 wasSpecialKey = true
525 end
526 else
527 local startSpecialKeyRepeating = false
528 if (sym == Input.KEY_left) then
529 --self.cursorPosition = math.max(1, self.cursorPosition - 1)
530 -- is now handled by Focus system
531 self:moveCursorLeft()
532 startSpecialKeyRepeating = true
533 wasSpecialKey = true
534 elseif (sym == Input.KEY_right) then
535 --self.cursorPosition = math.min(utf8Strlen(self.text) + 1, self.cursorPosition + 1)
536 -- is now handled by focus system
537 self:moveCursorRight()
538 startSpecialKeyRepeating = true
539 wasSpecialKey = true
540 elseif (sym == Input.KEY_home) then
541 self.cursorPosition = 1
542 wasSpecialKey = true
543 elseif (sym == Input.KEY_end) then
544 self.cursorPosition = utf8Strlen(self.text) + 1
545 wasSpecialKey = true
546 elseif (sym == Input.KEY_delete) then
547 self:deleteText(true)
548 startSpecialKeyRepeating = true
549 wasSpecialKey = true
550 elseif (sym == Input.KEY_backspace) then
551 self:deleteText(false)
552 startSpecialKeyRepeating = true
553 wasSpecialKey = true
554 elseif sym == Input.KEY_esc then
555 self.isEscDown = true
556 wasSpecialKey = true
557 elseif sym == Input.KEY_return then
558 self.isReturnDown = true
559 wasSpecialKey = true
560 end
561
562 if (startSpecialKeyRepeating) then
563 self.isRepeatingSpecialKeyDown = true
564 self.repeatingSpecialKeySym = sym
565 self.repeatingSpecialKeyDelayTime = TextInputElement.INITIAL_REPEAT_DELAY
566 self.repeatingSpecialKeyRemainingDelayTime = self.repeatingSpecialKeyDelayTime
567 end
568
569 if (not wasSpecialKey) then
570 if self:getIsUnicodeAllowed(unicode) then
571 local textLength = utf8Strlen(self.text)
572 if ((not self.maxCharacters) or (textLength < self.maxCharacters)) then
573 self.text =
574 ((self.cursorPosition > 1) and utf8Substr(self.text, 0, self.cursorPosition - 1) or "") ..
575 unicodeToUtf8(unicode) ..
576 ((self.cursorPosition <= textLength) and utf8Substr(self.text, self.cursorPosition - 1) or "")
577
578 self.cursorPosition = self.cursorPosition + 1
579
580 self:raiseCallback("onTextChangedCallback", self, self.text)
581 end
582 end
583 end
584
585 self:updateVisibleTextElements()
586
587 eventUsed = true
588 end
589 end
590
591 return eventUsed
592end

limitTextToAvailableWidth

Description
Definition
limitTextToAvailableWidth()
Code
959function TextInputElement.limitTextToAvailableWidth(text, textSize, availableWidth, trimFront)
960 local resultingText = text
961 local indexOfFirstCharacter = 0
962 local indexOfLastCharacter = utf8Strlen(text)
963
964 if availableWidth then
965 if trimFront then
966 while getTextWidth(textSize, resultingText) > availableWidth do
967 --print("1a limiting text : " .. resultingText)
968 resultingText = utf8Substr(resultingText, 1)
969 indexOfFirstCharacter = indexOfFirstCharacter + 1
970 --print("1b limiting text : " .. resultingText)
971 end
972 else
973 local textLength = utf8Strlen(resultingText)
974 while getTextWidth(textSize, resultingText) > availableWidth do
975 --print("2a limiting text : " .. resultingText)
976 textLength = textLength - 1
977 resultingText = utf8Substr(resultingText, 0, textLength)
978 indexOfLastCharacter = indexOfLastCharacter - 1
979 --print("2b limiting text : " .. resultingText)
980 end
981 end
982 end
983
984 return resultingText, indexOfFirstCharacter, indexOfLastCharacter
985end

loadFromXML

Description
Definition
loadFromXML()
Code
100function TextInputElement:loadFromXML(xmlFile, key)
101 TextInputElement:superClass().loadFromXML(self, xmlFile, key)
102
103 self:addCallback(xmlFile, key.."#onEnter", "onEnterCallback")
104 self:addCallback(xmlFile, key.."#onTextChanged", "onTextChangedCallback")
105 self:addCallback(xmlFile, key.."#onEnterPressed", "onEnterPressedCallback")
106 self:addCallback(xmlFile, key.."#onEscPressed", "onEscPressedCallback")
107 self:addCallback(xmlFile, key.."#onIsUnicodeAllowed", "onIsUnicodeAllowedCallback")
108
109 self.imeKeyboardType = Utils.getNoNil(getXMLString(xmlFile, key.."#imeKeyboardType"), self.imeKeyboardType)
110 self.imeTitle = self:translate(getXMLString(xmlFile, key.."#imeTitle"))
111 self.imeDescription = self:translate(getXMLString(xmlFile, key.."#imeDescription"))
112 self.imePlaceholder = self:translate(getXMLString(xmlFile, key.."#imePlaceholder"))
113
114 self.maxCharacters = Utils.getNoNil(getXMLInt(xmlFile, key.."#maxCharacters"), self.maxCharacters)
115 self.maxInputTextWidth = unpack(GuiUtils.getNormalizedValues(getXMLString(xmlFile, key.."#maxInputTextWidth"), {self.outputSize[1]}, {self.maxInputTextWidth}))
116 self.cursorOffset = GuiUtils.getNormalizedValues(getXMLString(xmlFile, key.."#cursorOffset"), self.outputSize, self.cursorOffset)
117 self.cursorSize = GuiUtils.getNormalizedValues(getXMLString(xmlFile, key.."#cursorSize"), self.outputSize, self.cursorSize)
118
119 self.enterWhenClickOutside = Utils.getNoNil(getXMLBool(xmlFile, key .. "#enterWhenClickOutside"), self.enterWhenClickOutside)
120
121 GuiOverlay.loadOverlay(self, self.cursor, "cursor", self.imageSize, nil, xmlFile, key)
122 GuiOverlay.createOverlay(self.cursor)
123
124 self.isPassword = Utils.getNoNil(getXMLBool(xmlFile, key .. "#isPassword"), self.isPassword)
125
126 self:finalize()
127end

loadProfile

Description
Definition
loadProfile()
Code
131function TextInputElement:loadProfile(profile, applyProfile)
132 TextInputElement:superClass().loadProfile(self, profile, applyProfile)
133
134 self.maxCharacters = profile:getNumber("maxCharacters", self.maxCharacters)
135 self.maxInputTextWidth = unpack(GuiUtils.getNormalizedValues(profile:getValue("maxInputTextWidth"), {self.outputSize[1]}, {self.maxInputTextWidth}))
136 self.cursorOffset = GuiUtils.getNormalizedValues(profile:getValue("cursorOffset"), self.outputSize, self.cursorOffset)
137 self.cursorSize = GuiUtils.getNormalizedValues(profile:getValue("cursorSize"), self.outputSize, self.cursorSize)
138 self.isPassword = profile:getBool("isPassword", self.isPassword)
139
140 GuiOverlay.loadOverlay(self, self.cursor, "cursor", self.imageSize, profile, nil, nil)
141
142 if applyProfile then
143 self:applyTextInputAspectScale()
144 end
145
146 self:finalize()
147end

mouseEvent

Description
Definition
mouseEvent()
Code
352function TextInputElement:mouseEvent(posX, posY, isDown, isUp, button, eventUsed)
353 if self:getIsActive() then
354 local isCursorInside = GuiUtils.checkOverlayOverlap(posX, posY, self.absPosition[1], self.absPosition[2], self.size[1], self.size[2])
355
356 if not self.forcePressed then
357 if eventUsed then
358 self:setOverlayState(GuiOverlay.STATE_NORMAL)
359 end
360
361 if not eventUsed and isCursorInside and not FocusManager:isLocked() then
362 FocusManager:setHighlight(self)
363
364 eventUsed = true
365 if self:getOverlayState() == GuiOverlay.STATE_NORMAL then
366 self:setOverlayState(GuiOverlay.STATE_FOCUSED)
367 end
368
369 if isDown and button == Input.MOUSE_BUTTON_LEFT then
370 self.textInputMouseDown = true
371
372 if not self.useImeForMouse then
373 self:setOverlayState(GuiOverlay.STATE_PRESSED)
374 end
375 end
376
377 if isUp and button == Input.MOUSE_BUTTON_LEFT and self.textInputMouseDown then
378 self.textInputMouseDown = false
379
380 if self.useImeForMouse then
381 self:openIme()
382 end
383 self:setOverlayState(GuiOverlay.STATE_PRESSED)
384 self:setForcePressed(true)
385 end
386 else
387 if (isDown and button == Input.MOUSE_BUTTON_LEFT) or self.textInputMouseDown or self:getOverlayState() ~= GuiOverlay.STATE_PRESSED then
388 FocusManager:unsetHighlight(self)
389 end
390
391 self.textInputMouseDown = false
392 end
393 elseif self.enterWhenClickOutside then
394 if not isCursorInside and isUp and button == Input.MOUSE_BUTTON_LEFT then
395 -- Dismiss when clicking outside of the box
396 self:abortIme()
397 self:setForcePressed(false)
398
399
400 self:raiseCallback("onEnterPressedCallback", self, true)
401 end
402 end
403
404 if not eventUsed then
405 eventUsed = TextInputElement:superClass().mouseEvent(self, posX, posY, isDown, isUp, button, eventUsed)
406 end
407 end
408
409 return eventUsed
410end

moveCursorLeft

Description
Definition
moveCursorLeft()
Code
414function TextInputElement:moveCursorLeft()
415 self:setCursorPosition(self.cursorPosition - 1)
416end

moveCursorRight

Description
Definition
moveCursorRight()
Code
420function TextInputElement:moveCursorRight()
421 self:setCursorPosition(self.cursorPosition + 1)
422end

new

Description
Definition
new()
Code
38function 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.useImeForMouse = GS_PLATFORM_TYPE == GS_PLATFORM_TYPE_GGP and self.useIme -- Stadia requires mouse to trigger ime too
64 self.preImeText = ""
65 self.imeActive = false
66 self.blockTime = 0
67
68 self.isReturnDown = false
69 self.isEscDown = false
70 self.isCapturingInput = false
71 self.hadFocusOnCapture = false
72 self.enterWhenClickOutside = true
73
74 self.imeKeyboardType = "normal"
75
76 self.forceFocus = true
77
78 return self
79end

onClose

Description
Definition
onClose()
Code
770function TextInputElement:onClose()
771 TextInputElement:superClass().onClose(self)
772 -- makes sure that the input mode is disabled when clicking directly on a "back" button while text input is active
773 self:abortIme()
774 self:setForcePressed(false)
775end

onFocusActivate

Description
Definition
onFocusActivate()
Code
750function TextInputElement:onFocusActivate()
751 if self.blockTime <= 0 then
752 TextInputElement:superClass().onFocusActivate(self)
753 self:raiseCallback("onEnterCallback", self)
754
755 if self.forcePressed then
756 self:abortIme()
757 -- deactivate input
758 self:setForcePressed(false)
759 self:setOverlayState(TextInputElement.STATE_FOCUSED)
760 self:raiseCallback("onEnterPressedCallback", self)
761 else
762 self:openIme()
763 self:setForcePressed(true)
764 end
765 end
766end

onFocusLeave

Description
Definition
onFocusLeave()
Code
742function TextInputElement:onFocusLeave()
743 self:abortIme()
744 self:setForcePressed(false)
745 TextInputElement:superClass().onFocusLeave(self)
746end

openIme

Description
Definition
openIme()
Code
480function TextInputElement:openIme()
481 if self.useIme and imeOpen(self.text, self.imeTitle, self.imeDescription, self.imePlaceholder, self.imeKeyboardType, Utils.getNoNil(self.maxCharacters, 512), self.absPosition[1], self.absPosition[2], self.size[1], self.size[2]) then
482 self.imeActive = true
483 self.preImeText = self.text
484 return true
485 end
486 return false
487end

reset

Description
Definition
reset()
Code
283function TextInputElement:reset()
284 TextInputElement:superClass().reset(self)
285
286 if (self.isRepeatingSpecialKeyDown) then
287 self:stopSpecialKeyRepeating()
288 end
289end

setAlpha

Description
Definition
setAlpha()
Code
268function TextInputElement:setAlpha(alpha)
269 TextInputElement:superClass().setAlpha(self, alpha)
270 if self.cursor ~= nil then
271 self.cursor.alpha = self.alpha
272 end
273end

setCaptureInput

Description
Set input capturing state. When capturing, the standard input bindings are disabled (input context switch).
Definition
setCaptureInput()
Code
225function TextInputElement:setCaptureInput(isCapturing)
226 self.blockTime = 200
227 if not self.isCapturingInput and isCapturing then
228 -- reset control key flags to avoid immediately returning out of edit mode:
229 self.isReturnDown = false
230 self.isEscDown = false
231
232 self.target:disableInputForDuration(0)
233
234 if TextInputElement.inputContextActive then
235 -- Special case handling for mouse click activation of text input elements. Because of the call order,
236 -- another text element may previously have been active when this one has been activated by click. Avoid
237 -- corrupting the input context by reverting here first.
238 g_inputBinding:revertContext(true)
239 end
240
241 g_inputBinding:setContext(TextInputElement.INPUT_CONTEXT_NAME, true, false)
242 TextInputElement.inputContextActive = true
243
244 if not GS_IS_CONSOLE_VERSION then
245 -- Special case handling for gaming stations which do not have keyboards available for players:
246 -- Register menu back and accept actions so players can exit text boxes with gamepads using either input,
247 -- by default bound to buttons "A" for accept and "B" for back.
248 g_inputBinding:registerActionEvent(InputAction.MENU_BACK, self, self.inputEvent, false, true, false, true)
249 g_inputBinding:registerActionEvent(InputAction.MENU_ACCEPT, self, self.inputEvent, false, true, false, true)
250 end
251
252 self.isCapturingInput = true
253 elseif self.isCapturingInput and not isCapturing then
254 if TextInputElement.inputContextActive then
255 -- Special case handling for mouse click activation of text input elements. Ensure to avoid double reverts
256 -- when switching from one text input to another.
257 g_inputBinding:revertContext(true) -- revert and clear text input context
258 TextInputElement.inputContextActive = false
259 end
260
261 self.target:disableInputForDuration(200)
262 self.isCapturingInput = false
263 end
264end

setForcePressed

Description
Definition
setForcePressed()
Code
308function TextInputElement:setForcePressed(force)
309 if force then
310 self.hadFocusOnCapture = self:getOverlayState() == GuiOverlay.STATE_FOCUSED
311 self:setCaptureInput(true)
312 else
313 self:setCaptureInput(false)
314 end
315
316 self.forcePressed = force
317 if self.forcePressed then
318 FocusManager:setFocus(self)
319 self:setOverlayState(GuiOverlay.STATE_PRESSED)
320 else
321 local newState = GuiOverlay.STATE_NORMAL
322 if self.hadFocusOnCapture then
323 newState = GuiOverlay.STATE_FOCUSED
324 self.hadFocusOnCapture = false
325 end
326
327 self:setOverlayState(newState)
328 end
329
330 if (self.isRepeatingSpecialKeyDown) then
331 self:stopSpecialKeyRepeating()
332 end
333
334 self:updateVisibleTextElements()
335end

setText

Description
Definition
setText()
Code
293function TextInputElement:setText(text)
294 local textLength = utf8Strlen(text)
295 if ((self.maxCharacters) and (textLength > self.maxCharacters)) then
296 text = utf8Substr(text, 0, self.maxCharacters)
297 textLength = utf8Strlen(text)
298 end
299
300 TextInputElement:superClass().setText(self, text)
301
302 self.cursorPosition = textLength + 1
303 self:updateVisibleTextElements()
304end

shouldFocusChange

Description
Focus methods
Definition
shouldFocusChange()
Code
736function TextInputElement:shouldFocusChange(direction)
737 return not self.forcePressed
738end

stopSpecialKeyRepeating

Description
Definition
stopSpecialKeyRepeating()
Code
471function TextInputElement:stopSpecialKeyRepeating()
472 self.isRepeatingSpecialKeyDown = false
473 self.repeatingSpecialKeySym = nil
474 self.repeatingSpecialKeyDelayTime = nil
475 self.repeatingSpecialKeyRemainingDelayTime = nil
476end

translate

Description
Definition
translate()
Code
91function TextInputElement:translate(str)
92 if str then
93 str = g_i18n:convertText(str)
94 end
95 return str
96end

update

Description
Definition
update()
Code
629function TextInputElement:update(dt)
630 TextInputElement:superClass().update(self, dt)
631
632 self.cursorBlinkTime = self.cursorBlinkTime+dt
633 while self.cursorBlinkTime > 2*self.cursorBlinkInterval do
634 self.cursorBlinkTime = self.cursorBlinkTime - 2*self.cursorBlinkInterval
635 end
636
637 if (self.isRepeatingSpecialKeyDown) then
638 self.repeatingSpecialKeyRemainingDelayTime = self.repeatingSpecialKeyRemainingDelayTime - dt
639 if (self.repeatingSpecialKeyRemainingDelayTime <= 0) then
640 if (self.repeatingSpecialKeySym == Input.KEY_left) then
641 self:moveCursorLeft()
642 elseif (self.repeatingSpecialKeySym == Input.KEY_right) then
643 self:moveCursorRight()
644 elseif (self.repeatingSpecialKeySym == Input.KEY_delete) then
645 self:deleteText(true)
646 elseif (self.repeatingSpecialKeySym == Input.KEY_backspace) then
647 self:deleteText(false)
648 end
649 self:updateVisibleTextElements()
650
651 -- reduce key delay each frame down to the minimum to accelerate input when holding control keys
652 self.repeatingSpecialKeyDelayTime = math.max(TextInputElement.MIN_REPEAT_DELAY, self.repeatingSpecialKeyDelayTime * (0.1^(dt/100)))
653 self.repeatingSpecialKeyRemainingDelayTime = self.repeatingSpecialKeyDelayTime
654 end
655 end
656 if (self.useIme and self.imeActive) then
657 local done,cancel = imeIsComplete()
658 if done then
659 self:setForcePressed(false)
660 if not cancel then
661 self:setText(imeGetLastString())
662 self:raiseCallback("onEnterPressedCallback", self)
663 else
664 self:setText(self.preImeText)
665 self.preImeText = ""
666 self:raiseCallback("onEscPressedCallback", self)
667 end
668 self.imeActive = false
669 else
670 self:setText(imeGetLastString())
671 self:setCursorPosition(imeGetCursorPos()+1)
672 self:updateVisibleTextElements()
673 end
674 end
675
676 if self.blockTime > 0 then
677 self.blockTime = self.blockTime - dt
678 end
679end

updateVisibleTextElements

Description
Definition
updateVisibleTextElements()
Code
816function TextInputElement:updateVisibleTextElements()
817 self.isCursorVisible = false
818 self.isVisibleTextPart1Visible = false
819 self.visibleTextPart1 = ""
820 self.isVisibleTextPart2Visible = false
821 self.visibleTextPart2 = ""
822
823 self.areFrontDotsVisible = false
824 self.areBackDotsVisible = false
825
826 self.firstVisibleCharacterPosition = 1
827
828 setTextBold(self.textBold)
829
830 local displayText = self.text
831 if self.isPassword then
832 displayText = string.rep("*", #self.text)
833 end
834
835 local textLength = utf8Strlen(displayText)
836 local availableTextWidth = self:getAvailableTextWidth()
837
838 if (self:getIsActive() and (self:getOverlayState() == GuiOverlay.STATE_PRESSED)) then
839 -- input is gathered, cursor is shown,
840 -- text is displayed at an arbitrary position, both additonal text markers may be displayed
841
842 self.isCursorVisible = true
843
844 if (self.cursorPosition < self.firstVisibleCharacterPosition) then
845 -- cursor was moved to the left to display additional text
846 self.firstVisibleCharacterPosition = self.cursorPosition
847 end
848
849 if (self.firstVisibleCharacterPosition > 1) then
850 self.areFrontDotsVisible = true
851 end
852
853 local textInvisibleFrontTrimmed = utf8Substr(displayText, self.firstVisibleCharacterPosition-1)
854 local textWidthInvisibleFrontTrimmed = getTextWidth(self.textSize, textInvisibleFrontTrimmed)
855 availableTextWidth = self:getAvailableTextWidth()
856
857 if (availableTextWidth and (textWidthInvisibleFrontTrimmed > availableTextWidth)) then
858 -- not all text fits into the visible area
859 if (self.cursorPosition <= textLength) then
860 -- the cursor is not at the last position of the text
861 --self.isBackAdditionalTextMarkerVisible = true
862 self.areBackDotsVisible = true
863 availableTextWidth = self:getAvailableTextWidth()
864 end
865 end
866
867
868 local visibleText = TextInputElement.limitTextToAvailableWidth(textInvisibleFrontTrimmed, self.textSize, availableTextWidth)
869 local visibleTextWidth = getTextWidth(self.textSize, visibleText)
870 local visibleTextLength = utf8Strlen(visibleText)
871
872 if (availableTextWidth and (self.cursorPosition > self.firstVisibleCharacterPosition + visibleTextLength)) then
873 -- the cursor is on the right side and not visible anymore
874 -- text has to be shifted for the cursor to become visible again
875 --self.isFrontAdditionalTextMarkerVisible = true
876 self.areFrontDotsVisible = true
877 availableTextWidth = self:getAvailableTextWidth()
878
879 local textTrimmedAtCursor = utf8Substr(textInvisibleFrontTrimmed, 0, self.cursorPosition - self.firstVisibleCharacterPosition)
880 visibleText = TextInputElement.limitTextToAvailableWidth(
881 textTrimmedAtCursor, self.textSize, availableTextWidth, true)
882 visibleTextWidth = getTextWidth(self.textSize, visibleText)
883 visibleTextLength = utf8Strlen(visibleText)
884 self.firstVisibleCharacterPosition = self.cursorPosition - visibleTextLength
885 end
886
887 if ((availableTextWidth) and (not self.areBackDotsVisible) and (self.firstVisibleCharacterPosition > 1)) then
888 -- check if there is still room for additonal characters (can happen if text gets deleted)
889 local lastCharacterPosition = visibleTextLength + self.firstVisibleCharacterPosition
890 local nextCharacter = utf8Substr(displayText, self.firstVisibleCharacterPosition - 1, 1)
891 local additionalCharacterWidth = getTextWidth(self.textSize, nextCharacter)
892 if (((visibleTextWidth + additionalCharacterWidth) <= availableTextWidth) and (self.firstVisibleCharacterPosition > 1)) then
893 while (((visibleTextWidth + additionalCharacterWidth) <= availableTextWidth) and (self.firstVisibleCharacterPosition > 1)) do
894 -- there is still room for additonal characters
895 self.firstVisibleCharacterPosition = self.firstVisibleCharacterPosition - 1
896 visibleTextWidth = visibleTextWidth + additionalCharacterWidth
897 nextCharacter = utf8Substr(displayText, self.firstVisibleCharacterPosition - 1, 1)
898 additionalCharacterWidth = getTextWidth(self.textSize, nextCharacter)
899 end
900
901 if (self.firstVisibleCharacterPosition > 1) then
902 self.areFrontDotsVisible = false
903 local availableWidthWithoutFrontDots = self:getAvailableTextWidth()
904 self.areFrontDotsVisible = true
905 local neededWidthForCompleteText = getTextWidth(self.textSize, displayText)
906 if (neededWidthForCompleteText <= availableWidthWithoutFrontDots) then
907 self.areFrontDotsVisible = false
908 self.firstVisibleCharacterPosition = 1
909 end
910 else
911 -- all characters are visible
912 self.areFrontDotsVisible = false
913 end
914
915 visibleText = utf8Substr(displayText, self.firstVisibleCharacterPosition - 1, lastCharacterPosition)
916 end
917 end
918
919
920 self.isVisibleTextPart1Visible = true
921 self.visibleTextPart1 = utf8Substr(visibleText, 0, self.cursorPosition - self.firstVisibleCharacterPosition)
922 if (visibleTextLength > (self.cursorPosition - self.firstVisibleCharacterPosition)) then
923 self.isVisibleTextPart2Visible = true
924 self.visibleTextPart2 = utf8Substr(visibleText, self.cursorPosition - self.firstVisibleCharacterPosition)
925 end
926
927 else
928 -- input is not gathered, cursor is not shown,
929 -- text is displayed from its beginning, only back additonal text marker may be displayed if text is too long
930 local textWidth = getTextWidth(self.textSize, displayText)
931 -- check if additional text marker has to be displayed
932 if (availableTextWidth and (textWidth > availableTextWidth)) then
933 --self.isBackAdditionalTextMarkerVisible = true
934 self.areBackDotsVisible = true
935 availableTextWidth = self:getAvailableTextWidth()
936 end
937
938 -- set visible text
939 if (availableTextWidth and (textWidth > availableTextWidth)) then
940 -- not all text fits into the visible area
941 self.visibleTextPart1 = TextInputElement.limitTextToAvailableWidth(displayText, self.textSize, availableTextWidth)
942 self.isVisibleTextPart1Visible = true
943 else
944 -- all text fits into the visible area
945 self.visibleTextPart1 = displayText
946 self.isVisibleTextPart1Visible = true
947 end
948 end
949 setTextBold(false)
950
951 -- print(string.format("updateVisibleTextElements finished :"))
952 -- print(string.format(
953 -- "text: %s - cursorPosition: %d - firstVisibleCharacterPosition: %d - areFrontDotsVisible: %s - isVisibleTextPart1Visible: %s - visibleTextPart1: %s - isCursorVisible: %s - isVisibleTextPart2Visible: %s - visibleTextPart2: %s - areBackDotsVisible: %s",
954 -- 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)))
955end