how to hide keyboard while closing layer which contains my TextField - cocos2d-x

I am using TextField in my new project which is in cocos2d-x 3.2.It's working fine when i enter text and then enter then it hides my keyboard but when I enter text & i kept my keyboard opened at that time if i close my PopUp layer containing my text Field then my keyboard remained opened . I don't know how i can hide or close my keyboard in this situation. please help...
Here is my Code ..
// Adding TextField in my Layer
TextFiledd = TextField::create("", "fonts/HelveticaLTStd-Cond_0.ttf" , ButtonFontSize);
TextFiledd->setContentSize(Size(Playername_bg->getContentSize().width ,Playername_bg->getContentSize().height));
TextFiledd->setPosition(Point(Playername_bg->getPositionX(),Playername_bg->getPositionY()));
TextFiledd->setAnchorPoint(Vec2::ANCHOR_MIDDLE);
TextFiledd->setMaxLength(10);
TextFiledd->setMaxLengthEnabled(true);
TextFiledd->addEventListener(CC_CALLBACK_2(PlayerName::textFieldEvent, this));
TextFiledd->setColor(Color3B::YELLOW);
TextFiledd->setBright(true);
TextFiledd->setTouchAreaEnabled(true);
TextFiledd->setTouchSize(Playername_bg->getContentSize());
bgFrameSprite->addChild(TextFiledd,PopUpTag);
// Delegate methods
void PlayerName::textFieldEvent(cocos2d::Ref *pSender, TextField::EventType type)
{
playerNameText = (TextField*)pSender;
CCLOG(" Player name : %s",playerNameText->getStringValue().c_str());
std::string key = Player_Name;
PlayerSettings::setPlayerName(key.c_str(), playerNameText->getStringValue().c_str());
switch (type)
{
case TextField::EventType::ATTACH_WITH_IME:
{
TextField* textField = dynamic_cast<TextField*>(pSender);
Size widgetSize = WinSize;
runAction(CCMoveTo::create(0.225f,Vec2(0, widgetSize.height / 12.0f)));
textField->setTextHorizontalAlignment(TextHAlignment::LEFT);
textField->setTextVerticalAlignment(TextVAlignment::TOP);
playerNameText->setText(str);
}
break;
case TextField::EventType::DETACH_WITH_IME:
{
TextField* textField = dynamic_cast<TextField*>(pSender);
Size widgetSize = WinSize;
runAction(CCMoveTo::create(0.175f, Vec2(0, 0)));
textField->setTextHorizontalAlignment(TextHAlignment::LEFT);
textField->setTextVerticalAlignment(TextVAlignment:
}
break;
case TextField::EventType::INSERT_TEXT:
break;
case TextField::EventType::DELETE_BACKWARD:
break;
default:
break;
}
}

This works for me (cocos2d-x-3.11.1):
textField->detachWithIME()
on iOS and Android.

Related

How to add a cursor/text position indicator to a <textarea> controlled by javascript?

I am making a typewriter like website (here) that uses a textarea and javascript (from button clicks) to add/remove from the textarea.
The next thing I want to add is an indicator to show where the next update (insert/remove) will be so I guess its always at the of the textarea value.
The key details that clash with other solutions are
The textarea is disabled (+ its a textarea and not a p tag)
Users add characters by using the buttons and not by typing with their keyboards
The user isn't selecting or has a selection while typing
Some solutions involve css that break the website
This is how I insert characters
function insert(char) {
document.getElementById("textarea").value += char
update()
}
to the textarea + a button
<textarea id="textarea" class="textarea" disabled>
</textarea>
<a onclick="insert('1')">
<div class="letterbox">
<p class="typewritter">1</p>
</div>
</a>
(btw I know I spelled typewriter wrong on the website and will fix that later)
If you want to make a custom insertion point (the blinking line) you can do that by adding and removing a chosen symbol ('|' for example) from the text with an interval. Perhaps something like this would do:
const insertionSymbol = '|';
const blinkInterval = 1000; // time in ms between insertion point updates
let blinking = true; // whether the insertion line is hidden
let textarea = document.getElementById('textarea');
setInterval(function() {
if(blinking) {
textarea.value += insertionSymbol;
} else {
textarea.value = textarea.value.slice(0,-1);
}
blinking = !blinking;
}, blinkInterval);
that would require you to change the insert and delete functions:
function insert(char) {
if(blinking) {
textarea.value += char;
} else {
// inserting the character before the insertion point by removing the insertion point temporarily
textarea.value = textarea.value.slice(0,-1) + char + insertionSymbol;
}
}
function delete() {
if(blinking) {
textarea.value = textarea.slice(0,-1);
} else {
// deleting the character before the insertion point by removing the insertion point temporarily
textarea.value = textarea.value.slice(0,-2) + insertionSymbol;
}
}
This idea can be expanded. for example, if you want to add a insertion point cool-down (i.e. change the insertion point to stay visible for some time after an update, like you see in most text editors), you can change the interval to run every millisecond, and add a timer for the next update. like this:
// ... all the variable definitions like before
let timer = blinkInterval;
setInterval(function() {
timer --;
if(timer == 0) {
if(blinking) {
textarea.value += insertionSymbol;
} else {
textarea.value = textarea.value.slice(0,-1);
}
blinking = !blinking;
timer = blinkInterval;
}
}, 1);
function insert(char) {
if(blinking) {
blinking = false;
textarea.value += char + insertionSymbol;
} else {
// inserting the character before the insertion point by removing the insertion point temporarily
textarea.value = textarea.value.slice(0,-1) + char + insertionSymbol;
}
timer = blinkInterval;
}
function delete() {
if(blinking) {
blinking = false;
textarea.value = textarea.slice(0,-1) + insertionSymbol;
} else {
// deleting the character before the insertion point by removing the insertion point temporarily
textarea.value = textarea.value.slice(0,-2) + insertionSymbol;
}
timer = blinkInterval;
}
Note: I'm writing the code blindly (I didn't run it to see if it works) so I'm sorry in advance for any mistakes.
I think overriding textarea attributes is meaningless. The indicator that you want is already in it's characteristic.
Remove the disabled tag from your textarea and just block the keyboard pressing with the below code snippet. [because not using keyboard typing is your feature]
document.onkeydown = function (e) {
return false;
}
If you want to you can bind the function to focus action of the textarea.
My suggestion on this would be to have the textarea active, NOT disabled and always on focus. This way you will have the blinking effect you want. Then have a pointer-events:none css on the textarea so no one can click on it and you have the blink you want. So my steps would be:
Remove disabled from textarea
Add pointer-events:none css rule to the textarea
On the update() function I observe add either a focus or a click event so the textarea gets focus on each insert()
One way to do it would be to have a loop running non stop (with a requestAnimationFrame maybe ?) to add and remove a | character every other second, which would simulate the usual text position indicator you have inside most text areas

The best method to create typewriter effect?

Hey everyone so I am creating a game that focuses on character to character interactivity. So when you interact with a character a chat box opens and the characters start talking to one another. I have the text setup like an old school typewriter effect one letter at a time. As of now I create it by typing each letter on separate frames and have them play through. When it gets to then end of the sentence in order for the user to go on to the next sentence I have a button that they tap Here is the code:
private function nextConvo(e:MouseEvent):void
{
nNext += 1;
trace(nNext);
if (nNext == 1)
{
conversation.gotoAndPlay(1);
}else
if (nNext == 2)
{
conversation.gotoAndPlay(117);
}
}
As you can see i set it up to play the next frame with the new conversation so on and so on. I have a lot more text to do I realized it will be really time consuming and wonder if there is a easier way.
A method to where it types the string in the text box and I can still use my button so when the user wants to see the next conversation they can press the next button.
I saw a video here of someone showing the code way of doing it but Not sure how I would implement the button without having to add a lot of new mouse listeners and timers. Code Method
Please any help would be appreciated.
Omg, yes, you will go nuts if you show one character per frame :)
The idea is to have a function to handle this for you that you have ONCE somewhere (for example, on your main timeline). Then you can call it from everywhere and just pass the text, textfield to type into and a button.
private var _myText:String;
private var _myTextField:TextField;
private var _myButton:Button;
private var _currentCharacterPosition:int;
public function typeText(text:String, myTextField:TextField myButton:Button):void
{
_myText = text;
_myTextField = myTextField;
_myButton = myButton;
_myButton.visible = false;
_currentCharacterPosition = 1;
typeNextCharacter();
}
private function typeNextCharacter():void
{
_myTextField.text = _myText.substr(0, _currentCharacterPosition);
if (_currentCharacterPosition == _myText.length)
{
// all text is typed out, show your button
myButton.visible = true;
}
else
{
// type next character. 0.2 is the delay between letters (200 ms)
_currentCharacterPosition++;
setTimeout(typeNextCharacter, 0.2);
}
}
Assuming you have the textfield and button in the same place (same frame), you could then do this in that frame:
_root.typeText("This is my text to type out", myTextField, myButton);

How can I detect StaticText in AS3?

I have StaticText fields in my flash project and I need to run some code when the mouse is hovering over them. So I tried this code
stage.addEventListener(MouseEvent.MOUSE_OVER, mouseRollOver);
function mouseRollOver(event:MouseEvent):void {
var tf:StaticText = event.target as StaticText;
if (tf){
//my code
}
}
but it doesn't work. When I use dynamic text fields and replace StaticText with TextField in the var tf, it works fine. I also thought that I could get this thing working with static text fields if I could make the mouse detect not StaticText as a target but some kind of object that has certain text properties (like "selectable" set to true), but I couldn't figure out how to do this. Anyway, I need to detect a static text field as a target somehow. Any help would be appreciated.
Thanks in advance
Your best option would be to put the static text box in a movieclip, and then assign your code based around that. Static text boxes don't have instance names, and can't be manipulated.
It is hard to do this. See this link enter link description here
As you can see you can check if the DisplayObject is StaticText and by checking the mousX and MouseY properties you can find if the rollover is related to this field. By if you use Dynamic text and uncheck selectable field you will get a textfield that acts as StaticField
EDIT
this is an explanation what I mean:
Let we have a StaticText field into stage in Black flash document.
var myFieldLabel:StaticText
var i:uint;
//This for check for all staticFields in state and trace its text. It is possible and it is working. I my case I have only one field and I get reference to it in myFieldLabel:StaticText var. Also I change it's alpha to 0.3.
for (i = 0; i < this.numChildren; i++)
{
var displayitem:DisplayObject = this.getChildAt(i);
if (displayitem instanceof StaticText) {
trace("a static text field is item " + i + " on the display list");
myFieldLabel = StaticText(displayitem);
trace("and contains the text: " + myFieldLabel.text);
trace( myFieldLabel.mouseX);
myFieldLabel.alpha = 0.3;
}
}
//Adds event listener to the stage for mouse move event
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseRollOver);
//This is an event handler. I check if the mouse position is within the static field
function mouseRollOver(evnt:MouseEvent):void
{
if ( 0 <= myFieldLabel.mouseX && myFieldLabel.mouseX <= myFieldLabel.width && 0 <= myFieldLabel.mouseY && myFieldLabel.mouseY <= myFieldLabel.height )
{
mouseOverStaticText( evnt)
}
else
{
mouseNotOverStaticText( evnt)
}
}
// this two methods change the static field alpha. Thay are only to show that is posible to detect and manipulate some properties of the StaticField.
function mouseOverStaticText( evnt)
{
myFieldLabel.alpha = 1;
}
function mouseNotOverStaticText( evnt)
{
myFieldLabel.alpha = 0.3;
}
I'm not sure what is the purpose of the managing of the StaticText field. StaticText is not design to be managed if you have to do something this is almost sure that the field must not be a static - they can be dynamic ( without selectible property ) or can be capsulated with MovieClip or there can be a different solution in your case.

How can I add an event listener to scrolling content?

I want to put some mouse event to scrolling text in dynamic text field.
For example: I type several sentences into one dynamic text field. For each sentence, I want to have a different mouse event. Like this:
sentenceA.addEventListener(MouseEvent.CLICK, functionA);
function functionA(evt:MouseEvent):void
{
trace("bla");
}
How can I add an eventlistener to each sentence in the scrolling text? Because the position of the mouse event should move when the relative text scrolling.
here you go...
_txt.htmlText = "<a href='event:sentence1'>This is one sentenc.</a> <a href='event:sentence2'>This is another sentence.</a>"
_txt.addEventListener(TextEvent.LINK, clickCopyHandler);
function clickCopyHandler(e:TextEvent):void {
trace(e.text);
}
var sentences:Array = [ sentenceA, sentenceB, ...... ];
function clickAllText(e:MouseEvent):void
{
var index:int;
for each(var s:String in sentences)
{
index = dynamicTextField.text.indexOf(s);
if(index >= 0 && index <= 3)
{
//if the sentence is in the front
this["sentence"+sentences.indexOf(s)]();
break;
}
}
}
function sentence0():void
{
}
function sentence1():void
{
}
If that is not the case, you would need to either use different text fields, or
get the proximity of the mouse point to the sentence x and y location on the
display.
Take a closer look at flash.event.TextEvent.LINK, it's thrown when you click on html text which has an attribute href='event:someText'. Consider the following example
var tf:TextField = new TextField();
tf.htmlText = "<a href='event:first'>sentence1.</a><a href='event:second'>sentence2.</a>";
tf.addEventListener("link", clickHandler); //link is value of flash.event.TextEvent.LINK
function clickHandler(e:TextEvent):void {
//here should be something like the following
if (e.text == "first") sentence1();
else if (e.text == "second") sentence2();
}
well, I guess you caught the idea! The problem is that sentences are to be put into tag, but you can make links look like ordinary text. If that variant does not fits your needs, you may try to compare selection boundaries(tf.selectionBeginIndex and tf.selectionEndIndex) with boundaries of sentences after click.

AS3 TextField - unwanted carriage return when setting value to ""

I have an input TextField and have a KeyboardEvent.KEY_DOWN even listener on the stage to listen for the Keyboard.ENTER event. The event listener adds the entered text to an array or whatever, and then clears the TextField. The problem is that when the Enter key event fires and the TextField value is set to "", it leaves a carriage return in the TextField and the cursor positioned on the second line. WTF? I've been coding AS2 and AS3 for a LONG time and have never ran into this before. Am I losing my mind? Please help, people! :-)
Example:
var myTextArray:Array = new Array();
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
function onKeyDown(e:KeyboardEvent):void{
if(e.keyCode == Keyboard.ENTER){
if(_inputText.text != null){
myTextArray.push(_inputText.text);
}
_inputText.text = "";
}
}
Simply replace KEY_DOWN with KEY_UP. It fixes the problem (for me at least)
Use KEY_DOWN -> Your code -> KEY_UP -> empty Field
An example (nasty code):
Message.addEventListener(KeyboardEvent.KEY_DOWN, function(e:KeyboardEvent):void
{
if(e.keyCode == Keyboard.ENTER)
{
// Your code...
}
});
Message.addEventListener(KeyboardEvent.KEY_UP, function(e:KeyboardEvent):void
{
if(e.keyCode == Keyboard.ENTER)
{
Message.text = "";
}
});
If you are able to enter a carriage return, it means the TextField is multiline, isn't?
Have you tried to empty your input text in a KeyboardEvent.KEY_UP event listener callback function?
Are you hitting enter with text field in focus? In that case, it might be that onKeyDown is called before the text field's value is updated by the keyboard action. You set the textfield to empty string in the onKeyDown, and then flash adds a new line to it.
Add a text input event listener to the text field and add trace statements to both event handlers to know the order of events.
If you are in Flash authoring mode (in the IDE), you need to uncheck Control -> Disable Keyboard Shortcuts while testing. Also try making a "cleanup" handler for KEY_UP.
inputfield.addEventListener(Event.CHANGE, onChange);
private function onChange(e:Event):void {
if ( inputfield.text.charCodeAt(inputfield.text.length - 1) == 13 ) {
inputfield.text = inputfield.text.substr(0, inputfield.text.length - 1);
}
}
I know it is a very old question, still thought of sharing my solution. I disabled multiline feature of textbox in fla file. After that I don't get any carriage return in textbox.
This does seem to be some kind of bug - I get it too. If you just set textField.text = "" in your constructor (or where-ever) it seems to resolve the problem.