File indexing completed on 2024-04-14 05:41:04

0001 /**
0002  * SPDX-FileCopyrightText: (C) 2003 by Sébastien Laoût <slaout@linux62.org>
0003  * SPDX-License-Identifier: GPL-2.0-or-later
0004  */
0005 
0006 #ifndef BACKGROUNDMANAGER_H
0007 #define BACKGROUNDMANAGER_H
0008 
0009 #include <QtCore/QList>
0010 #include <QtCore/QObject>
0011 #include <QtCore/QTimer>
0012 #include <QtGui/QColor>
0013 
0014 class QPixmap;
0015 class QString;
0016 
0017 /** A node in the list of background images of BackgroundManager.
0018  * It can only be used by BackgroundManager because it is an internal structure of this manager.
0019  * @author Sébastien Laoût
0020  */
0021 class BackgroundEntry
0022 {
0023     friend class BackgroundManager;
0024 
0025 public:
0026     ~BackgroundEntry();
0027 
0028 protected:
0029     BackgroundEntry(const QString &location);
0030 
0031     QString name;
0032     QString location;
0033     bool tiled;       /// << Only valid after some object subscribed to this image! Because it's only read at this time.
0034     QPixmap *pixmap;  /// << Only valid (non-null) after some object subscribed to this image! Because it's only read at this time.
0035     QPixmap *preview; /// << Only valid (non-null) after some object requested the preview.
0036     int customersCount;
0037 };
0038 
0039 /** A node in the list of opaque background images (with a background color applied to an image) of BackgroundManager.
0040  * It can only be used by BackgroundManager because it is an internal structure of this manager.
0041  * @author Sébastien Laoût
0042  */
0043 class OpaqueBackgroundEntry
0044 {
0045     friend class BackgroundManager;
0046 
0047 public:
0048     ~OpaqueBackgroundEntry();
0049 
0050 protected:
0051     OpaqueBackgroundEntry(const QString &name, const QColor &color);
0052 
0053     QString name;
0054     QColor color;
0055     QPixmap *pixmap;
0056     int customersCount;
0057 };
0058 
0059 /** Manage the list of background images.
0060  * BASIC FUNCTIONNING OF A BACKGROUND CHOOSER:
0061  *   It get all image names with imageNames() to put them in eg. a QComboBox and then,
0062  *   when it's time to get the preview of an image it call preview() with the image name to get it.
0063  *   Preview are only computed on demand and then cached to fast the next demands (only the pointer will have to be returned).
0064  *   Previews are scaled to fit in a rectangle of 100 by 75 pixels, and with a white background color.
0065  *   They are also saved to files, so that the scaling/opaquification has not to be done later (they will be directly loaded from file).
0066  *   Previews are saved in Global::backgroundsFolder()+"previews/", so that emptying the folder is sufficient to remove them.
0067  * BASIC FUNCTIONING OF AN IMAGE REQUESTER:
0068  *   When eg. a basket is assigned an image name, it register it with subscribe().
0069  *   The full pixmap is then loaded from file and cached (if it was not already loaded) and the "tiled" property is read from the image configuration file.
0070  *   If this object want to have the pixmap applied on a background color (for no transparency => really faster drawing),
0071  *   it should register for the couple (imageName,color) with subscribe(): the pixmap will be created in the cache.
0072  *   Then, the object can get the subscribed images with pixmap() or opaquePixmap() and know if it's tiled with tiled().
0073  *   When the user removed the object background image (or when the object/basket/... is removed), the object should call unsubscribe() for
0074  *   EVERY subscribed image and image couples. Usage count is decreased for those images and a garbage collector will remove the cached images
0075  *   if nothing is subscribed to them (to free memory).
0076  * @author Sébastien Laoût
0077  */
0078 class BackgroundManager : private QObject
0079 {
0080     Q_OBJECT
0081 private:
0082     /// LIST OF IMAGES:
0083     typedef QList<BackgroundEntry *> BackgroundsList;
0084     typedef QList<OpaqueBackgroundEntry *> OpaqueBackgroundsList;
0085 
0086 public:
0087     /// CONTRUCTOR AND DESTRUCTOR:
0088     BackgroundManager();
0089     ~BackgroundManager() override;
0090     /// SUBSCRIPTION TO IMAGES:
0091     bool subscribe(const QString &image);                      /// << @Return true if the loading is a success. In the counter-case, calling methods below is unsafe with this @p image name.
0092     bool subscribe(const QString &image, const QColor &color); /// << Idem.
0093     void unsubscribe(const QString &image);
0094     void unsubscribe(const QString &image, const QColor &color);
0095     /// GETTING THE IMAGES AND PROPERTIES:
0096     QPixmap *pixmap(const QString &image);
0097     QPixmap *opaquePixmap(const QString &image, const QColor &color);
0098     bool tiled(const QString &image);
0099     /// LIST OF IMAGES AND PREVIEWS:
0100     bool exists(const QString &image);
0101     QStringList imageNames();
0102     QPixmap *preview(const QString &image);
0103     /// USED FOR EXPORTATION:
0104     QString pathForImageName(const QString &image); /// << It is STRONGLY advised to not use those two methods unless it's to copy (export) the images or something like that...
0105     QString previewPathForImageName(const QString &image);
0106     /// USED FOR IMPORTATION:
0107     void addImage(const QString &fullPath);
0108 
0109 private:
0110     BackgroundEntry *backgroundEntryFor(const QString &image);
0111     OpaqueBackgroundEntry *opaqueBackgroundEntryFor(const QString &image, const QColor &color);
0112 
0113 private:
0114     BackgroundsList m_backgroundsList;
0115     OpaqueBackgroundsList m_opaqueBackgroundsList;
0116     QTimer m_garbageTimer;
0117 private Q_SLOTS:
0118     void requestDelayedGarbage();
0119     void doGarbage();
0120 };
0121 
0122 #endif // BACKGROUNDMANAGER_H