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

FileDialog - Optymalizacja rekurencyjnie wypisywanych lokacji plików

Ostatnio zmodyfikowano 2026-06-04 12:53
Autor Wiadomość
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)
C/C++
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;
   
//std::wcout << rightScrollbar->getValue() << " : " << pos.y << L"\n";
   
_files[ i ]->setPosition( pos );
}

rysowanie lewego panelu bez optymalizacji ale z przycinaniem obrazu do okienka
C/C++
float LocationRect::getTotalHeight() {
   
float h =( float ) _rect.size.y;
   
   
if( _isOpen ) {
       
for( auto & child: _children ) {
           
h += child->getTotalHeight();
       
}
    }
   
return h;
}

void FileDialog::drawLeftPanel() {
   
// ograniczenie widoku do rozmiaru recta
   
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 )
    )
;
   
   
// ustawienie widoku
   
view.setViewport( vp );
   
window->setView( view );
   
   
/*
 sf::RectangleShape leftRect(sf::Vector2f(_leftRect.size));
 leftRect.setPosition(sf::Vector2f(_leftRect.position));
 leftRect.setFillColor(sf::Color(255, 47, 47, 127));
 window->draw(leftRect);
 */
   
    // pozycjonowanie itemów folderów
   
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();
   
}
   
   
// desktop/documents/pictures etc.
   
for( auto & fav: _locations )
       
 fav->draw();
   
   
}
P-184163
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?
P-184164
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
P-184165
DejaVu
» 2026-06-03 17:00:40
to renderuj tylko to co widoczne - chyba wiesz które elementy na liście są widoczne?
P-184166
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
P-184167
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 :-)

C/C++
void FileDialog::buildVisibleLocations() {
   
   
_visibleLocations.clear();
   
   
for( auto & location: _locations ) {
       
addVisibleLocation( location );
   
}
   
   
updateLeftScrollbar();
}

C/C++
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 );
       
}
    }
}

C/C++
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 );
   
   
// dictionaries
   
_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" ) );
   
   
// load the harddrivers
   
DWORD drives = GetLogicalDrives();
   
for( int i = 0; i < 32; i++ )
   
if(( drives >> i ) & 1 ) {
       
//printf("%c:\\\n", 'A' + i);
       
_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 );
       
};
       
       
// KLIK W NAZWĘ -> otwórz po PRAWEJ
       
_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 );
       
};
       
       
// KLIK W STRZAŁKĘ -> tylko rozwiń/zwiń po LEWEJ
       
_locations[ i ]->_onclick_arrow_func =[ this, i ]() {
           
auto & node = _locations[ i ];
           
if( !node->_hasChildren ) return;
           
           
if( node->_isOpen ) {
               
node->close();
           
}
           
else {
               
// UWAGA: przekazujemy onPick, żeby POTOMKOWIE mieli poprawny "open po prawej"
               
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 );
           
       
};
   
}
   
   
// scrollbar
   
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();
}

C/C++
void FileDialog::update() {
   
Dialog::update();
   
   
for( auto & file: _files )
       
 file->update();
   
   
auto visibleLocations = _visibleLocations;
   
   
for( auto & location: visibleLocations ) {
       
location->update();
   
}
   
// ...
   
P-184168
« 1 »
  Strona 1 z 1