From b34bdfea4cfaa938806aa5544c332ececaf23b0b Mon Sep 17 00:00:00 2001 From: Thyphoon Date: Sun, 14 Sep 2025 20:35:17 +0200 Subject: [PATCH] Update README.md --- README.md | 194 +++++++++++++++++++++++------------------------------- 1 file changed, 82 insertions(+), 112 deletions(-) diff --git a/README.md b/README.md index e8a1887..35ce7c9 100644 --- a/README.md +++ b/README.md @@ -1,143 +1,113 @@ -# Visionneuse de Vignettes en PureBasic / Thumbnail Viewer in PureBasic +# PureBasic Advanced Thumbnail Gadget -Ce projet est un composant d'interface utilisateur avancé pour PureBasic qui permet d'afficher des centaines ou des milliers de vignettes d'images de manière fluide et efficace. Il est conçu pour être facilement intégré dans n'importe quelle application nécessitant une galerie d'images performante. +A powerful and flexible thumbnail viewer component for PureBasic, designed for high performance with asynchronous image loading and caching. This gadget is perfect for applications that need to display a large number of images without freezing the user interface, such as image browsers, file managers, or digital asset managers. -*This project is an advanced UI component for PureBasic that allows displaying hundreds or thousands of image thumbnails smoothly and efficiently. It is designed to be easily integrated into any application requiring a high-performance image gallery.* - -## Fonctionnalités / Features ✨ - - * **Chargement Asynchrone :** Les images sont chargées en arrière-plan grâce au multithreading, ce qui évite de figer l'application. - - * ***Asynchronous Loading:*** *Images are loaded in the background using multithreading, which prevents the application from freezing.* - - * **Système de Cache :** Un cache intelligent conserve les images chargées en mémoire pour un réaffichage instantané et gère la libération de la mémoire pour les images qui ne sont plus visibles. - - * ***Caching System:*** *An intelligent cache keeps loaded images in memory for instant redisplay and manages memory release for images that are no longer visible.* - - * **Défilement Fluide :** Le défilement vertical est optimisé pour une expérience utilisateur agréable, même avec de nombreuses vignettes. - - * ***Smooth Scrolling:*** *Vertical scrolling is optimized for a pleasant user experience, even with many thumbnails.* - - * **Modes d'Affichage :** Les images peuvent être ajustées pour s'adapter, remplir ou s'étirer dans l'espace de la vignette (`#Image_Style_Fit`, `#Image_Style_Fill`, `#Image_Style_Stretch`). - - * ***Display Modes:*** *Images can be adjusted to fit, fill, or stretch within the thumbnail area (`#Image_Style_Fit`, `#Image_Style_Fill`, `#Image_Style_Stretch`).* - - * **Dessin Vectoriel :** L'utilisation du sous-système `VectorDrawing` assure un rendu de haute qualité et une bonne compatibilité avec les écrans à haute résolution (HiDPI). - - * ***Vector Drawing:*** *The use of the `VectorDrawing` subsystem ensures high-quality rendering and compatibility with high-resolution (HiDPI) displays.* - - * **Sélection Multiple :** Support de la sélection d'une ou plusieurs vignettes (y compris la sélection de plage avec la touche **Majuscule**). - - * ***Multiple Selection:*** *Supports selecting one or more thumbnails (including range selection with the **Shift** key).* +\! ----- -## Structure du Projet / Project Structure 🏗️ +## Features -Le code est organisé en plusieurs modules logiques pour une meilleure clarté et maintenance. -*The code is organized into several logical modules for better clarity and maintainability.* - - * **`Core`** : Définit les structures de données de base utilisées dans le projet. / *Defines the basic data structures used in the project.* - * **`ImgTools`** : Fournit des fonctions utilitaires pour le redimensionnement et le positionnement des images. / *Provides utility functions for image resizing and positioning.* - * **`Cache`** : Gère toute la logique de chargement en arrière-plan et de mise en cache des images. / *Manages all the background loading and image caching logic.* - * **`Thumbs`** : Contient le gadget principal (`ThumbsGadget`) et gère l'affichage, les événements et les interactions utilisateur. / *Contains the main gadget (`ThumbsGadget`) and handles display, events, and user interactions.* + * [cite\_start]**Asynchronous Loading**: Uses a pool of worker threads to load images in the background, ensuring the UI remains responsive at all times[cite: 11, 126, 175]. + * [cite\_start]**Image Caching**: An intelligent cache manages loaded images, freeing memory by cleaning up unused thumbnails automatically[cite: 82, 232, 233]. + * **Dynamic Customization**: + * Adjust thumbnail **size** in real-time. + * [cite\_start]Switch between **display styles**: `Fit`, `Fill`, and `Stretch` on the fly[cite: 48, 436]. + * [cite\_start]**High-DPI Aware**: The interface is fully scaled for high-resolution displays, ensuring crisp visuals[cite: 296, 597]. + * **Advanced User Interaction**: + * [cite\_start]Smooth, pixel-based scrolling[cite: 290]. + * [cite\_start]Multi-selection with **Shift** for ranges and **Ctrl** for individual toggling[cite: 496, 506]. + * [cite\_start]**Easy Integration**: Built with a simple callback system, allowing you to easily feed it data from any source (local files, network, database, etc.)[cite: 254, 562, 564]. + * **Self-Contained Modules**: The code is organized into logical modules (`Cache`, `Thumbs`, `ImgTools`) for better readability and maintenance. ----- -## Prérequis et Compilation / Prerequisites and Compilation ⚙️ +## Requirements -Pour compiler et utiliser ce projet, vous aurez besoin de : -*To compile and use this project, you will need:* - - * **PureBasic 6.04 LTS (x64)** ou une version plus récente. / *or a more recent version.* - * **Système d'exploitation / OS :** Windows (testé principalement sur cette plateforme / *tested mainly on this platform*). - -### Options du Compilateur / Compiler Options - -Assurez-vous que les options suivantes sont activées dans les paramètres de votre compilateur. -*Make sure the following options are enabled in your compiler settings.* - - * ✅ **Activer le support des threads (Thread-Safe)** : Essentiel pour le système de cache. / *Essential for the caching system.* - * ✅ **Activer la prise en charge DPI (DPI-Aware)** : Pour un affichage correct sur les écrans modernes. / *For correct display on modern screens.* + * **PureBasic Compiler** (developed with v6.21 x64). + * **Compiler Options**: The following options must be enabled for your project: + * [cite\_start]**Thread-Safe**: This is mandatory for the multi-threaded cache to work correctly[cite: 10, 13]. + * [cite\_start]**DPI-Aware**: Required for correct UI scaling on modern displays[cite: 597]. ----- -## Comment l'utiliser ? / How to Use It? 🚀 +## How to Use -L'intégration du gadget dans votre propre fenêtre est simple. Voici un exemple de base. -*Integrating the gadget into your own window is simple. Here is a basic example.* +Integrating the thumbnail gadget into your own PureBasic project is straightforward. [cite\_start]The included test code (`CompilerIf #PB_Compiler_IsMainFile`) serves as a practical example[cite: 552, 553]. + +### Step 1: Initialize the System + +In your main program, before creating the gadget, initialize the image cache. ```purebasic -;- Incorporez les modules du projet ici / Include the project's modules here +; Enable necessary image decoders +UseJPEGImageDecoder() +UsePNGImageDecoder() -Global NewList CurrentList.s() -Global CurrentListMutex.i = CreateMutex() +; Initialize the cache system +Cache::InitCache() +``` -; 1. Créez une fonction de rappel (callback) pour charger les chemins d'images -; 1. Create a callback function to load the image paths -Procedure CallBackLoadFiles(GadgetId.i, Index.i, Length.l) - Protected n.l, TmpIndex.i - Protected *Ptr.Core::FileData +### Step 2: Implement the Data Callback Function - LockMutex(CurrentListMutex) - For n = 1 To Length - TmpIndex = Index + n - 1 - If TmpIndex >= 0 And TmpIndex < ListSize(CurrentList()) - SelectElement(CurrentList(), TmpIndex) - - ; On demande au cache de préparer le fichier / Ask the cache to prepare the file - *Ptr = Cache::GetFileDataFromCache(CurrentList()) - ; On lie le pointeur de données à l'index de la vignette / Link the data pointer to the thumbnail index - Thumbs::AddImageToThumb(GadgetId, TmpIndex, *Ptr) - EndIf - Next - Thumbs::LimitIndex(GadgetId, ListSize(CurrentList())) - UnlockMutex(CurrentListMutex) +Create a procedure that the `Thumbs` gadget will call whenever it needs to load image data. This function receives a starting `Index` and the `Length` (number of items) to load. Your job is to provide a pointer to the image data for each index. + +```purebasic +; This is your custom function to link your list of files to the gadget +Procedure MyCallBackLoad(GadgetId.i, Index.i, Length.l) + Protected i + For i = 0 To Length - 1 + Protected CurrentIndex = Index + i + + ; 1. Get the file path from your own list (e.g., a List() or Array()) + SelectElement(MyFileList(), CurrentIndex) + Protected FilePath.s = MyFileList() + + ; 2. Ask the cache for a pointer to the file's data structure + Protected *Ptr.Core::FileData = Cache::GetFileDataFromCache(FilePath) + + ; 3. Give this pointer back to the Thumbs gadget for the correct index + Thumbs::AddImageToThumb(GadgetId, CurrentIndex, *Ptr) + Next + + ; 4. Update the gadget's scroll limits + Thumbs::LimitIndex(GadgetId, ListSize(MyFileList())) EndProcedure +``` +### Step 3: Create the Gadget -; 2. Créez votre fenêtre et le gadget / Create your window and the gadget -If OpenWindow(0, 0, 0, 800, 600, "Exemple de Vignettes / Thumbnail Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget) - - ; Créez le gadget en spécifiant la taille des vignettes et la fonction de rappel - ; Create the gadget, specifying the thumbnail size and the callback function - Thumbs::ThumbsGadget(1, 0, 0, WindowWidth(0), WindowHeight(0), 128, @CallBackLoadFiles()) - - ; 3. Remplissez votre liste de chemins d'images / Populate your list of image paths - LockMutex(CurrentListMutex) - ExamineDirectory(0, "C:\Your\Images", "*.jpg") - While NextDirectoryEntry(0) - AddElement(CurrentList()) - CurrentList() = "C:\Your\Images\" + DirectoryEntryName(0) - Wend - FinishDirectory(0) - UnlockMutex(CurrentListMutex) - - ; 4. Forcez la mise à jour pour afficher les nouvelles images / Force an update to display the new images - Thumbs::ForceUpdate(1) +Create the `ThumbsGadget` in your window and pass a pointer to your callback function. - ; Boucle d'événements classique / Classic event loop - Repeat - Select WaitWindowEvent() - Case #PB_Event_CloseWindow - Quit = 1 - Case #PB_Event_SizeWindow - ResizeGadget(1, 0, 0, WindowWidth(0), WindowHeight(0)) - EndSelect - Until Quit = 1 - - Thumbs::FreeThumbsGadget(1) -EndIf +```purebasic +; Create the gadget and link it to your callback +Thumbs::ThumbsGadget(#MyThumbsGadget, 0, 0, 800, 600, 128, @MyCallBackLoad()) +``` + +### Step 4: Clean Up on Exit + +When your application closes, make sure to free the resources used by the gadget and the cache. + +```purebasic +; Clean up before closing the window +Thumbs::FreeThumbsGadget(#MyThumbsGadget) +Cache::QuitCache() ``` ----- -## Auteur / Author ✍️ +## Code Structure - * **Thyphoon** +The project is divided into several modules, each with a specific responsibility: -## Licence / License 📜 + * [cite\_start]**`Module Helpers`**: Contains simple utility functions like `Min()` and `Max()`[cite: 16]. + * [cite\_start]**`Module ImgTools`**: Provides image manipulation utilities, primarily the `ImageToContainer` procedure for calculating scaling dimensions[cite: 43, 58, 59]. + * **`Module Cache`**: The core of the background processing. [cite\_start]It manages a thread pool to load images and a central map to cache them, preventing duplicate loading and managing memory[cite: 82, 98, 126]. + * **`Module Thumbs`**: The main UI component. [cite\_start]It handles drawing, scrolling, user input (clicks, keyboard), and communication with the cache via callbacks[cite: 252, 253]. -Ce projet est distribué sous une licence libre et non restrictive. Vous pouvez l'utiliser, le modifier et le distribuer sans contrainte. Un crédit est apprécié mais non obligatoire. +----- -*This project is distributed under a free and unrestricted license. You can use, modify, and distribute it without constraints. Credit is appreciated but not required.* \ No newline at end of file +## Author & License + + * [cite\_start]**Author**: Thyphoon [cite: 4] + * **License**: Free and unrestricted. [cite\_start]Credit is appreciated but not required[cite: 6]. [cite\_start]Please feel free to share any improvements[cite: 8]. \ No newline at end of file