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

[SFML 2.X] Easy Notepad - aplikacja notatnik

Ostatnio zmodyfikowano 2025-06-19 12:24
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
» 2025-05-19 17:20:43
Rozwiązanie:
C/C++
else if( wchar == ' ' || wchar == '\t' ) {
   
white_char = wchar;
   
line = line + wchar + word;
   
word = L"";
}

zamienić na
C/C++
else if( wchar == ' ' || wchar == '\t' ) {
   
white_char = wchar;
   
line = line + word + wchar; // tutaj zmiana
   
word = L"";
}

Rezultat:
P-182367
tBane
Temat założony przez niniejszego użytkownika
» 2025-05-19 21:10:56
Dodałem ograniczenie długości linii. Prawie kompletne - pozostaje tylko napisać wrapowanie pojedynczego słowa gdy jest dłuższe niż długość linii

C/C++
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 = L' ';
   
   
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;
       
}
       
       
// TO-DO if word is longer than line_width
       
       
if( wchar == L' ' || wchar == L'\t' ) {
           
white_char = wchar;
           
word = word + white_char;
           
           
if( line_length > - 1 && !word.empty() ) {
               
sf::Text test_text( line + white_char + word, font, characterSize );
               
test_text.setPosition( 0, 0 ); // wymagane do poprawnego działania getGlobalBounds()
               
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"";
       
}
       
else {
           
word += wchar;
       
}
    }
   
   
// dodaj ostatnią linię
   
if( !word.empty() || !line.empty() ) {
       
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 );
   
}
   
   
return t;
}
P-182372
tBane
Temat założony przez niniejszego użytkownika
» 2025-05-21 18:13:30
Dodałem ponownie pozycjonowanie kursora pisania względem położenia myszy ale z rozdzieleniem na funkcje (setCursorPosition, getCursorPosition). Nadal nie napisałem poprawnie dzielenia długiego słowa na linie, bo mi się nie udało :-/

C/C++
#include <SFML/Graphics.hpp>
#include <iostream>

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;
int cursorPosition = - 1;

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 = L' ';
   
   
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 ) {
               
               
sf::Text test_text( line + white_char + word, font, characterSize );
               
test_text.setPosition( 0, 0 ); // wymagane do poprawnego działania getGlobalBounds()
               
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"";
       
}
       
else {
           
word += wchar;
       
}
    }
   
   
// dodaj ostatnią linię
   
if( !word.empty() || !line.empty() ) {
       
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 );
   
}
   
   
return t;
}

int getCursorPosition() {
   
   
int cur_pos = 0;
   
   
for( auto & text: texts ) {
       
for( size_t i = 0; i < text->getString().getSize(); ++i ) {
           
           
sf::Vector2f charPos = text->findCharacterPos( i );
           
float nextX = text->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 cur_pos;
               
else
                   
 return cur_pos + 1;
               
           
}
           
           
cur_pos += 1;
       
}
    }
   
   
return - 1;
}

void setCursorPosition( int cursor_position ) {
   
   
int index = 0;
   
   
for( auto & text: texts ) {
       
       
if( index + text->getString().toWideString().size() >= cursor_position ) {
           
           
sf::Vector2f charPos = text->findCharacterPos( cursor_position - index );
           
cursor.setPosition( charPos );
           
return;
       
}
       
else
           
 index = index + text->getString().toWideString().size();
       
   
}
}

int main()
{
   
   
sf::View view( sf::FloatRect( 0, 0, 640, 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"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt "
    L"ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco "
    L"laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in "
    L"voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat "
    L"non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
;
   
   
texts.clear();
   
   
   
cursor = sf::RectangleShape( sf::Vector2f( 2, characterSize ) );
   
cursor.setFillColor( sf::Color::Red );
   
   
sf::Clock clock;
   
   
while( window->isOpen() )
   
{
       
       
mousePosition = sf::Mouse::getPosition( * window ); // get the mouse position about window
       
worldMousePosition = window->mapPixelToCoords( mousePosition ); // get global mouse position
       
       
texts = wrapText( window->getSize().x );
       
       
sf::Event event;
       
while( window->pollEvent( event ) ) {
           
           
if( event.type == sf::Event::Closed )
               
 window->close();
           
           
if( event.type == sf::Event::Resized )
           
{
               
// Aktualizacja widoku bez skalowania
               
sf::View view;
               
view.setSize( static_cast < float >( event.size.width ), static_cast < float >( event.size.height ) );
               
view.setCenter( view.getSize() / 2.f );
               
window->setView( view );
           
}
           
else if( event.type == sf::Event::MouseMoved ) {
               
cursorPosition = getCursorPosition();
               
setCursorPosition( cursorPosition );
           
}
           
else if( event.type == sf::Event::KeyPressed ) {
               
if( event.key.code == sf::Keyboard::Left ) {
                   
if( cursorPosition > 0 ) {
                       
cursorPosition -= 1;
                   
}
                   
                }
               
else if( event.key.code == sf::Keyboard::Right ) {
                   
if( cursorPosition < text.size() + 1 ) {
                       
cursorPosition += 1;
                   
}
                   
                }
               
               
setCursorPosition( cursorPosition );
               
           
}
           
           
        }
       
       
       
       
       
       
window->clear( sf::Color( 48, 48, 48, 255 ) );
       
for( auto & text: texts )
           
 window->draw( * text );
       
       
window->draw( cursor );
       
window->display();
   
}
}
P-182383
tBane
Temat założony przez niniejszego użytkownika
» 2025-05-21 19:49:47
Chciałbym z dumą przedstawić kompletny wraper Tekstu. Poniższa funkcja dzieli text na linie o stałej szerokości line_length :-) Co ciekawe ChatGPT się gubi z tym kodem - jest zbyt mało źródeł i zbyt zaawansowany.

C/C++
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 = L' ';
   
   
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().getSize().x >= 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().getSize().x >= 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 + character, 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().getSize().x >= 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"";
       
}
       
else {
           
word += wchar;
       
}
    }
   
   
// dodaj ostatnią linię
   
   
if( line == L"" ) {
       
sf::Text test_word( word, font, characterSize );
       
       
if( test_word.getGlobalBounds().getSize().x >= 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().getSize().x >= 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 + character, 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() ) {
       
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 );
   
}
   
   
return t;
}
P-182384
DejaVu
» 2025-05-22 10:00:50
Jaka wersja ChatGPT się gubi? :)
P-182388
tBane
Temat założony przez niniejszego użytkownika
» 2025-05-22 14:29:08
ChatGPT-4o. Nawet deep research nie pomogło. :-/

Dodałem przysuwanie kursora za pomocą strzałek oraz naprawiłem podwójne dodawanie ostatniego znaku w pierwszej linii gdy jest dłuższa niż podana szerokość.
Teraz zastanawiam się jak dodać zaznaczanie tekstu.


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

sf::Font font;
short characterSize;

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

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

sf::RectangleShape cursor;
int cursorPosition = - 1;

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 = L' ';
   
   
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"";
       
}
       
else {
           
word += wchar;
       
}
    }
   
   
// dodaj ostatnią linię
   
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"";
       
}
    }
   
   
if( !word.empty() || !line.empty() ) {
       
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 );
   
}
   
   
return t;
}

int getCursorPosition() {
   
   
int cur_pos = 0;
   
   
for( auto & text: texts ) {
       
for( size_t i = 0; i < text->getString().getSize(); ++i ) {
           
           
sf::Vector2f charPos = text->findCharacterPos( i );
           
float nextX = text->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 cur_pos;
               
else
                   
 return cur_pos + 1;
               
           
}
           
           
cur_pos += 1;
       
}
    }
   
   
return cur_pos;
}

void setCursorPosition( int cursor_position ) {
   
   
int index = 0;
   
   
for( auto & text: texts ) {
       
       
if( index + text->getString().toWideString().size() >= cursor_position ) {
           
           
sf::Vector2f charPos = text->findCharacterPos( cursor_position - index );
           
cursor.setPosition( charPos );
           
return;
       
}
       
else
           
 index = index + text->getString().toWideString().size();
       
   
}
}

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

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

int main()
{
   
   
sf::View view( sf::FloatRect( 0, 0, 640, 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"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx "
    L"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt "
    L"ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco "
    L"laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in "
    L"voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat "
    L"non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
;
   
   
texts.clear();
   
   
   
cursor = sf::RectangleShape( sf::Vector2f( 2, characterSize ) );
   
cursor.setFillColor( sf::Color::Red );
   
   
sf::Clock clock;
   
   
while( window->isOpen() )
   
{
       
       
mousePosition = sf::Mouse::getPosition( * window ); // get the mouse position about window
       
worldMousePosition = window->mapPixelToCoords( mousePosition ); // get global mouse position
       
       
for( auto & t: texts )
           
 delete t;
       
       
texts = wrapText( window->getSize().x );
       
       
sf::Event event;
       
while( window->pollEvent( event ) ) {
           
           
if( event.type == sf::Event::Closed )
               
 window->close();
           
           
if( event.type == sf::Event::Resized )
           
{
               
// Aktualizacja widoku bez skalowania
               
sf::View view;
               
view.setSize( static_cast < float >( event.size.width ), static_cast < float >( event.size.height ) );
               
view.setCenter( view.getSize() / 2.f );
               
window->setView( view );
           
}
           
else if( event.type == sf::Event::MouseMoved ) {
               
cursorPosition = getCursorPosition();
               
setCursorPosition( cursorPosition );
           
}
           
else if( event.type == sf::Event::TextEntered ) {
               
               
            }
           
else if( event.type == sf::Event::KeyPressed ) {
               
if( event.key.code == sf::Keyboard::Left ) {
                   
if( cursorPosition > 0 ) {
                       
cursorPosition -= 1;
                   
}
                   
                }
               
else if( event.key.code == sf::Keyboard::Right ) {
                   
if( cursorPosition < text.size() + 1 ) {
                       
cursorPosition += 1;
                   
}
                   
                }
               
else if( event.key.code == sf::Keyboard::Up ) {
                   
cursorPosition = setCursorUp();
               
}
               
else if( event.key.code == sf::Keyboard::Down ) {
                   
cursorPosition = setCursorDown();
               
}
               
               
setCursorPosition( cursorPosition );
               
           
}
           
           
        }
       
       
window->clear( sf::Color( 48, 48, 48, 255 ) );
       
for( auto & text: texts )
           
 window->draw( * text );
       
       
window->draw( cursor );
       
window->display();
   
}
}
P-182389
tBane
Temat założony przez niniejszego użytkownika
» 2025-05-23 15:44:12
Nie mam pojęcia jak zaznaczać tekst :-/ tzn nie mam żadnego pomysłu jak podzielić sf::Text. Ma ktoś pomysł jak to zrealizować gdy ma się int selecting_start, int selecting_end ?

ps. poprawiona wersja, która poprawnie dodaje ostatni biały znak dla ostatniego słowa. Ale niestety nie działa wprowadzanie enterów, bo generuje jakieś dziwne znaki ..


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

sf::Font font;
short characterSize;

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

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

sf::RectangleShape cursor;
int cursorPosition = - 1;

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

std::vector < sf::Text * > wrapText( int line_length = - 1 ) {
   
std::vector < sf::Text * > t;
   
std::wstring line = L"";
   
std::wstring word = L"";
   
wchar_t white_char = '\0';
   
   
for( auto & wchar: text ) {
       
if( wchar == '\n' ) {
           
line = line + white_char + word;
           
sf::Text * new_text = new sf::Text( line, font, characterSize );
           
new_text->setFillColor( sf::Color::White );
           
if( !t.empty() )
               
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
           
else
               
 new_text->setPosition( 0, 0 );
           
           
t.push_back( new_text );
           
line = L"";
           
word = L"";
           
continue;
       
}
       
       
       
       
if( wchar == L' ' || wchar == L'\t' ) {
           
white_char = wchar;
           
word = word + white_char;
           
           
if( line_length > - 1 ) {
               
               
if( line == L"" ) {
                   
sf::Text test_word( word, font, characterSize );
                   
                   
if( test_word.getGlobalBounds().width >= line_length ) {
                       
                       
std::wstring part_of_word = L"";
                       
wchar_t character = '\0';
                       
                       
for( wchar_t & ch: word ) {
                           
character = ch;
                           
sf::Text w( part_of_word + character, font, characterSize );
                           
if( w.getGlobalBounds().width >= line_length ) {
                               
sf::Text * new_text = new sf::Text( part_of_word, font, characterSize );
                               
new_text->setFillColor( sf::Color::White );
                               
if( !t.empty() )
                                   
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
                               
else
                                   
 new_text->setPosition( 0, 0 );
                               
                               
t.push_back( new_text );
                               
part_of_word = character;
                           
}
                           
else
                               
 part_of_word = part_of_word + character;
                           
                       
}
                       
                       
if( part_of_word != L"" ) {
                           
sf::Text * new_text = new sf::Text( part_of_word, font, characterSize );
                           
new_text->setFillColor( sf::Color::White );
                           
if( !t.empty() )
                               
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
                           
else
                               
 new_text->setPosition( 0, 0 );
                           
                           
t.push_back( new_text );
                           
part_of_word = L"";
                       
}
                       
                       
word = L"";
                       
continue;
                   
}
                }
               
               
sf::Text test_text( line + white_char + word, font, characterSize );
               
if( test_text.getGlobalBounds().width >= line_length ) {
                   
sf::Text * new_text = new sf::Text( line, font, characterSize );
                   
new_text->setFillColor( sf::Color::White );
                   
if( !t.empty() )
                       
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
                   
else
                       
 new_text->setPosition( 0, 0 );
                   
                   
t.push_back( new_text );
                   
line = word;
                   
word = L"";
                   
continue;
                   
               
}
               
else
                   
 line = line + word;
               
           
}
           
           
           
word = L"";
           
white_char = '\0';
       
}
       
else {
           
word += wchar;
       
}
    }
   
   
// dodaj ostatnią linię
   
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"";
       
}
    }
   
   
if( !word.empty() || !line.empty() ) {
       
if( white_char != '\0' )
           
 line = line + white_char + word;
       
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 );
   
}
   
   
return t;
}

int getCursorPosition() {
   
   
int cur_pos = 0;
   
   
for( auto & text: texts ) {
       
for( size_t i = 0; i < text->getString().getSize(); ++i ) {
           
           
sf::Vector2f charPos = text->findCharacterPos( i );
           
float nextX = text->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 cur_pos;
               
else
                   
 return cur_pos + 1;
               
           
}
           
           
bool isLastChar =( i == text->getString().getSize() - 1 );
           
if( isLastChar &&
           
worldMousePosition.x > charRect.left &&
           
worldMousePosition.y >= charRect.top &&
           
worldMousePosition.y <= charRect.top + charRect.height )
           
{
               
return cur_pos + 1;
           
}
           
           
cur_pos += 1;
       
}
    }
   
   
return cur_pos;
}

void setCursorPosition( int cursor_position ) {
   
   
int index = 0;
   
   
for( auto & t: texts ) {
       
       
if( index + t->getString().toWideString().size() >= cursor_position ) {
           
           
sf::Vector2f charPos = t->findCharacterPos( cursor_position - index );
           
cursor.setPosition( charPos.x, charPos.y );
           
return;
       
}
       
else
           
 index = index + t->getString().toWideString().size();
       
   
}
}

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

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

int main()
{
   
   
sf::View view( sf::FloatRect( 0, 0, 640, 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"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt "
    L"ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco "
    L"laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in "
    L"voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat "
    L"non proident, sunt in culpa qui officia deserunt mollit\tanim id\test\t\t laborum."
;
   
   
texts = wrapText( window->getSize().x );
   
   
cursor = sf::RectangleShape( sf::Vector2f( 2, characterSize ) );
   
cursor.setFillColor( sf::Color::Red );
   
   
sf::Clock clock;
   
   
while( window->isOpen() )
   
{
       
       
mousePosition = sf::Mouse::getPosition( * window ); // get the mouse position about window
       
worldMousePosition = window->mapPixelToCoords( mousePosition ); // get global mouse position
       
       
sf::Event event;
       
while( window->pollEvent( event ) ) {
           
           
if( event.type == sf::Event::Closed )
               
 window->close();
           
           
if( event.type == sf::Event::Resized )
           
{
               
// Aktualizacja widoku bez skalowania
               
sf::View view;
               
view.setSize( static_cast < float >( event.size.width ), static_cast < float >( event.size.height ) );
               
view.setCenter( view.getSize() / 2.f );
               
window->setView( view );
           
}
           
else if( event.type == sf::Event::MouseMoved ) {
               
cursorPosition = getCursorPosition();
               
setCursorPosition( cursorPosition );
           
}
           
else if( event.type == sf::Event::TextEntered ) {
               
               
if( event.text.unicode < 128 ) {
                   
                   
if( event.text.unicode == '\b' ) {
                       
// backspace
                       
if( text.size() > 0 && cursorPosition > 0 ) {
                           
text.erase( cursorPosition - 1, 1 );
                           
cursorPosition -= 1;
                       
}
                       
                    }
                   
else if( event.text.unicode == 32 ) {
                       
// space
                       
text.insert( cursorPosition, 1, ' ' );
                       
cursorPosition += 1;
                   
}
                   
else if( event.text.unicode == 13 ) {
                       
// enter
                       
text.insert( cursorPosition, 1, '\n' );
                       
cursorPosition += 1;
                       
                   
}
                   
else {
                       
// is character
                       
text.insert( cursorPosition, 1, char( event.text.unicode ) );
                       
cursorPosition += 1;
                   
}
                }
               
               
for( auto & t: texts )
                   
 delete t;
               
               
texts = wrapText( window->getSize().x );
               
setCursorPosition( cursorPosition );
           
}
           
else if( event.type == sf::Event::KeyPressed ) {
               
if( event.key.code == sf::Keyboard::Left ) {
                   
if( cursorPosition > 0 ) {
                       
cursorPosition -= 1;
                   
}
                   
                }
               
else if( event.key.code == sf::Keyboard::Right ) {
                   
if( cursorPosition < text.size() + 1 ) {
                       
cursorPosition += 1;
                   
}
                   
                }
               
else if( event.key.code == sf::Keyboard::Up ) {
                   
cursorPosition = setCursorUp();
               
}
               
else if( event.key.code == sf::Keyboard::Down ) {
                   
cursorPosition = setCursorDown();
               
}
               
               
               
setCursorPosition( cursorPosition );
               
           
}
           
           
        }
       
       
window->clear( sf::Color( 48, 48, 48, 255 ) );
       
for( auto & text: texts )
           
 window->draw( * text );
       
       
window->draw( cursor );
       
window->display();
   
}
}
P-182390
tBane
Temat założony przez niniejszego użytkownika
» 2025-05-23 19:09:56
Kurde. Źle się za to zabrałem. Gdy skierujemy kursor na początek linii to cofa się o linię wyżej. A przecież powinna być możliwość ustawienia kursora zarówno na początku linii jak i na końcu. Czyli teraz trzeba przepisać na nowo getCursorPosition() i setCursrorPosition() w taki sposób, by zamiast pojedynczego int cursorPosition była dodatkowo informacja na której linii cursor leży. A co za tym idzie kod odpowiedzialny za edycję tekstu też jest niepoprawny. No i wszystko na marne :D
P-182391
1 2 « 3 » 4 5 6 7 8 9 10
Poprzednia strona Strona 3 z 10 Następna strona