Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[SFML 2.X] Easy Notepad - aplikacja notatnik

Ostatnio zmodyfikowano 2025-06-19 12:24
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
» 2025-05-23 20:36:00
Poprawiłem pozycjonowanie kursora. Teraz już poprawnie dodaje i usuwa znaki z wyjątkiem znaków nowej linii. Pomoże ktoś ? :-)

Mogę zapłacić za pomoc 150zł

Potrzebuję:
-poprawnie obsługiwać entery, żeby nie wyświetlało tych kwadratów
-wczytywać pozycję kursora (getMousePosition)
-ustawiać kursor w linii y i pozycji x
-dodać opcję zaznaczania tekstu pomiędzu selection_start_index a selection_end_index



C/C++
#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>
sf::RenderWindow * window;

sf::Font font;
short characterSize;

std::wstring text;
std::vector < sf::Text * > texts;

sf::Vector2i mousePosition;
sf::Vector2f worldMousePosition;

sf::RectangleShape cursor;
sf::Vector2i cursorPosition = sf::Vector2i( 0, 0 );

sf::Clock timeClock;
sf::Time currentTime;


int selecting_start = 2; // selecting start cursor
int selecting_end = 4; // selecting end cursor

std::vector < sf::Text * > wrapText( int line_length = - 1 ) {
   
std::vector < sf::Text * > t;
   
std::wstring line = L"";
   
std::wstring word = L"";
   
wchar_t white_char = '\0';
   
   
for( auto & wchar: text ) {
       
if( wchar == '\n' ) {
           
line = line + white_char + word;
           
sf::Text * new_text = new sf::Text( line, font, characterSize );
           
new_text->setFillColor( sf::Color::White );
           
if( !t.empty() )
               
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
           
else
               
 new_text->setPosition( 0, 0 );
           
           
t.push_back( new_text );
           
line = L"";
           
word = L"";
           
continue;
       
}
       
       
       
       
if( wchar == L' ' || wchar == L'\t' ) {
           
white_char = wchar;
           
word = word + white_char;
           
           
if( line_length > - 1 ) {
               
               
if( line == L"" ) {
                   
sf::Text test_word( word, font, characterSize );
                   
                   
if( test_word.getGlobalBounds().width >= line_length ) {
                       
                       
std::wstring part_of_word = L"";
                       
wchar_t character = '\0';
                       
                       
for( wchar_t & ch: word ) {
                           
character = ch;
                           
sf::Text w( part_of_word + character, font, characterSize );
                           
if( w.getGlobalBounds().width >= line_length ) {
                               
sf::Text * new_text = new sf::Text( part_of_word, font, characterSize );
                               
new_text->setFillColor( sf::Color::White );
                               
if( !t.empty() )
                                   
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
                               
else
                                   
 new_text->setPosition( 0, 0 );
                               
                               
t.push_back( new_text );
                               
part_of_word = character;
                           
}
                           
else
                               
 part_of_word = part_of_word + character;
                           
                       
}
                       
                       
if( part_of_word != L"" ) {
                           
sf::Text * new_text = new sf::Text( part_of_word, font, characterSize );
                           
new_text->setFillColor( sf::Color::White );
                           
if( !t.empty() )
                               
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
                           
else
                               
 new_text->setPosition( 0, 0 );
                           
                           
t.push_back( new_text );
                           
part_of_word = L"";
                       
}
                       
                       
word = L"";
                       
continue;
                   
}
                }
               
               
sf::Text test_text( line + white_char + word, font, characterSize );
               
if( test_text.getGlobalBounds().width >= line_length ) {
                   
sf::Text * new_text = new sf::Text( line, font, characterSize );
                   
new_text->setFillColor( sf::Color::White );
                   
if( !t.empty() )
                       
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
                   
else
                       
 new_text->setPosition( 0, 0 );
                   
                   
t.push_back( new_text );
                   
line = word;
                   
word = L"";
                   
continue;
                   
               
}
               
else
                   
 line = line + word;
               
           
}
           
           
           
word = L"";
           
white_char = '\0';
       
}
       
else if( wchar != '\0' ) {
           
word += wchar;
       
}
    }
   
   
// dodaj ostatnią linię
   
sf::Text test_word( word, font, characterSize );
   
   
if( test_word.getGlobalBounds().width >= line_length ) {
       
       
std::wstring part_of_word = L"";
       
wchar_t character = '\0';
       
       
for( wchar_t & ch: word ) {
           
character = ch;
           
sf::Text w( part_of_word + character, font, characterSize );
           
if( w.getGlobalBounds().width >= line_length ) {
               
sf::Text * new_text = new sf::Text( part_of_word, font, characterSize );
               
new_text->setFillColor( sf::Color::White );
               
if( !t.empty() )
                   
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
               
else
                   
 new_text->setPosition( 0, 0 );
               
               
t.push_back( new_text );
               
part_of_word = character;
           
}
           
else
               
 part_of_word = part_of_word + character;
           
       
}
       
       
if( part_of_word != L"" ) {
           
sf::Text * new_text = new sf::Text( part_of_word, font, characterSize );
           
new_text->setFillColor( sf::Color::White );
           
if( !t.empty() )
               
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
           
else
               
 new_text->setPosition( 0, 0 );
           
           
t.push_back( new_text );
           
part_of_word = L"";
       
}
       
       
word = L"";
   
}
   
   
if( !word.empty() || !line.empty() ) {
       
       
sf::Text test_text( line + word, font, characterSize );
       
if( line_length > - 1 && test_text.getGlobalBounds().width >= line_length && !line.empty() ) {
           
// dodaj najpierw obecną linię
           
sf::Text * new_text = new sf::Text( line, font, characterSize );
           
new_text->setFillColor( sf::Color::White );
           
new_text->setPosition( 0, t.empty() ? 0
               
: t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
           
t.push_back( new_text );
           
           
// a potem słowo w nowej linii
           
new_text = new sf::Text( word, font, characterSize );
           
new_text->setFillColor( sf::Color::White );
           
new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
           
t.push_back( new_text );
       
}
       
else {
           
// zmieściło się wszystko — dodaj jako jedna linia
           
sf::Text * new_text = new sf::Text( line + word, font, characterSize );
           
new_text->setFillColor( sf::Color::White );
           
new_text->setPosition( 0, t.empty() ? 0
               
: t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
           
t.push_back( new_text );
       
}
    }
   
   
return t;
}

sf::Vector2i getCursorPosition() {
   
   
sf::Vector2i cur_pos = sf::Vector2i( 0, 0 );
   
   
for( int t = 0; t < texts.size(); t++ ) {
       
       
for( size_t i = 0; i < texts[ t ]->getString().getSize(); ++i ) {
           
           
sf::Vector2f charPos = texts[ t ]->findCharacterPos( i );
           
float nextX = texts[ t ]->findCharacterPos( i + 1 ).x;
           
           
sf::FloatRect charRect( charPos.x, charPos.y, nextX - charPos.x, font.getLineSpacing( characterSize ) );
           
           
if( charRect.contains( worldMousePosition ) ) {
               
               
if( worldMousePosition.x < charRect.left + charRect.width / 2 )
                   
 return sf::Vector2i( i, t );
               
else
                   
 return sf::Vector2i( i + 1, t );
               
           
}
           
           
bool isLastChar =( i == texts[ t ]->getString().getSize() - 1 );
           
if( isLastChar &&
           
worldMousePosition.x > charRect.left &&
           
worldMousePosition.y >= charRect.top &&
           
worldMousePosition.y <= charRect.top + charRect.height )
           
{
               
return sf::Vector2i( i + 1, t );
           
}
        }
    }
   
   
return cur_pos;
}

void setCursorPosition( sf::Vector2i cursor_position ) {
   
cursorPosition = cursor_position;
   
   
// Przechodzimy przez wszystkie linie tekstu
   
for( int t = 0; t < texts.size(); t++ ) {
       
       
if( t == cursor_position.y ) {
           
std::wstring line = texts[ t ]->getString().toWideString();
           
           
if( cursor_position.x <= line.size() ) {
               
sf::Vector2f charPos = texts[ t ]->findCharacterPos( cursor_position.x );
               
               
cursor.setPosition( charPos.x, charPos.y );
               
return;
           
}
        }
    }
}

int getCursorIndex( sf::Vector2i position ) {
   
int index = 0;
   
for( int i = 0; i < position.y && i < texts.size(); ++i ) {
       
index += texts[ i ]->getString().getSize();
   
}
   
index += position.x;
   
return index;
}

sf::Vector2i getCursorFromIndex( int index ) {
   
int current = 0;
   
for( int y = 0; y < texts.size(); ++y ) {
       
int lineSize = texts[ y ]->getString().getSize();
       
if( index <= current + lineSize ) {
           
return sf::Vector2i( index - current, y );
       
}
       
current += lineSize;
   
}
   
if( !texts.empty() )
       
 return sf::Vector2i( texts.back()->getString().getSize(), texts.size() - 1 );
   
   
return sf::Vector2i( 0, 0 );
}

int main()
{
   
   
sf::View view( sf::FloatRect( 0, 0, 480, 640 ) );
   
window = new sf::RenderWindow( sf::VideoMode( view.getSize().x, view.getSize().y ), "Easy Notepad!", sf::Style::Titlebar | sf::Style::Close );
   
   
font.loadFromFile( "arial.ttf" );
   
characterSize = 17;
   
text =
   
L"Gracz najpierw zagaduje handlarza gdyż ten jest najbliżej. Handlarz oferuje skórzane ubranie w zamian za dostarczenie kilku skór od myśliwego, "
    L"którego gracz mijał wcześniej. Zielarka da graczowi trochę złota w zamian za przyniesienie kilku roślin leczniczych. "
    L"U kowala gracz może zakupić oręż - zwyczajny prosty miecz gdyż jest to niewprawiony kowal w miecznictwie. "
    L"Zaś do wieży mędrca nie da się dostać.Gracz rusza spowrotem do myśliwego po skóry, lecz ten jest nieufny, "
    L"ale ostatecznie zgadza się i daje graczowi skóry."
;
   
   
   
texts = wrapText( window->getSize().x );
   
   
cursor = sf::RectangleShape( sf::Vector2f( 2, characterSize ) );
   
cursor.setFillColor( sf::Color::Red );
   
   
sf::Clock clock;
   
   
while( window->isOpen() )
   
{
       
       
mousePosition = sf::Mouse::getPosition( * window ); // get the mouse position about window
       
worldMousePosition = window->mapPixelToCoords( mousePosition ); // get global mouse position
       
       
currentTime = timeClock.getElapsedTime();
       
       
sf::Event event;
       
while( window->pollEvent( event ) ) {
           
           
if( event.type == sf::Event::Closed )
               
 window->close();
           
           
if( event.type == sf::Event::Resized )
           
{
               
// Aktualizacja widoku bez skalowania
               
sf::View view;
               
view.setSize( static_cast < float >( event.size.width ), static_cast < float >( event.size.height ) );
               
view.setCenter( view.getSize() / 2.f );
               
window->setView( view );
           
}
           
else if( event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Left ) {
               
sf::Vector2i cur_pos = getCursorPosition();
               
setCursorPosition( cur_pos );
           
}
           
else if( event.type == sf::Event::TextEntered ) {
               
               
if( event.text.unicode < 128 ) {
                   
                   
int index = 0;
                   
for( int i = 0; i < cursorPosition.y; i++ ) {
                       
index = index + texts[ i ]->getString().toWideString().size();
                   
}
                   
index = index + cursorPosition.x;
                   
                   
if( event.text.unicode == '\b' ) {
                       
                       
if( index > 0 && !text.empty() ) {
                           
text.erase( index - 1, 1 );
                           
index -= 1;
                       
}
                    }
                   
else if( event.text.unicode == 32 ) {
                       
// space
                       
text.insert( index, 1, char( ' ' ) );
                       
index += 1;
                   
}
                   
else if( event.text.unicode == 13 ) {
                       
// enter
                       
text.insert( index, 1, char( '\n' ) );
                       
index += 1;
                   
}
                   
else {
                       
// is character
                       
text.insert( index, 1, wchar_t( event.text.unicode ) );
                       
index += 1;
                   
}
                   
                   
for( auto & t: texts )
                       
 delete t;
                   
                   
texts = wrapText( window->getSize().x );
                   
                   
cursorPosition = getCursorFromIndex( index );
                   
setCursorPosition( cursorPosition );
               
}
               
               
            }
           
else if( event.type == sf::Event::KeyPressed ) {
               
if( event.key.code == sf::Keyboard::Left ) {
                   
if( cursorPosition.x > 0 ) {
                       
cursorPosition.x -= 1;
                   
}
                   
else {
                       
if( cursorPosition.y > 0 ) {
                           
cursorPosition.y -= 1;
                           
cursorPosition.x = texts[ cursorPosition.y ]->getString().toWideString().size();
                       
}
                    }
                   
                }
               
else if( event.key.code == sf::Keyboard::Right ) {
                   
if( cursorPosition.x < texts[ cursorPosition.y ]->getString().toWideString().size() ) {
                       
cursorPosition.x += 1;
                   
}
                   
else {
                       
if( cursorPosition.y < texts.size() - 1 ) {
                           
cursorPosition.x = 0;
                           
cursorPosition.y += 1;
                       
}
                       
                       
                       
                    }
                   
                   
                }
               
else if( event.key.code == sf::Keyboard::Up ) {
                   
if( cursorPosition.y > 0 )
                       
 cursorPosition.y -= 1;
                   
               
}
               
else if( event.key.code == sf::Keyboard::Down ) {
                   
if( cursorPosition.y < texts.size() - 1 )
                       
 cursorPosition.y += 1;
                   
               
}
               
               
               
setCursorPosition( cursorPosition );
               
           
}
           
           
        }
       
       
window->clear( sf::Color( 48, 48, 48, 255 ) );
       
for( auto & text: texts )
           
 window->draw( * text );
       
       
if( std::fmod( currentTime.asSeconds(), 0.6f ) < 0.3f )
           
 window->draw( cursor );
       
       
window->display();
   
}
}
P-182392
DejaVu
» 2025-05-24 21:35:07
Usuń wszystkie znaki '\r', a potem podziel na wiersze '\n'.
P-182393
tBane
Temat założony przez niniejszego użytkownika
» 2025-05-24 21:38:30
Operuję tylko na znakach '\0' '\n' ' ' '\t'. Nie korzystam ze znaków '\r'

// edit
wprowadziłem poprawki by nie wczytywało znaków '\r' ale to nic nie dało.
Oznaczyłem korekty komentarzem "// poprawka"

// edit2
entery przesuwają karetkę w prawo o 1. Ja już się pogubiłem w tym kodzie :-/

C/C++
#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>
sf::RenderWindow * window;

sf::Font font;
short characterSize;

std::wstring text;
std::vector < sf::Text * > texts;

sf::Vector2i mousePosition;
sf::Vector2f worldMousePosition;

sf::RectangleShape cursor;
sf::Vector2i cursorPosition = sf::Vector2i( 0, 0 );

sf::Clock timeClock;
sf::Time currentTime;


int selecting_start = 2; // selecting start cursor
int selecting_end = 4; // selecting end cursor

std::vector < sf::Text * > wrapText( int line_length = - 1 ) {
   
std::vector < sf::Text * > t;
   
std::wstring line = L"";
   
std::wstring word = L"";
   
wchar_t white_char = '\0';
   
   
for( auto & wchar: text ) {
       
if( wchar == '\n' ) {
           
           
if( white_char != '\0' && white_char != '\r' ) // poprawka
               
 line = line + word + white_char;
           
else
               
 line = line + word;
           
           
sf::Text * new_text = new sf::Text( line, font, characterSize );
           
new_text->setFillColor( sf::Color::White );
           
if( !t.empty() )
               
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
           
else
               
 new_text->setPosition( 0, 0 );
           
           
t.push_back( new_text );
           
line = L"";
           
word = L"";
           
continue;
       
}
       
       
       
       
if( wchar == L' ' || wchar == L'\t' ) {
           
white_char = wchar;
           
word = word + white_char;
           
           
if( line_length > - 1 ) {
               
               
if( line == L"" ) {
                   
sf::Text test_word( word, font, characterSize );
                   
                   
if( test_word.getGlobalBounds().width >= line_length ) {
                       
                       
std::wstring part_of_word = L"";
                       
wchar_t character = '\0';
                       
                       
for( wchar_t & ch: word ) {
                           
character = ch;
                           
sf::Text w( part_of_word + character, font, characterSize );
                           
if( w.getGlobalBounds().width >= line_length ) {
                               
sf::Text * new_text = new sf::Text( part_of_word, font, characterSize );
                               
new_text->setFillColor( sf::Color::White );
                               
if( !t.empty() )
                                   
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
                               
else
                                   
 new_text->setPosition( 0, 0 );
                               
                               
t.push_back( new_text );
                               
part_of_word = character;
                           
}
                           
else
                               
 part_of_word = part_of_word + character;
                           
                       
}
                       
                       
if( part_of_word != L"" ) {
                           
sf::Text * new_text = new sf::Text( part_of_word, font, characterSize );
                           
new_text->setFillColor( sf::Color::White );
                           
if( !t.empty() )
                               
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
                           
else
                               
 new_text->setPosition( 0, 0 );
                           
                           
t.push_back( new_text );
                           
part_of_word = L"";
                       
}
                       
                       
word = L"";
                       
continue;
                   
}
                }
               
               
sf::Text test_text( line + white_char + word, font, characterSize );
               
if( test_text.getGlobalBounds().width >= line_length ) {
                   
sf::Text * new_text = new sf::Text( line, font, characterSize );
                   
new_text->setFillColor( sf::Color::White );
                   
if( !t.empty() )
                       
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
                   
else
                       
 new_text->setPosition( 0, 0 );
                   
                   
t.push_back( new_text );
                   
line = word;
                   
word = L"";
                   
continue;
                   
               
}
               
else
                   
 line = line + word;
               
           
}
           
           
           
word = L"";
           
white_char = '\0';
       
}
       
else if( wchar != '\0' && wchar != '\r' ) { // poprawka
           
word += wchar;
       
}
    }
   
   
// dodaj ostatnią linię
   
sf::Text test_word( word, font, characterSize );
   
   
if( test_word.getGlobalBounds().width >= line_length ) {
       
       
std::wstring part_of_word = L"";
       
wchar_t character = '\0';
       
       
for( wchar_t & ch: word ) {
           
character = ch;
           
sf::Text w( part_of_word + character, font, characterSize );
           
if( w.getGlobalBounds().width >= line_length ) {
               
sf::Text * new_text = new sf::Text( part_of_word, font, characterSize );
               
new_text->setFillColor( sf::Color::White );
               
if( !t.empty() )
                   
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
               
else
                   
 new_text->setPosition( 0, 0 );
               
               
t.push_back( new_text );
               
part_of_word = character;
           
}
           
else
               
 part_of_word = part_of_word + character;
           
       
}
       
       
if( part_of_word != L"" ) {
           
sf::Text * new_text = new sf::Text( part_of_word, font, characterSize );
           
new_text->setFillColor( sf::Color::White );
           
if( !t.empty() )
               
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
           
else
               
 new_text->setPosition( 0, 0 );
           
           
t.push_back( new_text );
           
part_of_word = L"";
       
}
       
       
word = L"";
   
}
   
   
if( !word.empty() || !line.empty() ) {
       
       
sf::Text test_text( line + word, font, characterSize );
       
if( line_length > - 1 && test_text.getGlobalBounds().width >= line_length && !line.empty() ) {
           
// dodaj najpierw obecną linię
           
sf::Text * new_text = new sf::Text( line, font, characterSize );
           
new_text->setFillColor( sf::Color::White );
           
new_text->setPosition( 0, t.empty() ? 0
               
: t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
           
t.push_back( new_text );
           
           
// a potem słowo w nowej linii
           
new_text = new sf::Text( word, font, characterSize );
           
new_text->setFillColor( sf::Color::White );
           
new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
           
t.push_back( new_text );
       
}
       
else {
           
// zmieściło się wszystko — dodaj jako jedna linia
           
sf::Text * new_text = new sf::Text( line + word, font, characterSize );
           
new_text->setFillColor( sf::Color::White );
           
new_text->setPosition( 0, t.empty() ? 0
               
: t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
           
t.push_back( new_text );
       
}
    }
   
   
return t;
}

sf::Vector2i getCursorPosition() {
   
   
sf::Vector2i cur_pos = sf::Vector2i( 0, 0 );
   
   
for( int t = 0; t < texts.size(); t++ ) {
       
       
for( size_t i = 0; i < texts[ t ]->getString().getSize(); ++i ) {
           
           
sf::Vector2f charPos = texts[ t ]->findCharacterPos( i );
           
float nextX = texts[ t ]->findCharacterPos( i + 1 ).x;
           
           
sf::FloatRect charRect( charPos.x, charPos.y, nextX - charPos.x, font.getLineSpacing( characterSize ) );
           
           
if( charRect.contains( worldMousePosition ) ) {
               
               
if( worldMousePosition.x < charRect.left + charRect.width / 2 )
                   
 return sf::Vector2i( i, t );
               
else
                   
 return sf::Vector2i( i + 1, t );
               
           
}
           
           
bool isLastChar =( i == texts[ t ]->getString().getSize() - 1 );
           
if( isLastChar &&
           
worldMousePosition.x > charRect.left &&
           
worldMousePosition.y >= charRect.top &&
           
worldMousePosition.y <= charRect.top + charRect.height )
           
{
               
return sf::Vector2i( i + 1, t );
           
}
        }
    }
   
   
return cur_pos;
}

void setCursorPosition( sf::Vector2i cursor_position ) {
   
cursorPosition = cursor_position;
   
   
// Przechodzimy przez wszystkie linie tekstu
   
for( int t = 0; t < texts.size(); t++ ) {
       
       
if( t == cursor_position.y ) {
           
std::wstring line = texts[ t ]->getString().toWideString();
           
           
if( cursor_position.x <= line.size() ) {
               
sf::Vector2f charPos = texts[ t ]->findCharacterPos( cursor_position.x );
               
               
cursor.setPosition( charPos.x, charPos.y );
               
return;
           
}
        }
    }
}

int getCursorIndex( sf::Vector2i position ) {
   
int index = 0;
   
for( int i = 0; i < position.y && i < texts.size(); ++i ) {
       
index += texts[ i ]->getString().getSize();
   
}
   
index += position.x;
   
return index;
}

sf::Vector2i getCursorFromIndex( int index ) {
   
int current = 0;
   
for( int y = 0; y < texts.size(); ++y ) {
       
int lineSize = texts[ y ]->getString().getSize();
       
if( index <= current + lineSize ) {
           
return sf::Vector2i( index - current, y );
       
}
       
current += lineSize;
   
}
   
if( !texts.empty() )
       
 return sf::Vector2i( texts.back()->getString().getSize(), texts.size() - 1 );
   
   
return sf::Vector2i( 0, 0 );
}

int main()
{
   
   
sf::View view( sf::FloatRect( 0, 0, 480, 640 ) );
   
window = new sf::RenderWindow( sf::VideoMode( view.getSize().x, view.getSize().y ), "Easy Notepad!", sf::Style::Titlebar | sf::Style::Close );
   
   
font.loadFromFile( "arial.ttf" );
   
characterSize = 17;
   
text =
   
L"Gracz najpierw zagaduje handlarza gdyż ten jest najbliżej. Handlarz oferuje skórzane ubranie w zamian za dostarczenie kilku skór od myśliwego, "
    L"którego gracz mijał wcześniej. Zielarka da graczowi trochę złota w zamian za przyniesienie kilku roślin leczniczych. "
    L"U kowala gracz może zakupić oręż - zwyczajny prosty miecz gdyż jest to niewprawiony kowal w miecznictwie. "
    L"Zaś do wieży mędrca nie da się dostać.Gracz rusza spowrotem do myśliwego po skóry, lecz ten jest nieufny, "
    L"ale ostatecznie zgadza się i daje graczowi skóry."
;
   
   
   
texts = wrapText( window->getSize().x );
   
   
cursor = sf::RectangleShape( sf::Vector2f( 2, characterSize ) );
   
cursor.setFillColor( sf::Color::Red );
   
   
sf::Clock clock;
   
   
while( window->isOpen() )
   
{
       
       
mousePosition = sf::Mouse::getPosition( * window ); // get the mouse position about window
       
worldMousePosition = window->mapPixelToCoords( mousePosition ); // get global mouse position
       
       
currentTime = timeClock.getElapsedTime();
       
       
sf::Event event;
       
while( window->pollEvent( event ) ) {
           
           
if( event.type == sf::Event::Closed )
               
 window->close();
           
           
if( event.type == sf::Event::Resized )
           
{
               
// Aktualizacja widoku bez skalowania
               
sf::View view;
               
view.setSize( static_cast < float >( event.size.width ), static_cast < float >( event.size.height ) );
               
view.setCenter( view.getSize() / 2.f );
               
window->setView( view );
           
}
           
else if( event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Left ) {
               
sf::Vector2i cur_pos = getCursorPosition();
               
setCursorPosition( cur_pos );
           
}
           
else if( event.type == sf::Event::TextEntered ) {
               
               
if( event.text.unicode < 128 ) {
                   
                   
int index = 0;
                   
for( int i = 0; i < cursorPosition.y; i++ ) {
                       
index = index + texts[ i ]->getString().toWideString().size();
                   
}
                   
index = index + cursorPosition.x;
                   
                   
if( event.text.unicode == '\b' ) {
                       
                       
if( index > 0 && !text.empty() ) {
                           
text.erase( index - 1, 1 );
                           
index -= 1;
                       
}
                    }
                   
else if( event.text.unicode == 32 ) {
                       
// space
                       
text.insert( index, 1, char( ' ' ) );
                       
index += 1;
                   
}
                   
else if( event.text.unicode == 13 ) {
                       
// enter
                       
text.insert( index, 1, char( '\n' ) );
                       
index += 1;
                   
}
                   
else {
                       
// is character
                       
text.insert( index, 1, wchar_t( event.text.unicode ) );
                       
index += 1;
                   
}
                   
                   
for( auto & t: texts )
                       
 delete t;
                   
                   
texts = wrapText( window->getSize().x );
                   
                   
cursorPosition = getCursorFromIndex( index );
                   
setCursorPosition( cursorPosition );
               
}
               
               
            }
           
else if( event.type == sf::Event::KeyPressed ) {
               
if( event.key.code == sf::Keyboard::Left ) {
                   
if( cursorPosition.x > 0 ) {
                       
cursorPosition.x -= 1;
                   
}
                   
else {
                       
if( cursorPosition.y > 0 ) {
                           
cursorPosition.y -= 1;
                           
cursorPosition.x = texts[ cursorPosition.y ]->getString().toWideString().size();
                       
}
                    }
                   
                }
               
else if( event.key.code == sf::Keyboard::Right ) {
                   
if( cursorPosition.x < texts[ cursorPosition.y ]->getString().toWideString().size() ) {
                       
cursorPosition.x += 1;
                   
}
                   
else {
                       
if( cursorPosition.y < texts.size() - 1 ) {
                           
cursorPosition.x = 0;
                           
cursorPosition.y += 1;
                       
}
                       
                       
                       
                    }
                   
                   
                }
               
else if( event.key.code == sf::Keyboard::Up ) {
                   
if( cursorPosition.y > 0 )
                       
 cursorPosition.y -= 1;
                   
               
}
               
else if( event.key.code == sf::Keyboard::Down ) {
                   
if( cursorPosition.y < texts.size() - 1 )
                       
 cursorPosition.y += 1;
                   
               
}
               
               
               
setCursorPosition( cursorPosition );
               
           
}
           
           
        }
       
       
window->clear( sf::Color( 48, 48, 48, 255 ) );
       
for( auto & text: texts )
           
 window->draw( * text );
       
       
if( std::fmod( currentTime.asSeconds(), 0.6f ) < 0.3f )
           
 window->draw( cursor );
       
       
window->display();
   
}
}
P-182394
DejaVu
» 2025-05-24 22:05:54
Jeżeli masz kratkę to wyświetlasz znak którego nie powinieneś. debuggerem możesz zobaczyć co to za znak. Jeżeli dzielisz tekst na linie to nawet '\n' nie powinien się znaleźć w linii.
P-182395
tBane
Temat założony przez niniejszego użytkownika
» 2025-05-24 22:10:19
Ok, nie ma już tych kratek. Teraz gdy wprowadzam enter to przesuwa mi karetkę w prawo

Mogę zapłacić za napisanie programu 150zł

// edit
To chyba źle działają te funkcje:
C/C++
cursorPosition = getCursorFromIndex( index );
setCursorPosition( cursorPosition );


C/C++
#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>
sf::RenderWindow * window;

sf::Font font;
short characterSize;

std::wstring text;
std::vector < sf::Text * > texts;

sf::Vector2i mousePosition;
sf::Vector2f worldMousePosition;

sf::RectangleShape cursor;
sf::Vector2i cursorPosition = sf::Vector2i( 0, 0 );

sf::Clock timeClock;
sf::Time currentTime;


int selecting_start = 2; // selecting start cursor
int selecting_end = 4; // selecting end cursor

std::vector < sf::Text * > wrapText( int line_length = - 1 ) {
   
std::vector < sf::Text * > t;
   
std::wstring line = L"";
   
std::wstring word = L"";
   
wchar_t white_char = '\0';
   
   
for( auto & wchar: text ) {
       
if( wchar == '\n' ) {
           
           
if( white_char != '\0' && white_char != '\r' ) // poprawka
               
 line = line + word + white_char;
           
else
               
 line = line + word;
           
           
sf::Text * new_text = new sf::Text( line, font, characterSize );
           
new_text->setFillColor( sf::Color::White );
           
if( !t.empty() )
               
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
           
else
               
 new_text->setPosition( 0, 0 );
           
           
t.push_back( new_text );
           
line = L"";
           
word = L"";
           
continue;
       
}
       
       
       
       
if( wchar == L' ' || wchar == L'\t' ) {
           
white_char = wchar;
           
word = word + white_char;
           
           
if( line_length > - 1 ) {
               
               
if( line == L"" ) {
                   
sf::Text test_word( word, font, characterSize );
                   
                   
if( test_word.getGlobalBounds().width >= line_length ) {
                       
                       
std::wstring part_of_word = L"";
                       
wchar_t character = '\0';
                       
                       
for( wchar_t & ch: word ) {
                           
character = ch;
                           
sf::Text w( part_of_word + character, font, characterSize );
                           
if( w.getGlobalBounds().width >= line_length ) {
                               
sf::Text * new_text = new sf::Text( part_of_word, font, characterSize );
                               
new_text->setFillColor( sf::Color::White );
                               
if( !t.empty() )
                                   
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
                               
else
                                   
 new_text->setPosition( 0, 0 );
                               
                               
t.push_back( new_text );
                               
part_of_word = character;
                           
}
                           
else
                               
 part_of_word = part_of_word + character;
                           
                       
}
                       
                       
if( part_of_word != L"" ) {
                           
sf::Text * new_text = new sf::Text( part_of_word, font, characterSize );
                           
new_text->setFillColor( sf::Color::White );
                           
if( !t.empty() )
                               
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
                           
else
                               
 new_text->setPosition( 0, 0 );
                           
                           
t.push_back( new_text );
                           
part_of_word = L"";
                       
}
                       
                       
word = L"";
                       
continue;
                   
}
                }
               
               
sf::Text test_text( line + white_char + word, font, characterSize );
               
if( test_text.getGlobalBounds().width >= line_length ) {
                   
sf::Text * new_text = new sf::Text( line, font, characterSize );
                   
new_text->setFillColor( sf::Color::White );
                   
if( !t.empty() )
                       
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
                   
else
                       
 new_text->setPosition( 0, 0 );
                   
                   
t.push_back( new_text );
                   
line = word;
                   
word = L"";
                   
continue;
                   
               
}
               
else
                   
 line = line + word;
               
           
}
           
           
           
word = L"";
           
white_char = '\0';
       
}
       
else if( wchar != '\0' && wchar != '\r' ) { // poprawka
           
word += wchar;
       
}
    }
   
   
// dodaj ostatnią linię
   
sf::Text test_word( word, font, characterSize );
   
   
if( test_word.getGlobalBounds().width >= line_length ) {
       
       
std::wstring part_of_word = L"";
       
wchar_t character = '\0';
       
       
for( wchar_t & ch: word ) {
           
character = ch;
           
sf::Text w( part_of_word + character, font, characterSize );
           
if( w.getGlobalBounds().width >= line_length ) {
               
sf::Text * new_text = new sf::Text( part_of_word, font, characterSize );
               
new_text->setFillColor( sf::Color::White );
               
if( !t.empty() )
                   
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
               
else
                   
 new_text->setPosition( 0, 0 );
               
               
t.push_back( new_text );
               
part_of_word = character;
           
}
           
else
               
 part_of_word = part_of_word + character;
           
       
}
       
       
if( part_of_word != L"" ) {
           
sf::Text * new_text = new sf::Text( part_of_word, font, characterSize );
           
new_text->setFillColor( sf::Color::White );
           
if( !t.empty() )
               
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
           
else
               
 new_text->setPosition( 0, 0 );
           
           
t.push_back( new_text );
           
part_of_word = L"";
       
}
       
       
word = L"";
   
}
   
   
if( !word.empty() || !line.empty() ) {
       
       
sf::Text test_text( line + word, font, characterSize );
       
if( line_length > - 1 && test_text.getGlobalBounds().width >= line_length && !line.empty() ) {
           
// dodaj najpierw obecną linię
           
sf::Text * new_text = new sf::Text( line, font, characterSize );
           
new_text->setFillColor( sf::Color::White );
           
new_text->setPosition( 0, t.empty() ? 0
               
: t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
           
t.push_back( new_text );
           
           
// a potem słowo w nowej linii
           
new_text = new sf::Text( word, font, characterSize );
           
new_text->setFillColor( sf::Color::White );
           
new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
           
t.push_back( new_text );
       
}
       
else {
           
// zmieściło się wszystko — dodaj jako jedna linia
           
sf::Text * new_text = new sf::Text( line + word, font, characterSize );
           
new_text->setFillColor( sf::Color::White );
           
new_text->setPosition( 0, t.empty() ? 0
               
: t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
           
t.push_back( new_text );
       
}
    }
   
   
return t;
}

sf::Vector2i getCursorPosition() {
   
   
sf::Vector2i cur_pos = sf::Vector2i( 0, 0 );
   
   
for( int t = 0; t < texts.size(); t++ ) {
       
       
for( size_t i = 0; i < texts[ t ]->getString().getSize(); ++i ) {
           
           
sf::Vector2f charPos = texts[ t ]->findCharacterPos( i );
           
float nextX = texts[ t ]->findCharacterPos( i + 1 ).x;
           
           
sf::FloatRect charRect( charPos.x, charPos.y, nextX - charPos.x, font.getLineSpacing( characterSize ) );
           
           
if( charRect.contains( worldMousePosition ) ) {
               
               
if( worldMousePosition.x < charRect.left + charRect.width / 2 )
                   
 return sf::Vector2i( i, t );
               
else
                   
 return sf::Vector2i( i + 1, t );
               
           
}
           
           
bool isLastChar =( i == texts[ t ]->getString().getSize() - 1 );
           
if( isLastChar &&
           
worldMousePosition.x > charRect.left &&
           
worldMousePosition.y >= charRect.top &&
           
worldMousePosition.y <= charRect.top + charRect.height )
           
{
               
return sf::Vector2i( i + 1, t );
           
}
        }
    }
   
   
return cur_pos;
}

void setCursorPosition( sf::Vector2i cursor_position ) {
   
cursorPosition = cursor_position;
   
   
// Przechodzimy przez wszystkie linie tekstu
   
for( int t = 0; t < texts.size(); t++ ) {
       
       
if( t == cursor_position.y ) {
           
std::wstring line = texts[ t ]->getString().toWideString();
           
           
if( cursor_position.x <= line.size() ) {
               
sf::Vector2f charPos = texts[ t ]->findCharacterPos( cursor_position.x );
               
               
cursor.setPosition( charPos.x, charPos.y );
               
return;
           
}
        }
    }
}

int getCursorIndex( sf::Vector2i position ) {
   
int index = 0;
   
for( int i = 0; i < position.y && i < texts.size(); ++i ) {
       
index += texts[ i ]->getString().getSize();
   
}
   
index += position.x;
   
return index;
}

sf::Vector2i getCursorFromIndex( int index ) {
   
int current = 0;
   
for( int y = 0; y < texts.size(); ++y ) {
       
int lineSize = texts[ y ]->getString().getSize();
       
if( index <= current + lineSize ) {
           
return sf::Vector2i( index - current, y );
       
}
       
current += lineSize;
   
}
   
if( !texts.empty() )
       
 return sf::Vector2i( texts.back()->getString().getSize(), texts.size() - 1 );
   
   
return sf::Vector2i( 0, 0 );
}

int main()
{
   
   
sf::View view( sf::FloatRect( 0, 0, 480, 640 ) );
   
window = new sf::RenderWindow( sf::VideoMode( view.getSize().x, view.getSize().y ), "Easy Notepad!", sf::Style::Titlebar | sf::Style::Close );
   
   
font.loadFromFile( "arial.ttf" );
   
characterSize = 17;
   
text =
   
L"Gracz najpierw zagaduje handlarza gdyż ten jest najbliżej. Handlarz oferuje skórzane ubranie w zamian za dostarczenie kilku skór od myśliwego, "
    L"którego gracz mijał wcześniej. Zielarka da graczowi trochę złota w zamian za przyniesienie kilku roślin leczniczych. "
    L"U kowala gracz może zakupić oręż - zwyczajny prosty miecz gdyż jest to niewprawiony kowal w miecznictwie. "
    L"Zaś do wieży mędrca nie da się dostać.Gracz rusza spowrotem do myśliwego po skóry, lecz ten jest nieufny, "
    L"ale ostatecznie zgadza się i daje graczowi skóry."
;
   
   
   
texts = wrapText( window->getSize().x );
   
   
cursor = sf::RectangleShape( sf::Vector2f( 2, characterSize ) );
   
cursor.setFillColor( sf::Color::Red );
   
   
sf::Clock clock;
   
   
while( window->isOpen() )
   
{
       
       
mousePosition = sf::Mouse::getPosition( * window ); // get the mouse position about window
       
worldMousePosition = window->mapPixelToCoords( mousePosition ); // get global mouse position
       
       
currentTime = timeClock.getElapsedTime();
       
       
sf::Event event;
       
while( window->pollEvent( event ) ) {
           
           
if( event.type == sf::Event::Closed )
               
 window->close();
           
           
if( event.type == sf::Event::Resized )
           
{
               
// Aktualizacja widoku bez skalowania
               
sf::View view;
               
view.setSize( static_cast < float >( event.size.width ), static_cast < float >( event.size.height ) );
               
view.setCenter( view.getSize() / 2.f );
               
window->setView( view );
           
}
           
else if( event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Left ) {
               
sf::Vector2i cur_pos = getCursorPosition();
               
setCursorPosition( cur_pos );
           
}
           
else if( event.type == sf::Event::TextEntered ) {
               
               
if( event.text.unicode < 128 ) {
                   
                   
int index = 0;
                   
for( int i = 0; i < cursorPosition.y; i++ ) {
                       
index = index + texts[ i ]->getString().toWideString().size();
                   
}
                   
index = index + cursorPosition.x;
                   
                   
if( event.text.unicode == '\b' ) {
                       
                       
if( index > 0 && !text.empty() ) {
                           
text.erase( index - 1, 1 );
                           
index -= 1;
                       
}
                    }
                   
else if( event.text.unicode == 32 ) {
                       
// space
                       
text.insert( index, 1, char( ' ' ) );
                       
index += 1;
                   
}
                   
else if( event.text.unicode == 13 ) {
                       
// enter
                       
text.insert( index, 1, char( '\n' ) );
                       
index += 1;
                   
}
                   
else {
                       
// is character
                       
text.insert( index, 1, wchar_t( event.text.unicode ) );
                       
index += 1;
                   
}
                   
                   
for( auto & t: texts )
                       
 delete t;
                   
                   
texts = wrapText( window->getSize().x );
                   
                   
cursorPosition = getCursorFromIndex( index );
                   
setCursorPosition( cursorPosition );
               
}
               
               
            }
           
else if( event.type == sf::Event::KeyPressed ) {
               
if( event.key.code == sf::Keyboard::Left ) {
                   
if( cursorPosition.x > 0 ) {
                       
cursorPosition.x -= 1;
                   
}
                   
else {
                       
if( cursorPosition.y > 0 ) {
                           
cursorPosition.y -= 1;
                           
cursorPosition.x = texts[ cursorPosition.y ]->getString().toWideString().size();
                       
}
                    }
                   
                }
               
else if( event.key.code == sf::Keyboard::Right ) {
                   
if( cursorPosition.x < texts[ cursorPosition.y ]->getString().toWideString().size() ) {
                       
cursorPosition.x += 1;
                   
}
                   
else {
                       
if( cursorPosition.y < texts.size() - 1 ) {
                           
cursorPosition.x = 0;
                           
cursorPosition.y += 1;
                       
}
                       
                       
                       
                    }
                   
                   
                }
               
else if( event.key.code == sf::Keyboard::Up ) {
                   
if( cursorPosition.y > 0 )
                       
 cursorPosition.y -= 1;
                   
               
}
               
else if( event.key.code == sf::Keyboard::Down ) {
                   
if( cursorPosition.y < texts.size() - 1 )
                       
 cursorPosition.y += 1;
                   
               
}
               
               
               
setCursorPosition( cursorPosition );
               
           
}
           
           
        }
       
       
window->clear( sf::Color( 48, 48, 48, 255 ) );
       
for( auto & text: texts )
           
 window->draw( * text );
       
       
if( std::fmod( currentTime.asSeconds(), 0.6f ) < 0.3f )
           
 window->draw( cursor );
       
       
window->display();
   
}
}
P-182396
pekfos
» 2025-05-25 18:18:17
Liczysz indeksy w oparciu o podzielony tekst, który nie zawiera wszystkich znaków z pliku, po czym używasz tego indeksu by modyfikować plik. To tak nie będzie działać. Błędne zachowanie które teraz widzisz zdaje się bierze właśnie z tego że znaki nowej linii nie trafiają texts. Możesz pewnie zrobić tak:
C/C++
if( wchar == '\n' ) {
   
   
if( white_char != '\0' && white_char != '\r' )
       
 line = line + word + white_char;
   
else
       
 line = line + word;
   
   
line += '\n'; ///////////////////////////////////////
   
P-182397
tBane
Temat założony przez niniejszego użytkownika
» 2025-05-25 18:54:08
Jest jeszcze jeden bug. Jak zrobi się enter i jest się w nowej linii, to żeby przesunąć karetkę w prawo trzeba dwa razy kliknąć klawisz strzałkę w prawo ..

C/C++
#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>
sf::RenderWindow * window;

sf::Font font;
short characterSize;

std::wstring text;
std::vector < sf::Text * > texts;

sf::Vector2i mousePosition;
sf::Vector2f worldMousePosition;

sf::RectangleShape cursor;
sf::Vector2i cursorPosition = sf::Vector2i( 0, 0 );

sf::Clock timeClock;
sf::Time currentTime;


int selecting_start = 2; // selecting start cursor
int selecting_end = 4; // selecting end cursor

std::vector < sf::Text * > wrapText( int line_length = - 1 ) {
   
std::vector < sf::Text * > t;
   
std::wstring line = L"";
   
std::wstring word = L"";
   
wchar_t white_char = '\0';
   
   
for( auto & wchar: text ) {
       
if( wchar == '\n' ) {
           
           
if( white_char != '\0' && white_char != '\r' )
               
 line = line + white_char + word;
           
else
               
 line = line + word;
           
           
line = line + L"\n";
           
           
sf::Text * new_text = new sf::Text( line, font, characterSize );
           
new_text->setFillColor( sf::Color::White );
           
if( !t.empty() )
               
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
           
else
               
 new_text->setPosition( 0, 0 );
           
           
t.push_back( new_text );
           
line = L"";
           
word = L"";
           
white_char = '\0';
           
continue;
       
}
       
       
       
       
if( wchar == L' ' || wchar == L'\t' ) {
           
white_char = wchar;
           
word = word + white_char;
           
           
if( line_length > - 1 ) {
               
               
if( line == L"" ) {
                   
sf::Text test_word( word, font, characterSize );
                   
                   
if( test_word.getGlobalBounds().width >= line_length ) {
                       
                       
std::wstring part_of_word = L"";
                       
wchar_t character = '\0';
                       
                       
for( wchar_t & ch: word ) {
                           
character = ch;
                           
sf::Text w( part_of_word + character, font, characterSize );
                           
if( w.getGlobalBounds().width >= line_length ) {
                               
sf::Text * new_text = new sf::Text( part_of_word, font, characterSize );
                               
new_text->setFillColor( sf::Color::White );
                               
if( !t.empty() )
                                   
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
                               
else
                                   
 new_text->setPosition( 0, 0 );
                               
                               
t.push_back( new_text );
                               
part_of_word = character;
                           
}
                           
else
                               
 part_of_word = part_of_word + character;
                           
                       
}
                       
                       
if( part_of_word != L"" ) {
                           
sf::Text * new_text = new sf::Text( part_of_word, font, characterSize );
                           
new_text->setFillColor( sf::Color::White );
                           
if( !t.empty() )
                               
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
                           
else
                               
 new_text->setPosition( 0, 0 );
                           
                           
t.push_back( new_text );
                           
part_of_word = L"";
                       
}
                       
                       
word = L"";
                       
continue;
                   
}
                }
               
               
sf::Text test_text( line + white_char + word, font, characterSize );
               
if( test_text.getGlobalBounds().width >= line_length ) {
                   
sf::Text * new_text = new sf::Text( line, font, characterSize );
                   
new_text->setFillColor( sf::Color::White );
                   
if( !t.empty() )
                       
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
                   
else
                       
 new_text->setPosition( 0, 0 );
                   
                   
t.push_back( new_text );
                   
line = word;
                   
word = L"";
                   
continue;
                   
               
}
               
else
                   
 line = line + word;
               
           
}
           
           
           
word = L"";
           
white_char = '\0';
       
}
       
else if( wchar != '\0' && wchar != '\r' ) { // poprawka
           
word += wchar;
       
}
    }
   
   
// dodaj ostatnią linię
   
sf::Text test_word( word, font, characterSize );
   
   
if( test_word.getGlobalBounds().width >= line_length ) {
       
       
std::wstring part_of_word = L"";
       
wchar_t character = '\0';
       
       
for( wchar_t & ch: word ) {
           
character = ch;
           
sf::Text w( part_of_word + character, font, characterSize );
           
if( w.getGlobalBounds().width >= line_length ) {
               
sf::Text * new_text = new sf::Text( part_of_word, font, characterSize );
               
new_text->setFillColor( sf::Color::White );
               
if( !t.empty() )
                   
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
               
else
                   
 new_text->setPosition( 0, 0 );
               
               
t.push_back( new_text );
               
part_of_word = character;
           
}
           
else
               
 part_of_word = part_of_word + character;
           
       
}
       
       
if( part_of_word != L"" ) {
           
sf::Text * new_text = new sf::Text( part_of_word, font, characterSize );
           
new_text->setFillColor( sf::Color::White );
           
if( !t.empty() )
               
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
           
else
               
 new_text->setPosition( 0, 0 );
           
           
t.push_back( new_text );
           
part_of_word = L"";
       
}
       
       
word = L"";
   
}
   
   
if( !word.empty() || !line.empty() ) {
       
       
sf::Text test_text( line + word, font, characterSize );
       
if( line_length > - 1 && test_text.getGlobalBounds().width >= line_length && !line.empty() ) {
           
// dodaj najpierw obecną linię
           
sf::Text * new_text = new sf::Text( line, font, characterSize );
           
new_text->setFillColor( sf::Color::White );
           
new_text->setPosition( 0, t.empty() ? 0
               
: t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
           
t.push_back( new_text );
           
           
// a potem słowo w nowej linii
           
new_text = new sf::Text( word, font, characterSize );
           
new_text->setFillColor( sf::Color::White );
           
new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
           
t.push_back( new_text );
       
}
       
else {
           
// zmieściło się wszystko — dodaj jako jedna linia
           
sf::Text * new_text = new sf::Text( line + word, font, characterSize );
           
new_text->setFillColor( sf::Color::White );
           
new_text->setPosition( 0, t.empty() ? 0
               
: t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
           
t.push_back( new_text );
       
}
    }
   
   
return t;
}

sf::Vector2i getCursorPosition() {
   
   
sf::Vector2i cur_pos = sf::Vector2i( 0, 0 );
   
   
for( int t = 0; t < texts.size(); t++ ) {
       
       
for( size_t i = 0; i < texts[ t ]->getString().getSize(); ++i ) {
           
           
sf::Vector2f charPos = texts[ t ]->findCharacterPos( i );
           
float nextX = texts[ t ]->findCharacterPos( i + 1 ).x;
           
           
sf::FloatRect charRect( charPos.x, charPos.y, nextX - charPos.x, font.getLineSpacing( characterSize ) );
           
           
if( charRect.contains( worldMousePosition ) ) {
               
               
if( worldMousePosition.x < charRect.left + charRect.width / 2 )
                   
 return sf::Vector2i( i, t );
               
else
                   
 return sf::Vector2i( i + 1, t );
               
           
}
           
           
bool isLastChar =( i == texts[ t ]->getString().getSize() - 1 );
           
if( isLastChar &&
           
worldMousePosition.x > charRect.left &&
           
worldMousePosition.y >= charRect.top &&
           
worldMousePosition.y <= charRect.top + charRect.height )
           
{
               
return sf::Vector2i( i + 1, t );
           
}
        }
    }
   
   
return cur_pos;
}

int getCursorIndex( sf::Vector2i position ) {
   
int index = 0;
   
for( int i = 0; i < position.y && i < texts.size(); ++i ) {
       
index += texts[ i ]->getString().getSize();
   
}
   
index += position.x;
   
return index;
}

sf::Vector2i getCursorFromIndex( int index ) {
   
int current = 0;
   
for( int y = 0; y < texts.size(); ++y ) {
       
int lineSize = texts[ y ]->getString().getSize();
       
if( index <= current + lineSize ) {
           
return sf::Vector2i( index - current, y );
       
}
       
current += lineSize;
   
}
   
if( !texts.empty() )
       
 return sf::Vector2i( texts.back()->getString().getSize(), texts.size() - 1 );
   
   
return sf::Vector2i( 0, 0 );
}

void setCursorPosition( sf::Vector2i cursor_position ) {
   
cursorPosition = cursor_position;
   
   
for( int t = 0; t < texts.size(); t++ ) {
       
if( t == cursor_position.y ) {
           
std::wstring line = texts[ t ]->getString().toWideString();
           
           
if( cursor_position.x < line.size() ) {
               
sf::Vector2f charPos = texts[ t ]->findCharacterPos( cursor_position.x );
               
cursor.setPosition( charPos.x, charPos.y );
               
return;
           
}
           
else {
               
// Kursor na końcu linii
               
sf::Vector2f endPos = texts[ t ]->findCharacterPos( line.size() );
               
cursor.setPosition( endPos.x, endPos.y );
               
return;
           
}
        }
    }
}

int main()
{
   
   
sf::View view( sf::FloatRect( 0, 0, 480, 640 ) );
   
window = new sf::RenderWindow( sf::VideoMode( view.getSize().x, view.getSize().y ), "Easy Notepad!", sf::Style::Titlebar | sf::Style::Close );
   
   
font.loadFromFile( "arial.ttf" );
   
characterSize = 17;
   
text =
   
L"Gracz najpierw zagaduje handlarza gdyż ten jest najbliżej. Handlarz oferuje skórzane ubranie w zamian za dostarczenie kilku skór od myśliwego, "
    L"którego gracz mijał wcześniej. Zielarka da graczowi trochę złota w zamian za przyniesienie kilku roślin leczniczych. "
    L"U kowala gracz może zakupić oręż - zwyczajny prosty miecz gdyż jest to niewprawiony kowal w miecznictwie. "
    L"Zaś do wieży mędrca nie da się dostać.Gracz rusza spowrotem do myśliwego po skóry, lecz ten jest nieufny, "
    L"ale ostatecznie zgadza się i daje graczowi skóry.\n"
    L"Gracz wraca ze skórami do handlarza i odbiera nowe ubranie \"skórzane kurtka\" oraz \"skórzane spodnie\"."
    L"Handlarz jednak jeszcze jedno zadanie ma dla gracza. Dostawa towarów ze wschodu się opóźnia i trzeba sprawdzić "
    L"co się z nią stało i tak gracz rusza z kolejnym zadaniem \"spóźniona dostawa\"."
;
   
   
   
texts = wrapText( window->getSize().x );
   
   
cursor = sf::RectangleShape( sf::Vector2f( 2, characterSize ) );
   
cursor.setFillColor( sf::Color::Red );
   
   
sf::Clock clock;
   
   
while( window->isOpen() )
   
{
       
       
mousePosition = sf::Mouse::getPosition( * window ); // get the mouse position about window
       
worldMousePosition = window->mapPixelToCoords( mousePosition ); // get global mouse position
       
       
currentTime = timeClock.getElapsedTime();
       
       
sf::Event event;
       
while( window->pollEvent( event ) ) {
           
           
if( event.type == sf::Event::Closed )
               
 window->close();
           
           
if( event.type == sf::Event::Resized )
           
{
               
// Aktualizacja widoku bez skalowania
               
sf::View view;
               
view.setSize( static_cast < float >( event.size.width ), static_cast < float >( event.size.height ) );
               
view.setCenter( view.getSize() / 2.f );
               
window->setView( view );
           
}
           
else if( event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Left ) {
               
sf::Vector2i cur_pos = getCursorPosition();
               
setCursorPosition( cur_pos );
           
}
           
else if( event.type == sf::Event::TextEntered ) {
               
               
if( event.text.unicode < 128 ) {
                   
int index = 0;
                   
for( int i = 0; i < cursorPosition.y; i++ ) {
                       
index += texts[ i ]->getString().toWideString().size();
                   
}
                   
index += cursorPosition.x;
                   
                   
if( event.text.unicode == '\b' ) {
                       
if( index > 0 && !text.empty() ) {
                           
text.erase( index - 1, 1 );
                           
index -= 1;
                       
}
                    }
                   
else if( event.text.unicode == 32 ) {
                       
text.insert( index, 1, L' ' );
                       
index += 1;
                   
}
                   
else if( event.text.unicode == 13 ) {
                       
text.insert( index, 1, L'\n' );
                       
index += 1;
                   
}
                   
else {
                       
text.insert( index, 1, wchar_t( event.text.unicode ) );
                       
index += 1;
                   
}
                   
                   
for( auto & t: texts )
                       
 delete t;
                   
                   
texts = wrapText( window->getSize().x );
                   
                   
// Po każdej zmianie kursor wstawiamy po index
                   
cursorPosition = getCursorFromIndex( index );
                   
setCursorPosition( cursorPosition );
               
}
               
               
            }
           
else if( event.type == sf::Event::KeyPressed ) {
               
if( event.key.code == sf::Keyboard::Left ) {
                   
if( cursorPosition.x > 0 ) {
                       
cursorPosition.x -= 1;
                   
}
                   
else {
                       
if( cursorPosition.y > 0 ) {
                           
cursorPosition.y -= 1;
                           
cursorPosition.x = texts[ cursorPosition.y ]->getString().toWideString().size();
                       
}
                    }
                   
                }
               
else if( event.key.code == sf::Keyboard::Right ) {
                   
if( cursorPosition.x < texts[ cursorPosition.y ]->getString().toWideString().size() ) {
                       
cursorPosition.x += 1;
                   
}
                   
else {
                       
if( cursorPosition.y < texts.size() - 1 ) {
                           
cursorPosition.x = 0;
                           
cursorPosition.y += 1;
                       
}
                       
                       
                       
                    }
                   
                   
                }
               
else if( event.key.code == sf::Keyboard::Up ) {
                   
if( cursorPosition.y > 0 )
                       
 cursorPosition.y -= 1;
                   
               
}
               
else if( event.key.code == sf::Keyboard::Down ) {
                   
if( cursorPosition.y < texts.size() - 1 )
                       
 cursorPosition.y += 1;
                   
               
}
               
               
               
setCursorPosition( cursorPosition );
               
           
}
           
           
        }
       
       
window->clear( sf::Color( 48, 48, 48, 255 ) );
       
for( auto & text: texts )
           
 window->draw( * text );
       
       
if( std::fmod( currentTime.asSeconds(), 0.6f ) < 0.3f )
           
 window->draw( cursor );
       
       
window->display();
   
}
}
P-182398
pekfos
» 2025-05-25 19:59:39
To są błędy o 1 w tym kodzie (poprawione):
C/C++
f( event.key.code == sf::Keyboard::Left ) {
   
if( cursorPosition.x > 0 ) {
       
cursorPosition.x -= 1;
   
}
   
else {
       
if( cursorPosition.y > 0 ) {
           
cursorPosition.y -= 1;
           
cursorPosition.x = texts[ cursorPosition.y ]->getString().toWideString().size() - 1; //////// -1
       
}
    }
   
}
else if( event.key.code == sf::Keyboard::Right ) {
   
if( cursorPosition.x + 1 < texts[ cursorPosition.y ]->getString().toWideString().size() ) { //////// +1
       
cursorPosition.x += 1;
   
}
   
else {
       
if( cursorPosition.y < texts.size() - 1 ) {
           
cursorPosition.x = 0;
           
cursorPosition.y += 1;
       
}
    }
}
Ustawiałeś wartości poza zakresem bo pewnie polegałeś na tym by mieć osobno pozycje na końcu linii N i na początku linii N+1. Teraz gdy znak nowej linii bierze udział w obliczeniach, te pozycje wynikają naturalnie z kursora przed \n (koniec linii N), i po \n (początek następnej linii).
P-182399
1 2 3 « 4 » 5 6 7 8 9 10
Poprzednia strona Strona 4 z 10 Następna strona