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 #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; int selecting_end = 4; 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; } } 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() ) { 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 ); 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 { 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; 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 ); worldMousePosition = window->mapPixelToCoords( mousePosition ); currentTime = timeClock.getElapsedTime(); sf::Event event; while( window->pollEvent( event ) ) { if( event.type == sf::Event::Closed ) window->close(); if( event.type == sf::Event::Resized ) { 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 ) { text.insert( index, 1, char( ' ' ) ); index += 1; } else if( event.text.unicode == 13 ) { text.insert( index, 1, char( '\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 ); 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(); } }
|
|
DejaVu |
» 2025-05-24 21:35:07 Usuń wszystkie znaki '\r', a potem podziel na wiersze '\n'. |
|
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 :-/ #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; int selecting_end = 4; 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 + 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' ) { word += wchar; } } 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() ) { 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 ); 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 { 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; 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 ); worldMousePosition = window->mapPixelToCoords( mousePosition ); currentTime = timeClock.getElapsedTime(); sf::Event event; while( window->pollEvent( event ) ) { if( event.type == sf::Event::Closed ) window->close(); if( event.type == sf::Event::Resized ) { 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 ) { text.insert( index, 1, char( ' ' ) ); index += 1; } else if( event.text.unicode == 13 ) { text.insert( index, 1, char( '\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 ); 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(); } }
|
|
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. |
|
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: cursorPosition = getCursorFromIndex( index ); setCursorPosition( cursorPosition );
#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; int selecting_end = 4; 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 + 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' ) { word += wchar; } } 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() ) { 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 ); 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 { 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; 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 ); worldMousePosition = window->mapPixelToCoords( mousePosition ); currentTime = timeClock.getElapsedTime(); sf::Event event; while( window->pollEvent( event ) ) { if( event.type == sf::Event::Closed ) window->close(); if( event.type == sf::Event::Resized ) { 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 ) { text.insert( index, 1, char( ' ' ) ); index += 1; } else if( event.text.unicode == 13 ) { text.insert( index, 1, char( '\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 ); 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(); } }
|
|
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: if( wchar == '\n' ) { if( white_char != '\0' && white_char != '\r' ) line = line + word + white_char; else line = line + word; line += '\n'; |
|
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 .. #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; int selecting_end = 4; 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' ) { word += wchar; } } 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() ) { 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 ); 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 { 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 { 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 ); worldMousePosition = window->mapPixelToCoords( mousePosition ); currentTime = timeClock.getElapsedTime(); sf::Event event; while( window->pollEvent( event ) ) { if( event.type == sf::Event::Closed ) window->close(); if( event.type == sf::Event::Resized ) { 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 ); 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(); } }
|
|
pekfos |
» 2025-05-25 19:59:39 To są błędy o 1 w tym kodzie (poprawione): 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; } } } else if( event.key.code == sf::Keyboard::Right ) { if( cursorPosition.x + 1 < texts[ cursorPosition.y ]->getString().toWideString().size() ) { 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). |
|
1 2 3 « 4 » 5 6 7 8 9 10 |