2020-08-13 21:08:54 +02:00
|
|
|
/*
|
|
|
|
SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
|
|
|
|
SPDX-FileCopyrightText: 2014 Sebastian Kügler <sebas@kde.org>
|
|
|
|
|
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
*/
|
2013-05-15 17:57:13 +02:00
|
|
|
|
|
|
|
#ifndef UNITS_H
|
|
|
|
#define UNITS_H
|
|
|
|
|
|
|
|
#include <QObject>
|
2014-01-22 00:28:09 +01:00
|
|
|
#include <QQmlPropertyMap>
|
2013-05-15 17:57:13 +02:00
|
|
|
|
|
|
|
#include <Plasma/Theme>
|
|
|
|
|
2019-09-25 15:55:17 +02:00
|
|
|
#include <KConfigWatcher>
|
|
|
|
|
2014-01-22 01:36:30 +01:00
|
|
|
class QQuickItem;
|
|
|
|
|
2015-11-20 14:26:16 +01:00
|
|
|
class SharedAppFilter : public QObject
|
|
|
|
{
|
2021-03-05 19:15:32 +01:00
|
|
|
Q_OBJECT
|
2015-11-20 14:26:16 +01:00
|
|
|
public:
|
2018-04-13 09:05:17 +02:00
|
|
|
explicit SharedAppFilter(QObject *parent = nullptr);
|
2018-05-23 08:05:31 +02:00
|
|
|
~SharedAppFilter() override;
|
2015-11-20 14:26:16 +01:00
|
|
|
|
|
|
|
Q_SIGNALS:
|
|
|
|
void fontChanged();
|
|
|
|
|
|
|
|
protected:
|
2018-05-23 08:05:31 +02:00
|
|
|
bool eventFilter(QObject *watched, QEvent *event) override;
|
2015-11-20 14:26:16 +01:00
|
|
|
};
|
|
|
|
|
2014-08-12 23:12:15 +02:00
|
|
|
/**
|
|
|
|
* @class Units
|
|
|
|
* @short Expose sizes to QML
|
|
|
|
*/
|
2013-05-15 17:57:13 +02:00
|
|
|
class Units : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The fundamental unit of space that should be used for sizes, expressed in pixels.
|
2020-09-16 00:56:22 +02:00
|
|
|
* Given the screen has an accurate DPI settings, it corresponds to the height of
|
|
|
|
* the font's boundingRect.
|
2013-05-15 17:57:13 +02:00
|
|
|
*/
|
2014-02-03 16:32:29 +01:00
|
|
|
Q_PROPERTY(int gridUnit READ gridUnit NOTIFY gridUnitChanged)
|
2013-05-15 17:57:13 +02:00
|
|
|
|
2014-01-22 00:28:09 +01:00
|
|
|
/**
|
2014-01-22 23:59:23 +01:00
|
|
|
* units.iconSizes provides access to platform-dependent icon sizing
|
|
|
|
*
|
|
|
|
* The icon sizes provided are normalized for different DPI, so icons
|
|
|
|
* will scale depending on the DPI.
|
|
|
|
*
|
2014-01-25 03:30:45 +01:00
|
|
|
* Icon sizes from KIconLoader, adjusted to devicePixelRatio:
|
2014-01-22 23:59:23 +01:00
|
|
|
* * small
|
|
|
|
* * smallMedium
|
|
|
|
* * medium
|
|
|
|
* * large
|
|
|
|
* * huge
|
|
|
|
* * enormous
|
2017-04-26 13:37:32 +02:00
|
|
|
* * desktop (DEPRECATED: use iconSizeHints instead)
|
2017-01-12 01:05:10 +01:00
|
|
|
*
|
2014-01-22 00:28:09 +01:00
|
|
|
*/
|
2021-03-05 19:15:32 +01:00
|
|
|
// note the iconSizeChanged signal indicates that one (or more) of these icons have changed
|
|
|
|
// but the property map itself remains constant
|
2017-01-08 16:02:56 +01:00
|
|
|
Q_PROPERTY(QQmlPropertyMap *iconSizes READ iconSizes CONSTANT)
|
2014-01-22 00:28:09 +01:00
|
|
|
|
2017-04-26 13:37:32 +02:00
|
|
|
/**
|
|
|
|
* units.iconSizeHints provides access to user-configurable icon size hints,
|
|
|
|
* to be used where appropriate in the user interface.
|
|
|
|
*
|
|
|
|
* Conceptually, an icon size hint is a key that has one of the sizes from
|
|
|
|
* @iconSizes property as value.
|
|
|
|
*
|
|
|
|
* Currently available hints:
|
|
|
|
* * panel
|
|
|
|
* * desktop
|
|
|
|
*/
|
2021-03-05 19:15:32 +01:00
|
|
|
// note the iconSizeHintsChanged signal indicates that one (or more) of these icons have changed
|
|
|
|
// but the property map itself remains constant
|
2017-04-26 13:37:32 +02:00
|
|
|
Q_PROPERTY(QQmlPropertyMap *iconSizeHints READ iconSizeHints CONSTANT)
|
|
|
|
|
2014-01-23 01:26:19 +01:00
|
|
|
// layout hints
|
2014-01-27 19:51:08 +01:00
|
|
|
|
|
|
|
/**
|
2014-06-19 03:10:43 +02:00
|
|
|
* units.smallSpacing is the amount of spacing that should be used around smaller UI elements,
|
|
|
|
* for example as spacing in Columns. Internally, this size depends on the size of
|
2014-01-27 19:51:08 +01:00
|
|
|
* the default font as rendered on the screen, so it takes user-configured font size and DPI
|
|
|
|
* into account.
|
|
|
|
*/
|
2014-01-23 01:26:19 +01:00
|
|
|
Q_PROPERTY(int smallSpacing READ smallSpacing NOTIFY spacingChanged)
|
2014-01-27 19:51:08 +01:00
|
|
|
|
|
|
|
/**
|
2014-02-05 20:04:33 +01:00
|
|
|
* units.largeSpacing is the amount of spacing that should be used inside bigger UI elements,
|
2014-01-27 19:51:08 +01:00
|
|
|
* for example between an icon and the corresponding text. Internally, this size depends on
|
|
|
|
* the size of the default font as rendered on the screen, so it takes user-configured font
|
|
|
|
* size and DPI into account.
|
|
|
|
*/
|
2014-01-23 01:26:19 +01:00
|
|
|
Q_PROPERTY(int largeSpacing READ largeSpacing NOTIFY spacingChanged)
|
|
|
|
|
2014-01-23 04:05:45 +01:00
|
|
|
/**
|
2014-01-27 19:51:08 +01:00
|
|
|
* The ratio between physical and device-independent pixels. This value does not depend on the \
|
|
|
|
* size of the configured font. If you want to take font sizes into account when scaling elements,
|
2021-04-08 17:20:30 +02:00
|
|
|
* use PlasmaCore.Theme.mSize(PlasmaCore.Theme.defaultFont), PlasmaCore.Units.smallSpacing and PlasmaCore.Units.largeSpacing.
|
2014-01-27 19:51:08 +01:00
|
|
|
* The devicePixelRatio follows the definition of "device independent pixel" by Microsoft.
|
2014-01-23 04:05:45 +01:00
|
|
|
*/
|
2014-01-28 01:15:38 +01:00
|
|
|
Q_PROPERTY(qreal devicePixelRatio READ devicePixelRatio NOTIFY devicePixelRatioChanged)
|
2014-01-23 01:26:19 +01:00
|
|
|
|
2014-02-03 16:30:50 +01:00
|
|
|
/**
|
|
|
|
* units.longDuration should be used for longer, screen-covering animations, for opening and
|
|
|
|
* closing of dialogs and other "not too small" animations
|
|
|
|
*/
|
|
|
|
Q_PROPERTY(int longDuration READ longDuration NOTIFY durationChanged)
|
|
|
|
|
|
|
|
/**
|
2014-06-19 03:10:43 +02:00
|
|
|
* units.shortDuration should be used for short animations, such as accentuating a UI event,
|
2014-02-03 16:30:50 +01:00
|
|
|
* hover events, etc..
|
|
|
|
*/
|
|
|
|
Q_PROPERTY(int shortDuration READ shortDuration NOTIFY durationChanged)
|
|
|
|
|
2020-12-12 07:39:47 +01:00
|
|
|
/**
|
|
|
|
* units.veryShortDuration should be used for elements that should animate near instantly,
|
|
|
|
* but should have a hint of smoothness
|
|
|
|
*/
|
|
|
|
Q_PROPERTY(int veryShortDuration READ veryShortDuration NOTIFY durationChanged)
|
|
|
|
|
2020-04-05 04:42:18 +02:00
|
|
|
/**
|
|
|
|
* units.veryLongDuration should be used for specialty animations that benefit
|
|
|
|
* from being even longer than longDuration.
|
|
|
|
*/
|
|
|
|
Q_PROPERTY(int veryLongDuration READ veryLongDuration NOTIFY durationChanged)
|
|
|
|
|
Add a humanMoment unit to the various Units
Time in milliseconds equivalent to the theoretical human moment, which can be used
to determine whether how long to wait until the user should be informed of something,
or can be used as the limit for how long something should wait before being
automatically initiated.
Some examples:
- When the user types text in a search field, wait no longer than this duration after
the user completes typing before starting the search
- When loading data which would commonly arrive rapidly enough to not require interaction,
wait this long before showing a spinner
This might seem an arbitrary number, but given the psychological effect that three
seconds seems to be what humans consider a moment (and in the case of waiting for
something to happen, a moment is that time when you think "this is taking a bit long,
isn't it?"), the idea is to postpone for just before such a conceptual moment. The reason
for the two seconds, rather than three, is to function as a middle ground: Not long enough
that the user would think that something has taken too long, for also not so fast as to
happen too soon.
See also
https://www.psychologytoday.com/blog/all-about-addiction/201101/tick-tock-tick-hugs-and-life-in-3-second-intervals
(the actual paper is hidden behind an academic paywall and consequently not readily
available to us, so the source will have to be the blog entry above)
see also https://invent.kde.org/frameworks/kirigami/-/merge_requests/268
2021-03-31 15:18:49 +02:00
|
|
|
/**
|
|
|
|
* Time in milliseconds equivalent to the theoretical human moment, which can be used
|
|
|
|
* to determine whether how long to wait until the user should be informed of something,
|
|
|
|
* or can be used as the limit for how long something should wait before being
|
|
|
|
* automatically initiated.
|
|
|
|
*
|
|
|
|
* Some examples:
|
|
|
|
*
|
|
|
|
* - When the user types text in a search field, wait no longer than this duration after
|
|
|
|
* the user completes typing before starting the search
|
|
|
|
* - When loading data which would commonly arrive rapidly enough to not require interaction,
|
|
|
|
* wait this long before showing a spinner
|
|
|
|
*
|
|
|
|
* This might seem an arbitrary number, but given the psychological effect that three
|
|
|
|
* seconds seems to be what humans consider a moment (and in the case of waiting for
|
|
|
|
* something to happen, a moment is that time when you think "this is taking a bit long,
|
|
|
|
* isn't it?"), the idea is to postpone for just before such a conceptual moment. The reason
|
|
|
|
* for the two seconds, rather than three, is to function as a middle ground: Not long enough
|
|
|
|
* that the user would think that something has taken too long, for also not so fast as to
|
|
|
|
* happen too soon.
|
|
|
|
*
|
|
|
|
* See also
|
|
|
|
* https://www.psychologytoday.com/blog/all-about-addiction/201101/tick-tock-tick-hugs-and-life-in-3-second-intervals
|
|
|
|
* (the actual paper is hidden behind an academic paywall and consequently not readily
|
|
|
|
* available to us, so the source will have to be the blog entry above)
|
|
|
|
*
|
|
|
|
* @since 5.81
|
|
|
|
*/
|
|
|
|
Q_PROPERTY(int humanMoment READ humanMoment CONSTANT)
|
|
|
|
|
2013-05-15 17:57:13 +02:00
|
|
|
public:
|
2021-03-05 19:15:32 +01:00
|
|
|
/// @cond INTERNAL_DOCS
|
2014-08-13 00:57:42 +02:00
|
|
|
|
2013-05-15 17:57:13 +02:00
|
|
|
~Units();
|
|
|
|
|
2017-01-08 16:00:20 +01:00
|
|
|
/**
|
|
|
|
* @return a reference to the global Units instance
|
|
|
|
* @since 5.31
|
|
|
|
*/
|
|
|
|
static Units &instance();
|
|
|
|
|
2014-01-27 19:51:08 +01:00
|
|
|
/**
|
|
|
|
* @return pixel value for a grid Unit. Depends on DPI and font size.
|
|
|
|
*/
|
2014-01-24 12:33:39 +01:00
|
|
|
int gridUnit() const;
|
2014-01-22 01:18:54 +01:00
|
|
|
|
2014-01-23 04:05:45 +01:00
|
|
|
/**
|
|
|
|
* @return The ratio between physical and device-independent pixels.
|
|
|
|
*/
|
2014-01-23 02:18:06 +01:00
|
|
|
qreal devicePixelRatio() const;
|
2014-01-22 00:28:09 +01:00
|
|
|
|
2014-01-27 19:51:08 +01:00
|
|
|
/**
|
|
|
|
* @return map with iconsizes, indexed by name
|
|
|
|
*/
|
2014-01-22 00:28:09 +01:00
|
|
|
QQmlPropertyMap *iconSizes() const;
|
2013-05-15 17:57:13 +02:00
|
|
|
|
2017-04-26 13:37:32 +02:00
|
|
|
/**
|
|
|
|
* @return map with user-configurable icon size hints, indexed by name
|
|
|
|
* @since 5.33
|
|
|
|
*/
|
|
|
|
QQmlPropertyMap *iconSizeHints() const;
|
|
|
|
|
2014-01-27 19:51:08 +01:00
|
|
|
/**
|
|
|
|
* @return Pixel value for large spacing between elements.
|
|
|
|
* @since 5.0
|
|
|
|
*/
|
2014-01-23 01:26:19 +01:00
|
|
|
int smallSpacing() const;
|
2014-01-27 19:51:08 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Pixel value for large spacing between elements.
|
|
|
|
* @since 5.0
|
|
|
|
*/
|
2014-01-23 01:26:19 +01:00
|
|
|
int largeSpacing() const;
|
|
|
|
|
2014-02-03 16:30:50 +01:00
|
|
|
/**
|
|
|
|
* @return Duration for long animations, in milliseconds.
|
|
|
|
* @since 5.0
|
|
|
|
*/
|
|
|
|
int longDuration() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Duration for short animations, in milliseconds.
|
|
|
|
* @since 5.0
|
|
|
|
*/
|
|
|
|
int shortDuration() const;
|
2020-04-05 04:42:18 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Duration for very long animations, in milliseconds.
|
|
|
|
* @since 5.69
|
|
|
|
*/
|
|
|
|
int veryLongDuration() const;
|
2020-12-12 07:39:47 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Duration for instantaneous animations, in milliseconds.
|
|
|
|
* @since 5.78
|
|
|
|
*/
|
|
|
|
int veryShortDuration() const;
|
Add a humanMoment unit to the various Units
Time in milliseconds equivalent to the theoretical human moment, which can be used
to determine whether how long to wait until the user should be informed of something,
or can be used as the limit for how long something should wait before being
automatically initiated.
Some examples:
- When the user types text in a search field, wait no longer than this duration after
the user completes typing before starting the search
- When loading data which would commonly arrive rapidly enough to not require interaction,
wait this long before showing a spinner
This might seem an arbitrary number, but given the psychological effect that three
seconds seems to be what humans consider a moment (and in the case of waiting for
something to happen, a moment is that time when you think "this is taking a bit long,
isn't it?"), the idea is to postpone for just before such a conceptual moment. The reason
for the two seconds, rather than three, is to function as a middle ground: Not long enough
that the user would think that something has taken too long, for also not so fast as to
happen too soon.
See also
https://www.psychologytoday.com/blog/all-about-addiction/201101/tick-tock-tick-hugs-and-life-in-3-second-intervals
(the actual paper is hidden behind an academic paywall and consequently not readily
available to us, so the source will have to be the blog entry above)
see also https://invent.kde.org/frameworks/kirigami/-/merge_requests/268
2021-03-31 15:18:49 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Duration for very long wait times
|
|
|
|
* @since 5.81
|
|
|
|
*/
|
|
|
|
int humanMoment() const;
|
2021-03-05 19:15:32 +01:00
|
|
|
/// @endcond
|
2014-02-03 16:30:50 +01:00
|
|
|
|
2016-07-20 17:04:09 +02:00
|
|
|
/**
|
2021-07-14 10:55:55 +02:00
|
|
|
* @return a size rounded to the nearest inferior standard icon size.
|
2016-07-20 17:04:09 +02:00
|
|
|
* sizes larger than iconSizes.huge, it will be returned unmodified
|
|
|
|
* @param int size the size we want to be rounded down
|
|
|
|
* @see iconSizes
|
|
|
|
*/
|
|
|
|
Q_INVOKABLE static int roundToIconSize(int size);
|
|
|
|
|
2013-05-15 17:57:13 +02:00
|
|
|
Q_SIGNALS:
|
2014-01-23 02:18:06 +01:00
|
|
|
void devicePixelRatioChanged();
|
2013-05-15 17:57:13 +02:00
|
|
|
void gridUnitChanged();
|
2017-01-12 01:05:10 +01:00
|
|
|
void iconSizesChanged();
|
2017-04-26 13:37:32 +02:00
|
|
|
void iconSizeHintsChanged();
|
2014-01-23 01:26:19 +01:00
|
|
|
void spacingChanged();
|
2014-02-03 16:30:50 +01:00
|
|
|
void durationChanged();
|
2013-05-15 17:57:13 +02:00
|
|
|
|
|
|
|
private Q_SLOTS:
|
2014-01-22 00:28:09 +01:00
|
|
|
void iconLoaderSettingsChanged();
|
2015-11-20 14:26:16 +01:00
|
|
|
void updateSpacing();
|
2013-05-15 17:57:13 +02:00
|
|
|
|
|
|
|
private:
|
2017-12-13 07:35:58 +01:00
|
|
|
Units(QObject *parent = nullptr);
|
2021-03-05 19:15:32 +01:00
|
|
|
Units(Units const &) = delete; // Copy construct
|
|
|
|
Units(Units &&) = delete; // Move construct
|
|
|
|
Units &operator=(Units const &) = delete; // Copy assign
|
|
|
|
Units &operator=(Units &&) = delete; // Move assign
|
2017-01-08 16:00:20 +01:00
|
|
|
|
2014-01-28 13:49:23 +01:00
|
|
|
void updateDevicePixelRatio();
|
2019-09-25 15:55:17 +02:00
|
|
|
void updateAnimationSpeed();
|
2014-01-25 02:40:52 +01:00
|
|
|
/**
|
|
|
|
* @return The dpi-adjusted size for a given icon size
|
|
|
|
*/
|
|
|
|
int devicePixelIconSize(const int size) const;
|
2014-01-23 01:26:19 +01:00
|
|
|
|
2014-01-23 01:47:42 +01:00
|
|
|
int m_gridUnit;
|
2014-01-23 02:18:06 +01:00
|
|
|
qreal m_devicePixelRatio;
|
2014-01-23 01:47:42 +01:00
|
|
|
|
2014-01-22 00:28:09 +01:00
|
|
|
QQmlPropertyMap *m_iconSizes;
|
2017-04-26 13:37:32 +02:00
|
|
|
QQmlPropertyMap *m_iconSizeHints;
|
2015-11-20 14:26:16 +01:00
|
|
|
static SharedAppFilter *s_sharedAppFilter;
|
2014-01-23 01:47:42 +01:00
|
|
|
|
2014-01-23 01:26:19 +01:00
|
|
|
int m_smallSpacing;
|
|
|
|
int m_largeSpacing;
|
2014-02-03 16:30:50 +01:00
|
|
|
|
2019-09-25 15:55:17 +02:00
|
|
|
KConfigWatcher::Ptr m_animationSpeedWatcher;
|
2014-02-03 16:30:50 +01:00
|
|
|
int m_longDuration;
|
2013-05-15 17:57:13 +02:00
|
|
|
};
|
|
|
|
|
2021-03-05 19:15:32 +01:00
|
|
|
#endif // UNITS_H
|