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ść
pekfos
» 2025-05-18 17:17:14
Zwróć uwagę by tekst podzielony na słowa był renderowany tak samo jak renderowany jednym ciągiem przez SFML, inaczej kolorowanie będzie miało wpływ na składanie tekstu. Słowem kluczowym tu jest kerning.
https://www.sfml-dev.org/documentation/2.6.2/classsf_1_1Font.php#ab357e3e0e158f1dfc454a78e111cb5d6
To bardziej uwaga do robienia edytora tekstowego, a nie edytora do kodu źródłowego, bo do kodu się typowo używa czcionki o stałej szerokości.
P-182358
tBane
Temat założony przez niniejszego użytkownika
» 2025-05-18 18:36:59
Na razie mam coś takiego. Nie za bardzo wiem jak sprawdzać słowa klucze.


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

sf::Font font;
short characterSize;

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

sf::Vector2i mousePosition;
sf::Vector2f worldMousePosition;
sf::RectangleShape cursor;

std::vector < std::wstring > key_words;

bool isStartKey( std::wstring text ) {
   
for( auto & key: key_words ) {
       
if( L"<" + key + L">" == text )
           
 return true;
       
   
}
   
   
return false;
}

bool isEndKey( std::wstring text ) {
   
for( auto & key: key_words ) {
       
if( L"</" + key + L">" == text )
           
 return true;
       
   
}
   
   
return false;
}

void setKeyWords() {
   
key_words.push_back( L"character" );
}

std::vector < sf::Text * > wrapText() {
   
std::vector < sf::Text * > t;
   
std::wstring line = L"";
   
std::wstring word = L"";
   
wchar_t wchar;
   
   
for( auto & wchar: text ) {
       
std::cout << static_cast < unsigned char >( wchar );
       
       
if( wchar == '\n' ) {
           
// TO-DO lub linia jest za dłuha
           
sf::Text * new_text = new sf::Text( line, font, characterSize );
           
new_text->setFillColor( sf::Color::White );
           
if( t.size() > 0 )
               
 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"";
       
}
       
else if( wchar == ' ' ) {
           
line = line + L" " + word;
           
word = L"";
       
}
       
else if( wchar == '\t' ) {
           
line = line + L"\t" + word;
           
word = L"";
       
}
       
else {
           
word = word + wchar;
       
}
       
    }
   
   
return t;
}

std::pair < sf::Text *, int > getCursorPosition() {
   
   
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 { text, i };
               
else
                return
{ text, i + 1 };
               
           
}
        }
    }
   
   
return { nullptr, - 1 };
}

int main()
{
   
sf::RenderWindow window( sf::VideoMode( { 640, 640 } ), "Easy Notepad!", sf::Style::Default );
   
   
font.loadFromFile( "arial.ttf" );
   
characterSize = 17;
   
text = L"<character> to jest Character</character>, lorem ipsum,\n"
    L"lorem ipsum,lorem ipsum,lorem ipsum,\n"
    L"zażółć gęślą jaźń ći,\n"
    L"lorem ipsum,lorem ipsum,lorem ipsum"
;
   
   
setKeyWords();
   
texts.clear();
   
texts = wrapText();
   
   
cursor = sf::RectangleShape( sf::Vector2f( 2, characterSize ) );
   
cursor.setFillColor( sf::Color::Red );
   
   
while( window.isOpen() )
   
{
       
       
mousePosition = sf::Mouse::getPosition( window ); // get the mouse position about window
       
worldMousePosition = window.mapPixelToCoords( mousePosition ); // get global mouse position
       
       
std::pair < sf::Text *, int > t = getCursorPosition();
       
if( t.first != nullptr && t.second != - 1 )
           
 cursor.setPosition( t.first->findCharacterPos( t.second ) );
       
       
sf::Event event;
       
while( window.pollEvent( event ) ) {
           
if( event.type == sf::Event::Closed ) {
               
window.close();
           
}
           
           
        }
       
       
window.clear( sf::Color( 48, 48, 48, 255 ) );
       
for( auto & text: texts )
           
 window.draw( * text );
       
       
window.draw( cursor );
       
window.display();
   
}
}
P-182359
pekfos
» 2025-05-18 23:12:48
Nie za bardzo wiem jak sprawdzać słowa klucze.
A jaki tu w ogóle jest cel? Słowa kluczowe i co dalej? Bo jak to ma być więcej niż kolorowanie wybranych słów, to najlepszym sposobem jest po prostu napisanie analizatora leksykalnego dla tego języka, znając jego gramatykę. Bez znajomości gramatyki, nie można nawet dobrze odpowiedzieć na bieżące pytanie, bo nie wiadomo czym jest "słowo kluczowe".
P-182360
tBane
Temat założony przez niniejszego użytkownika
» 2025-05-18 23:24:21
Chodziło mi o coś takiego, by pomiędzy "słowami kluczami" był kolor czerwony a poza szary ... Lepiej chyba wyjaśni to ta grafika. Chciałbym w ten sposób kolorować skrypty :-)

P-182361
pekfos
» 2025-05-18 23:31:34
No tego bym się nie spodziewał. Dalej nie odpowiada to na żadne pytanie. No chyba że to jest XML.
P-182362
tBane
Temat założony przez niniejszego użytkownika
» 2025-05-18 23:33:30
No właśnie chcę zrobić coś podobnego do formatowania tekstu jak w XML - kolorowanie dla parsera

a słowa klucze to, by były np.

character
monster
position
item
quest
dialog
P-182363
pekfos
» 2025-05-18 23:53:58
No właśnie chcę zrobić coś podobnego do formatowania tekstu jak w XML
XML nie ma nic wspólnego z formatowaniem tekstu.

Chciałbym w ten sposób kolorować skrypty :-)
To użyj kodu który masz do parsowania by wykrywać słowa kluczowe i je kolorować. Oczywiście na tekście przed podziałem na linie.
P-182364
tBane
Temat założony przez niniejszego użytkownika
» 2025-05-19 00:16:39
Nie mam jeszcze parsera. Ale mniejsza na razie wróćmy na początek i rozwiążmy problem tabulatorów. Tabulatory są przesunięte o słowo. Ma ktoś pomysł dlaczego wrapText nie działa? :-/ ChatGPT nie pomoze bo nie ma źródeł :-/


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

sf::Font font;
short characterSize;

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

sf::Vector2i mousePosition;
sf::Vector2f worldMousePosition;
sf::RectangleShape cursor;

std::vector < sf::Text * > wrapText() {
   
std::vector < sf::Text * > t;
   
std::wstring line = L"";
   
std::wstring word = L"";
   
wchar_t wchar;
   
wchar_t white_char = ' ';
   
   
for( auto & wchar: text ) {
       
std::cout << static_cast < unsigned char >( wchar );
       
       
if( wchar == '\n' ) {
           
// TO-DO lub linia jest za dłuha
           
line = line + white_char + word;
           
sf::Text * new_text = new sf::Text( line, font, characterSize );
           
new_text->setFillColor( sf::Color::White );
           
if( t.size() > 0 )
               
 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"";
       
}
       
else if( wchar == ' ' || wchar == '\t' ) {
           
white_char = wchar;
           
line = line + wchar + word;
           
word = L"";
       
}
       
else {
           
word = word + wchar;
       
}
       
    }
   
   
line = line + white_char + word;
   
sf::Text * new_text = new sf::Text( line, font, characterSize );
   
new_text->setFillColor( sf::Color::White );
   
if( t.size() > 0 )
       
 new_text->setPosition( 0, t.back()->getPosition().y + font.getLineSpacing( characterSize ) );
   
else
       
 new_text->setPosition( 0, 0 );
   
   
t.push_back( new_text );
   
   
   
return t;
}

std::pair < sf::Text *, int > getCursorPosition() {
   
   
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 { text, i };
               
else
                return
{ text, i + 1 };
               
           
}
        }
    }
   
   
return { nullptr, - 1 };
}

int main()
{
   
sf::RenderWindow window( sf::VideoMode( { 640, 640 } ), "Easy Notepad!", sf::Style::Default );
   
   
font.loadFromFile( "arial.ttf" );
   
characterSize = 17;
   
text = L"<character> to jest Character</character>, lorem ipsum,\n"
    L"lorem ipsum,lorem ipsum,lorem ipsum,\n"
    L"zażółć gęślą jaźń ći,\n"
    L"lorem ipsum\tlorem ipsum\tlorem ipsum"
;
   
   
texts.clear();
   
texts = wrapText();
   
   
cursor = sf::RectangleShape( sf::Vector2f( 2, characterSize ) );
   
cursor.setFillColor( sf::Color::Red );
   
   
while( window.isOpen() )
   
{
       
       
mousePosition = sf::Mouse::getPosition( window ); // get the mouse position about window
       
worldMousePosition = window.mapPixelToCoords( mousePosition ); // get global mouse position
       
       
std::pair < sf::Text *, int > t = getCursorPosition();
       
if( t.first != nullptr && t.second != - 1 )
           
 cursor.setPosition( t.first->findCharacterPos( t.second ) );
       
       
sf::Event event;
       
while( window.pollEvent( event ) ) {
           
if( event.type == sf::Event::Closed ) {
               
window.close();
           
}
           
           
        }
       
       
window.clear( sf::Color( 48, 48, 48, 255 ) );
       
for( auto & text: texts )
           
 window.draw( * text );
       
       
window.draw( cursor );
       
window.display();
   
}
}
P-182365
1 « 2 » 3 4 5 6 7 8 9 10
Poprzednia strona Strona 2 z 10 Następna strona