diff --git a/Mainpage.dox b/Mainpage.dox index 2a0d66d6..750181a2 100644 --- a/Mainpage.dox +++ b/Mainpage.dox @@ -1,201 +1,201 @@ /* * This file is part of Kirigami * SPDX-FileCopyrightText: 2016 Marco Martin * * SPDX-License-Identifier: LGPL-2.0-or-later */ /** \mainpage kirigami \section overview Introduction Kirigami is a set of QtQuick components for building adaptable UIs based on Qt Quick Controls 2. Its goal is to enable creation of applications that look and feel great on mobile as well as desktop devices and follow the KDE Human Interface Guidelines. The target of those components is anybody that wants to do an application using QtQuick as its main UI, especially if targeting a mobile platform, without adding many dependencies. They work on a variety of platforms, such as Plasma Mobile, Desktop Linux, Android, iOS and Windows. It is a Tier-1 KDE Framework starting with KDE Frameworks 5.37. \section components Main Components - \link org::kde::kirigami::ApplicationWindow ApplicationWindow \endlink - \link org::kde::kirigami::Action Action \endlink - \link org::kde::kirigami::GlobalDrawer GlobalDrawer \endlink - \link org::kde::kirigami::ContextDrawer ContextDrawer \endlink - \link org::kde::kirigami::OverlayDrawer OverlayDrawer \endlink - \link org::kde::kirigami::Page Page \endlink - \link org::kde::kirigami::ScrollablePage ScrollablePage \endlink - \link org::kde::kirigami::OverlaySheet OverlaySheet \endlink - \link PageRouter PageRouter \endlink - \link PageRoute PageRoute \endlink - \link org::kde::kirigami::Theme Theme \endlink - \link org::kde::kirigami::Units Units \endlink -- \link org::kde::kirigami::Icon Icon \endlink +- \link Icon Icon \endlink - \link org::kde::kirigami::AbstractApplicationHeader AbstractApplicationHeader \endlink - \link org::kde::kirigami::AbstractApplicationWindow AbstractApplicationWindow \endlink - \link org::kde::kirigami::AbstractListItem AbstractListItem \endlink - \link org::kde::kirigami::ApplicationHeader ApplicationHeader \endlink - \link org::kde::kirigami::BasicListItem BasicListItem \endlink - \link org::kde::kirigami::ListSectionHeader ListSectionHeader \endlink - \link org::kde::kirigami::SwipeListItem SwipeListItem \endlink - \link org::kde::kirigami::Heading Heading \endlink - \link org::kde::kirigami::Label Label \endlink \section example Minimal Example @code import QtQuick 2.1 import QtQuick.Controls 2.0 as QQC2 import org.kde.kirigami 2.4 as Kirigami Kirigami.ApplicationWindow { id: root header: Kirigami.ApplicationHeader {} globalDrawer: Kirigami.GlobalDrawer { title: "Hello App" titleIcon: "applications-graphics" actions: [ Kirigami.Action { text: "View" iconName: "view-list-icons" Kirigami.Action { text: "action 1" } Kirigami.Action { text: "action 2" } Kirigami.Action { text: "action 3" } }, Kirigami.Action { text: "action 3" }, Kirigami.Action { text: "action 4" } ] } contextDrawer: Kirigami.ContextDrawer { id: contextDrawer } pageStack.initialPage: mainPageComponent Component { id: mainPageComponent Kirigami.ScrollablePage { title: "Hello" actions { main: Kirigami.Action { iconName: sheet.sheetOpen ? "dialog-cancel" : "document-edit" onTriggered: { print("Action button in buttons page clicked"); sheet.sheetOpen = !sheet.sheetOpen } } left: Kirigami.Action { iconName: "go-previous" onTriggered: { print("Left action triggered") } } right: Kirigami.Action { iconName: "go-next" onTriggered: { print("Right action triggered") } } contextualActions: [ Kirigami.Action { text:"Action for buttons" iconName: "bookmarks" onTriggered: print("Action 1 clicked") }, Kirigami.Action { text:"Action 2" iconName: "folder" enabled: false }, Kirigami.Action { text: "Action for Sheet" visible: sheet.sheetOpen } ] } Kirigami.OverlaySheet { id: sheet onSheetOpenChanged: page.actions.main.checked = sheetOpen QQC2.Label { wrapMode: Text.WordWrap text: "Lorem ipsum dolor sit amet" } } //Page contents... } } } @endcode \section deployment Deployment CMake is recomended for both building Kirigami and the project using it, QMake is supported as well, so we can have several configurations, depending what is the host build system and how the deployment needs to be done. Kirigami can be built in two ways: both as a module or statically linked in the application, leading to four combinations: * Kirigami built as a module with CMake * Kirigami statically built with CMake (needed to link statically from applications built with CMake) * Kirigami built as a module with QMake * Kirigami statically built with QMake (needed to link statically from applications built with QMake) The simplest and recomended way to use Kirigami is to just use the module provided by the Linux distribution, or build it as a module and deploy it together the main application. For example when building an application on Android with CMake, if Kirigami for Android is built and installed in the same temporary directory before the application, the create-apk- step of the application will include the Kirigami files as well in the APK. If QMake needs to be used, it's recomended to follow the schema of the example app present in the folder examples/minimalqmake of the Kirigami source code. It will use Kirigami statically linked only on Android, while on desktop systems it will use the version provided by the distribution. What platforms use the static version and what the dynamic one can be freely adjusted. The application needs to have a folder called "3rdparty" containing clones of two KDE repositories: kirigami and breeze-icons (available at git://anongit.kde.org/kirigami.git and git://anongit.kde.org/breeze-icons.git). The relevant part in the .pro file is: @code android: { include(3rdparty/kirigami/kirigami.pri) } @endcode While the main.cpp file will have something like: @code #include #include #ifdef Q_OS_ANDROID #include "./3rdparty/kirigami/src/kirigamiplugin.h" #endif int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); QQmlApplicationEngine engine; #ifdef Q_OS_ANDROID KirigamiPlugin::getInstance().registerTypes(); #endif .... } @endcode @authors Marco Martin \
Sebastian Kuegler \
Aleix Pol Gonzalez \
Dirk Hohndel \
@maintainers Marco Martin \ @licenses @lgpl */ // DOXYGEN_SET_RECURSIVE = YES -// DOXYGEN_SET_EXCLUDE_PATTERNS += *_p.h */private/* */examples/* +// DOXYGEN_SET_EXCLUDE_PATTERNS += *_p.h */private/* */examples/* */doc/* // DOXYGEN_SET_PROJECT_NAME = Kirigami // vim:ts=4:sw=4:expandtab:filetype=doxygen diff --git a/docs/pics/icon/active.png b/docs/pics/icon/active.png new file mode 100644 index 00000000..476efc83 Binary files /dev/null and b/docs/pics/icon/active.png differ diff --git a/docs/pics/icon/selected.png b/docs/pics/icon/selected.png new file mode 100644 index 00000000..d5beebfa Binary files /dev/null and b/docs/pics/icon/selected.png differ diff --git a/examples/icon/CustomSource.qml b/examples/icon/CustomSource.qml new file mode 100644 index 00000000..8cb5968b --- /dev/null +++ b/examples/icon/CustomSource.qml @@ -0,0 +1,3 @@ +Kirgami.Icon { + source: "image://provider/kirigami.svg" +} \ No newline at end of file diff --git a/examples/icon/Fallback.qml b/examples/icon/Fallback.qml new file mode 100644 index 00000000..fd44ad52 --- /dev/null +++ b/examples/icon/Fallback.qml @@ -0,0 +1,4 @@ +Kirgami.Icon { + source: "this-icon-does-not-exist" + fallback: "view-refresh" +} \ No newline at end of file diff --git a/examples/icon/FilesystemSource.qml b/examples/icon/FilesystemSource.qml new file mode 100644 index 00000000..85838054 --- /dev/null +++ b/examples/icon/FilesystemSource.qml @@ -0,0 +1,3 @@ +Kirgami.Icon { + source: "/home/example/cool.svg" +} \ No newline at end of file diff --git a/examples/icon/IconThemeSource.qml b/examples/icon/IconThemeSource.qml new file mode 100644 index 00000000..cb8e557b --- /dev/null +++ b/examples/icon/IconThemeSource.qml @@ -0,0 +1,3 @@ +Kirgami.Icon { + source: "view-refresh" +} \ No newline at end of file diff --git a/examples/icon/InternetSource.qml b/examples/icon/InternetSource.qml new file mode 100644 index 00000000..c769bb41 --- /dev/null +++ b/examples/icon/InternetSource.qml @@ -0,0 +1,3 @@ +Kirgami.Icon { + source: "https://example.com/kirigami.png" +} \ No newline at end of file diff --git a/examples/icon/ResourceSource.qml b/examples/icon/ResourceSource.qml new file mode 100644 index 00000000..afb730bd --- /dev/null +++ b/examples/icon/ResourceSource.qml @@ -0,0 +1,3 @@ +Kirgami.Icon { + source: "qrc:/kirigami.svg" +} \ No newline at end of file diff --git a/src/icon.h b/src/icon.h index d43c326c..6b480d4d 100644 --- a/src/icon.h +++ b/src/icon.h @@ -1,106 +1,198 @@ /* * SPDX-FileCopyrightText: 2011 Marco Martin * SPDX-FileCopyrightText: 2014 Aleix Pol Gonzalez + * SPDX-FileCopyrightText: 2020 Carson Black * * SPDX-License-Identifier: LGPL-2.0-or-later */ #pragma once #include #include #include #include class QNetworkAccessManager; class QNetworkReply; namespace Kirigami { class PlatformTheme; } +/** + * Class for rendering an icon in UI. + */ class Icon : public QQuickItem { Q_OBJECT + /** + * The source of this icon. An `Icon` can pull from: + * + * * The icon theme: + * @include icon/IconThemeSource.qml + * * The filesystem: + * @include icon/FilesystemSource.qml + * * Remote URIs: + * @include icon/InternetSource.qml + * * Custom providers: + * @include icon/CustomSource.qml + * * Your application's bundled resources: + * @include icon/ResourceSource.qml + * + * @note See https://doc.qt.io/qt-5/qtquickcontrols2-icons.html for how to + * bundle icon themes in your application to refer to them by name instead of + * by resource URL. + * + * @note Use `fallback` to provide a fallback theme name for icons. + */ Q_PROPERTY(QVariant source READ source WRITE setSource NOTIFY sourceChanged) + + /** + * The name of a fallback icon to load from the icon theme when the `source` + * cannot be found. The default fallback icon is `"unknown"`. + * + * @include icon/Fallback.qml + * + * @note This will only be loaded if source is unavailable (e.g. it doesn't exist, or network issues have prevented loading). + */ + Q_PROPERTY(QString fallback READ fallback WRITE setFallback NOTIFY fallbackChanged) + + /** + * Whether pixmaps will be scaled smoothly if the size of this `Icon` is + * different from the source size. + */ Q_PROPERTY(bool smooth READ smooth WRITE setSmooth NOTIFY smoothChanged) + + /** + * The `implicitWidth` of this item, derived from the `source` image. + */ Q_PROPERTY(int implicitWidth READ implicitWidth CONSTANT) + + /** + * The `implicitHeight` of this item, derived from the `source` image. + */ Q_PROPERTY(int implicitHeight READ implicitHeight CONSTANT) + + /** + * Whether this icon will use the QIcon::Active mode when drawing the icon, + * resulting in a graphical effect being applied to the icon to indicate that + * it is currently active. + * + * This is typically used to indicate when an item is being hovered or pressed. + * + * @image html icon/active.png + * + * The color differences under the default KDE color palette, Breeze. Note + * that a dull highlight background is typically displayed behind active icons and + * it is recommended to add one if you are creating a custom component. + */ Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged) + + /** + * Whether this icon's `source` is valid and it is being used. + */ Q_PROPERTY(bool valid READ valid NOTIFY validChanged) + + /** + * Whether this icon will use the QIcon::Selected mode when drawing the icon, + * resulting in a graphical effect being applied to the icon to indicate that + * it is currently selected. + * + * This is typically used to indicate when a list item is currently selected. + * + * @image html icon/selected.png + * + * The color differences under the default KDE color palette, Breeze. Note + * that a blue background is typically displayed behind selected elements. + */ Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectedChanged) + + /** + * Whether this icon will be treated as a mask. When an icon is being used + * as a mask, all non-transparent colors are replaced with the color provided in the Icon's + * @link Icon::color color @endlink property. + * + * @see color + */ Q_PROPERTY(bool isMask READ isMask WRITE setIsMask NOTIFY isMaskChanged) + + /** + * The color to use when drawing this icon when `isMask` is enabled. + * If this property is not set or is `Qt::transparent`, the icon will use + * the text or the selected text color, depending on if `selected` is set to + * true. + */ Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) - Q_PROPERTY(QString fallback READ fallback WRITE setFallback NOTIFY fallbackChanged) public: Icon(QQuickItem *parent = nullptr); ~Icon(); void setSource(const QVariant &source); QVariant source() const; int implicitWidth() const; int implicitHeight() const; void setSmooth(const bool smooth); bool smooth() const; void setActive(bool active = true); bool active() const; bool valid() const; void setSelected(bool selected = true); bool selected() const; void setIsMask(bool mask); bool isMask() const; void setColor(const QColor &color); QColor color() const; QString fallback() const; void setFallback(const QString &fallback); QSGNode* updatePaintNode(QSGNode* node, UpdatePaintNodeData* data) override; Q_SIGNALS: void sourceChanged(); void smoothChanged(); void enabledChanged(); void activeChanged(); void validChanged(); void selectedChanged(); void isMaskChanged(); void colorChanged(); void fallbackChanged(const QString &fallback); protected: void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; QImage findIcon(const QSize& size); void handleFinished(QNetworkReply* reply); void handleRedirect(QNetworkReply* reply); QIcon::Mode iconMode() const; bool guessMonochrome(const QImage &img); void updatePolish() override; private: Kirigami::PlatformTheme *m_theme = nullptr; QPointer m_networkReply; QHash m_monochromeHeuristics; QVariant m_source; bool m_smooth; bool m_changed; bool m_active; bool m_selected; bool m_isMask; bool m_isMaskHeuristic = false; QImage m_loadedImage; QColor m_color = Qt::transparent; QString m_fallback = QStringLiteral("unknown"); QImage m_icon; };