File indexing completed on 2024-05-05 04:46:59

0001 /*
0002  * <one line to give the program's name and a brief idea of what it does.>
0003  * Copyright (C) 2019  camilo <chiguitar@unal.edu.co>
0004  *
0005  * This program is free software: you can redistribute it and/or modify
0006  * it under the terms of the GNU General Public License as published by
0007  * the Free Software Foundation, either version 3 of the License, or
0008  * (at your option) any later version.
0009  *
0010  * This program is distributed in the hope that it will be useful,
0011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013  * GNU General Public License for more details.
0014  *
0015  * You should have received a copy of the GNU General Public License
0016  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0017  */
0018 
0019 #pragma once
0020 
0021 #include <QObject>
0022 #include <QQmlEngine>
0023 
0024 #include "mauikit_export.h"
0025 
0026 #include <QSettings>
0027 
0028 #include <KAboutData>
0029 
0030 class QQuickWindow;
0031 class QQuickItem;
0032 class QWindow;
0033 
0034 namespace MauiMan
0035 {
0036   class ThemeManager;
0037 }
0038 
0039 /**
0040  * @brief An abstraction for a client-side-decoration button.
0041  * 
0042  * This class is exposed as the type `CSDButton` to the QML engine, and it is used for creating the CSD window control themes.
0043  * 
0044  * CSDButton represents a button and its states. By reading the theme configuration, this class changes the images used as its state changes. The states need to be set manually.
0045  */
0046 class CSDButton : public QObject
0047 {
0048     Q_OBJECT
0049     QML_ELEMENT
0050     Q_DISABLE_COPY(CSDButton)
0051     
0052     /**
0053      * Whether the button is currently being hovered.
0054      * Uses the `Hover` config entry to read the image file asset.
0055      */
0056     Q_PROPERTY(bool isHovered READ isHovered WRITE setIsHovered NOTIFY isHoveredChanged)
0057     
0058     /**
0059      * Whether the window is currently maximized.
0060      * Uses the `Restore` config section to read the image file assets.
0061      */
0062     Q_PROPERTY(bool isMaximized READ isMaximized WRITE setIsMaximized NOTIFY isMaximizedChanged)
0063     
0064     /**
0065      * Whether the button is currently being pressed.
0066      * Uses the `Pressed` config entry to read the image file asset.
0067      */
0068     Q_PROPERTY(bool isPressed READ isPressed WRITE setIsPressed NOTIFY isPressedChanged)
0069     
0070     /**
0071      * Whether the window is currently focused.
0072      * Uses the `Normal` config entry to read the image file asset, if focused, other wise, the `Backdrop` entry.
0073      */
0074     Q_PROPERTY(bool isFocused READ isFocused WRITE setIsFocused NOTIFY isFocusedChanged)
0075     
0076     /**
0077      * The button type.
0078      * @see CSDButtonType
0079      */
0080     Q_PROPERTY(CSDButtonType type READ type WRITE setType NOTIFY typeChanged)
0081     
0082     /**
0083      * The source file path of the theme being used.
0084      */
0085     Q_PROPERTY(QUrl source READ source NOTIFY sourceChanged FINAL)
0086     
0087     /**
0088      * The style to be used for picking up the image assets and config.
0089      * By default this will be set to the current preferred window controls style preference from MauiMan.
0090      * However, this can be overridden to another existing style. 
0091      */
0092     Q_PROPERTY(QString style READ style WRITE setStyle NOTIFY styleChanged)
0093     
0094 public:
0095     
0096     /**
0097      * @brief The states of a window control button.
0098      */
0099     enum CSDButtonState
0100     {
0101         /**
0102          * The window surface is focused
0103          */
0104         Normal,
0105         
0106         /**
0107          * The button is being hovered but has not been activated
0108          */
0109         Hover,
0110         
0111         /**
0112          * The button is being pressed and has not been released
0113          */
0114         Pressed,
0115         
0116         /**
0117          * The window surface is in not focused
0118          */
0119         Backdrop,
0120         
0121         /**
0122          * The window or the button are not enabled
0123          */
0124         Disabled
0125     }; Q_ENUM(CSDButtonState)
0126     
0127     /**
0128      * @brief The possible types of supported window control buttons
0129      */
0130     enum CSDButtonType
0131     {
0132         /**
0133          * Closes the window surface
0134          */
0135         Close,
0136         
0137         /**
0138          * Minimizes/hides the window surface
0139          */
0140         Minimize,
0141         
0142         /**
0143          * Maximizes the window surface
0144          */
0145         Maximize,
0146         
0147         /**
0148          * Restores the window surface to the previous geometry it had before being maximized
0149          */
0150         Restore,
0151         
0152         /**
0153          * Makes the window surface occupy the whole screen area
0154          */
0155         Fullscreen,
0156         
0157         /**
0158          * No button
0159          */
0160         None
0161     };Q_ENUM(CSDButtonType)
0162         
0163     explicit CSDButton(QObject *parent =nullptr);
0164     
0165     CSDButtonState state() const;
0166     void setState(const CSDButtonState &state);
0167     QUrl source() const;
0168     
0169     bool isHovered() const;
0170     void setIsHovered(bool newIsHovered);
0171     
0172     bool isMaximized() const;
0173     void setIsMaximized(bool newIsMaximized);
0174     
0175     bool isPressed() const;
0176     void setIsPressed(bool newIsPressed);
0177     
0178     bool isFocused() const;
0179     void setIsFocused(bool newIsFocused);
0180     
0181     CSDButton::CSDButtonType type() const;
0182     void setType(CSDButton::CSDButtonType newType);
0183     
0184     QString style() const;
0185     void setStyle(const QString &style);
0186     
0187 public Q_SLOTS:
0188     
0189     /**
0190      * @brief Maps a based string value convention representing a button type to a CSDButton::CSDButtonType
0191      * 
0192      * Usually each window control button is represented as a single letter, and the order of the window control buttons are an array of those string values. 
0193      * 
0194      * An example would be the following array `{"I", "A", "X"}`, which represents the following order: minimize, maximize, close
0195      * 
0196      */
0197     CSDButton::CSDButtonType mapType(const QString &value);
0198     
0199 private:
0200     typedef QHash<CSDButtonState, QUrl> CSDButtonSources;
0201 
0202     CSDButtonType m_type = CSDButtonType::None;
0203     QUrl m_source;
0204     QUrl m_dir;
0205     CSDButtonState m_state = CSDButtonState::Normal;
0206     
0207     CSDButtonSources m_sources; //the state and the source associated
0208     QString m_style;
0209     
0210     bool m_isHovered;
0211     
0212     bool m_isMaximized;
0213     
0214     bool m_isPressed;
0215     
0216     bool m_isFocused;
0217     
0218     QString mapButtonType(const CSDButtonType &type);
0219     QString mapButtonState(const CSDButtonState &type);
0220     QUrl extractStateValue(QSettings &settings, const CSDButton::CSDButtonState &state);
0221     void setSources();
0222     void requestCurrentSource();
0223     
0224 Q_SIGNALS:
0225     void stateChanged();
0226     void sourceChanged();
0227     void isHoveredChanged();
0228     void isMaximizedChanged();
0229     void isPressedChanged();
0230     void isFocusedChanged();
0231     void typeChanged();
0232     void styleChanged();
0233 };
0234 
0235 /**
0236  * @brief The client-side-decorations manager for the MauiKit application.
0237  */
0238 class CSDControls : public QObject
0239 {
0240     Q_OBJECT
0241     QML_ANONYMOUS
0242     Q_DISABLE_COPY(CSDControls)
0243     
0244     /**
0245      * Whether the application shall use CSD (client side decorations).
0246      * 
0247      * @note This property by default uses the MauiMan global preference, but can it be overridden. To reset it back to the original system preference value set it to `undefined`.
0248      */
0249     Q_PROPERTY(bool enableCSD READ enableCSD WRITE setEnableCSD RESET resetEnableCSD NOTIFY enableCSDChanged)
0250     
0251     /**
0252      * The source file path of the style being used.
0253      */
0254     Q_PROPERTY(QUrl source READ source NOTIFY sourceChanged FINAL)
0255     
0256     /**
0257      * The name of the style/theme being used.
0258      * This is picked up from the global MauiMan preferences and can not be overridden by the application.
0259      * This preference is exposed to the end user in the Maui Settings.
0260      */
0261     Q_PROPERTY(QString styleName READ styleName NOTIFY styleNameChanged FINAL)
0262     
0263     /**
0264      * The model of the window control buttons to be shown, and the order in which they should appear in the right side.
0265      * Although the WindowControlsLinux type can be placed arbitrary, it is strongly suggested to always placed them in a right-side area
0266      */
0267     Q_PROPERTY(QStringList rightWindowControls MEMBER m_rightWindowControls FINAL CONSTANT)
0268     
0269 public:    
0270     explicit CSDControls(QObject *parent =nullptr);
0271     
0272     bool enableCSD() const;
0273     
0274     void setEnableCSD(const bool &value);
0275     void resetEnableCSD();
0276     
0277     QUrl source() const;
0278     QString styleName() const;
0279     
0280 private:
0281     typedef QHash<CSDButton::CSDButtonType, CSDButton*> CSDButtons;
0282 
0283     MauiMan::ThemeManager *m_themeSettings;
0284     
0285     bool m_enableCSD = false;
0286     bool m_enabledCSD_blocked = false;
0287     
0288     QUrl m_source;
0289     QString m_styleName = QStringLiteral("Nitrux");
0290     QStringList m_rightWindowControls;
0291     
0292     void getWindowControlsSettings();
0293     void setStyle();
0294     
0295 Q_SIGNALS:
0296     void enableCSDChanged();
0297     void styleNameChanged();
0298     void sourceChanged();
0299 };
0300 
0301 class Notify;
0302 class KAboutComponent;
0303 
0304 
0305 /**
0306  * @brief The MauiApp class
0307  * The MauiApp is a global singleton instance, can be accessed from QML as an attached property, so it can be used by importing `org.mauikit.controls`
0308  *
0309  * @warning It is needed that the first instance creation is made on the application main entry point before the QML engine creates the window surface, so the style and other parts are correctly loaded.
0310  * 
0311  * Example:
0312  * @code
0313  * import org.mauikit.controls as Maui
0314  *
0315  * Maui.ApplicationWindow
0316  * {
0317  *      title: Maui.App.about.name
0318  *      Maui.App.controls.enableCSD: true
0319  * }
0320  * @endcode
0321  */
0322 class MAUIKIT_EXPORT MauiApp : public QObject
0323 {
0324     Q_OBJECT
0325     QML_NAMED_ELEMENT(App)
0326     QML_ATTACHED(MauiApp)
0327     QML_UNCREATABLE("Cannot be created MauiApp")
0328     Q_DISABLE_COPY(MauiApp)
0329     
0330     /**
0331      * The information metadata about the application.
0332      * See the KAboutData documentation for more details.
0333      * @note This is the information parsed for feeding the ApplicationWindow's about dialog.
0334      */
0335     Q_PROPERTY(KAboutData about READ getAbout CONSTANT FINAL)
0336     
0337     /**
0338      * The URL to the image asset for the application icon.
0339      */
0340     Q_PROPERTY(QString iconName READ getIconName WRITE setIconName NOTIFY iconNameChanged)
0341     
0342     /**
0343      * An URL link to the application donation page.
0344      */
0345     Q_PROPERTY(QString donationPage READ getDonationPage WRITE setDonationPage NOTIFY donationPageChanged)
0346     
0347     /**
0348      * The client-side-decorations manager.
0349      * @see CSDControls
0350      */
0351     Q_PROPERTY(CSDControls * controls READ controls CONSTANT FINAL)
0352     
0353     /**
0354      * The formatted MauiKit string version.
0355      */
0356     Q_PROPERTY(QString mauikitVersion READ getMauikitVersion CONSTANT FINAL)
0357     
0358 public:
0359     /**
0360      * @brief Retrieves information of the MauiKit framework wrapped into a KAboutComponent object.
0361      */
0362     static KAboutComponent aboutMauiKit();
0363     
0364     /**
0365      * @private
0366      */
0367     static MauiApp *qmlAttachedProperties(QObject *object);
0368     
0369     /**
0370      * @brief Retrieves the single instance of MauiApp. 
0371      */
0372     static MauiApp *instance()
0373     {
0374         if (m_instance)
0375             return m_instance;
0376         
0377         m_instance = new MauiApp;
0378         return m_instance;
0379     }
0380     
0381     /**
0382      * @brief The formatted MauiKit version string
0383      */
0384     static QString getMauikitVersion();
0385     
0386     /**
0387      * @brief The file URL to the application icon
0388      */
0389     QString getIconName() const;
0390     
0391     /**
0392      * @brief Set the file URL to the application icon.
0393      * Usually it is a self contained URL
0394      */
0395     void setIconName(const QString &value);
0396     
0397     /**
0398      * @brief Donation web page link
0399      * @return URL link
0400      */
0401     QString getDonationPage() const;
0402     
0403     /**
0404      * @brief Set the donation web page link
0405      * @param value the URL link
0406      */
0407     void setDonationPage(const QString &value);
0408 
0409     /**
0410      * @brief Gather information about this module.
0411      * @return
0412      */
0413     KAboutData getAbout() const;
0414     
0415     CSDControls *controls() const;
0416     
0417 private:
0418     static MauiApp *m_instance;
0419     MauiMan::ThemeManager *m_themeSettings;
0420     
0421     MauiApp();
0422     CSDControls * m_controls;
0423     QString m_iconName;
0424     QString m_donationPage;
0425     
0426     static void setDefaultMauiStyle();
0427     
0428 Q_SIGNALS:
0429     void iconNameChanged();
0430     void donationPageChanged();
0431     void currentIconThemeChanged(QString currentIconTheme);
0432 };
0433 
0434 QML_DECLARE_TYPEINFO(MauiApp, QML_HAS_ATTACHED_PROPERTIES)
0435