tBane Temat założony przez niniejszego użytkownika |
» 2025-06-07 19:21:58 a w taki sposób. Myślałem, że ostatni znak tylko ma "\r\n" a tu jednak każda linia. Ok. Dzięki. Taką funkcję napisałem std::wstring clip_text = sf::Clipboard::getString().toWideString(); while( clip_text.find( L"\r\n" ) != std::wstring::npos ) { clip_text.erase( clip_text.find( L"\r\n" ), 1 ); };
Cały kod Edytora poniżej: #include <SFML/Graphics.hpp> #include <iostream> #include <vector> #include <cmath>
sf::RenderWindow * window;
sf::Font font; short characterSize;
std::wstring text; 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;
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; } 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 < lines.size(); t++ ) { for( size_t i = 0; i < lines[ t ]->getString().getSize(); ++i ) { sf::Vector2f charPos = lines[ t ]->findCharacterPos( i ); float nextX = lines[ 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 == lines[ 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 < lines.size(); ++i ) { index += lines[ i ]->getString().getSize(); } index += position.x; return index; }
sf::Vector2i getCursorFromIndex( int index ) { if( index <= 0 || lines.empty() ) return sf::Vector2i( 0, 0 ); int current = 0; for( int y = 0; y < lines.size(); ++y ) { int lineSize = lines[ y ]->getString().getSize(); if( index <= current + lineSize ) { return sf::Vector2i( index - current, y ); } current += lineSize; } return sf::Vector2i( lines.back()->getString().toWideString().size(), lines.size() - 1 ); }
void setCursorUp() { if( lines.empty() ) return; 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( lines.empty() ) return; 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 setCursorPosition( sf::Vector2i cursor_position ) { cursorPosition = cursor_position; if( cursor_position == sf::Vector2i( 0, 0 ) ) { cursor.setPosition( sf::Vector2f( 0, 0 ) ); return; } for( int t = 0; t < lines.size(); t++ ) { if( t == cursor_position.y ) { std::wstring line = lines[ t ]->getString().toWideString(); if( line.size() == 0 ) { cursor.setPosition( lines[ t ]->getPosition() ); return; } if( cursor_position.x < line.size() ) { sf::Vector2f charPos = lines[ t ]->findCharacterPos( cursor_position.x ); cursor.setPosition( charPos.x, charPos.y ); return; } sf::Vector2f endPos = lines[ 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; lines = 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::KeyPressed && event.key.control && event.key.code == sf::Keyboard::V ) { int index = getCursorIndex( cursorPosition ); std::wstring clip_text = sf::Clipboard::getString().toWideString(); while( clip_text.find( L"\r\n" ) != std::wstring::npos ) { clip_text.erase( clip_text.find( L"\r\n" ), 1 ); }; text.insert( index, clip_text ); index += clip_text.size(); lines = wrapText( window->getSize().x ); cursorPosition = getCursorFromIndex( index ); setCursorPosition( cursorPosition ); } else if( event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Delete ) { int index = getCursorIndex( cursorPosition ); if( !text.empty() ) { text.erase( index, 1 ); lines = wrapText( window->getSize().x ); } } else if( event.type == sf::Event::TextEntered ) { int index = getCursorIndex( cursorPosition ); if( event.text.unicode == 8 ) { if( index > 0 && !text.empty() ) { text.erase( index - 1, 1 ); index -= 1; } } else if( event.text.unicode == 13 ) { text.insert( index, 1, L'\n' ); index += 1; } else { wchar_t character = static_cast < wchar_t >( event.text.unicode ); if( character >= 32 && character != 127 ) { text.insert( index, 1, character ); index += 1; } } for( auto & t: lines ) delete t; lines = 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( !lines.empty() && cursorPosition.y > 0 ) { cursorPosition.y -= 1; cursorPosition.x = lines[ cursorPosition.y ]->getString().toWideString().size() - 1; } } } else if( event.key.code == sf::Keyboard::Right ) { if( !lines.empty() && cursorPosition.x < lines[ cursorPosition.y ]->getString().toWideString().size() ) { 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(); } setCursorPosition( cursorPosition ); } } window->clear( sf::Color( 48, 48, 48, 255 ) ); 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-08 18:32:41 Napisałem nowy wraper tekstu. Teraz jest czytelniejszy. Pozostało dopisac zawijanie słów dłuższych niż zadana długość linii. #include <SFML/Graphics.hpp> #include <iostream> #include <vector> #include <cmath>
sf::RenderWindow * window;
sf::Font font; short characterSize;
std::wstring text; 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;
int selecting_start = 2; int selecting_end = 4; std::vector < sf::Text * > wrap_text( int line_width, std::wstring text ) { std::vector < sf::Text * > wrapped_text; std::wstring line = L""; std::wstring word = L""; sf::Color textColor = sf::Color::White; for( auto & character: text ) { if( sf::Text( line + word + character, font, characterSize ).getGlobalBounds().width > line_width ) { sf::Text * t = new sf::Text( line + L"\n", font, characterSize ); ( wrapped_text.empty() ) ? t->setPosition( 0, 0 ) : t->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); t->setFillColor( textColor ); wrapped_text.push_back( t ); line = L""; } else if( character == L'\n' ) { if( sf::Text( line + word + L"\n", font, characterSize ).getGlobalBounds().width > line_width ) { sf::Text * t = new sf::Text( line, font, characterSize ); ( wrapped_text.empty() ) ? t->setPosition( 0, 0 ) : t->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); t->setFillColor( textColor ); wrapped_text.push_back( t ); sf::Text * t2 = new sf::Text( word + L"\n", font, characterSize ); ( wrapped_text.empty() ) ? t2->setPosition( 0, 0 ) : t2->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); t2->setFillColor( textColor ); wrapped_text.push_back( t2 ); line = L""; word = L""; } else { sf::Text * t = new sf::Text( line + word + L"\n", font, characterSize ); ( wrapped_text.empty() ) ? t->setPosition( 0, 0 ) : t->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); t->setFillColor( textColor ); wrapped_text.push_back( t ); line = L""; word = L""; } } else if( character == L' ' || character == L'\t' ) { if( sf::Text( line + word, font, characterSize ).getGlobalBounds().width > line_width ) { sf::Text * t = new sf::Text( line + L"\n", font, characterSize ); ( wrapped_text.empty() ) ? t->setPosition( 0, 0 ) : t->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); t->setFillColor( textColor ); wrapped_text.push_back( t ); line = L""; } else { line = line + word + character; } word = L""; } else { word = word + character; } } if( line != L"" || word != L"" ) { sf::Text * t = new sf::Text( line + word, font, characterSize ); ( wrapped_text.empty() ) ? t->setPosition( 0, 0 ) : t->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); t->setFillColor( textColor ); wrapped_text.push_back( t ); } return wrapped_text; }
sf::Vector2i getCursorPosition() { sf::Vector2i cur_pos = sf::Vector2i( 0, 0 ); for( int t = 0; t < lines.size(); t++ ) { for( size_t i = 0; i < lines[ t ]->getString().getSize(); ++i ) { sf::Vector2f charPos = lines[ t ]->findCharacterPos( i ); float nextX = lines[ 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 == lines[ 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 < lines.size(); ++i ) { index += lines[ i ]->getString().getSize(); } index += position.x; return index; }
sf::Vector2i getCursorFromIndex( int index ) { if( index <= 0 || lines.empty() ) return sf::Vector2i( 0, 0 ); int current = 0; for( int y = 0; y < lines.size(); ++y ) { int lineSize = lines[ y ]->getString().getSize(); if( index <= current + lineSize ) { return sf::Vector2i( index - current, y ); } current += lineSize; } return sf::Vector2i( lines.back()->getString().toWideString().size(), lines.size() - 1 ); }
void setCursorUp() { if( lines.empty() ) return; 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( lines.empty() ) return; 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 setCursorPosition( sf::Vector2i cursor_position ) { cursorPosition = cursor_position; if( cursor_position == sf::Vector2i( 0, 0 ) ) { cursor.setPosition( sf::Vector2f( 0, 0 ) ); return; } std::wstring line = lines[ cursorPosition.y ]->getString().toWideString(); if( line.size() == 0 ) { cursor.setPosition( lines[ cursorPosition.y ]->getPosition() ); return; } if( cursor_position.x < line.size() ) { sf::Vector2f charPos = lines[ cursorPosition.y ]->findCharacterPos( cursor_position.x ); cursor.setPosition( charPos.x, charPos.y ); return; } sf::Vector2f endPos = lines[ cursorPosition.y ]->findCharacterPos( line.size() ); cursor.setPosition( endPos.x, endPos.y ); }
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( "C:/Windows/Fonts/arial.ttf" ); characterSize = 17; text = L""; lines = wrap_text( window->getSize().x, text ); 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::KeyPressed && event.key.control && event.key.code == sf::Keyboard::V ) { int index = getCursorIndex( cursorPosition ); std::wstring clip_text = sf::Clipboard::getString().toWideString(); while( clip_text.find( L"\r\n" ) != std::wstring::npos ) { clip_text.erase( clip_text.find( L"\r\n" ), 1 ); }; text.insert( index, clip_text ); index += clip_text.size(); for( auto & line: lines ) delete line; lines = wrap_text( window->getSize().x, text ); cursorPosition = getCursorFromIndex( index ); setCursorPosition( cursorPosition ); } else if( event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Delete ) { int index = getCursorIndex( cursorPosition ); if( !text.empty() ) { text.erase( index, 1 ); for( auto & line: lines ) delete line; lines = wrap_text( window->getSize().x, text ); } } else if( event.type == sf::Event::TextEntered ) { int index = getCursorIndex( cursorPosition ); if( event.text.unicode == 8 ) { if( index > 0 && !text.empty() ) { text.erase( index - 1, 1 ); index -= 1; } } else if( event.text.unicode == 13 ) { text.insert( index, 1, L'\n' ); index += 1; } else if( event.text.unicode == 9 ) { text.insert( index, 1, L'\t' ); index += 1; } else { wchar_t character = static_cast < wchar_t >( event.text.unicode ); if( character >= 32 && character != 127 ) { text.insert( index, 1, character ); index += 1; } } for( auto & t: lines ) delete t; lines = wrap_text( window->getSize().x, text ); 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( !lines.empty() && cursorPosition.y > 0 ) { cursorPosition.y -= 1; cursorPosition.x = lines[ cursorPosition.y ]->getString().toWideString().size() - 1; } } } else if( event.key.code == sf::Keyboard::Right ) { if( !lines.empty() && cursorPosition.x < lines[ cursorPosition.y ]->getString().toWideString().size() ) { 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(); } setCursorPosition( cursorPosition ); } } window->clear( sf::Color( 48, 48, 48, 255 ) ); 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-10 18:28:27 Dodałem zawijanie słów dłuższych niż linia. Kod testowany i działa :-) #include <SFML/Graphics.hpp> #include <iostream> #include <vector> #include <cmath>
sf::RenderWindow * window;
sf::Font font; short characterSize;
std::wstring text; 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;
int selecting_start = 2; int selecting_end = 4; std::vector < sf::Text * > wrap_text( int line_width, std::wstring text ) { std::vector < sf::Text * > wrapped_text; std::wstring line = L""; std::wstring word = L""; sf::Color textColor = sf::Color::White; for( auto & character: text ) { if( sf::Text( word + character, font, characterSize ).getGlobalBounds().width > line_width ) { if( line != L"" ) { sf::Text * t = new sf::Text( line, font, characterSize ); ( wrapped_text.empty() ) ? t->setPosition( 0, 0 ) : t->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); wrapped_text.push_back( t ); line = L""; } std::wstring l = L""; word = word + character; for( wchar_t & c: word ) { if( sf::Text( l + c, font, characterSize ).getGlobalBounds().width > line_width ) { sf::Text * t = new sf::Text( l, font, characterSize ); ( wrapped_text.empty() ) ? t->setPosition( 0, 0 ) : t->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); wrapped_text.push_back( t ); l = c; } else l = l + c; } sf::Text * t = new sf::Text( l, font, characterSize ); ( wrapped_text.empty() ) ? t->setPosition( 0, 0 ) : t->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); wrapped_text.push_back( t ); word = L""; } else if( sf::Text( line + word + character, font, characterSize ).getGlobalBounds().width > line_width ) { sf::Text * t = new sf::Text( line, font, characterSize ); ( wrapped_text.empty() ) ? t->setPosition( 0, 0 ) : t->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); t->setFillColor( textColor ); wrapped_text.push_back( t ); line = L""; word = word + character; } else if( character == L'\n' ) { if( sf::Text( line + word + L"\n", font, characterSize ).getGlobalBounds().width > line_width ) { sf::Text * t = new sf::Text( line, font, characterSize ); ( wrapped_text.empty() ) ? t->setPosition( 0, 0 ) : t->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); t->setFillColor( textColor ); wrapped_text.push_back( t ); sf::Text * t2 = new sf::Text( word + L"\n", font, characterSize ); ( wrapped_text.empty() ) ? t2->setPosition( 0, 0 ) : t2->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); t2->setFillColor( textColor ); wrapped_text.push_back( t2 ); line = L""; word = L""; } else { sf::Text * t = new sf::Text( line + word + L"\n", font, characterSize ); ( wrapped_text.empty() ) ? t->setPosition( 0, 0 ) : t->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); t->setFillColor( textColor ); wrapped_text.push_back( t ); line = L""; word = L""; } } else if( character == L' ' || character == L'\t' ) { if( sf::Text( line + word, font, characterSize ).getGlobalBounds().width > line_width ) { sf::Text * t = new sf::Text( line + L"\n", font, characterSize ); ( wrapped_text.empty() ) ? t->setPosition( 0, 0 ) : t->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); t->setFillColor( textColor ); wrapped_text.push_back( t ); line = L""; } else { line = line + word + character; } word = L""; } else { word = word + character; } } if( line != L"" || word != L"" ) { sf::Text * t = new sf::Text( line + word, font, characterSize ); ( wrapped_text.empty() ) ? t->setPosition( 0, 0 ) : t->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); t->setFillColor( textColor ); wrapped_text.push_back( t ); } return wrapped_text; }
sf::Vector2i getCursorPosition() { if( worldMousePosition.y > lines[ lines.size() - 1 ]->getGlobalBounds().top + font.getLineSpacing( characterSize ) ) { return sf::Vector2i( lines[ lines.size() - 1 ]->getString().toWideString().size(), lines.size() - 1 ); } sf::Vector2i cur_pos = sf::Vector2i( 0, 0 ); for( int t = 0; t < lines.size(); t++ ) { for( size_t i = 0; i < lines[ t ]->getString().getSize(); ++i ) { sf::Vector2f charPos = lines[ t ]->findCharacterPos( i ); float nextX = lines[ 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 == lines[ 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 < lines.size(); ++i ) { index += lines[ i ]->getString().getSize(); } index += position.x; return index; }
sf::Vector2i getCursorFromIndex( int index ) { if( index <= 0 || lines.empty() ) return sf::Vector2i( 0, 0 ); int current = 0; for( int y = 0; y < lines.size(); ++y ) { int lineSize = lines[ y ]->getString().getSize(); if( index <= current + lineSize ) { return sf::Vector2i( index - current, y ); } current += lineSize; } return sf::Vector2i( lines.back()->getString().toWideString().size(), lines.size() - 1 ); }
void setCursorUp() { if( lines.empty() ) return; 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( lines.empty() ) return; 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 setCursorPosition( sf::Vector2i cursor_position ) { cursorPosition = cursor_position; if( cursor_position == sf::Vector2i( 0, 0 ) ) { cursor.setPosition( sf::Vector2f( 0, 0 ) ); return; } std::wstring line = lines[ cursorPosition.y ]->getString().toWideString(); if( line.size() == 0 ) { cursor.setPosition( lines[ cursorPosition.y ]->getPosition() ); return; } if( cursor_position.x < line.size() ) { sf::Vector2f charPos = lines[ cursorPosition.y ]->findCharacterPos( cursor_position.x ); cursor.setPosition( charPos.x, charPos.y ); return; } sf::Vector2f endPos = lines[ cursorPosition.y ]->findCharacterPos( line.size() ); cursor.setPosition( endPos.x, endPos.y ); }
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( "C:/Windows/Fonts/arial.ttf" ); characterSize = 17; text = L""; lines = wrap_text( window->getSize().x, text ); 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::KeyPressed && event.key.control && event.key.code == sf::Keyboard::V ) { int index = getCursorIndex( cursorPosition ); std::wstring clip_text = sf::Clipboard::getString().toWideString(); while( clip_text.find( L"\r\n" ) != std::wstring::npos ) { clip_text.erase( clip_text.find( L"\r\n" ), 1 ); }; text.insert( index, clip_text ); index += clip_text.size(); for( auto & line: lines ) delete line; lines = wrap_text( window->getSize().x, text ); cursorPosition = getCursorFromIndex( index ); setCursorPosition( cursorPosition ); } else if( event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Delete ) { int index = getCursorIndex( cursorPosition ); if( !text.empty() ) { text.erase( index, 1 ); for( auto & line: lines ) delete line; lines = wrap_text( window->getSize().x, text ); } } else if( event.type == sf::Event::TextEntered ) { int index = getCursorIndex( cursorPosition ); if( event.text.unicode == 8 ) { if( index > 0 && !text.empty() ) { text.erase( index - 1, 1 ); index -= 1; } } else if( event.text.unicode == 13 ) { text.insert( index, 1, L'\n' ); index += 1; } else if( event.text.unicode == 9 ) { text.insert( index, 1, L'\t' ); index += 1; } else { wchar_t character = static_cast < wchar_t >( event.text.unicode ); if( character >= 32 && character != 127 ) { text.insert( index, 1, character ); index += 1; } } for( auto & t: lines ) delete t; lines = wrap_text( window->getSize().x, text ); 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( !lines.empty() && cursorPosition.y > 0 ) { cursorPosition.y -= 1; cursorPosition.x = lines[ cursorPosition.y ]->getString().toWideString().size() - 1; } } } else if( event.key.code == sf::Keyboard::Right ) { if( !lines.empty() && cursorPosition.x < lines[ cursorPosition.y ]->getString().toWideString().size() ) { 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(); } setCursorPosition( cursorPosition ); } } window->clear( sf::Color( 48, 48, 48, 255 ) ); 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-10 18:37:40 Zastanawiam się teraz jak zrobić zaznaczanie tekstu. Co o tym sądzicie? Dobre rozwiązanie ? class Selection { public: sf::Vector2i position; std::vector < sf::RectangleShape > rects; };
|
|
pekfos |
» 2025-06-10 22:13:51 A jak by to miało działać? Więcej sensu by miały 2 pozycje, wektor prostokątów możesz sobie darować. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-06-11 00:50:51 Ale wektor prostokątów jest mi potrzebny do renderu obszaru zaznaczenia. Jak to inaczej zrobić? |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-06-11 18:28:38 Napisałem kod zaznaczania tekstu. Teraz przy pomocy lewego przycisku myszy i przeciągnięcia można zaznaczać tekst. Do renderowania zaznaczonego obszary wykorzystałem wektor std::vector < sf::RectangleShape* > rects, a dokładniej to trzy prostokąty - górny, dolny i środkowy. Zaznaczony tekst można edytować, tzn jak zacznie się pisac tekst to nowy tekst zastąpi ten zaznaczony. Zaznaczony tekst można także skasować przy pomocy klawisza backspace. #include <SFML/Graphics.hpp> #include <iostream> #include <vector> #include <cmath>
sf::RenderWindow * window;
sf::Color text_color = sf::Color::White; sf::Color background_color = sf::Color( 48, 48, 48, 255 ); sf::Color selection_color = sf::Color( 3, 55, 161, 255 );
sf::Font font; short characterSize;
std::wstring text; std::vector < sf::Text * > lines;
sf::Vector2i mousePosition; sf::Vector2f worldMousePosition; bool mousePress = false;
sf::RectangleShape cursor; sf::Vector2i cursorPosition = sf::Vector2i( 0, 0 );
sf::Clock timeClock; sf::Time currentTime;
std::vector < sf::Text * > wrap_text( int line_width, std::wstring text ) { std::vector < sf::Text * > wrapped_text; std::wstring line = L""; std::wstring word = L""; for( auto & character: text ) { if( sf::Text( word + character, font, characterSize ).getGlobalBounds().width > line_width ) { if( line != L"" ) { sf::Text * t = new sf::Text( line, font, characterSize ); ( wrapped_text.empty() ) ? t->setPosition( 0, 0 ) : t->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); wrapped_text.push_back( t ); line = L""; } std::wstring l = L""; word = word + character; for( wchar_t & c: word ) { if( sf::Text( l + c, font, characterSize ).getGlobalBounds().width > line_width ) { sf::Text * t = new sf::Text( l, font, characterSize ); ( wrapped_text.empty() ) ? t->setPosition( 0, 0 ) : t->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); wrapped_text.push_back( t ); l = c; } else l = l + c; } sf::Text * t = new sf::Text( l, font, characterSize ); ( wrapped_text.empty() ) ? t->setPosition( 0, 0 ) : t->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); wrapped_text.push_back( t ); word = L""; } else if( sf::Text( line + word + character, font, characterSize ).getGlobalBounds().width > line_width ) { sf::Text * t = new sf::Text( line, font, characterSize ); ( wrapped_text.empty() ) ? t->setPosition( 0, 0 ) : t->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); wrapped_text.push_back( t ); line = L""; word = word + character; } else if( character == L'\n' ) { if( sf::Text( line + word + L"\n", font, characterSize ).getGlobalBounds().width > line_width ) { sf::Text * t = new sf::Text( line, font, characterSize ); ( wrapped_text.empty() ) ? t->setPosition( 0, 0 ) : t->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); wrapped_text.push_back( t ); sf::Text * t2 = new sf::Text( word + L"\n", font, characterSize ); ( wrapped_text.empty() ) ? t2->setPosition( 0, 0 ) : t2->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); wrapped_text.push_back( t2 ); line = L""; word = L""; } else { sf::Text * t = new sf::Text( line + word + L"\n", font, characterSize ); ( wrapped_text.empty() ) ? t->setPosition( 0, 0 ) : t->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); wrapped_text.push_back( t ); line = L""; word = L""; } } else if( character == L' ' || character == L'\t' ) { if( sf::Text( line + word, font, characterSize ).getGlobalBounds().width > line_width ) { sf::Text * t = new sf::Text( line + L"\n", font, characterSize ); ( wrapped_text.empty() ) ? t->setPosition( 0, 0 ) : t->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); wrapped_text.push_back( t ); line = L""; } else { line = line + word + character; } word = L""; } else { word = word + character; } } if( line != L"" || word != L"" ) { sf::Text * t = new sf::Text( line + word, font, characterSize ); ( wrapped_text.empty() ) ? t->setPosition( 0, 0 ) : t->setPosition( 0, wrapped_text.back()->getPosition().y + font.getLineSpacing( characterSize ) ); wrapped_text.push_back( t ); } for( auto & line: lines ) line->setFillColor( text_color ); return wrapped_text; }
sf::Vector2i getCursorPosition() { if( worldMousePosition.y >= lines.back()->getGlobalBounds().top ) { for( size_t i = 0; i < lines.back()->getString().toWideString().size(); ++i ) { sf::Vector2f charPos = lines.back()->findCharacterPos( i ); sf::Vector2f nextPos = lines.back()->findCharacterPos( i + 1 ); float charWidth = nextPos.x - charPos.x; if( worldMousePosition.x < charPos.x + charWidth / 2.f ) { return sf::Vector2i( i, lines.size() - 1 ); } } return sf::Vector2i( lines.back()->getString().toWideString().size(), lines.size() - 1 ); } sf::Vector2i cur_pos = sf::Vector2i( 0, 0 ); for( int t = 0; t < lines.size(); t++ ) { for( size_t i = 0; i < lines[ t ]->getString().getSize(); ++i ) { sf::Vector2f charPos = lines[ t ]->findCharacterPos( i ); float nextX = lines[ 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 == lines[ 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 < lines.size(); ++i ) { index += lines[ i ]->getString().getSize(); } index += position.x; return index; }
sf::Vector2i getCursorFromIndex( int index ) { if( index <= 0 || lines.empty() ) return sf::Vector2i( 0, 0 ); int current = 0; for( int y = 0; y < lines.size(); ++y ) { int lineSize = lines[ y ]->getString().getSize(); if( index <= current + lineSize ) { return sf::Vector2i( index - current, y ); } current += lineSize; } return sf::Vector2i( lines.back()->getString().toWideString().size(), lines.size() - 1 ); }
void setCursorUp() { if( lines.empty() ) return; 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( lines.empty() ) return; 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 setCursorPosition( sf::Vector2i cursor_position ) { cursorPosition = cursor_position; if( cursor_position == sf::Vector2i( 0, 0 ) ) { cursor.setPosition( sf::Vector2f( 0, 0 ) ); return; } std::wstring line = lines[ cursorPosition.y ]->getString().toWideString(); if( line.size() == 0 ) { cursor.setPosition( lines[ cursorPosition.y ]->getPosition() ); return; } if( cursor_position.x < line.size() ) { sf::Vector2f charPos = lines[ cursorPosition.y ]->findCharacterPos( cursor_position.x ); cursor.setPosition( charPos.x, charPos.y ); return; } sf::Vector2f endPos = lines[ cursorPosition.y ]->findCharacterPos( line.size() ); cursor.setPosition( endPos.x, endPos.y ); }
class Selection { public: int start_index = 0; int end_index = 0; std::vector < sf::RectangleShape * > rects; void draw() { sf::Vector2i start_position; sf::Vector2i end_position; if( start_index < end_index ) { start_position = getCursorFromIndex( start_index ); end_position = getCursorFromIndex( end_index ); } else { start_position = getCursorFromIndex( end_index ); end_position = getCursorFromIndex( start_index ); } int start_x = std::min( start_position.x, end_position.x ); int end_x = std::max( start_position.x, end_position.x ); int start_y = std::min( start_position.y, end_position.y ); int end_y = std::max( start_position.y, end_position.y ); float rect_start_x =( start_x == 0 ) ? 0 : lines[ start_y ]->findCharacterPos( start_x ).x; float rect_end_x = lines[ end_y ]->findCharacterPos( end_x ).x; float rect_start_y =( start_x == 0 ) ? 0 : lines[ start_y ]->findCharacterPos( start_x ).y; float rect_end_y = lines[ end_y ]->findCharacterPos( end_x ).y; for( auto & r: rects ) delete r; rects.clear(); if( end_y == start_y ) { sf::RectangleShape * rect = new sf::RectangleShape( sf::Vector2f( rect_end_x - rect_start_x + 1, font.getLineSpacing( characterSize ) ) ); rect->setPosition( rect_start_x, rect_start_y ); rect->setFillColor( selection_color ); rects.push_back( rect ); } else if( end_y - start_y >= 1 ) { sf::RectangleShape * top_rect = new sf::RectangleShape( sf::RectangleShape( sf::Vector2f( window->getSize().x - rect_start_x, font.getLineSpacing( characterSize ) ) ) ); top_rect->setPosition( rect_start_x, rect_start_y ); top_rect->setFillColor( selection_color ); rects.push_back( top_rect ); sf::RectangleShape * center_rect = new sf::RectangleShape( sf::RectangleShape( sf::Vector2f( window->getSize().x,( end_y - start_y - 1 ) * font.getLineSpacing( characterSize ) ) ) ); center_rect->setPosition( 0, rect_start_y + font.getLineSpacing( characterSize ) ); center_rect->setFillColor( selection_color ); rects.push_back( center_rect ); sf::RectangleShape * bottom_rect = new sf::RectangleShape( sf::RectangleShape( sf::Vector2f( rect_end_x, font.getLineSpacing( characterSize ) ) ) ); bottom_rect->setPosition( 0, rect_end_y ); bottom_rect->setFillColor( selection_color ); rects.push_back( bottom_rect ); } for( auto & rect: rects ) window->draw( * rect ); } };
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( "C:/Windows/Fonts/arial.ttf" ); characterSize = 17; text = L""; text = L"Tak? O Co chodzi?\n" L"Tak? O Co chodzi?\n" L"Tak? O Co chodzi?\n" L"Tak? O Co chodzi?"; lines = wrap_text( window->getSize().x, text ); cursor = sf::RectangleShape( sf::Vector2f( 2, characterSize ) ); cursor.setFillColor( sf::Color::Red ); sf::Clock clock; Selection * selection = nullptr; 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::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left ) { mousePress = true; sf::Vector2i cur_pos = getCursorPosition(); if( selection != nullptr ) delete selection; selection = new Selection(); selection->start_index = getCursorIndex( cur_pos ); selection->end_index = getCursorIndex( cur_pos ); setCursorPosition( cur_pos ); } else if( event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Left ) { sf::Vector2i cur_pos = getCursorPosition(); setCursorPosition( cur_pos ); mousePress = false; } else if( event.type == sf::Event::MouseMoved ) { if( mousePress ) { sf::Vector2i cur_pos = getCursorPosition(); selection->end_index = getCursorIndex( cur_pos ); setCursorPosition( cur_pos ); } } else if( event.type == sf::Event::KeyPressed && event.key.control && event.key.code == sf::Keyboard::V ) { int index = getCursorIndex( cursorPosition ); std::wstring clip_text = sf::Clipboard::getString().toWideString(); while( clip_text.find( L"\r\n" ) != std::wstring::npos ) { clip_text.erase( clip_text.find( L"\r\n" ), 1 ); }; text.insert( index, clip_text ); index += clip_text.size(); for( auto & line: lines ) delete line; lines = wrap_text( window->getSize().x, text ); cursorPosition = getCursorFromIndex( index ); setCursorPosition( cursorPosition ); } else if( event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Delete ) { int index = getCursorIndex( cursorPosition ); if( !text.empty() ) { text.erase( index, 1 ); for( auto & line: lines ) delete line; lines = wrap_text( window->getSize().x, text ); } } else if( event.type == sf::Event::TextEntered ) { int index = getCursorIndex( cursorPosition ); if( event.text.unicode == 8 ) { if( index > 0 && !text.empty() ) { if( selection == nullptr ||( selection != nullptr && selection->start_index == selection->end_index ) ) { text.erase( index - 1, 1 ); index -= 1; } else { text.erase( selection->start_index, selection->end_index = selection->start_index ); index = selection->start_index; delete selection; selection = nullptr; } } } else if( event.text.unicode == 13 ) { text.insert( index, 1, L'\n' ); index += 1; } else if( event.text.unicode == 9 ) { text.insert( index, 1, L'\t' ); index += 1; } else { wchar_t character = static_cast < wchar_t >( event.text.unicode ); if( character >= 32 && character != 127 ) { if( selection != nullptr && selection->start_index != selection->end_index ) { text.erase( selection->start_index, selection->end_index - selection->start_index ); index = selection->start_index; delete selection; selection = nullptr; } text.insert( index, 1, character ); index += 1; } } for( auto & t: lines ) delete t; lines = wrap_text( window->getSize().x, text ); 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( !lines.empty() && cursorPosition.y > 0 ) { cursorPosition.y -= 1; cursorPosition.x = lines[ cursorPosition.y ]->getString().toWideString().size() - 1; } } } else if( event.key.code == sf::Keyboard::Right ) { if( !lines.empty() && cursorPosition.x < lines[ cursorPosition.y ]->getString().toWideString().size() ) { 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(); } setCursorPosition( cursorPosition ); } } window->clear( background_color ); if( selection ) { selection->draw(); } for( auto & line: lines ) window->draw( * line ); if( std::fmod( currentTime.asSeconds(), 0.6f ) < 0.3f ) window->draw( cursor ); window->display(); } }
|
|
pekfos |
» 2025-06-11 19:54:17 Ale wektor prostokątów jest mi potrzebny do renderu obszaru zaznaczenia. Jak to inaczej zrobić? Po co chcesz to przechowywać? To już podpada pod zbieractwo. Zwłaszcza gdy ten kod wygląda tak: for( auto & r: rects ) delete r;
rects.clear();
for( auto & rect: rects ) window->draw( * rect ); Po prostu miej jeden shape i rysuj go na bieżąco. Ten obiekt nie musi istnieć po wywołaniu draw. I czemu wszystko tworzysz przez new? Programowałeś w Javie w poprzednim życiu? |
|
1 2 3 4 5 6 « 7 » 8 9 10 |