File indexing completed on 2024-04-21 03:55:57

0001 /*
0002  *  SPDX-FileCopyrightText: 2021 Jonah BrĂ¼chert <jbb@kaidan.im>
0003  *  SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
0004  *
0005  *  SPDX-License-Identifier: LGPL-2.0-or-later
0006  */
0007 
0008 #ifndef KIRIGAMI_UNITS_H
0009 #define KIRIGAMI_UNITS_H
0010 
0011 #include <memory>
0012 
0013 #include <QObject>
0014 #include <QQmlEngine>
0015 
0016 #include "kirigamiplatform_export.h"
0017 
0018 class QQmlEngine;
0019 
0020 namespace Kirigami
0021 {
0022 namespace Platform
0023 {
0024 class Units;
0025 class UnitsPrivate;
0026 
0027 /**
0028  * @class IconSizes units.h <Kirigami/Units>
0029  *
0030  * Provides access to platform-dependent icon sizing
0031  */
0032 class KIRIGAMIPLATFORM_EXPORT IconSizes : public QObject
0033 {
0034     Q_OBJECT
0035     QML_ELEMENT
0036     QML_UNCREATABLE("Grouped Property")
0037 
0038     Q_PROPERTY(int sizeForLabels READ sizeForLabels NOTIFY sizeForLabelsChanged FINAL)
0039     Q_PROPERTY(int small READ small NOTIFY smallChanged FINAL)
0040     Q_PROPERTY(int smallMedium READ smallMedium NOTIFY smallMediumChanged FINAL)
0041     Q_PROPERTY(int medium READ medium NOTIFY mediumChanged FINAL)
0042     Q_PROPERTY(int large READ large NOTIFY largeChanged FINAL)
0043     Q_PROPERTY(int huge READ huge NOTIFY hugeChanged FINAL)
0044     Q_PROPERTY(int enormous READ enormous NOTIFY enormousChanged FINAL)
0045 
0046 public:
0047     IconSizes(Units *units);
0048 
0049     int sizeForLabels() const;
0050     int small() const;
0051     int smallMedium() const;
0052     int medium() const;
0053     int large() const;
0054     int huge() const;
0055     int enormous() const;
0056 
0057     Q_INVOKABLE int roundedIconSize(int size) const;
0058 
0059 private:
0060     KIRIGAMIPLATFORM_NO_EXPORT float iconScaleFactor() const;
0061 
0062     Units *m_units;
0063 
0064 Q_SIGNALS:
0065     void sizeForLabelsChanged();
0066     void smallChanged();
0067     void smallMediumChanged();
0068     void mediumChanged();
0069     void largeChanged();
0070     void hugeChanged();
0071     void enormousChanged();
0072 };
0073 
0074 /**
0075  * @class Units units.h <Kirigami/Units>
0076  *
0077  * A set of values to define semantically sizes and durations.
0078  */
0079 class KIRIGAMIPLATFORM_EXPORT Units : public QObject
0080 {
0081     Q_OBJECT
0082     QML_ELEMENT
0083     QML_SINGLETON
0084 
0085     friend class IconSizes;
0086 
0087     /**
0088      * The fundamental unit of space that should be used for sizes, expressed in pixels.
0089      * Given the screen has an accurate DPI settings, it corresponds to the height of
0090      * the font's boundingRect.
0091      */
0092     Q_PROPERTY(int gridUnit READ gridUnit NOTIFY gridUnitChanged FINAL)
0093 
0094     /**
0095      * units.iconSizes provides access to platform-dependent icon sizing
0096      *
0097      * The icon sizes provided are normalized for different DPI, so icons
0098      * will scale depending on the DPI.
0099      *
0100      * * sizeForLabels (the largest icon size that fits within fontMetrics.height) @since 5.80 @since org.kde.kirigami 2.16
0101      * * small
0102      * * smallMedium
0103      * * medium
0104      * * large
0105      * * huge
0106      * * enormous
0107      */
0108     Q_PROPERTY(Kirigami::Platform::IconSizes *iconSizes READ iconSizes CONSTANT FINAL)
0109 
0110     /**
0111      * This property holds the amount of spacing that should be used between smaller UI elements,
0112      * such as a small icon and a label in a button.
0113      * Internally, this size depends on the size of the default font as rendered on the screen,
0114      * so it takes user-configured font size and DPI into account.
0115      */
0116     Q_PROPERTY(int smallSpacing READ smallSpacing NOTIFY smallSpacingChanged FINAL)
0117 
0118     /**
0119      * This property holds the amount of spacing that should be used between medium UI elements,
0120      * such as buttons and text fields in a toolbar.
0121      * Internally, this size depends on the size of the default font as rendered on the screen,
0122      * so it takes user-configured font size and DPI into account.
0123      */
0124     Q_PROPERTY(int mediumSpacing READ mediumSpacing NOTIFY mediumSpacingChanged FINAL)
0125 
0126     /**
0127      * This property holds the amount of spacing that should be used between bigger UI elements,
0128      * such as a large icon and a heading in a card.
0129      * Internally, this size depends on the size of the default font as rendered on the screen,
0130      * so it takes user-configured font size and DPI into account.
0131      */
0132     Q_PROPERTY(int largeSpacing READ largeSpacing NOTIFY largeSpacingChanged FINAL)
0133 
0134     /**
0135      * units.veryLongDuration should be used for specialty animations that benefit
0136      * from being even longer than longDuration.
0137      */
0138     Q_PROPERTY(int veryLongDuration READ veryLongDuration NOTIFY veryLongDurationChanged FINAL)
0139 
0140     /**
0141      * units.longDuration should be used for longer, screen-covering animations, for opening and
0142      * closing of dialogs and other "not too small" animations
0143      */
0144     Q_PROPERTY(int longDuration READ longDuration NOTIFY longDurationChanged FINAL)
0145 
0146     /**
0147      * units.shortDuration should be used for short animations, such as accentuating a UI event,
0148      * hover events, etc..
0149      */
0150     Q_PROPERTY(int shortDuration READ shortDuration NOTIFY shortDurationChanged FINAL)
0151 
0152     /**
0153      * units.veryShortDuration should be used for elements that should have a hint of smoothness,
0154      * but otherwise animate near instantly.
0155      */
0156     Q_PROPERTY(int veryShortDuration READ veryShortDuration NOTIFY veryShortDurationChanged FINAL)
0157 
0158     /**
0159      * Time in milliseconds equivalent to the theoretical human moment, which can be used
0160      * to determine whether how long to wait until the user should be informed of something,
0161      * or can be used as the limit for how long something should wait before being
0162      * automatically initiated.
0163      *
0164      * Some examples:
0165      *
0166      * - When the user types text in a search field, wait no longer than this duration after
0167      *   the user completes typing before starting the search
0168      * - When loading data which would commonly arrive rapidly enough to not require interaction,
0169      *   wait this long before showing a spinner
0170      *
0171      * This might seem an arbitrary number, but given the psychological effect that three
0172      * seconds seems to be what humans consider a moment (and in the case of waiting for
0173      * something to happen, a moment is that time when you think "this is taking a bit long,
0174      * isn't it?"), the idea is to postpone for just before such a conceptual moment. The reason
0175      * for the two seconds, rather than three, is to function as a middle ground: Not long enough
0176      * that the user would think that something has taken too long, for also not so fast as to
0177      * happen too soon.
0178      *
0179      * See also
0180      * https://www.psychologytoday.com/blog/all-about-addiction/201101/tick-tock-tick-hugs-and-life-in-3-second-intervals
0181      * (the actual paper is hidden behind an academic paywall and consequently not readily
0182      * available to us, so the source will have to be the blog entry above)
0183      *
0184      * \note This should __not__ be used as an animation duration, as it is deliberately not scaled according
0185      * to the animation settings. This is specifically for determining when something has taken too long and
0186      * the user should expect some kind of feedback. See veryShortDuration, shortDuration, longDuration, and
0187      * veryLongDuration for animation duration choices.
0188      *
0189      * @since 5.81
0190      * @since org.kde.kirigami 2.16
0191      */
0192     Q_PROPERTY(int humanMoment READ humanMoment NOTIFY humanMomentChanged FINAL)
0193 
0194     /**
0195      * time in ms by which the display of tooltips will be delayed.
0196      *
0197      * @sa ToolTip.delay property
0198      */
0199     Q_PROPERTY(int toolTipDelay READ toolTipDelay NOTIFY toolTipDelayChanged FINAL)
0200 
0201 public:
0202     ~Units() override;
0203 
0204     int gridUnit() const;
0205     void setGridUnit(int size);
0206 
0207     int smallSpacing() const;
0208     void setSmallSpacing(int size);
0209 
0210     int mediumSpacing() const;
0211     void setMediumSpacing(int size);
0212 
0213     int largeSpacing() const;
0214     void setLargeSpacing(int size);
0215 
0216     int veryLongDuration() const;
0217     void setVeryLongDuration(int duration);
0218 
0219     int longDuration() const;
0220     void setLongDuration(int duration);
0221 
0222     int shortDuration() const;
0223     void setShortDuration(int duration);
0224 
0225     int veryShortDuration() const;
0226     void setVeryShortDuration(int duration);
0227 
0228     int humanMoment() const;
0229     void setHumanMoment(int duration);
0230 
0231     int toolTipDelay() const;
0232     void setToolTipDelay(int delay);
0233 
0234     IconSizes *iconSizes() const;
0235 
0236     static Units *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine);
0237 
0238 Q_SIGNALS:
0239     void gridUnitChanged();
0240     void smallSpacingChanged();
0241     void mediumSpacingChanged();
0242     void largeSpacingChanged();
0243     void veryLongDurationChanged();
0244     void longDurationChanged();
0245     void shortDurationChanged();
0246     void veryShortDurationChanged();
0247     void humanMomentChanged();
0248     void toolTipDelayChanged();
0249     void wheelScrollLinesChanged();
0250 
0251 protected:
0252     explicit Units(QObject *parent = nullptr);
0253     bool eventFilter(QObject *watched, QEvent *event) override;
0254 
0255 private:
0256     std::unique_ptr<UnitsPrivate> d;
0257 };
0258 
0259 }
0260 }
0261 
0262 #endif