tBane Temat założony przez niniejszego użytkownika |
» 2024-10-03 18:57:26 Nadal mam problem ze scrollbarem. Gdzieś mam błąd w obliczaniu jego pozycji, bo wychodzi poza zakres. Wie ktoś jak to naprawić ? float scrollValue = 4.0f; float minValue = 0.0f; float maxValue = 8.0f; float scrollLength = 4.0f; scrollPosition.y = position.y +( scrollValue - minValue ) /( maxValue - minValue ) *( size.y - scrollLength / 2.0f * size.x );
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-10-03 19:23:27 Nieopanowane, scroll nie porusza się równo z kursorem, ale już mi się nie chce poprawiać. W miarę jako tako działa - kiedyś to naprawię :D Wrzucam kod jakby ktoś kiedyś potrzebował.. Użycie Open Dialog Boxavoid testOpenDialogBox() { cam = new Camera(); OpenDialogBox * openDial = new OpenDialogBox(); while( window->isOpen() ) { prevTime = currentTime; currentTime = timeClock.getElapsedTime(); dt = currentTime.asSeconds() - prevTime.asSeconds(); mousePosition = sf::Mouse::getPosition( * window ); worldMousePosition = window->mapPixelToCoords( mousePosition ); GUIwasHover = false; GUIwasClicked = false; sf::Event event; while( window->pollEvent( event ) ) { if( openDial ) { openDial->update( event, dt ); if( openDial->fileSelected ) { cout << openDial->getFilename() << "\n"; delete openDial; openDial = nullptr; } } } window->clear(); if( openDial ) openDial->draw(); window->display(); } }
Kod Open Dialog Boxa#ifndef OpenDialogBox_hpp #define OpenDialogBox_hpp
bool sortkey( std::filesystem::directory_entry first, std::filesystem::directory_entry second ) { if( first.path().extension() != second.path().extension() ) { if( first.path().extension() < second.path().extension() ) return true; else return false; } else { if( first.path().filename() < second.path().filename() ) return true; else return false; } }
class OpenDialogBox { public: sf::Vector2f position = sf::Vector2f( 300, 300 ); sf::RectangleShape rect; sf::RectangleShape titlebar; TextArea * title; sf::RectangleShape submitbar; TextArea * filename; TextArea * selectedFilename; TextButton * submitButton; std::filesystem::path current_path; std::vector < std::filesystem::directory_entry > paths; sf::RectangleShape textField[ 7 ]; TextArea * texts[ 7 ]; sf::Sprite icons[ 7 ]; Scrollbar * scrollbar; bool fileSelected; OpenDialogBox() { rect = sf::RectangleShape( sf::Vector2f( 512, 256 + 32 ) ); rect.setFillColor( sf::Color( 64, 64, 64 ) ); rect.setPosition( position.x - 256, position.y - 128 - 32 ); titlebar = sf::RectangleShape( sf::Vector2f( 512, 32 ) ); titlebar.setFillColor( sf::Color( 48, 48, 48 ) ); titlebar.setPosition( position.x - 256, position.y - 128 - 32 ); title = new TextArea( "Dialog box" ); title->setCharacterSize( 24 ); title->setPosition( sf::Vector2f( position.x - 256 + 8, position.y - 128 - 32 ) ); title->setRectColor( sf::Color::Transparent ); title->setTextColor( textColor ); clearTexts(); current_path = std::filesystem::current_path(); loadDirectory(); loadScrollbar(); sf::Vector2f pos; filename = new TextArea( "File name: " ); filename->setCharacterSize( 24 ); filename->generateRect(); filename->setRectColor( sf::Color::Transparent ); filename->setTextColor( textColor ); pos.x = position.x - 256; pos.y = position.y + 256 - 128 - filename->getSize().y; filename->setPosition( pos ); submitButton = new TextButton( "submit" ); pos.x = position.x + 256 - submitButton->rect.getSize().x / 2; pos.y = position.y + 256 - 128 - 16; submitButton->setPosition( pos ); selectedFilename = new TextArea( "" ); selectedFilename->setCharacterSize( 22 ); selectedFilename->setRectColor( sf::Color( 32, 32, 32 ) ); selectedFilename->setTextColor( textColor ); selectedFilename->setRectSize( sf::Vector2f( 256 + 48, submitButton->rect.getSize().y ) ); pos.x = position.x - 256 + filename->getSize().x; pos.y = position.y + 256 - 128 - selectedFilename->rect.getSize().y - 1; selectedFilename->setPosition( pos ); submitbar = sf::RectangleShape( sf::Vector2f( 512, submitButton->rect.getSize().y ) ); submitbar.setFillColor( sf::Color( 48, 48, 48 ) ); submitbar.setPosition( position.x - 256, position.y + 256 - 128 - 32 ); fileSelected = false; } ~OpenDialogBox() { delete title; delete filename; delete selectedFilename; delete submitButton; for( auto & t: texts ) delete t; delete scrollbar; } void clearTexts() { for( int i = 0; i < 7; i++ ) { textField[ i ] = sf::RectangleShape( sf::Vector2f( 512, 32 ) ); textField[ i ].setFillColor( sf::Color::Transparent ); textField[ i ].setPosition( position.x - 256, position.y - 128 + i * 32 ); texts[ i ] = new TextArea( "" ); texts[ i ]->setCharacterSize( 20 ); texts[ i ]->setRectColor( sf::Color::Transparent ); texts[ i ]->setTextColor( textColor ); texts[ i ]->setPosition( sf::Vector2f( position.x - 256 + 32 + 4, position.y - 128 + i * 32 + 4 ) ); icons[ i ] = sf::Sprite(); } } void loadScrollbar() { sf::Vector2f scrollbarSize = sf::Vector2f( 16, 256 - 32 ); sf::Vector2f scrollbarPosition = sf::Vector2f( position.x + 256 - scrollbarSize.x, position.y - 128 ); scrollbar = new Scrollbar( scrollbarSize, scrollbarPosition, 0, paths.size() - 1, 0, 7 ); } void loadDirectory() { paths.clear(); if( filesystem::exists( current_path ) && filesystem::is_directory( current_path ) ) { paths.emplace_back( current_path.parent_path() ); for( auto & entry: filesystem::directory_iterator( current_path ) ) { paths.push_back( entry ); } } std::sort( paths.begin(), paths.end(), sortkey ); } std::string getFilename() { return selectedFilename->text.getString(); } void update( sf::Event & event, float dt ) { scrollbar->update( event ); if( event.type == sf::Event::MouseButtonReleased ) { if( event.mouseButton.button == sf::Mouse::Left ) { submitButton->click(); for( short i = 0; i < 7; i++ ) { if( texts[ i ]->rect.getGlobalBounds().contains( worldMousePosition ) ) { if( i < paths.size() ) { selectedFilename->setString( texts[ i ]->s ); if( selectedFilename->s == texts[ i ]->s ) { if( paths[ i + short( scrollbar->scrollValue ) ].path().extension().string() == "" ) { current_path = std::filesystem::path( paths[ i + short( scrollbar->scrollValue ) ].path().string() ); clearTexts(); loadDirectory(); loadScrollbar(); } } } } } if( submitButton->state == buttonState::pressed ) { fileSelected = true; } } } for( short i = 0; i < 7; i++ ) { if( i + short( scrollbar->scrollValue ) < paths.size() ) { if( i + short( scrollbar->scrollValue ) == 0 ) { texts[ i ]->setString( ".." ); } else { texts[ i ]->setString( paths[ i + short( scrollbar->scrollValue ) ].path().filename().string() ); } texts[ i ]->generateRect(); icons[ i ] = sf::Sprite(); string extension = paths[ i + short( scrollbar->scrollValue ) ].path().extension().string(); if( extension == "" ) icons[ i ].setTexture( * getTexture( "GUI/icons/dictionary" )->texture ); else icons[ i ].setTexture( * getTexture( "GUI/icons/file" )->texture ); icons[ i ].setPosition( position.x - 256, position.y - 128 + i * 32 ); } } submitButton->update( dt ); } void draw() { window->draw( rect ); window->draw( titlebar ); title->draw(); window->draw( submitbar ); filename->draw(); selectedFilename->draw(); submitButton->draw(); scrollbar->draw(); for( short i = 0; i < 7; i++ ) { window->draw( textField[ i ] ); texts[ i ]->draw(); window->draw( icons[ i ] ); } } };
#endif
Kod Scrollbara#ifndef Scrollbar_hpp #define Scrollbar_hpp
class Scrollbar { public: sf::Vector2f size; sf::Vector2f position; float minValue; float maxValue; float scrollValue; float scrollLength; sf::RectangleShape bar; sf::Sprite barTop; sf::Sprite barBottom; sf::Sprite barCenter; sf::RectangleShape scroll; sf::Sprite scrollTop; sf::Sprite scrollBottom; sf::Sprite scrollCenter; bool pressed; sf::Vector2f mouseStartPos; sf::Vector2f mouseOffset; Scrollbar( sf::Vector2f size, sf::Vector2f position, float minValue, float maxValue, float scrollValue, float scrollLength ) { this->size = size; this->position = position; this->minValue = minValue; this->maxValue = maxValue; this->scrollValue = scrollValue; this->scrollLength = scrollLength; bar = sf::RectangleShape( size ); bar.setFillColor( sf::Color::Blue ); scroll = sf::RectangleShape( sf::Vector2f( size.x, getScrollHeight() ) ); scroll.setOrigin( 0, 0 ); scroll.setFillColor( sf::Color::Red ); pressed = false; scrollTop = sf::Sprite(); scrollTop.setTexture( * getTexture( "GUI/scrollbar/scroll_top" )->texture ); scrollBottom = sf::Sprite(); scrollBottom.setTexture( * getTexture( "GUI/scrollbar/scroll_bottom" )->texture ); scrollCenter = sf::Sprite(); scrollCenter.setTexture( * getTexture( "GUI/scrollbar/scroll_center" )->texture ); barTop = sf::Sprite(); barTop.setTexture( * getTexture( "GUI/scrollbar/bar_top" )->texture ); barBottom = sf::Sprite(); barBottom.setTexture( * getTexture( "GUI/scrollbar/bar_bottom" )->texture ); barCenter = sf::Sprite(); barCenter.setTexture( * getTexture( "GUI/scrollbar/bar_center" )->texture ); } ~Scrollbar() { } void setValue( int value ) { scrollValue = value; if( scrollValue > maxValue - scrollLength + 1 ) scrollValue = maxValue - scrollLength + 1; if( scrollValue < minValue ) scrollValue = minValue; } float getScrollHeight() { if( maxValue - minValue + 1 >= scrollLength ) { float height = scrollLength / maxValue * size.y; if( height < size.x * 3 ) height = size.x * 3; return height; } else return size.y; } void update( sf::Event & event ) { bar.setPosition( position ); barTop.setPosition( position.x, position.y ); barTop.setScale( bar.getSize().x / 16.0f, bar.getSize().x / 16.0f ); barCenter.setPosition( position.x, position.y + scroll.getSize().x ); barCenter.setScale( bar.getSize().x / 16.0f,( bar.getSize().y - 2.0f * bar.getSize().x ) / 16.0f ); barBottom.setPosition( position.x, position.y + bar.getSize().y - bar.getSize().x ); barBottom.setScale( bar.getSize().x / 16.0f, bar.getSize().x / 16.0f ); sf::Vector2f scrollPosition; scrollPosition.x = position.x; scrollPosition.y = position.y +( scrollValue - minValue ) /( maxValue - scrollLength + 1 ) *( size.y - getScrollHeight() ); if( event.type == sf::Event::MouseButtonPressed ) { if( event.mouseButton.button == sf::Mouse::Left ) { sf::Vector2f mousePos = window->mapPixelToCoords( sf::Vector2i( event.mouseButton.x, event.mouseButton.y ) ); if( scroll.getGlobalBounds().contains( worldMousePosition ) ) { pressed = true; mouseStartPos = mousePos; mouseOffset = scrollPosition - mousePos; } } } if( event.type == sf::Event::MouseButtonReleased ) { if( event.mouseButton.button == sf::Mouse::Left ) { pressed = false; } } if( event.type == sf::Event::MouseMoved ) { if( pressed ) { sf::Vector2f mousePos = window->mapPixelToCoords( sf::Vector2i( event.mouseMove.x, event.mouseMove.y ) ); if( fabs( mousePos.x - mouseStartPos.x ) > 100 ) mousePos = mouseStartPos; float value =( mousePos.y + mouseOffset.y - position.y ) /( size.y - getScrollHeight() ) *( maxValue - minValue ) + minValue; setValue( value ); } } scroll.setPosition( scrollPosition ); scrollTop.setPosition( scrollPosition.x, scrollPosition.y ); scrollTop.setScale( scroll.getSize().x / 16.0f, scroll.getSize().x / 16.0f ); scrollCenter.setPosition( scrollPosition.x, scrollPosition.y + scroll.getSize().x ); scrollCenter.setScale( scroll.getSize().x / 16.0f,( getScrollHeight() - 2.0f * scroll.getSize().x ) / 16.0f ); scrollBottom.setPosition( scrollPosition.x, scrollPosition.y + getScrollHeight() - scroll.getSize().x ); scrollBottom.setScale( scroll.getSize().x / 16.0f, scroll.getSize().x / 16.0f ); } void draw() { window->draw( bar ); window->draw( barTop ); window->draw( barBottom ); window->draw( barCenter ); window->draw( scroll ); window->draw( scrollTop ); window->draw( scrollCenter ); window->draw( scrollBottom ); } };
#endif
Kod Text Area#ifndef TextArea_hpp #define TextArea_hpp
class TextArea { public: string s; sf::Vector2f position; sf::Text text; sf::RectangleShape rect; TextArea( string s ) { this->s = s; text = sf::Text(); text.setFont( basicFont ); text.setCharacterSize( 16 ); text.setString( s ); sf::Vector2f textPos; textPos.x = position.x + float( text.getCharacterSize() ) * 0.2f; textPos.y = position.y; text.setPosition( textPos ); generateRect(); } ~TextArea() { } void generateRect() { sf::Vector2f size; size.x = float( text.getLocalBounds().getSize().x ) + float( text.getCharacterSize() ) * 0.5f; size.y = float( text.getCharacterSize() ) * 1.3f; rect.setSize( size ); } void setRectSize( sf::Vector2f size ) { rect.setSize( size ); } void setString( string s ) { this->s = s; text.setString( s ); } void setPosition( sf::Vector2f position ) { this->position = position; rect.setPosition( position ); sf::Vector2f textPos; textPos.x = position.x + float( text.getCharacterSize() ) * 0.15f; textPos.y = position.y; text.setPosition( textPos ); } void setCharacterSize( short val ) { text.setCharacterSize( val ); } void setRectColor( sf::Color color ) { rect.setFillColor( color ); } void setTextColor( sf::Color color ) { text.setFillColor( color ); } sf::Vector2f getSize() { return rect.getSize(); } void update( float dt ) { } void draw() { window->draw( rect ); window->draw( text ); } };
#endif
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-10-16 11:44:26 Ponawiam temat gdyż potrzebuję dalszej pomocy. Jest kilka błędów które nie mogę namierzyć. -wpisywanie w pasku nazwy pliku nazwy zaznaczonego folderu void update( sf::Event & event, float dt ) { scrollbar->update( event ); if( event.type == sf::Event::MouseButtonReleased ) { if( event.mouseButton.button == sf::Mouse::Left ) { submitButton->click(); for( short i = 0; i < 7; i++ ) { if( texts[ i ]->rect.getGlobalBounds().contains( worldMousePosition ) ) { if( i < paths.size() ) { selectedFilename->setString( texts[ i ]->s ); if( selectedFilename->s == texts[ i ]->s ) { if( paths[ i + short( scrollbar->scrollValue ) ].path().extension().string() == "" ) { current_path = std::filesystem::path( paths[ i + short( scrollbar->scrollValue ) ].path().string() ); clearTexts(); loadDirectory(); loadScrollbar(); } } } } } if( submitButton->state == buttonState::pressed ) { fileSelected = true; } } } }
-niedziałający powrót do poprzedniego folderu void loadDirectory() { paths.clear(); if( filesystem::exists( current_path ) && filesystem::is_directory( current_path ) ) { paths.emplace_back( current_path.parent_path() ); for( auto & entry: filesystem::directory_iterator( current_path ) ) { paths.push_back( entry ); } } std::sort( paths.begin(), paths.end(), sortkey ); }
|
|
pekfos |
» 2024-10-16 13:30:25 Przydałyby się jakieś objawy, albo kod do uruchomienia. Jeżeli selectedFilename jest tym co trafia do paska zaznaczonego pliku, to robisz to bezwarunkowo niezależnie czy jest to katalog czy nie. if( paths[ i + short( scrollbar->scrollValue ) ].path().extension().string() == "" ) Czy to ma być test na katalog? Powinieneś użyć is_directory, plik nie musi mieć rozszerzenia, a katalog może je mieć. selectedFilename->setString( texts[ i ]->s );
if( selectedFilename->s == texts[ i ]->s ) { To wygląda jak zawsze prawdziwy warunek bo sprawdzasz czy jest ustawiony tekst który przed chwilą wpisałeś. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-10-16 13:51:38 Przydałyby się jakieś objawy, albo kod do uruchomienia. Tu link do całego projektu. https://github.com/tBane1995/Open-Dialog-Boxzrobiłem coś takiego: if( i < paths.size() ) { if( !paths[ i + short( scrollbar->scrollValue ) ].is_directory() ) selectedFilename->setString( texts[ i ]->s ); if( paths[ i + short( scrollbar->scrollValue ) ].is_directory() ) { current_path = std::filesystem::path( paths[ i + short( scrollbar->scrollValue ) ].path().string() ); clearTexts(); loadDirectory(); loadScrollbar(); } }
Pozostał jeszcze jeden błąd i nie wiem jak go zlokalizować. Dziwne lokacje się pojawiają w DialogBoxie i nawigacja leży. |
|
pekfos |
» 2024-10-16 13:53:25 I... działa? Nie działa? Kod wygląda jakby chciał mieć tam else. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-10-16 13:57:44 Ok. Poprawione. Ale nadal jest problem z nawigacją. Dodałem jeszcze "zerowanie" nazwy pliku gdy wybierzemy folder. if( i + short( scrollbar->scrollValue ) < paths.size() ) { if( !paths[ i + short( scrollbar->scrollValue ) ].is_directory() ) selectedFilename->setString( texts[ i ]->s ); else { current_path = std::filesystem::path( paths[ i + short( scrollbar->scrollValue ) ].path().string() ); selectedFilename->setString( "" ); clearTexts(); loadDirectory(); loadScrollbar(); } }
|
|
pekfos |
» 2024-10-16 14:13:41 Musisz być nieco bardziej pomocny w opisywaniu objawów (lub kroków do zreprodukowania problemu). Klikając po tym gui zauważyłem taki problem, że niekoniecznie ".." jest katalogiem nadrzędnym. Ten wpis ustawiasz zawsze jako pierwszy if( i + short( scrollbar->scrollValue ) < paths.size() ) { if( i + short( scrollbar->scrollValue ) == 0 ) { texts[ i ]->setString( ".." ); } ale to wymaga by katalog nadrzędny faktycznie był pierwszy po sortowaniu, w przeciwnym razie pojawi się jako podrzędny katalog, a inny będzie oznaczony jako "..". Wiesz jaki katalog pokazujesz w dialogu, zawartość najlepiej reprezentuj jako ścieżki względne, a katalog nadrzędny jako dosłowne "..". Wchodząc w katalog, albo uzyskując ścieżkę do wskazanego pliku, sklejasz te 2 człony operatorem /. Wchodząc i wychodząc z katalogu wielokrotnie może się to kumulować jako "a/b/c/../c/../d/../c/.." więc wchodząc do katalogu najlepiej znormalizować ścieżkę ( https://en.cppreference.com/w/cpp/filesystem/path/lexically_normal). Problem szczególnie dobrze widać gdy masz katalog z rozszerzeniem, np "SFML-2.6.1" bo sortowanie faworyzuje brak rozszerzenia. Masz też gdzieś błąd o 1 przez który katalog który ma dokładnie 7 elementów nie ma scrolla, a przez dodanie katalogu nadrzędnego ma 8 wpisów i ostatni z nich jest nieosiągalny. |
|
1 2 3 « 4 » 5 |