Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: using the erase function of sf::sting  (Read 4369 times)

0 Members and 1 Guest are viewing this topic.

Paradoxic4

  • Newbie
  • *
  • Posts: 2
    • View Profile
using the erase function of sf::sting
« on: May 21, 2014, 06:56:13 am »
The following code produces some odd behavior.  As the attached pictures show, I am able to input text just fine, but when I press backspace, it changes the last character to that little circle, after which pressing backspace again does nothing.  This seems to imply to me that the place in the sf::string which once held the last character still exists, and that pressing backspace repeatedly just continually replaces the last character with the little circle.  Hence, the string has not changes size, and calling getSize() will continue to produce the same number at every frame.  Is this supposed to be the case, or am I doing something wrong?  Thank you for your help.

int main()
{
        sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");
        sf::Font myFont;
        if (!myFont.loadFromFile("resources/roman.ttf"))
        {
                cout << "The font was not loaded!\n";
        }

        sf::Text Text;
        Text.setFont(myFont);
        Text.setCharacterSize(24);
        Text.setColor(sf::Color::Red);
        Text.setPosition(10, 10);

        sf::String userInput;


        while (window.isOpen())
        {
                sf::Event event;
                while (window.pollEvent(event))
                {
                        if (event.type == sf::Event::Closed)
                        {
                                window.close();
                        }

                        if (event.type == sf::Event::TextEntered)
                        {
                                userInput.insert(userInput.getSize(), event.text.unicode);
                        }
                       
                        if (event.type == sf::Event::KeyPressed)
                        {
                                if (event.key.code == sf::Keyboard::BackSpace)
                                {
                                        userInput.erase(userInput.getSize() - 1,1);
                                }
                        }
                }
               
                Text.setString(userInput.getData());

                window.clear();
                window.draw(Text);
                window.display();
        }

        return 0;
}
 

Geheim

  • Full Member
  • ***
  • Posts: 201
    • View Profile
    • Email
Re: using the erase function of sf::sting
« Reply #1 on: May 21, 2014, 07:42:57 am »
Afaik, backspace also triggers the TextEntered event and has a unicode value, so you add it first and then delete it. What you should do instead of the KeyPressed event is checking if this "text" was entered and delete your last char then there. I dont know the unicode from backspace by heart though, just look it up :)
Failing to succeed does not mean failing to progress!

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: using the erase function of sf::sting
« Reply #2 on: May 21, 2014, 07:48:44 am »
Quote
I dont know the unicode from backspace by heart though, just look it up
'\b'
Laurent Gomila - SFML developer

Paradoxic4

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: using the erase function of sf::sting
« Reply #3 on: May 24, 2014, 11:53:47 pm »
Thank you Geheim, that worked perfectly!  Do you have any idea as to why that works, but my original code did not?

Geheim

  • Full Member
  • ***
  • Posts: 201
    • View Profile
    • Email
Re: using the erase function of sf::sting
« Reply #4 on: May 25, 2014, 12:18:56 am »
Because pressing the backslash triggers sf::Event::KeyPressed AND sf::Event::TextEntered.
As Laurent thankfully posted, the backslash character literal is '\b' which gets triggered by TextEntered.

So in you code you erase a character, but you also add the backslash to your text, which probably results as this circle in your text.
Failing to succeed does not mean failing to progress!

Haze

  • Full Member
  • ***
  • Posts: 201
    • View Profile
    • Github Profile
Re: using the erase function of sf::sting
« Reply #5 on: May 27, 2014, 06:16:10 am »
Before manipulating a character from a TextEntered event, you should check if the character is actually printable, otherwise you probably want to discard it.
You can use the isprint function:
if (isprint(event.text.unicode))
{
...



Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: using the erase function of sf::sting
« Reply #6 on: May 27, 2014, 08:09:31 am »
cctype functions like isprint may not be safe on Unicode.  From what I can tell the behavior is implementation-defined on anything non-ASCII.  So check that it's < 128 before applying functions like isprint and iscntrl.

Of course, there are some control characters in Unicode too, but dealing with the ASCII non-printables should be good enough.