How to correctly set text of input field from script in Unity Engine? - unity3d

I have developer console in my game and when you press up arrow it'll load previous command that you used, to input filed. But when I try to change text from script I'll write the previous command to the input filed but the input filed is not editable anymore until you press esc key.
I am using the new TMPro.TMP_InputField.
inputField.text = typedCommands[(typedCommands.Count) - backCount];
inputField.caretPosition = inputField.text.Length;
On the first line I am setting text variable of the input field and on the second one I am setting cursor behind tha last character in the input field.
When I try to delete all text from the input filed from editor when the game is running I get this error:
IndexOutOfRangeException: Index was outside the bounds of the array.
TMPro.TMP_InputField.GenerateCaret (UnityEngine.UI.VertexHelper vbo, UnityEngine.Vector2 roundingOffset) (at Library/PackageCache/com.unity.textmeshpro#2.0.0/Scripts/Runtime/TMP_InputField.cs:3304)
TMPro.TMP_InputField.OnFillVBO (UnityEngine.Mesh vbo) (at Library/PackageCache/com.unity.textmeshpro#2.0.0/Scripts/Runtime/TMP_InputField.cs:3271)
TMPro.TMP_InputField.UpdateGeometry () (at Library/PackageCache/com.unity.textmeshpro#2.0.0/Scripts/Runtime/TMP_InputField.cs:3209)
TMPro.TMP_InputField.Rebuild (UnityEngine.UI.CanvasUpdate update) (at Library/PackageCache/com.unity.textmeshpro#2.0.0/Scripts/Runtime/TMP_InputField.cs:3184)
UnityEngine.UI.CanvasUpdateRegistry.PerformUpdate () (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/CanvasUpdateRegistry.cs:198)
UnityEngine.Canvas:SendWillRenderCanvases()
It seems that the input field change its value but it doesn't see that there is some text in itself that you did not type directly in it.
EDIT:
Here is more code for better understanding. I call this piece of code from the update loop.
private void typedCommandFunc()
{
if (Input.GetKeyDown(KeyCode.UpArrow) && backCount != (typedCommands.Count))
backCount++;
if (Input.GetKeyDown(KeyCode.DownArrow) && backCount > 0)
backCount--;
if(backCount != 0)
{
inputField.text = typedCommands[(typedCommands.Count) - backCount];
inputField.caretPosition = inputField.text.Length;
}
}

Based on your error log, it seems like the problem is with generating the caret:
IndexOutOfRangeException: Index was outside the bounds of the array.
TMPro.TMP_InputField.GenerateCaret(UnityEng...
It might not be possible to make a caret right after where the string ends, try:
inputField.caretPosition = inputField.text.Length -1;
instead.
If you really wanted to make a caret right after the string ends, use the same code, but have a blank white-space at the end of the input-field.It gives an illusion to the player where the caret is at the end of the string (Though, it is just at an empty white-space).
Also, it is possible for your typedCommands to have nothing and you might be still accessing it, so hence you might want to do:
if(backCount != 0 && typedCommands.Count != 0)

typedCommands.Count returns the length of typedCommands. Whenever backCount is equal to 0 the code actually reads typedCommands[typedCommands.Count]. This won't work since an array starts at 0 and typedCommands.Count will start counting at one and will return a value that is one outside of the bounds of the array.
You should always subtract 1 from the count to stay inside the bounds of the array like so:
inputField.text = typedCommands[typedCommands.Count - 1 - backCount];

Related

Converting numbers into timestamps (inserting colons at specific places)

I'm using AutoHotkey for this as the code is the most understandable to me. So I have a document with numbers and text, for example like this
120344 text text text
234000 text text
and the desired output is
12:03:44 text text text
23:40:00 text text
I'm sure StrReplace can be used to insert the colons in, but I'm not sure how to specify the position of the colons or ask AHK to 'find' specific strings of 6 digit numbers. Before, I would have highlighted the text I want to apply StrReplace to and then press a hotkey, but I was wondering if there is a more efficient way to do this that doesn't need my interaction. Even just pointing to the relevant functions I would need to look into to do this would be helpful! Thanks so much, I'm still very new to programming.
hfontanez's answer was very helpful in figuring out that for this problem, I had to use a loop and substring function. I'm sure there are much less messy ways to write this code, but this is the final version of what worked for my purposes:
Loop, read, C:\[location of input file]
{
{ If A_LoopReadLine = ;
Continue ; this part is to ignore the blank lines in the file
}
{
one := A_LoopReadLine
x := SubStr(one, 1, 2)
y := SubStr(one, 3, 2)
z := SubStr(one, 5)
two := x . ":" . y . ":" . z
FileAppend, %two%`r`n, C:\[location of output file]
}
}
return
Assuming that the "timestamp" component is always 6 characters long and always at the beginning of the string, this solution should work just fine.
String test = "012345 test test test";
test = test.substring(0, 2) + ":" + test.substring(2, 4) + ":" + test.substring(4, test.length());
This outputs 01:23:45 test test test
Why? Because you are temporarily creating a String object that it's two characters long and then you insert the colon before taking the next pair. Lastly, you append the rest of the String and assign it to whichever String variable you want. Remember, the substring method doesn't modify the String object you are calling the method on. This method returns a "new" String object. Therefore, the variable test is unmodified until the assignment operation kicks in at the end.
Alternatively, you can use a StringBuilder and append each component like this:
StringBuilder sbuff = new StringBuilder();
sbuff.append(test.substring(0,2));
sbuff.append(":");
sbuff.append(test.substring(2,4));
sbuff.append(":");
sbuff.append(test.substring(4,test.length()));
test = sbuff.toString();
You could also use a "fancy" loop to do this, but I think for something this simple, looping is just overkill. Oh, I almost forgot, this should work with both of your test strings because after the last colon insert, the code takes the substring from index position 4 all the way to the end of the string indiscriminately.

iText PDFSweep RegexBasedCleanupStrategy not work in some case

I'm trying to use iText PDFSweep RegexBasedCleanupStrategy to redact some words from pdf, however I only want to redact the word but not appear in other word, eg.
I want to redact "al" as single word, but I don't want to redact the "al" in "mineral".
So I add the word boundary("\b") in the Regex as parameter to RegexBasedCleanupStrategy,
new RegexBasedCleanupStrategy("\\bal\\b")
however the pdfAutoSweep.cleanUp not work if the word is at the end of line.
In short
The cause of this issue is that the routine that flattens the extracted text chunks into a single String for applying the regular expression does not insert any indicator for a line break. Thus, in that String the last letter from one line is immediately followed by the first letter of the next which hides the word boundary. One can fix the behavior by adding an appropriate character to the String in case of a line break.
The problematic code
The routine that flattens the extracted text chunks into a single String is CharacterRenderInfo.mapString(List<CharacterRenderInfo>) in the package com.itextpdf.kernel.pdf.canvas.parser.listener. In case of a merely horizontal gap this routine inserts a space character but in case of a vertical offset, i.e. a line break, it adds nothing extra to the StringBuilder in which the String representation is generated:
if (chunk.sameLine(lastChunk)) {
// we only insert a blank space if the trailing character of the previous string wasn't a space, and the leading character of the current string isn't a space
if (chunk.getLocation().isAtWordBoundary(lastChunk.getLocation()) && !chunk.getText().startsWith(" ") && !chunk.getText().endsWith(" ")) {
sb.append(' ');
}
indexMap.put(sb.length(), i);
sb.append(chunk.getText());
} else {
indexMap.put(sb.length(), i);
sb.append(chunk.getText());
}
A possible fix
One can extend the code above to insert a newline character in case of a line break:
if (chunk.sameLine(lastChunk)) {
// we only insert a blank space if the trailing character of the previous string wasn't a space, and the leading character of the current string isn't a space
if (chunk.getLocation().isAtWordBoundary(lastChunk.getLocation()) && !chunk.getText().startsWith(" ") && !chunk.getText().endsWith(" ")) {
sb.append(' ');
}
indexMap.put(sb.length(), i);
sb.append(chunk.getText());
} else {
sb.append('\n');
indexMap.put(sb.length(), i);
sb.append(chunk.getText());
}
This CharacterRenderInfo.mapString method is only called from the RegexBasedLocationExtractionStrategy method getResultantLocations() (package com.itextpdf.kernel.pdf.canvas.parser.listener), and only for the task mentioned, i.e. applying the regular expression in question. Thus, enabling it to properly allow recognition of word boundaries should not break anything but indeed should be considered a fix.
One merely might consider adding a different character for a line break, e.g. a plain space ' ' if one does not want to treat vertical gaps any different than horizontal ones. For a general fix one might, therefore, consider making this character a settable property of the strategy.
Versions
I tested with iText 7.1.4-SNAPSHOT and PDFSweep 2.0.3-SNAPSHOT.

Remove newline character in powerbuilder

How can I remove newline character from a string in powerbuilder? I have a column where I can write something and when I press enter it inserts a newline character. I want to remove it when I press save.
Thanks
To remove the Newline character...
ll_pos = PosA(ls_text, "~n")
do while(ll_pos > 0)
ls_text = ReplaceA(ls_text, ll_pos, 1, "")
ll_pos = PosA(ls_text, "~n")
loop
If you need to remove the Carriage Return as well...
ll_pos = PosA(ls_text, "~r~n")
do while(ll_pos > 0)
ls_text = ReplaceA(ls_text, ll_pos, 2, "")
ll_pos = PosA(ls_text, "~r~n")
loop
Another, completely different way to solve the problem is to make your Save button a Default button (third check box in the General tab). This way, when the user presses Enter, that button is actually activated. This prevents you from further processing. Of course, it remains to see if that behaviour is normal / desired.

maskedEditColumn datagridview how to use class? is it what i need?

I am trying to mask user's input in a datagridview column and i found this ready class Masked edit column Class that adds a 'mask edit column' option in the column types list. When i select this column type a mask field is being added in the list of column properties. I tried to do my job by adding some mask elements in this 'Mask' field, but when I run the code it didnt restrict me from adding other characters. I re-opened the 'edit columns menu' and I saw that the 'Mask' field was empty.
I want the text cell to accept 20 chars maximum and only: 1.Capital Letters(English & Greek), 2.these three chars(.,-), 3.Numbers 0-9
So as a first test i used only this mask(>????????????????????) but it didnt work as it didnt convert my characters to Uppercase and accepted more than 20 chars when i end the cell edit.
i am not sure the way to go is the Masked Text Box way. i have made many projects on vb and i used to use a loop in the textChanged event of a text box to restrict characters entry. the loop is this : (but i cant use it now in the valueChanged event cause it seems that 'value' doesn't have a selectionStart property.)
Dim charactersDisallowed As String = "!##$%^&*()+=|}{][:;?/><.,~""
Dim theText As String = txtCopies.Text
Dim Letter As String
Dim SelectionIndex As Integer = txtCopies.SelectionStart
Dim Change As Integer
For x As Integer = 0 To txtCopies.Text.Length - 1
Letter = txtCopies.Text.Substring(x, 1)
If charactersDisallowed.Contains(Letter) Then
theText = theText.Replace(Letter, String.Empty)
Change = 1
End If
Next
txtCopies.Text = theText
txtCopies.Select(SelectionIndex - Change, 0)
So,
Is a masked text cell what i need? and if yes( Why is this mask box not keeping the mask i enter? And how can i use this class to do my job?)
What can i alternately do to restrict some characters in a column's cells? (I will then convert to Uppercase on cellEndEdit)
I finally did it by removing the unwanted characters on cellvaluechanged event, which seems that is being raised when I end the cell's edit by for example hitting "Enter".

CATIA macro (Input box not working)

Help My Balloon finding macro is not working with input box, it works only when i manually add the balloon number.. please tell me what i m missing ...Ferdo m expecting you
Language="VBSCRIPT"
Sub CATMain()
Set drawingDocument1 = CATIA.ActiveDocument
Set selection1 = drawingDocument1.Selection
result = InputBox("Ballon Number ?", "Title") 'The variable is assigned the value entered in the InputBox
selection1.Search "CATDrwSearch.DrwBalloon.BalloonPartName_CAP= result ,all"
End Sub
I don't know what you are doing but the last line looks wrong. I don't know what the docs are for your function but you are passing the string result rather than the value of the variable result because it is in quotes. Assuming your line is otherwise right ...
selection1.Search "CATDrwSearch.DrwBalloon.BalloonPartName_CAP= " & result & ",all"