diff --git a/Applications/FileManager/DirectoryModel.cpp b/Applications/FileManager/DirectoryModel.cpp index 0b3bd1d50a..b2996abb59 100644 --- a/Applications/FileManager/DirectoryModel.cpp +++ b/Applications/FileManager/DirectoryModel.cpp @@ -9,8 +9,36 @@ #include #include +static HashMap>& thumbnail_cache() +{ + static HashMap>* s_map; + if (!s_map) + s_map = new HashMap>(); + return *s_map; +} + +int thumbnail_thread(void* model) +{ + for (;;) { + sleep(1); + for (auto& it : thumbnail_cache()) { + if (it.value) + continue; + if (auto png_bitmap = GraphicsBitmap::load_from_file(it.key)) { + auto thumbnail = GraphicsBitmap::create(png_bitmap->format(), { 32, 32 }); + Painter painter(*thumbnail); + painter.draw_scaled_bitmap(thumbnail->rect(), *png_bitmap, png_bitmap->rect()); + it.value = move(thumbnail); + ((DirectoryModel*)model)->did_update(); + } + } + } +} + DirectoryModel::DirectoryModel() { + create_thread(thumbnail_thread, this); + m_directory_icon = GraphicsBitmap::load_from_file("/res/icons/folder16.png"); m_file_icon = GraphicsBitmap::load_from_file("/res/icons/file16.png"); m_symlink_icon = GraphicsBitmap::load_from_file("/res/icons/link16.png"); @@ -83,10 +111,12 @@ const GraphicsBitmap& DirectoryModel::icon_for(const Entry& entry) const return *m_executable_icon; if (entry.name.ends_with(".png")) { if (!entry.thumbnail) { - if (auto png_bitmap = GraphicsBitmap::load_from_file(entry.full_path(*this))) { - entry.thumbnail = GraphicsBitmap::create(png_bitmap->format(), { 32, 32 }); - Painter painter(*entry.thumbnail); - painter.draw_scaled_bitmap(entry.thumbnail->rect(), *png_bitmap, png_bitmap->rect()); + auto path = entry.full_path(*this); + auto it = thumbnail_cache().find(path); + if (it != thumbnail_cache().end()) { + entry.thumbnail = (*it).value.copy_ref(); + } else { + thumbnail_cache().set(path, nullptr); } } if (!entry.thumbnail) diff --git a/Applications/FileManager/DirectoryModel.h b/Applications/FileManager/DirectoryModel.h index 6e743596e5..f78b0bfb14 100644 --- a/Applications/FileManager/DirectoryModel.h +++ b/Applications/FileManager/DirectoryModel.h @@ -5,6 +5,7 @@ #include class DirectoryModel final : public GModel { + friend int thumbnail_thread(void*); public: static Retained create() { return adopt(*new DirectoryModel); } virtual ~DirectoryModel() override;