SFML community forums

Help => Window => Topic started by: lmsmi1 on June 23, 2013, 07:50:08 am

Title: Backspace Char?
Post by: lmsmi1 on June 23, 2013, 07:50:08 am
I've loaded a TTF file and am trying to get the BackSpace key to make the last character be erased. However I'm getting some weird character when Backspace is pressed and am wondering how I can fix it to where it works like I want it to. Here's the code:

#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <SFML/Window.hpp>

sf::Color fontColor;
sf::Font mainFont;
sf::Clock myClock;

bool showCursor = false;
bool newLine = false;

void LoadFont() {
    mainFont.loadFromFile("dos.ttf");
    fontColor.r = 0;
    fontColor.g = 203;
    fontColor.b = 0;
}

int main() {
    sf::RenderWindow wnd(sf::VideoMode(1366, 768), "OpenCMD [Version 2, Beta 1]");
    wnd.setSize(sf::Vector2u(1366, 768));

    LoadFont();

    sf::Text myChar;
    myChar.setColor(fontColor);
    myChar.setFont(mainFont);
    myChar.setCharacterSize(18);
    myChar.setStyle(sf::Text::Regular);

    sf::String mainString = "System$~> ";
    sf::Text myTxt;
    myTxt.setColor(fontColor);
    myTxt.setString(mainString);
    myTxt.setFont(mainFont);
    myTxt.setCharacterSize(18);
    myTxt.setStyle(sf::Text::Regular);
    myTxt.setPosition(0, 0);

    sf::String cursor = "_";
    sf::Text myCursor;
    myCursor.setColor(fontColor);
    myCursor.setString(cursor);
    myCursor.setFont(mainFont);
    myCursor.setCharacterSize(18);
    myCursor.setStyle(sf::Text::Regular);
    myCursor.setPosition(myTxt.getGlobalBounds().width + 1, 0);

    sf::String bText;

    sf::Text buffer;
    buffer.setColor(fontColor);
    buffer.setFont(mainFont);
    buffer.setCharacterSize(18);
    buffer.setStyle(sf::Text::Regular);
    buffer.setPosition(myTxt.getGlobalBounds().width + 1, 0);

    while(wnd.isOpen()) {
        sf::Event myEvent;

        while (wnd.pollEvent(myEvent)) {
            if (myEvent.type == sf::Event::Closed) {
                wnd.close();
            }

            if (myEvent.type == sf::Event::KeyPressed) {
                if (myEvent.key.code == sf::Keyboard::Escape) {
                    wnd.close();
                }
                if (myEvent.key.code == sf::Keyboard::Return) {
                    newLine = true;
                }
            }

            if (myEvent.type == sf::Event::TextEntered) {
                if (myEvent.text.unicode < 128) {
                    bText.insert(bText.getSize(), myEvent.text.unicode);
                    buffer.setString(bText);
                }
                if (myEvent.text.unicode == sf::Keyboard::BackSpace) {
                    if (!bText.isEmpty()) {
                        bText.erase(bText.getSize(), 1);
                    }
                }
            }
        }

        if (newLine == true) {
            myTxt.setPosition(0, myTxt.getPosition().y + myTxt.getGlobalBounds().height + 1);
            bText.clear();
            buffer.setString(bText);
            buffer.setPosition(myTxt.getGlobalBounds().width + myCursor.getGlobalBounds().width + 1, myTxt.getPosition().y + 1);
            newLine = false;
        }

        wnd.draw(myTxt);
        wnd.draw(buffer);

        /*

        if (myClock.getElapsedTime() >= sf::milliseconds(500)) {
            myClock.restart();
            showCursor = !showCursor;
        }

        if(showCursor == true) {
            cursor = "_";
            myCursor.setPosition(myTxt.getGlobalBounds().width + buffer.getGlobalBounds().width + 1, myTxt.getPosition().y + 1);
        } else {
            cursor.clear();
        }

        wnd.draw(myCursor);

        */

        wnd.display();
    }
}
 
Title: Re: Backspace Char?
Post by: FRex on June 23, 2013, 08:07:18 am
            if (myEvent.type == sf::Event::TextEntered) {//lets assume we start with 'abc' in buffer
                if (myEvent.text.unicode < 128) {
                    bText.insert(bText.getSize(), myEvent.text.unicode);//if it was 'abc' now it's 'abc\b'
                    buffer.setString(bText);//text has 'abc\b' in it
                }
                if (myEvent.text.unicode == sf::Keyboard::BackSpace) {
                    if (!bText.isEmpty()) {
                        bText.erase(bText.getSize(), 1);//it's now 'abc' again, wrong, should be 'ab', also text still has 'abc\b'
                    }
                }
            }
        }
You always add characters, including backspace characters, and then set string to text, then you erase one character(so it'll just erase backspace character, you should erase two or don't add backspaces to string at all) but don't reset the string in text object so it tries and displays the backspace character.
Title: Re: Backspace Char?
Post by: Nexus on June 23, 2013, 08:19:05 am
if (myEvent.text.unicode == sf::Keyboard::BackSpace)
This is not correct, you're comparing a sf::Uint32 character with a sf::Keyboard::Key enumerator. They are not guaranteed to be equal.

The backspace character is represented by '\b'.
Title: Re: Backspace Char?
Post by: lmsmi1 on June 23, 2013, 06:04:39 pm
All right, I've changed by code around a bit:

if (myEvent.type == sf::Event::TextEntered) {
    if (myEvent.text.unicode < 128) {
        if (myEvent.text.unicode == '\b') {
            if (!bText.isEmpty()) {
                bText.erase(bText.getSize(), 2);
           }
        } else {
            bText.insert(bText.getSize(), myEvent.text.unicode);
        }
        buffer.setString(bText);
    }
}

And see that the backspace character isn't being displayed anymore, but when I do press it, it doesn't erase the last character typed "o" for example when I type "hello". I'm erasing two characters including the '\b', so it should be doing what I expect. What am I doing wrong?
Title: Re: Backspace Char?
Post by: Laurent on June 23, 2013, 06:10:53 pm
The character at getSize( )  is already one past the last one, so you're out of the valid range and never erase anything.

And no need to erase two characters, since you don't insert the backspace character.

And no need to filter out non-ASCII characters since you use a sf::String, which can store UTF-32 characters directly.
Title: Re: Backspace Char?
Post by: lmsmi1 on June 23, 2013, 07:41:00 pm
Okay then, how would I go about changing the BG color without using sf::RenderWindow::clear()? When I put it right before the main while loop, the BG blinks from black to blue (I set the BG color to blue) at an extremely fast speed. When I place the clear() inside the main while loop, the screen is fine, but remember: this is supposed to imitate a console like CMD, meaning it's supposed to show every line rendered, so since clear() is used over and over again, it doesn't let the screen keep the previously rendered lines on the screen. So is there a way to change the BG color without using clear()?
Title: Re: Backspace Char?
Post by: Laurent on June 23, 2013, 07:53:05 pm
Why do you ask a totally new question in the same thread? It will become a big mess... :P

Rendered things are never persistent, you must redraw everything every frame. So you must store all the visible text and draw it completely every frame after clearing the background.
Title: Re: Backspace Char?
Post by: lmsmi1 on June 23, 2013, 08:06:57 pm
Sorry, I'll start a new thread.