tBane Temat założony przez niniejszego użytkownika |
» 2025-06-03 22:58:46 No więc napisałem ale pozostało mi jeszcze pozycjonowanie kursora. Nie mam pomysłu jak rozwiązać ten problem. Skąd wziąć pozycję kursora? if( event.text.unicode == '\b' ) { if( lines.size() > 0 && cursorPosition != sf::Vector2i( 0, 0 ) ) { if( cursorPosition.x == 0 && cursorPosition.y > 0 ) { if( lines[ cursorPosition.y - 1 ]->getString().toWideString().size() == 0 ) { delete lines[ cursorPosition.y - 1 ]; lines[ cursorPosition.y - 1 ] = nullptr; cursorPosition.y -= 1; } else { std::wstring line = lines[ cursorPosition.y - 1 ]->getString().toWideString(); line.pop_back(); line = line + lines[ cursorPosition.y ]->getString().toWideString(); delete lines[ cursorPosition.y ]; lines[ cursorPosition.y ] = nullptr; lines[ cursorPosition.y - 1 ]->setString( line ); } lines = wrap_text( getTextFromLines() ); } else if( cursorPosition.x > 0 ) { std::wstring line = lines[ cursorPosition.y ]->getString().toWideString(); line.erase( cursorPosition.x - 1, 1 ); lines[ cursorPosition.y ]->setString( line ); cursorPosition.x -= 1; } } }
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-06-04 16:14:53 I znowu backspace nie działa poprawnie :-/ Dla pustej linii się wywala (miejsce z kodem oznaczyłem komentarzem "// backspace") #include <SFML/Graphics.hpp> #include <iostream> #include <vector> #include <cmath> #include <filesystem>
sf::RenderWindow * window;
sf::Font font; short characterSize; sf::Color textColor; sf::Color backgroundColor;
std::vector < sf::Text * > lines;
sf::Vector2i mousePosition; sf::Vector2f worldMousePosition;
sf::RectangleShape cursor; sf::Vector2i cursorPosition = sf::Vector2i( 0, 0 );
sf::Clock timeClock; sf::Time currentTime;
std::vector < sf::Text * > wrap_text( std::wstring text ) { std::vector < sf::Text * > lines; std::wstring line = L""; std::wstring word = L""; for( auto & character: text ) { if( character == L'\n' ) { if( sf::Text( line + word, font, characterSize ).getGlobalBounds().width > window->getSize().x ) { lines.push_back( new sf::Text( line, font, characterSize ) ); line = word; word = L""; } else { lines.push_back( new sf::Text( line + word, font, characterSize ) ); line = L""; word = L""; } } else if( character == L' ' || character == L'\t' ) { if( sf::Text( line + word, font, characterSize ).getGlobalBounds().width > window->getSize().x ) { lines.push_back( new sf::Text( line, font, characterSize ) ); line = word + character; word = L""; } else { line = line + word + character; word = L""; } } else word = word + character; } if( line != L"" || word != L"" ) { lines.push_back( new sf::Text( line + word, font, characterSize ) ); } for( int i = 0; i < lines.size(); i++ ) { lines[ i ]->setPosition( sf::Vector2f( 0, i * font.getLineSpacing( characterSize ) ) ); lines[ i ]->setFillColor( textColor ); } return lines; }
void setCursorUp() { if( cursorPosition.y > 0 ) { float targetX = cursor.getGlobalBounds().left; cursorPosition.y -= 1; sf::Text * line = lines[ cursorPosition.y ]; size_t lineLength = line->getString().toWideString().size(); size_t closestIndex = 0; float closestDistance = std::abs( line->findCharacterPos( 0 ).x - targetX ); for( size_t i = 1; i <= lineLength; ++i ) { sf::Vector2f pos = line->findCharacterPos( i ); float distance = std::abs( pos.x - targetX ); if( distance < closestDistance ) { closestIndex = i; closestDistance = distance; } } cursorPosition.x = closestIndex; cursor.setPosition( line->findCharacterPos( closestIndex ) ); } } void setCursorDown() { if( cursorPosition.y < lines.size() - 1 ) { float targetX = cursor.getGlobalBounds().left; cursorPosition.y += 1; sf::Text * line = lines[ cursorPosition.y ]; size_t lineLength = line->getString().toWideString().size(); size_t closestIndex = 0; float closestDistance = std::abs( line->findCharacterPos( 0 ).x - targetX ); for( size_t i = 1; i <= lineLength; ++i ) { sf::Vector2f pos = line->findCharacterPos( i ); float distance = std::abs( pos.x - targetX ); if( distance < closestDistance ) { closestIndex = i; closestDistance = distance; } } cursorPosition.x = closestIndex; cursor.setPosition( line->findCharacterPos( closestIndex ) ); } }
void cursorPositioning() { if( lines.size() == 0 ) { cursor.setPosition( 0, 0 ); return; } float line_length = lines[ cursorPosition.y ]->getString().toWideString().size(); sf::Vector2f pos; pos.x = lines[ cursorPosition.y ]->findCharacterPos( cursorPosition.x ).x; pos.y = cursorPosition.y * font.getLineSpacing( characterSize ); cursor.setPosition( pos ); }
int getIndex() { int index = 0; for( int i = 0; i < cursorPosition.y; ++i ) if( lines[ i ] != nullptr ) index += lines[ i ]->getString().toWideString().size(); else index += 1; index += cursorPosition.x; return index; }
sf::Vector2i getCursorPositionFromIndex( int index ) { int total = 0; for( int i = 0; i < lines.size(); ++i ) { if( lines[ i ] != nullptr ) { int len = lines[ i ]->getString().toWideString().size(); if( index <= total + len ) { int x = std::min( index - total, len ); return sf::Vector2i( x, i ); } total += len; } else total += 1; } int lastLine = lines.size() - 1; return sf::Vector2i( lines[ lastLine ]->getString().toWideString().size(), lastLine ); }
std::wstring getTextFromLines() { std::wstring text = L""; for( int i = 0; i < lines.size(); i += 1 ) if( lines[ i ] != nullptr ) { text = text + lines[ i ]->getString().toWideString(); } return text; }
std::string ConvertWideToUtf8( std::wstring wide ) { return std::string( wide.begin(), wide.end() ); }
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 v2", sf::Style::Titlebar | sf::Style::Close ); font = sf::Font(); font.loadFromFile( "arial.ttf" ); characterSize = 17; textColor = sf::Color( 192, 192, 192 ); backgroundColor = sf::Color( 48, 48, 48 ); lines = wrap_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\"." ); std::cout << "Current directory: " << std::filesystem::current_path() << std::endl; 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 ) { } else if( event.type == sf::Event::TextEntered ) { if( event.text.unicode < 128 ) { if( event.text.unicode == '\b' ) { if( lines.size() > 0 && cursorPosition != sf::Vector2i( 0, 0 ) ) { if( cursorPosition.x == 0 && cursorPosition.y > 0 ) { if( lines[ cursorPosition.y ]->getString().toWideString().size() == 0 ) { delete lines[ cursorPosition.y - 1 ]; lines[ cursorPosition.y - 1 ] = nullptr; cursorPosition.y -= 1; lines = wrap_text( getTextFromLines() ); } else { int index = getIndex(); std::wstring line1 = lines[ cursorPosition.y - 1 ]->getString().toWideString(); line1.pop_back(); std::wstring line2 = lines[ cursorPosition.y ]->getString().toWideString(); std::wstring line = line1 + line2; delete lines[ cursorPosition.y ]; lines[ cursorPosition.y ] = nullptr; index = index - 1; lines[ cursorPosition.y - 1 ]->setString( line ); lines = wrap_text( getTextFromLines() ); cursorPosition = getCursorPositionFromIndex( index ); } } else if( cursorPosition.x > 0 ) { std::wstring line = lines[ cursorPosition.y ]->getString().toWideString(); line.erase( cursorPosition.x - 1, 1 ); lines[ cursorPosition.y ]->setString( line ); cursorPosition.x -= 1; int index = getIndex(); lines = wrap_text( getTextFromLines() ); cursorPosition = getCursorPositionFromIndex( index ); } } } else if( event.text.unicode == 32 ) { std::wstring line = lines[ cursorPosition.y ]->getString().toWideString(); line.insert( cursorPosition.x, 1, ' ' ); lines[ cursorPosition.y ]->setString( line ); lines = wrap_text( getTextFromLines() ); cursorPosition.x += 1; } else if( event.text.unicode == 13 ) { std::wstring line = lines[ cursorPosition.y ]->getString().toWideString(); line.insert( cursorPosition.x, 1, '\n' ); lines[ cursorPosition.y ]->setString( line ); lines = wrap_text( getTextFromLines() ); cursorPosition.y += 1; cursorPosition.x = 0; } else { std::wstring line = lines[ cursorPosition.y ]->getString().toWideString(); line.insert( cursorPosition.x, 1, char( event.text.unicode ) ); lines[ cursorPosition.y ]->setString( line ); cursorPosition.x += 1; lines = wrap_text( getTextFromLines() ); } } cursorPositioning(); } 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 = lines[ cursorPosition.y ]->getString().toWideString().size(); } } else if( event.key.code == sf::Keyboard::Right ) { if( cursorPosition.x < lines[ cursorPosition.y ]->getString().getSize() ) cursorPosition.x += 1; else if( cursorPosition.y < lines.size() - 1 ) { cursorPosition.x = 0; cursorPosition.y += 1; } } else if( event.key.code == sf::Keyboard::Up ) { setCursorUp(); } else if( event.key.code == sf::Keyboard::Down ) { setCursorDown(); } cursorPositioning(); } } window->clear( backgroundColor ); for( auto & line: lines ) window->draw( * line ); if( std::fmod( currentTime.asSeconds(), 0.6f ) < 0.3f ) window->draw( cursor ); window->display(); } }
|
|
pekfos |
» 2025-06-04 22:18:02 Dla pustej linii się wywala (miejsce z kodem oznaczyłem komentarzem "// backspace") A co tu w ogóle działa? Podaj dokładne kroki do reprodukcji jak chcesz pogadać o konkretnym problemie. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-06-04 22:23:11 Działa wprowadzanie tekstu i dodawanie spacji oraz kasowanie tekstu ze środka linii. Ale nie rozumiem dlaczego backspace przed pustą linią nie działa no i ten enter też nie chce działać no chyba, że dodam L'\n" w następującej funkcji: std::wstring getTextFromLines() { std::wstring text = L""; for( int i = 0; i < lines.size(); i += 1 ) if( lines[ i ] != nullptr ) { text = text + lines[ i ]->getString().toWideString() + L"\n"; } return text; }
Ale backspace i tak nie działa .. :-/ |
|
pekfos |
» 2025-06-04 22:33:25 Mam tu problem żeby w ogóle dodać pustą linię. Enter robi dziwne rzeczy i wywala program. lines = wrap_text( L"A\n\nB" ); A
B Kursor w pustej linii, backspace kasuje "A". To ma więcej sensu: if( lines[ cursorPosition.y ]->getString().toWideString().size() == 0 ) { delete lines[ cursorPosition.y ]; lines[ cursorPosition.y ] = nullptr; cursorPosition.x = lines[ cursorPosition.y - 1 ]->getString().getSize(); cursorPosition.y -= 1; lines = wrap_text( getTextFromLines() ); } Drugi przypadek: Kursor na początku 3. linii, przed literą B. Backspace wywala program na pop_back(): int index = getIndex(); std::wstring line1 = lines[ cursorPosition.y - 1 ]->getString().toWideString(); line1.pop_back(); std::wstring line2 = lines[ cursorPosition.y ]->getString().toWideString(); Ten kod ma sens, natomiast linie miały mieć \n który chcesz tu usuwać, chyba że zdążyłeś zmienić koncepcję. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-06-04 22:40:22 Ok. Dziękuję za odpowiedź :-) Już poprawiłem te linie i teraz działa. Pozostało tylko do zrobienia wrapowanie tekstu za kursorem. // edit teraz nie działa wprowadzanie znaków. Gdy wprowadza się znaki z klawiatury i linia przekroczy szerokość okna to ostatnie słowo trafia do nowej linii, gdy dalej wprowadza się znaki i kolejne słowo przekroczy dopuszczalną szerokość to też tworzy kolejnę linię. Trzeba zrobić tak, by poprawnie zawijało tekst. #include <SFML/Graphics.hpp> #include <iostream> #include <vector> #include <cmath> #include <filesystem>
sf::RenderWindow * window;
sf::Font font; short characterSize; sf::Color textColor; sf::Color backgroundColor;
std::vector < sf::Text * > lines;
sf::Vector2i mousePosition; sf::Vector2f worldMousePosition;
sf::RectangleShape cursor; sf::Vector2i cursorPosition = sf::Vector2i( 0, 0 );
sf::Clock timeClock; sf::Time currentTime;
std::vector < sf::Text * > wrap_text( std::wstring text ) { std::vector < sf::Text * > lines; std::wstring line = L""; std::wstring word = L""; for( auto & character: text ) { if( character == L'\n' ) { if( sf::Text( line + word, font, characterSize ).getGlobalBounds().width > window->getSize().x ) { lines.push_back( new sf::Text( line, font, characterSize ) ); line = word; word = L""; } else { lines.push_back( new sf::Text( line + word, font, characterSize ) ); line = L""; word = L""; } } else if( character == L' ' || character == L'\t' ) { if( sf::Text( line + word, font, characterSize ).getGlobalBounds().width > window->getSize().x ) { lines.push_back( new sf::Text( line, font, characterSize ) ); line = word + character; word = L""; } else { line = line + word + character; word = L""; } } else word = word + character; } if( line != L"" || word != L"" ) { lines.push_back( new sf::Text( line + word, font, characterSize ) ); } for( int i = 0; i < lines.size(); i++ ) { lines[ i ]->setPosition( sf::Vector2f( 0, i * font.getLineSpacing( characterSize ) ) ); lines[ i ]->setFillColor( textColor ); } return lines; }
void setCursorUp() { if( cursorPosition.y > 0 ) { float targetX = cursor.getGlobalBounds().left; cursorPosition.y -= 1; sf::Text * line = lines[ cursorPosition.y ]; size_t lineLength = line->getString().toWideString().size(); size_t closestIndex = 0; float closestDistance = std::abs( line->findCharacterPos( 0 ).x - targetX ); for( size_t i = 1; i <= lineLength; ++i ) { sf::Vector2f pos = line->findCharacterPos( i ); float distance = std::abs( pos.x - targetX ); if( distance < closestDistance ) { closestIndex = i; closestDistance = distance; } } cursorPosition.x = closestIndex; cursor.setPosition( line->findCharacterPos( closestIndex ) ); } } void setCursorDown() { if( cursorPosition.y < lines.size() - 1 ) { float targetX = cursor.getGlobalBounds().left; cursorPosition.y += 1; sf::Text * line = lines[ cursorPosition.y ]; size_t lineLength = line->getString().toWideString().size(); size_t closestIndex = 0; float closestDistance = std::abs( line->findCharacterPos( 0 ).x - targetX ); for( size_t i = 1; i <= lineLength; ++i ) { sf::Vector2f pos = line->findCharacterPos( i ); float distance = std::abs( pos.x - targetX ); if( distance < closestDistance ) { closestIndex = i; closestDistance = distance; } } cursorPosition.x = closestIndex; cursor.setPosition( line->findCharacterPos( closestIndex ) ); } }
void cursorPositioning() { if( lines.size() == 0 ) { cursor.setPosition( 0, 0 ); return; } float line_length = lines[ cursorPosition.y ]->getString().toWideString().size(); sf::Vector2f pos; pos.x = lines[ cursorPosition.y ]->findCharacterPos( cursorPosition.x ).x; pos.y = cursorPosition.y * font.getLineSpacing( characterSize ); cursor.setPosition( pos ); }
int getIndex() { int index = 0; for( int i = 0; i < cursorPosition.y; ++i ) if( lines[ i ] != nullptr ) index += lines[ i ]->getString().toWideString().size(); else index += 1; index += cursorPosition.x; return index; }
sf::Vector2i getCursorPositionFromIndex( int index ) { int total = 0; for( int i = 0; i < lines.size(); ++i ) { if( lines[ i ] != nullptr ) { int len = lines[ i ]->getString().toWideString().size(); if( index <= total + len ) { int x = std::min( index - total, len ); return sf::Vector2i( x, i ); } total += len; } else total += 1; } int lastLine = lines.size() - 1; return sf::Vector2i( lines[ lastLine ]->getString().toWideString().size(), lastLine ); }
std::wstring getTextFromLines() { std::wstring text = L""; for( int i = 0; i < lines.size(); i += 1 ) if( lines[ i ] != nullptr ) { text = text + lines[ i ]->getString().toWideString() + L"\n"; } return text; }
std::string ConvertWideToUtf8( std::wstring wide ) { return std::string( wide.begin(), wide.end() ); }
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 v2", sf::Style::Titlebar | sf::Style::Close ); font = sf::Font(); font.loadFromFile( "arial.ttf" ); characterSize = 17; textColor = sf::Color( 192, 192, 192 ); backgroundColor = sf::Color( 48, 48, 48 ); lines = wrap_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\"." ); std::cout << "Current directory: " << std::filesystem::current_path() << std::endl; 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 ) { } else if( event.type == sf::Event::TextEntered ) { if( event.text.unicode < 128 ) { if( event.text.unicode == '\b' ) { if( lines.size() > 0 && cursorPosition != sf::Vector2i( 0, 0 ) ) { if( cursorPosition.x == 0 && cursorPosition.y > 0 ) { if( lines[ cursorPosition.y ]->getString().toWideString().size() == 0 ) { delete lines[ cursorPosition.y ]; lines[ cursorPosition.y ] = nullptr; cursorPosition.x = lines[ cursorPosition.y - 1 ]->getString().getSize(); cursorPosition.y -= 1; lines = wrap_text( getTextFromLines() ); } else { int index = getIndex(); std::wstring line1 = lines[ cursorPosition.y - 1 ]->getString().toWideString(); std::wstring line2 = lines[ cursorPosition.y ]->getString().toWideString(); std::wstring line = line1 + line2; delete lines[ cursorPosition.y ]; lines[ cursorPosition.y ] = nullptr; lines[ cursorPosition.y - 1 ]->setString( line ); lines = wrap_text( getTextFromLines() ); cursorPosition = getCursorPositionFromIndex( index ); } } else if( cursorPosition.x > 0 ) { std::wstring line = lines[ cursorPosition.y ]->getString().toWideString(); line.erase( cursorPosition.x - 1, 1 ); lines[ cursorPosition.y ]->setString( line ); cursorPosition.x -= 1; int index = getIndex(); lines = wrap_text( getTextFromLines() ); cursorPosition = getCursorPositionFromIndex( index ); } } } else if( event.text.unicode == 32 ) { std::wstring line = lines[ cursorPosition.y ]->getString().toWideString(); line.insert( cursorPosition.x, 1, ' ' ); lines[ cursorPosition.y ]->setString( line ); lines = wrap_text( getTextFromLines() ); cursorPosition.x += 1; } else if( event.text.unicode == 13 ) { std::wstring line = lines[ cursorPosition.y ]->getString().toWideString(); line.insert( cursorPosition.x, 1, '\n' ); lines[ cursorPosition.y ]->setString( line ); lines = wrap_text( getTextFromLines() ); cursorPosition.y += 1; cursorPosition.x = 0; } else { std::wstring line = lines[ cursorPosition.y ]->getString().toWideString(); line.insert( cursorPosition.x, 1, char( event.text.unicode ) ); lines[ cursorPosition.y ]->setString( line ); cursorPosition.x += 1; lines = wrap_text( getTextFromLines() ); } } cursorPositioning(); } 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 = lines[ cursorPosition.y ]->getString().toWideString().size(); } } else if( event.key.code == sf::Keyboard::Right ) { if( cursorPosition.x < lines[ cursorPosition.y ]->getString().getSize() ) cursorPosition.x += 1; else if( cursorPosition.y < lines.size() - 1 ) { cursorPosition.x = 0; cursorPosition.y += 1; } } else if( event.key.code == sf::Keyboard::Up ) { setCursorUp(); } else if( event.key.code == sf::Keyboard::Down ) { setCursorDown(); } cursorPositioning(); } } window->clear( backgroundColor ); for( auto & line: lines ) window->draw( * line ); if( std::fmod( currentTime.asSeconds(), 0.6f ) < 0.3f ) window->draw( cursor ); window->display(); } }
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-06-06 00:14:20 Nie jestem pewien co do tych emiterów na końcu linii bo wrapper wtedy nie zawija poprawnie tekstu |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-06-06 02:05:23 Skasowałem wszystko i wróciłem do punktu z enterem. Enter oczywiście nie działa - :-/ - nie rozumiem gdzie popełniłem błąd :-/ #include <SFML/Graphics.hpp> #include <iostream> #include <vector> #include <cmath> #include <filesystem>
sf::RenderWindow * window;
sf::Font font; short characterSize; sf::Color textColor; sf::Color backgroundColor;
std::vector < sf::Text * > lines;
sf::Vector2i mousePosition; sf::Vector2f worldMousePosition;
sf::RectangleShape cursor; sf::Vector2i cursorPosition = sf::Vector2i( 0, 0 );
sf::Clock timeClock; sf::Time currentTime;
std::vector < sf::Text * > wrap_text( std::wstring text ) { std::vector < sf::Text * > lines; std::wstring line = L""; std::wstring word = L""; for( auto & character: text ) { if( character == L'\n' ) { if( sf::Text( line + word, font, characterSize ).getGlobalBounds().width > window->getSize().x ) { lines.push_back( new sf::Text( line, font, characterSize ) ); line = word; word = L""; } else { lines.push_back( new sf::Text( line + word, font, characterSize ) ); line = L""; word = L""; } } else if( character == L' ' || character == L'\t' ) { if( sf::Text( line + word, font, characterSize ).getGlobalBounds().width > window->getSize().x ) { lines.push_back( new sf::Text( line, font, characterSize ) ); line = word + character; word = L""; } else { line = line + word + character; word = L""; } } else word = word + character; } if( line != L"" || word != L"" ) { lines.push_back( new sf::Text( line + word, font, characterSize ) ); } for( int i = 0; i < lines.size(); i++ ) { lines[ i ]->setPosition( sf::Vector2f( 0, i * font.getLineSpacing( characterSize ) ) ); lines[ i ]->setFillColor( textColor ); } return lines; }
void setCursorUp() { if( cursorPosition.y > 0 ) { float targetX = cursor.getGlobalBounds().left; cursorPosition.y -= 1; sf::Text * line = lines[ cursorPosition.y ]; size_t lineLength = line->getString().toWideString().size(); size_t closestIndex = 0; float closestDistance = std::abs( line->findCharacterPos( 0 ).x - targetX ); for( size_t i = 1; i <= lineLength; ++i ) { sf::Vector2f pos = line->findCharacterPos( i ); float distance = std::abs( pos.x - targetX ); if( distance < closestDistance ) { closestIndex = i; closestDistance = distance; } } cursorPosition.x = closestIndex; cursor.setPosition( line->findCharacterPos( closestIndex ) ); } } void setCursorDown() { if( cursorPosition.y < lines.size() - 1 ) { float targetX = cursor.getGlobalBounds().left; cursorPosition.y += 1; sf::Text * line = lines[ cursorPosition.y ]; size_t lineLength = line->getString().toWideString().size(); size_t closestIndex = 0; float closestDistance = std::abs( line->findCharacterPos( 0 ).x - targetX ); for( size_t i = 1; i <= lineLength; ++i ) { sf::Vector2f pos = line->findCharacterPos( i ); float distance = std::abs( pos.x - targetX ); if( distance < closestDistance ) { closestIndex = i; closestDistance = distance; } } cursorPosition.x = closestIndex; cursor.setPosition( line->findCharacterPos( closestIndex ) ); } }
void cursorPositioning() { float line_length = lines[ cursorPosition.y ]->getString().toWideString().size(); sf::Vector2f pos; pos.x = lines[ cursorPosition.y ]->findCharacterPos( cursorPosition.x ).x; pos.y = cursorPosition.y * font.getLineSpacing( characterSize ); cursor.setPosition( pos ); }
std::string ConvertWideToUtf8( std::wstring wide ) { return std::string( wide.begin(), wide.end() ); }
std::wstring getTextFromLines() { std::wstring text = L""; for( int i = 0; i < lines.size(); i += 1 ) text += lines[ i ]->getString().toWideString(); return text; }
int main() { sf::View view( sf::FloatRect( 0, 0, 128, 640 ) ); window = new sf::RenderWindow( sf::VideoMode( view.getSize().x, view.getSize().y ), "Easy Notepad v2", sf::Style::Titlebar | sf::Style::Close ); font = sf::Font(); font.loadFromFile( "arial.ttf" ); characterSize = 17; textColor = sf::Color( 192, 192, 192 ); backgroundColor = sf::Color( 48, 48, 48 ); lines = wrap_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\"." ); lines = wrap_text( L"Ala ma kota.\nMa też psa." ); 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 ) { } else if( event.type == sf::Event::TextEntered ) { if( event.text.unicode < 128 ) { if( event.text.unicode == '\b' ) { } else if( event.text.unicode == 32 ) { } else if( event.text.unicode == 13 ) { std::wstring line = lines[ cursorPosition.y ]->getString().toWideString(); line.insert( cursorPosition.x, 1, L'\n' ); lines[ cursorPosition.y ]->setString( line ); std::wstring text = getTextFromLines(); lines = wrap_text( text ); cursorPosition.y = 0; cursorPosition.x = 0; } else { } } cursorPositioning(); } 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 = lines[ cursorPosition.y ]->getString().toWideString().size(); } } else if( event.key.code == sf::Keyboard::Right ) { if( cursorPosition.x < lines[ cursorPosition.y ]->getString().getSize() ) cursorPosition.x += 1; else if( cursorPosition.y < lines.size() - 1 ) { cursorPosition.x = 0; cursorPosition.y += 1; } } else if( event.key.code == sf::Keyboard::Up ) { setCursorUp(); } else if( event.key.code == sf::Keyboard::Down ) { setCursorDown(); } cursorPositioning(); } } window->clear( backgroundColor ); for( auto & line: lines ) window->draw( * line ); if( std::fmod( currentTime.asSeconds(), 0.6f ) < 0.3f ) window->draw( cursor ); window->display(); } }
|
|
1 « 2 » 3 |