tBane Temat założony przez niniejszego użytkownika |
FileDialog - Optymalizacja rekurencyjnie wypisywanych lokacji plików » 2026-06-03 12:22:57 Cześć. Napisałem sobie File Dialog. tj okienko do listowania plików w katalogu. Lista dla plików jest optymalizowana w ten sposób, że wyświetlanych jest elementów wysokość_panelu/wysokość_itemu + 1. Dzięki temu wyświetlam stałą liczbę itemów dla plików i folderów. Chciałbym teraz optymalizować w podobny sposób lokacje po lewej stronie. Problematyczne jest to, że nie wiem jak to zrobić z rekurencyjnym przetwarzaniem katalogów (bo niektóre mogą być otwarte stąd ta rekurencja). Ma ktoś pomysł jak to optymalizować? :-) optymalizacja listowania plików i katalogów w prawym oknie (% basic_text_rect_height) for( int i = 0; i < _files.size(); i++ ) { std::filesystem::path path = _filesPaths[ i + scrollbarValue / basic_text_rect_height ]; _files[ i ]->setFile( path ); sf::Vector2i pos; pos.x = _rightRect->position.x; pos.y = _rightRect->position.y +( i * basic_text_rect_height ) - _rightScrollbar->getValue() % basic_text_rect_height; _files[ i ]->setPosition( pos ); }
rysowanie lewego panelu bez optymalizacji ale z przycinaniem obrazu do okienkafloat LocationRect::getTotalHeight() { float h =( float ) _rect.size.y; if( _isOpen ) { for( auto & child: _children ) { h += child->getTotalHeight(); } } return h; }
void FileDialog::drawLeftPanel() { sf::View view( sf::FloatRect( sf::Vector2f(( float ) _leftRect->position.x,( float ) _leftRect->position.y ), sf::Vector2f(( float ) _leftRect->size.x,( float ) _leftRect->size.y ) ) ); sf::FloatRect vp( sf::Vector2f(( float ) _leftRect->position.x / mainView.getSize().x,( float ) _leftRect->position.y / mainView.getSize().y ), sf::Vector2f(( float ) _leftRect->size.x / mainView.getSize().x,( float ) _leftRect->size.y / mainView.getSize().y ) ); view.setViewport( vp ); window->setView( view ); sf::Vector2i pos; pos.x = getContentPosition().x + dialog_padding; pos.y = getContentPosition().y - _leftScrollbar->getValue(); for( int i = 0; i < _locations.size(); i++ ) { _locations[ i ]->setPosition( pos ); pos.y +=( int ) _locations[ i ]->getTotalHeight(); } for( auto & fav: _locations ) fav->draw(); }
|
|
DejaVu |
» 2026-06-03 15:49:17 Ja nie zrozumiałem o co chodzi nawet - po lewej masz drzewko (które twierdzisz, że jest ogarniete), a po prawej lista (która nie ma zagnieżdżeń bo i dlaczego miałaby mieć). Gdzie jest problem i co chcesz optymalizować? :) Coś za wolno działa czy... co? |
|
tBane Temat założony przez niniejszego użytkownika |
» 2026-06-03 16:14:03 Nie drzewko po lewej stronie nie jest ogarnięte. Chodzi mi o to, że gdy odpalam folder z windosem to zawiesza (w dół 500 FPS ponad), bo jest dużo podkatalogów do wyświetlenia. próbuję zoptymalizować proces renderowania katalogów w tym lewym panelu :D |
|
DejaVu |
» 2026-06-03 17:00:40 to renderuj tylko to co widoczne - chyba wiesz które elementy na liście są widoczne? |
|
tBane Temat założony przez niniejszego użytkownika |
» 2026-06-03 17:07:03 Można by sprawdzać dla wszystkich lokacji po kolei intersection z panelem, ale to nie wydaje się optymalnym rozwiązaniem, bo trzeba przejrzeć je wszystkie...
Potrzebowałbym index pierwszego widocznego katalogu i jakoś wyznaczyć końcowy chyba i potem renderować z tymi parametrami |
|
tBane Temat założony przez niniejszego użytkownika |
» 2026-06-04 12:53:57 No mniej więcej tak to trzeba zrobić. :-) trzymaj, może kiedyś się to Tobie przyda :-) void FileDialog::buildVisibleLocations() { _visibleLocations.clear(); for( auto & location: _locations ) { addVisibleLocation( location ); } updateLeftScrollbar(); }
void FileDialog::addVisibleLocation( std::shared_ptr < LocationRect > location ) { if( !location ) return; _visibleLocations.push_back( location ); if( location->_isOpen ) { for( auto & child: location->_children ) { addVisibleLocation( child ); } } }
void FileDialog::createLeftPanel( int dictionariesCount ) { sf::Vector2i rectSize = sf::Vector2i( 100, dictionariesCount * basic_text_rect_height ); _leftRect = std::make_shared < sf::IntRect >( sf::Vector2i( 0, 0 ), rectSize ); const wchar_t * userProfile = _wgetenv( L"USERPROFILE" ); std::wstring up( userProfile ); _locations.push_back( std::make_shared < LocationRect >( up + L"\\AppData\\Roaming\\Microsoft\\Windows\\Recent" ) ); _locations.push_back( std::make_shared < LocationRect >( up + L"\\Documents" ) ); _locations.push_back( std::make_shared < LocationRect >( up + L"\\Music" ) ); _locations.push_back( std::make_shared < LocationRect >( up + L"\\Pictures" ) ); _locations.push_back( std::make_shared < LocationRect >( up + L"\\Downloads" ) ); _locations.push_back( std::make_shared < LocationRect >( up + L"\\Desktop" ) ); _locations.push_back( std::make_shared < LocationRect >( up + L"\\Videos" ) ); DWORD drives = GetLogicalDrives(); for( int i = 0; i < 32; i++ ) if(( drives >> i ) & 1 ) { _locations.push_back( std::make_shared < LocationRect >( std::wstring( 1, L'A' + i ) + L":\\" ) ); } for( int i = 0; i < _locations.size(); i++ ) { _locations[ i ]->setSize( sf::Vector2i( _leftRect->size.x, basic_text_rect_height ) ); _locations[ i ]->_onTreeChanged =[ this ]() { buildVisibleLocations(); setPosition( _position ); }; _locations[ i ]->_onclick_location_func =[ this, i ]() { currentPath = _locations[ i ]->_path.wstring(); loadDirectory(); _rightScrollbar->setMax(( int )( _filesPaths.size() - _files.size() + 1 ) * basic_text_rect_height ); _rightScrollbar->setValue( 0 ); setTheFiles(); setPosition( _position ); }; _locations[ i ]->_onclick_arrow_func =[ this, i ]() { auto & node = _locations[ i ]; if( !node->_hasChildren ) return; if( node->_isOpen ) { node->close(); } else { node->open([ this ]( const std::wstring & newPath ) { currentPath = newPath; loadDirectory(); _rightScrollbar->setMax(( int )( _filesPaths.size() - _files.size() + 1 ) * basic_text_rect_height ); _rightScrollbar->setValue( 0 ); setTheFiles(); setPosition( _position ); } ); } buildVisibleLocations(); setPosition( _position ); }; } sf::Vector2i scrollbarPos; scrollbarPos.x = _leftRect->position.x + _leftRect->size.x + dialog_padding; scrollbarPos.y = getContentPosition().y; sf::Vector2i scrollbarSize = sf::Vector2i( 16, _leftRect->size.y ); int scrollbarMax = 0; int scrollbarSliderSize =( dictionariesCount - 1 ) * basic_text_rect_height; _leftScrollbar = std::make_shared < Scrollbar >( scrollbarPos.x, scrollbarPos.y, scrollbarSize.x, scrollbarSize.y, 0, scrollbarMax, scrollbarSliderSize, 0 ); _leftScrollbar->_func =[ this ]() { setTheFiles(); setPosition( _position ); }; _leftScrollbar->setScrollArea( _leftRect, basic_text_rect_height * 0.5f ); buildVisibleLocations(); }
void FileDialog::update() { Dialog::update(); for( auto & file: _files ) file->update(); auto visibleLocations = _visibleLocations; for( auto & location: visibleLocations ) { location->update(); } |
|
| « 1 » |