Having an issue with TextMeshPro InputField using the ASCII Character 9 (Control-i (^i) - Horizontal Tab) when I'm setting up a shortcut for Italics.
Project: Building a simple text editor using rich text tags and universal hotkeys (Office). Underline and Bold work just fine as the ASCII control functions are not inputted into the text box.
Control-b (^b) - start of text
Control-u (^u) - negative acknowledgement
Is there a way to turn off Control-i (^i) from being inputted or validate the input to not include that character. The other way I was going to do this was to use a mediator that listened to the Input class's variable inputString and changed the text of the box from there.(Not Ideal)
SOLUTION:
Found the answer to my own questions with a bit of a work around I was overlooking.
Ended up using an additional TMP_InputValidator that was toggled when either control button was held. The override class used is as follows:
public class TMP_ControlValidator : TMP_InputValidator
{
public override char Validate(ref string text, ref int pos, char ch)
{
if (char.IsControl(ch))
{
return '\0';
}
pos++;
text += ch;
return ch;
}
}
Related
I am making this sum creator where user will have to type an answer using custom keyboard. and on check button click if answer is correct then new question is loaded.
My problem is after answering first question answer button reset to blank but when user types next answer, only one last alphabet is deleted (for example 5 from 15). and when i type 14 it shows 114 (1 from previously typed answer).
I need help to reset answer button text to blank.
I am using buttons because later i want to add more questions at the same time so user will have multiple answers to click and type.
Can anyone please help me on this? Also tell me if this is the right method to achieve what i want.
I am calling backspace function to delete previous answer and also setting text to blank.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Keyboard : MonoBehaviour
{
string word = null;
int wordIndex = -1;
string alpha = null;
string alpha2 = null;
public Text userAnswer1 = null;
public Text valueA, valueB;
public Text scoreCount;
private int a, b, answer1, score;
char[] nameChar = new char[5];
private void Start()
{
SumCreator();
}
public void nameFunc (string alphabet)
{
wordIndex++;
char[] keepchar = alphabet.ToCharArray();
nameChar[wordIndex] = keepchar[0];
alpha = nameChar[wordIndex].ToString();
word = word + alpha;
userAnswer1.text = word;
}
public void BackspaceFunction()
{
if (wordIndex >= 0)
{
wordIndex--;
alpha2 = null;
for (int i = 0; i < wordIndex + 1; i++)
{
alpha2 = alpha2 + nameChar[i].ToString();
}
word = alpha2;
userAnswer1.text = word;
}
}
public void SumCreator ()
{
a = Random.Range(0,15);
b = Random.Range(0,15);
answer1 = a + b;
valueA.text = a.ToString();
valueB.text = b.ToString();
scoreCount.text = "score " + score.ToString();
}
public void CheckAnswer()
{
Text buttonText = userAnswer1.GetComponentInChildren<Text>();
if (answer1 == int.Parse(userAnswer1.text))
{
score++;
// userAnswer1.text = string.Empty;
buttonText.text = string.Empty;
}
SumCreator();
}
}
I've edited my answer and removed the now irrelevant parts.
Once the button "Check" is clicked, first of all erase the text in the result textbox, then do the whole other logic.
To erase the text you can use next piece of code:
Text buttonText = buttonName.GetComponentInChildren<Text>();
buttonText.text = string.Empty;
You probably want to have this "buttonText" property as a global and get it once, at the start of the program instead of getting it every time the button is clicked. It won't do much difference in a small scale program, but it's a right way of thinking.
After checking your code a bit more, I can summarize your problem:
The whole logic of your program is flawed, there're many unnecessary complicated things which make it fail in several places. It is understandable, everybody goes through this stage, nothing to be ashamed or worried about. Either way it's my subjective opinion, which may be wrong.
Back to your code, all you have to do is update your result text, say "txtResult", once anything happens.
Once you click a number, do "txtResult += numberClicked".
Once you click backspace, remove last char of txtResult. Here is a question with many answers on how to do it, it's really simple.
Once you click "Check", in case it's the right number, set txtResult to empty.
Also, every time you update txtResult, you're supposed to update the UI too of course. Let's say you do it every time, it would be one line to update txtResult, and one line to update UI for each of the above 3 cases. So in total 6 lines. A check for an empty string while in "Backspace" function adds another line. My math could be wrong, but either way, it's quite short and simple approach, nothing too complicated.
You just lack relevant knowledge, otherwise you wouldn't be doing that nightmare in your Backspace function.
Regarding the "nameFunc" function, the whole 6 lines could be replaced with "txtResult += alphabet", isn't it? I'm not sure what you get in alphabet parameter, but either way, string is an array of chars, so you can also do "txtResult += alphabet[0]" instead of what you have there.
So, in total, you got it all right, the logic was right, you figured the main aspects. But you over complicated the whole thing. I believe you'll be fine after reading all this text, and wish you the best.
If you want to clear your Text object when you have succesfully entered your answer, you should not call your "BackSpace" function.
Just replace your code to this:
if (answer1 == int.Parse(userAnswer1.text))
{
score++;
userAnswer1.text = string.Empty;
This will clear the text element.
You could also look into using InputFields in Unity, which are designed for entering input and automatically support backspace and other keyboard functions.
If you do, make sure that you set the InputField's ContentType to either Integer Number or Decimal Number
I'm attempting to find a document on my window that has a rich text box with text in it using TestStack White, and extract that text.
I've tried to use the UIItem Label & TextBox, but White doesn't seem to be able to find the object during my test. The object can be found using the generic UIItem, but I want to be able to access the text it holds.
I'm implementing it like:
public [Unsure] MyRichTextBox
{
get { return Window.Get<[Unsure]>(SearchCriteria.ByClassName("RichTextBox")); }
}
and I'd like to be able to say:
Assert.That(MyRichTextBox.Text.Equals(x));
But it can't find what I'm looking for if I tag it as a Label or a TextBox, and I don't have access to .Text if I declare it a UIItem.
You want to use the type of TextBox. Then you can use BulkText to access the text in the RichEditBox.
First the Window:
TestStack.White.UIItems.WindowItems.Window _mainWindow;
app = TestStack.White.Application.Launch(startInfo);
_mainWindow = app.GetWindow("MyDialog");
Then Find the richEditBox:
public string _richeditdocument_ID = "rtbDocument";
private TextBox _richeditdocument_ = null;
public TextBox RichEditDocument
{
get
{
if (null == _richeditdocument_)
_richeditdocument_ = _mainWindow.Get<TextBox>(SearchCriteria.ByAutomationId(_richeditdocument_ID));
return _richeditdocument_;
}
}
Then use the following to access the text:
string data = RichEditDocument.BulkText;
Here are the code comments for using the Text Method in White:
// Summary:
// Enters the text in the textbox. The text would be cleared first. This is
// not as good performing as the BulkText method. This does raise all keyboard
// events - that means that your string will consist of letters that match the
// letters of your string but in current input language.
public virtual string Text { get; set; }
Here are the comments for using BulkText:
// Summary:
// Sets the text in the textbox. The text would be cleared first. This is a
// better performing than the Text method. This doesn't raise all keyboard events.
// The string will be set exactly as it is in your code.
According to my understanding of the documentation, when using TextFormatFlags.EndEllipsis the text should be trimmed to fit inside the display rectangle and replaced with an ellipsis:
EndEllipsis | Removes the end of trimmed lines, and replaces them with an ellipsis.
When using TextFormatFlags.WordEllipsis, the text should be trimmed to the last word that fits inside the display rectangle, and add an ellipsis:
WordEllipsis | Trims the line to the nearest word and an ellipsis is placed at the end of a trimmed line.
However, I can't seem to find any difference between these two.
Here is my test control's code:
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
this.Text = "This it my text. It's long enough to get cut in display.";
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var flags = (this.IsWordEllipsis) ? TextFormatFlags.WordEllipsis : TextFormatFlags.EndEllipsis;
TextRenderer.DrawText(e.Graphics, this.Text, this.Font, e.ClipRectangle, this.ForeColor, flags);
}
private bool _IsWordEllipsis;
public bool IsWordEllipsis
{
get { return _IsWordEllipsis; }
set { _IsWordEllipsis = value; this.Invalidate(); }
}
}
No matter what value I set the IsWordEllipsis property - the text is always rendered as
This it my text. It's long eno....
Shouldn't using the WordEllipsis flag trim the displayed string to the last complete word?
(This it my text. It's long ...)
Internally TextRenderer.DrawText calls DrawText function
Corresponding flags are:
DT_WORD_ELLIPSIS: Truncates any word that does not fit in the
rectangle and adds ellipses.
DT_END_ELLIPSIS For displayed text, if the end of a string does not
fit in the rectangle, it is truncated and ellipses are added. If a
word that is not at the end of the string goes beyond the limits of
the rectangle, it is truncated without ellipses.
I have interpreted .NET documentation for WordEllipsis same way as you, but above sentence probably better explains what this option is supposed to do.
In case it is still unclear take a look at this simple example, which tries to render var quote = "Not every thing that\n can be counted counts,\n and not everything that\n counts can be counted.";
I've created a Keyboard for my WPF application in XAML with the functionality of it done in the code behind C#. As of now, any key clicked (or touched), will display the respective key in a TextBox (as expected. However, when handling the HTML Code, the HTML Code gets displayed.
For reference, the button click:
private void btnQUOTATION_Click(object sender, RoutedEventArgs e)
{
HandleKeyboard(""");
}
The HandleKeyboard method:
private bool current spot = false;
private void HandleKeyboard(string key)
{
//Ternary operator
string valueSoFar = currentSpot ? txtBoxTest.Text : "";
string newValue = valueSoFar + key.ToString();
txtBoxTest.Text = newValue;
currentSpot = true;
}
Everything is fine and dandy with the other keys presented, except for quotation marks and apostrophes.
What I'm expecting in the TextBox txtBoxTest when the button for quotation marks is clicked (") is quote marks to show in the text box as quotation marks...instead of the HTML code it is showing now.
Since HandleKeyboard() cannot accept (""") or ("'") ... Is there a way to do this?
You could look to use the Encode and Decode HTML. You will need to use System.Web namespace.
e.g.
string key= "This is a "";
string deCodedKey = System.Web.HttpUtility.HtmlDecode(key);
If you put a breakpoint over the DeCodedKey line you should see it change back to ""
My requirement is i am trying to develop a text editor for my mother tongue language.
That is i am trying to develop tamil text editor using unicode characters.
When i am pressing key on the keyboard(English character like) k that time i want to replace two characters like "&H0b95" "&H0bcd".
How to i implement this concept? whether it is possible or not.
sample code when keypress event
e.keychar=chrw("&H0b95") & chrw("&H0bcd") 'This code is not Execute Becuase it get Only One Character'
TextBox1.Text=chrw("&H0b95") & chrw("&H0bcd")
I am already finish this concept but the only problem is cursor position is scroll that is when i am assigning the character to textbox that time selection start is zero so the cursor go to first position. after second line i am set the cursor position to the length of the text that is cursor come to end of the text.
so the problem is the cursor move up and down when i am pressing a key at all the times. how to solve this problem. can any body given an idea to me.
Click here! To See the Tamil Unicode Characters Table.
You need to stop the textbox from rendering, while you update the cursor position. I had done something similar before with a console application. But can't find the code to reference it here.
You need to update the SelectionStart Property and increase its length with the size of the new text inserted.
Something like:
int curPos = txtEditor.SelectionStart;
if (e.KeyChar == 'k')
{
txtEditor.Text=txtEditor.Text.Insert(txtEditor.SelectionStart, "jj");
txtEditor.SelectionLength = 0;
}
txtEditor.SelectionStart = curPos + 2; //or whatever the length of text u inserted
this TextBox, adds "jj" when the user presses k key. The cursor position is corrcted.
public class MyTextBox : TextBox
{
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.K)
{
int pos = this.SelectionStart;
this.Text = this.Text.Substring(0, this.SelectionStart) + "jj"
+ this.Text.Substring(this.SelectionStart);
this.SelectionStart = pos + 2;
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
}