# PureBasic Advanced Thumbnail Gadget 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. \! ----- ## Features * [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. ----- ## Requirements * **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]. ----- ## How to Use 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 ; Enable necessary image decoders UseJPEGImageDecoder() UsePNGImageDecoder() ; Initialize the cache system Cache::InitCache() ``` ### Step 2: Implement the Data Callback Function 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 Create the `ThumbsGadget` in your window and pass a pointer to your callback function. ```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() ``` ----- ## Code Structure The project is divided into several modules, each with a specific responsibility: * [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]. ----- ## 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].