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

Author Topic: Getting and drawing an inputted string.  (Read 3342 times)

0 Members and 1 Guest are viewing this topic.

Ausche

  • Newbie
  • *
  • Posts: 19
    • View Profile
Getting and drawing an inputted string.
« on: January 30, 2017, 09:21:18 pm »
I've spent a few hours on this looking up tutorials and other posts about this, but can't find anything to help me.

What I want to do is get input from the user, such as a filename, but echo what they've typed so far on the window.

Here's a simple version of what I got so far:

In game loop:

//outside of event loop..
std::string inputString;

//...inside loop
if (GUIevent.type == sf::Event::TextEntered){
            if (GUIevent.text.unicode < 128){
                inputString += static_cast<char>(GUIevent.text.unicode);
            }
        }else if(GUIevent.type == sf::Event::KeyPressed){
            if(GUIevent.key.code == sf::Keyboard::BackSpace){
                if(!inputString.empty()){
                    inputString.erase(inputString.size() - 1);
                }
            }
//...end loop
 

In draw function:

//Declaration:
sf::Text currentText;

//Function
void GUI_loadFile::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
        if(!inputString.empty()){
        const sf::String newString(std::string(inputString));

        currentText.setString(newString); //causes error here!

        target.draw(currentText);
        }
}
 

So essentially the draw function is called every iteration of the loop and the events above edit the string that gets cast as a sf::String and drawn as a sf::Text object. 

The error reads :
error: passing 'const sf::Text' as 'this' argument of 'void sf::Text::setString(const sf::String&)' discards qualifiers [-fpermissive]|
error: conversion from 'const sf::String(std::string) {aka const sf::String(std::basic_string<char>)}' to 'const sf::String' is ambiguous

Is there anyway to get the edited `std::string` into a `const std::string` or `const sf::String` so I can pass it to the text object? I've messed around with sstream and ostreams but couldn't get that to work either.
Struggling to make a game happen!

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Getting and drawing an inputted string.
« Reply #1 on: January 30, 2017, 09:52:43 pm »
Draw is const and is not supposed to modify any members. Your code is attempting to modify the text object.

Solutions are:
update the string outside of the draw function (because it shouldn't really be modified every frame anyway, should it?)
or, make the text object mutable (the hacky way to fix this :P)

As a side note, since inputString is already an std::string, it doesn't need converting to one.
Either way, you can pass an std::string to setString:
currentText.setString(inputString);
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Ausche

  • Newbie
  • *
  • Posts: 19
    • View Profile
Re: Getting and drawing an inputted string.
« Reply #2 on: January 30, 2017, 10:13:37 pm »
Ah okay, that makes sense.
I updated it so it only adjusts the currentText when necessary:

if (GUIevent.type == sf::Event::TextEntered){
     if (GUIevent.text.unicode < 128){
          inputString += static_cast<char>(GUIevent.text.unicode);
          currentText.setString(inputString);
     }
}
if(GUIevent.key.code == sf::Keyboard::BackSpace){
     if(!inputString.empty()){
          inputString.erase(inputString.size() - 1);
          currentText.setString(inputString);
     }
}
 

and I fixed the draw function:
void GUI_loadFile::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
        //...

        if(!inputString.empty()){
                target.draw(currentText);
        }
}
 

There's something weird about the delete part, might have something to do with how I erase the character, not sure. But it draws properly! Thank you.
Struggling to make a game happen!

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Getting and drawing an inputted string.
« Reply #3 on: January 30, 2017, 10:18:13 pm »
You can also use inputString.pop_back() to remove the last character.

Note that when you press a key, you get a TextEntered event and a keypress event. Make sure you're processing the delete one before and then don't process the text entered part.

Also, make sure you are testing the event's type before checking its key code. You may be doing this but it's not in your code snippet so I thought I'd mention it.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Ausche

  • Newbie
  • *
  • Posts: 19
    • View Profile
Re: Getting and drawing an inputted string.
« Reply #4 on: January 30, 2017, 10:43:45 pm »
That may have been the issue, and I am checking for the type, here's the full event loop:
while (currentWindow->pollEvent(GUIevent)){

     if(GUIevent.type == sf::Event::KeyPressed){
          if(GUIevent.key.code == sf::Keyboard::Escape){
               visible = false;
          }
          if(GUIevent.key.code == sf::Keyboard::BackSpace){
               if(inputString.size() != 0){
                    inputString.pop_back();
                    currentText.setString(inputString);
               }
          }

           //handle RETURN key

     }
     else if (GUIevent.type == sf::Event::TextEntered){
          if (GUIevent.text.unicode < 128){
               inputString += static_cast<char>(GUIevent.text.unicode);
               currentText.setString(inputString);
          }
     }
}
 

but I'm getting a compile error as pop_back() is not a member of std::string. I can think of a few other ways to remove the last character so I might try those out and see what happens.
Struggling to make a game happen!

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Getting and drawing an inputted string.
« Reply #5 on: January 30, 2017, 11:15:58 pm »
I'm sorry; are you not using C++11?
http://www.cplusplus.com/reference/string/string/pop_back/

I'm not sure if that logic will catch what I was saying. If you get both events, you still process them both. You would need to filter them out during TextEntered.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Getting and drawing an inputted string.
« Reply #6 on: January 31, 2017, 06:29:07 am »
You can use std::isprint to filter out non-printable characters in your TextEntered event.
Laurent Gomila - SFML developer

Ausche

  • Newbie
  • *
  • Posts: 19
    • View Profile
Re: Getting and drawing an inputted string.
« Reply #7 on: January 31, 2017, 02:22:14 pm »
I don't know if I'm using the very latest version of C++. Currently using Code::Blocks 16.01 release which supports C++11. And okay I see what you're saying, thank you!
Struggling to make a game happen!