summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlurchi <lurchi@strangeplace.net>2017-02-16 11:46:00 +0100
committerlurchi <lurchi@strangeplace.net>2017-02-16 11:46:00 +0100
commit73f03eb42144c13fdefbe60739a20b0814d4b74b (patch)
treebc9bf2aa15617c95e01ff359a593ce922201f91c
downloadsecushare-73f03eb42144c13fdefbe60739a20b0814d4b74b.tar.gz
secushare-73f03eb42144c13fdefbe60739a20b0814d4b74b.zip
Squashed 'prototype_2016/third_party/fluid/' content from commit b57cb0a
git-subtree-dir: prototype_2016/third_party/fluid git-subtree-split: b57cb0a65d732a3f74e15730cc667acb92ef3b04
-rw-r--r--.gitignore4
-rw-r--r--.mailmap2
-rw-r--r--.travis.yml54
-rw-r--r--.travis/PKGBUILD.in47
-rwxr-xr-x.travis/bintray-wrapper.sh42
-rw-r--r--.travis/bintray.json.in29
-rw-r--r--AUTHORS.md25
-rw-r--r--CMakeLists.txt84
-rw-r--r--LICENSE.MPL2373
-rw-r--r--README.md77
-rw-r--r--controls/+material/BaseListItem.qml45
-rw-r--r--controls/+material/BodyLabel.qml30
-rw-r--r--controls/+material/CaptionLabel.qml20
-rw-r--r--controls/+material/DialogLabel.qml23
-rw-r--r--controls/+material/DisplayLabel.qml48
-rw-r--r--controls/+material/HeadlineLabel.qml22
-rw-r--r--controls/+material/SubheadingLabel.qml29
-rw-r--r--controls/+material/ThinDivider.qml22
-rw-r--r--controls/+material/TitleLabel.qml21
-rw-r--r--controls/Action.qml79
-rw-r--r--controls/AppBar.qml194
-rw-r--r--controls/AppToolBar.qml62
-rw-r--r--controls/BaseListItem.qml43
-rw-r--r--controls/BodyLabel.qml51
-rw-r--r--controls/CMakeLists.txt67
-rw-r--r--controls/CaptionLabel.qml35
-rw-r--r--controls/Card.qml88
-rw-r--r--controls/CircleImage.qml49
-rw-r--r--controls/Dialog.qml169
-rw-r--r--controls/DialogLabel.qml38
-rw-r--r--controls/DisplayLabel.qml59
-rw-r--r--controls/FluidStyle.qml68
-rw-r--r--controls/FluidWindow.qml101
-rw-r--r--controls/HeadlineLabel.qml35
-rw-r--r--controls/Icon.qml173
-rw-r--r--controls/IconButton.qml39
-rw-r--r--controls/InfoBar.qml149
-rw-r--r--controls/ListItem.qml155
-rw-r--r--controls/ListItemDelegate.qml42
-rw-r--r--controls/Loadable.qml70
-rw-r--r--controls/NavigationDrawer.qml195
-rw-r--r--controls/NoiseBackground.qml99
-rw-r--r--controls/Page.qml139
-rw-r--r--controls/PageStack.qml51
-rw-r--r--controls/Placeholder.qml66
-rw-r--r--controls/Showable.qml68
-rw-r--r--controls/Sidebar.qml168
-rw-r--r--controls/SmoothFadeImage.qml309
-rw-r--r--controls/SmoothFadeLoader.qml137
-rw-r--r--controls/Subheader.qml45
-rw-r--r--controls/SubheadingLabel.qml51
-rw-r--r--controls/Tab.qml47
-rw-r--r--controls/TabbedPage.qml90
-rw-r--r--controls/ThinDivider.qml28
-rw-r--r--controls/TitleLabel.qml36
-rw-r--r--controls/Units.qml125
-rw-r--r--controls/controls.pri4
-rw-r--r--controls/controls.qrc46
-rw-r--r--controls/iconthemeimageprovider.cpp47
-rw-r--r--controls/iconthemeimageprovider.h25
-rw-r--r--controls/plugin.cpp42
-rw-r--r--controls/plugins.qmltypes569
-rw-r--r--controls/qmldir41
-rw-r--r--controls/qmldir_noplugin39
-rw-r--r--core/CMakeLists.txt32
-rw-r--r--core/Object.qml38
-rw-r--r--core/PlatformExtensions.qml51
-rw-r--r--core/Utils.qml106
-rw-r--r--core/clipboard.cpp54
-rw-r--r--core/clipboard.h41
-rw-r--r--core/core.pri19
-rw-r--r--core/core.qrc8
-rw-r--r--core/device.cpp152
-rw-r--r--core/device.h67
-rw-r--r--core/doc/fluidcore.qdocconf47
-rw-r--r--core/iconsimageprovider.cpp67
-rw-r--r--core/iconsimageprovider.h25
-rw-r--r--core/plugin.cpp90
-rw-r--r--core/plugins.qmltypes268
-rw-r--r--core/qmldateutils.cpp34
-rw-r--r--core/qmldateutils.h42
-rw-r--r--core/qmldir8
-rw-r--r--core/qmldir_noplugin5
-rw-r--r--core/qqmlsortfilterproxymodel.cpp283
-rw-r--r--core/qqmlsortfilterproxymodel.h129
-rw-r--r--core/standardpaths.cpp36
-rw-r--r--core/standardpaths.h51
-rw-r--r--demo/+material/StyledRectangle.qml22
-rw-r--r--demo/+universal/StyledRectangle.qml22
-rw-r--r--demo/BasicComponents.qml80
-rw-r--r--demo/CMakeLists.txt10
-rw-r--r--demo/CompoundComponents.qml76
-rw-r--r--demo/MaterialComponents.qml74
-rw-r--r--demo/NavigationComponents.qml74
-rw-r--r--demo/Pages/Basic/BusyIndicatorPage.qml44
-rw-r--r--demo/Pages/Basic/ButtonPage.qml115
-rw-r--r--demo/Pages/Basic/CheckBoxPage.qml101
-rw-r--r--demo/Pages/Basic/ProgressBarPage.qml127
-rw-r--r--demo/Pages/Basic/RadioButtonPage.qml100
-rw-r--r--demo/Pages/Basic/SliderPage.qml152
-rw-r--r--demo/Pages/Basic/SwitchPage.qml100
-rw-r--r--demo/Pages/Compound/CardPage.qml76
-rw-r--r--demo/Pages/Compound/InfoBarPage.qml30
-rw-r--r--demo/Pages/Compound/ListItemPage.qml40
-rw-r--r--demo/Pages/Compound/SubPage.qml31
-rw-r--r--demo/Pages/Material/ActionButtonPage.qml68
-rw-r--r--demo/Pages/Material/WavePage.qml41
-rw-r--r--demo/Pages/Navigation/NavDrawerPage.qml26
-rw-r--r--demo/Pages/Style/PalettePage.qml135
-rw-r--r--demo/Pages/Style/PaletteSwatch.qml173
-rw-r--r--demo/Pages/Style/TypographyPage.qml87
-rw-r--r--demo/Style.qml75
-rw-r--r--demo/StyledRectangle.qml21
-rw-r--r--demo/demo.pro9
-rw-r--r--demo/demo.qrc30
-rw-r--r--demo/main.cpp37
-rw-r--r--demo/main.qml104
-rw-r--r--doc/defaults.qdocconf23
-rw-r--r--doc/fluid.qdocconf59
-rw-r--r--doc/html-footer-offline.qdocconf18
-rw-r--r--doc/src/fluidcontrols.qdoc25
-rw-r--r--doc/src/fluidcore.qdoc30
-rw-r--r--doc/src/fluideffects.qdoc21
-rw-r--r--doc/src/fluidmaterial.qdoc21
-rw-r--r--doc/src/index.qdoc31
-rw-r--r--effects/BoxShadow.qml53
-rw-r--r--effects/CMakeLists.txt10
-rw-r--r--effects/CircleMask.qml51
-rw-r--r--effects/Vignette.qml77
-rw-r--r--effects/effects.pri1
-rw-r--r--effects/effects.qrc9
-rw-r--r--effects/plugins.qmltypes15
-rw-r--r--effects/qmldir6
-rw-r--r--fluid.pri8
-rw-r--r--material/ActionButton.qml106
-rw-r--r--material/CMakeLists.txt11
-rw-r--r--material/ElevationEffect.qml251
-rw-r--r--material/Ripple.qml290
-rw-r--r--material/Wave.qml80
-rw-r--r--material/material.pri2
-rw-r--r--material/material.qrc10
-rw-r--r--material/plugins.qmltypes569
-rw-r--r--material/qmldir7
-rwxr-xr-xscripts/fetch_icons.sh39
-rw-r--r--src/CMakeLists.txt79
-rw-r--r--src/FluidConfig.cmake.in11
-rw-r--r--src/dateutils.cpp82
-rw-r--r--src/dateutils.h44
-rw-r--r--src/src.pri5
-rw-r--r--tests/CMakeLists.txt1
-rw-r--r--tests/auto/CMakeLists.txt7
-rw-r--r--tests/auto/controls/CMakeLists.txt10
-rw-r--r--tests/auto/controls/controls.cpp16
-rw-r--r--tests/auto/controls/tst_icon.qml83
-rw-r--r--tests/auto/controls/tst_listitem.qml123
-rw-r--r--tests/auto/core/CMakeLists.txt10
-rw-r--r--tests/auto/core/core.cpp16
-rw-r--r--tests/auto/core/tst_clipboard.qml59
-rw-r--r--tests/auto/core/tst_utils.qml38
-rw-r--r--tests/auto/material/CMakeLists.txt12
-rw-r--r--tests/auto/material/material.cpp16
-rw-r--r--tests/auto/material/material.qrc5
-rw-r--r--tests/auto/material/qtquickcontrols2.conf2
-rw-r--r--tests/auto/material/tst_ripple.qml88
-rw-r--r--tests/auto/material/tst_typography.qml166
165 files changed, 11659 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..305f772
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
1build/
2material-design-icons/
3icons/
4*.user
diff --git a/.mailmap b/.mailmap
new file mode 100644
index 0000000..dccdf66
--- /dev/null
+++ b/.mailmap
@@ -0,0 +1,2 @@
1Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> <plfiorini@users.noreply.github.com>
2Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> <pierluigi.fiorini@hawaiios.org>
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..e0d227d
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,54 @@
1language: c
2
3compiler:
4 - gcc
5 - clang
6
7sudo: required
8
9env:
10 global:
11 # BINTRAY_USER
12 - secure: "vEoMBcWLvExapeJ7644Qa5j8zQcIRvSmZawrDWciQAVv47ckjS4CzeKxfniwYuVcMY+G8mk+NANM/cvEYhBuBx1YLRz7qR9WkLtIGs5ZN/Tqna8bEYDx4fz/grsaPIO0zSCOlFy4gjW4OTZc0Pi6h82UNkbu4VruCA0+KHRMeLbqP2SnhLTlKibofp3YgFLK+MpBjQ9m99rfkRlVWSdY6dscST3s5ROreTepoaP1Q4XzG1eRp2aLSqKurWnDdFdXZhInHeWxWwZ5lRPcCj29+oYgU8cvxA/D2DuDfPlM92XzqTTqD9tTztnz0klN/tQaXECaFZYu5/BC/o71FmWtYzuc7SScggFU1XLmEPdsYy8B/bDyvP+QueiwO/i3ZnEiSLccuN7fkEi2qCHLjpcMRJb/A6NKcgkyFHN65ncqcvG3xrk7mcCAMiupkpx0MVskiYI0HD3g/2auIEjDcqKbOGYV1mRwGhWwV51qfDYsAtSQcn5JaTN3ioFjfPpSI4swevAfOdBp1vhkFXvYQHDEWtyaQWQkiZN/D2osO3VoTgXMUF68I2BNskUVXqU/X18f3xzcv3PXsUCTWAY8tQ7iDt93UQyC/rtqnxUhKJqcnM2ri7GGk2yK/GHyjUonf9GO5mucPyAWzkPP13T6gj1Y/XH76wFBurdP89FUidyiVVE="
13 # BINTRAY_API_KEY
14 - secure: "Z4721k6LWdc7/UDVkBSVxr1G2nRWJu1817jCpuE+6pub65WhGqBB20xwI3jsp/J2U2iX3RUgLiJTCRPuQnLoxaDRXY1WZa2qXLumgGcYwgwgCLQgBIvV5OWwPgBpSl40f7w1c8qfEVTeFt4X51fwZR+2WSNzCn9dHZFICHwweasNXMe/1/nnopvZmTmnAICLTTGM3QL8TgrqnAevNtR9/ILGli6YewFmpPBiy/nV5SIPlay4s0gtpr4WOACHbCjyi2dY+OMgln+zcrV2Xe75b/G9G+JbjmQj2wb3MviQhQ9EXGhxcRZTmpgLmZ4VXuFizsl1ssfte7p8JEHdwJi1nnGkjuP0xcmfc/t8y3u/QFQbPd0K/xgQhrHVlVytDGgrwZdfGoHV43E5v338E6vPd0R4PaZbKKwvEfze3T+X04wrnMm2SgtVQnr4l0WBwYEsOLP+MdFyfHsXs74MMg+1VQcz6gnD7YPOPqftds0ZaEltIn6VOZqt72K06t544jjFv1fIxA0bWDFBgIECfF6dGRykaw/Jo/29VoUT9K4dfMX/V9LMxy1x3p/ltW1U0VryqUCzj/QqSJw82rEYkMMvQYq8x+eBdlYjbAZZhRGvMHYa+1uHwiKbyRyQQZlc+r8b1/usI9B2E4y12dPPGmHBW8gbRHfoGCX5m3aBkaqUpeE="
15 # BINTRAY_REPO_OWNER
16 - secure: "fHxkvRKupN+jmbncPeNIVxvAxmHpZskJ89jJoDM3Fdmheq08+BPCLVUaDX3C1Ux4ETCONKKFwiQ152M30TczU95OXCfs9N3Uo631CL0AFH0vavBPDtAdZyOdljS+gkFMRCT/NFxdTgaju128jYVqumJw6fSVke8Edh43cDURhhpD6Xr6qm45620Iua3/Vieu/IBzoCISV4RgBxSgPOBew8diIk9nVqk4nSeU9aP110lJ5ExhI++G7sRaZvlMTkHdti5Wcg2/MXy883IVAacieOALRmdBuW1lv1lgEkV6KZ0cjmiG8B0XuvkWCgx05wbY4FWnAZlU6mkuTUPo4Sg2JhtGUr1ejAHe3TF1g05s2JBiP8oX2vdflh5Immyi0afpdzJGxinrEXY39QBmfK8Donkn78Flz7NdLQz882bdQsQ3MnFGHG8FOqMdJWAAUxpn7L5SCgShH/GpspFnvONWKmJybsRAdMZTHJL7d4pwYgo854vo43p9RDGSZX/jdQ6Gb874rNUdtfWXZLWpaq4jH/jigC+WGG4r78kNIMoylRRqINfg2F7jjR4Z/rieePZ7d0IUeD4+a0XFriYuix415FPpRcogB4cpXmDn6ZQTCfd4QDBxILlv6phHMcTOvrwgBMd40OCtewkXrODIKqC6xaeWf99/8sJti5ZUZK5DiuA="
17
18arch:
19 packages:
20 - qt5-declarative
21 - qt5-quickcontrols2
22 - qt5-graphicaleffects
23 - qt5-svg
24 - extra-cmake-modules
25 - xorg-server-xvfb
26 - clang
27 #- clazy-git
28 script:
29 - scripts/fetch_icons.sh
30 - if [ "$CC" = "gcc" ]; then cmake . -DKDE_INSTALL_USE_QT_SYS_PATHS=ON -DCMAKE_INSTALL_PREFIX=/usr; fi
31 #- if [ "$CC" = "clang" ]; then env CLAZY_CHECKS="level1" cmake . -DCMAKE_CXX_COMPILER=clazy -DKDE_INSTALL_USE_QT_SYS_PATHS=ON -DCMAKE_INSTALL_PREFIX=/usr; fi
32 - if [ "$CC" = "clang" ]; then cmake . -DKDE_INSTALL_USE_QT_SYS_PATHS=ON -DCMAKE_INSTALL_PREFIX=/usr; fi
33 - make
34 - sudo make install
35 - xvfb-run -a -s "-screen 0 800x600x24" make check
36 - ./.travis/bintray-wrapper.sh
37
38script:
39 - "curl -s https://raw.githubusercontent.com/mikkeloscar/arch-travis/master/arch-travis.sh | bash"
40
41deploy:
42 provider: bintray
43 on:
44 branch: develop
45 condition: "$CC = gcc"
46 file: cibuild/bintray.json
47 user:
48 secure: "ABQ0Vh69XIJ38UOTGQOmnJ/zr1E0zNK6bDkqJ+ioujqBE8pvZuppdb9DyPmqscUgJWLQy8C7qfRMXMkkBUdecqV7LAFplO08yMxXmSNCq2gYi7l8jY6WCp+dyno+8tO7P7zO/8Vgae99c2MNkCVw8FpN7vFC3l5QLBUuEuSgCWYInW4aXkQnTkKNPN5hiMb7pJ7c1WMo6YKydkKs6yL4ACUkTzoR8iuTLqIAvi2w9UMzIUE16FGOHHUSZZI0UwExhSPTmH30pLddKexvdip6AyROGPDSqgh1zh9mIpYyz6BRWoTPR8LCpAFE2soTF2t0XdkRoQeZS6+zXJdU3AdJnEj1y2n9zxR3CSl+MfeJCz24yAJ+2shLyl+LZwhert7z45GC5CNrFsxliA7wMCuP3AeBEwCYaTgNcB5mQWK7+nyQuEZ43v/ffQiZUziEPOsHpxdggPN4TQ/KLSwC9eSKyh7dvlvupfd5p509d06239gXVNwDU45H3in2XKv9WQQIBXLW48IoY7YQFDvKCsAuNNn1fJLMLhg4MUqSYWSCYGjGn3nHBm9IJ0Y176dzN7c+2kP+Vm6x9PhWR6ZDpRVh4ygh+TKVNTVpzQ2bD/J+vWcGTf1KP4GJOLPWe7S0BsXNWry1jGz8v+9IDDPMVf9bFRSBZNSGD/qU8FCsS6nVXOU="
49 key:
50 secure: "x5L7Cc9ncaXhjLjGi/+0P1Yjzo5yPTPqB47odKvnvHVG91n7LR0tCY8pKMAITSlnKqxlV6q/jlr5Ur8JzY0hwwi1KaM7t80cjWn9feE79DsA2Tpdxks2eRLQs1kXoqepa+tpuxOCysrYL5KMw/ly3vnnnkeXleb05bdadZLxdf54BK+6pA8djwKoVAba4lQDBL4RrdN7yQYB5ZBdGHFO6BScaVR1xuykOalfSQsQWAQqENbnOSFpxkdxYt0FUsP2N0UwqZ7kbX7XtdRKCfubnRJ9YoNh4kbImRLKbosl1NX8+MAwbudnKa6AV3P+LxQZA6cU1T8JIu6W54A7pXJYnf2bOezSy4ifzE0L+4rgbrIQVL9AUcWpK8gDkdpPJ6B6gwWW8+VP+wDCnzXEk9DXBlOLCGeHBaDOJAeOkCC2NJ64hC0bQfILO79KKYkpQTTf1uepngeie7y50CmOq4CaxAX1rQcPz2GlZlp5XIOZX5ZV5GABxORCn4zANrs7hmhY44ooky6KltiA35vgFxJGfqkgSUWWFqHvEPwDN2anRLjlY+trMN3YRMBCnhL3WCtHjiJ5sUW6drUcBfzcoJxGY7JF31q8N7y0ZhdXNc5P6GC/f62ggHDnk9lklOb4DlEqh+npREk+o89TUU/RkXNPuLBpNiq3UwCrDlKbpoULhgs="
51
52notifications:
53 email: false
54 slack: lirios:fdUqVmPzqPskEL1UBhqapZ0w
diff --git a/.travis/PKGBUILD.in b/.travis/PKGBUILD.in
new file mode 100644
index 0000000..82a49c2
--- /dev/null
+++ b/.travis/PKGBUILD.in
@@ -0,0 +1,47 @@
1# Maintainer: Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
2
3pkgname=fluid-git
4pkgver=@PKGVER@
5pkgrel=1
6pkgdesc="Components for Qt Quick applications"
7arch=('i686' 'x86_64' 'armv6h' 'armv7h')
8url='https://github.com/lirios'
9license=('MPL2')
10depends=('qt5-quickcontrols2' 'qt5-graphicaleffects' 'qt5-svg')
11makedepends=('git' 'extra-cmake-modules')
12conflicts=('fluid')
13replaces=('fluid')
14provides=('fluid')
15groups=('liri-git')
16
17_gitroot="git://github.com/lirios/fluid.git"
18_gitbranch=@GITBRANCH@
19_gitname=$pkgname
20source=(${_gitname}::${_gitroot}#branch=${_gitbranch})
21md5sums=('SKIP')
22
23pkgver() {
24 cd ${srcdir}/${_gitname}
25 echo "$(git log -1 --format="%cd" --date=short | tr -d '-').$(git log -1 --format="%h")"
26}
27
28prepare() {
29 mkdir -p build
30}
31
32build() {
33 cd build
34 cmake ../${_gitname} \
35 -DCMAKE_INSTALL_PREFIX=/usr \
36 -DLIB_INSTALL_DIR=lib \
37 -DLIBEXEC_INSTALL_DIR=lib \
38 -DQML_INSTALL_DIR=lib/qt/qml \
39 -DKDE_INSTALL_USE_QT_SYS_PATHS=ON \
40 -DCMAKE_BUILD_TYPE=RelWithDebInfo
41 make
42}
43
44package() {
45 cd build
46 make DESTDIR="${pkgdir}" install
47}
diff --git a/.travis/bintray-wrapper.sh b/.travis/bintray-wrapper.sh
new file mode 100755
index 0000000..04c2ebd
--- /dev/null
+++ b/.travis/bintray-wrapper.sh
@@ -0,0 +1,42 @@
1#!/bin/bash
2#
3# This file is part of Liri.
4#
5# Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
6#
7# $BEGIN_LICENSE:BSD$
8#
9# You may use this file under the terms of the BSD license as follows:
10#
11# Redistribution and use in source and binary forms, with or without
12# modification, are permitted provided that the following conditions are met:
13# * Redistributions of source code must retain the above copyright
14# notice, this list of conditions and the following disclaimer.
15# * Redistributions in binary form must reproduce the above copyright
16# notice, this list of conditions and the following disclaimer in the
17# documentation and/or other materials provided with the distribution.
18# * Neither the name of the Hawaii Project nor the
19# names of its contributors may be used to endorse or promote products
20# derived from this software without specific prior written permission.
21#
22# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25# DISCLAIMED. IN NO EVENT SHALL Pier Luigi Fiorini BE LIABLE FOR ANY
26# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32#
33# $END_LICENSE$
34#
35
36if [ "$CC" = "gcc" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then
37 if [ "$TRAVIS_BRANCH" = "develop" -o "$TRAVIS_BRANCH" = "master" ]; then
38 curl -s https://raw.githubusercontent.com/lirios/repotools/${TRAVIS_BRANCH}/travis/bintray.sh > .travis/bintray.sh
39 chmod 755 .travis/bintray.sh
40 exec ./.travis/bintray.sh
41 fi
42fi
diff --git a/.travis/bintray.json.in b/.travis/bintray.json.in
new file mode 100644
index 0000000..690b379
--- /dev/null
+++ b/.travis/bintray.json.in
@@ -0,0 +1,29 @@
1{
2 "package": {
3 "name": "fluid",
4 "repo": "archlinux-@GITBRANCH@",
5 "subject": "liri",
6 "desc": "A collection of cross-platform QtQuick components for building fluid and dynamic applications",
7 "website_url": "http://liri.io",
8 "issue_tracker_url": "https://github.com/lirios/fluid",
9 "vcs_url": "https://github.com/lirios/fluid",
10 "licenses": ["MPL-2.0"],
11 "labels": ["qt", "qml", "quick", "controls", "material"]
12 },
13 "version": {
14 "name": "@PKGVER@",
15 "desc": "Arch Linux build from CI",
16 "released": "@TODAY@",
17 "vcs_tag": "@GITREV@",
18 "attributes": [
19 {"name": "gitrevision", "values": ["@GITREV@"], "type": "string"},
20 {"name": "gitdate", "values": ["@GITDATE@"], "type": "date"}
21 ],
22 "gpgSign": false
23 },
24 "files": [
25 {"includePattern": "cibuild/(fluid-git-.*.pkg.tar.xz)", "uploadPattern": "@ARCH@/$1", "matrixParams": {"override": 1}},
26 {"includePattern": "cibuild/(fluid.db.tar.gz)", "uploadPattern": "@ARCH@/fluid.db", "matrixParams": {"override": 1}}
27 ],
28 "publish": true
29}
diff --git a/AUTHORS.md b/AUTHORS.md
new file mode 100644
index 0000000..77aee46
--- /dev/null
+++ b/AUTHORS.md
@@ -0,0 +1,25 @@
1Fluid
2=====
3
4# Authors
5
6 * Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
7 * Michael Spencer <sonrisesoftware@gmail.com>
8
9This is the list of contributors to this code base.
10
11Names are sorted by number of commits at the time of this writing.
12Commit data has been generated with:
13
14```sh
15git shortlog -s -e -n
16```
17
18Commit counts have been removed, since they change pretty frequently.
19
20Remember to update this file before any release is made, also make sure
21a .mailmap file is maintained if committer names and email addresses
22change over time.
23
24 * Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
25 * Michael Spencer <sonrisesoftware@gmail.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..3411262
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,84 @@
1project(Fluid)
2
3cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
4cmake_policy(VERSION 3.4.1)
5
6# Instruct CMake to run moc and rrc automatically when needed
7set(CMAKE_AUTOMOC ON)
8set(CMAKE_AUTORCC ON)
9
10# Apple-specific configuration
11set(APPLE_SUPPRESS_X11_WARNING ON)
12
13# Set version
14set(PROJECT_VERSION "0.9.0")
15set(PROJECT_VERSION_MAJOR 0)
16set(PROJECT_SOVERSION 0)
17
18# Set up packaging
19if(NOT USE_SUPERBUILD)
20 set(CPACK_PACKAGE_NAME "fluid")
21 set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
22 set(CPACK_GENERATOR "TGZ")
23 set(CPACK_SET_DESTDIR FALSE)
24 set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
25 set(CPACK_SOURCE_IGNORE_FILES "/build/;/.git;/.tx/;~$;${CPACK_SOURCE_IGNORE_FILES}")
26 include(CPack)
27 add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source)
28endif()
29
30# ECM
31find_package(ECM 1.7.0 REQUIRED NO_MODULE)
32list(APPEND CMAKE_MODULE_PATH
33 "${ECM_MODULE_PATH}"
34 "${ECM_KDE_MODULE_DIR}"
35)
36
37# Macros
38include(FeatureSummary)
39include(KDEInstallDirs)
40include(KDECompilerSettings)
41include(KDECMakeSettings)
42
43# Build flags
44set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -fvisibility-inlines-hidden -Werror -Wall -Wextra -Wformat -Wswitch-default -Wunused-parameter -pedantic -std=c++11")
45
46# Assume release build by default
47if(NOT CMAKE_BUILD_TYPE)
48 set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "" FORCE)
49endif()
50
51# Find Qt5
52set(REQUIRED_QT_VERSION "5.7.0")
53find_package(Qt5 ${REQUIRED_QT_VERSION} CONFIG REQUIRED COMPONENTS
54 Svg Gui Qml Quick QuickTest QuickControls2)
55
56# Find QT_INSTALL_DOCS
57get_target_property(QMAKE_EXECUTABLE Qt5::qmake LOCATION)
58if(NOT QT_INSTALL_DOCS)
59 exec_program(${QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_DOCS" RETURN_VALUE return_code OUTPUT_VARIABLE QT_INSTALL_DOCS)
60endif()
61
62# Documentation target
63find_program(QDOC_EXECUTABLE qdoc-qt5 qdoc)
64add_custom_target(docs
65 COMMAND QT_INSTALL_DOCS=${QT_INSTALL_DOCS} QT_VERSION_TAG=5.7 FLUID_VERSION=${PROJECT_VERSION} FLUID_VERSION_TAG=1.0 FLUID_BUILD_DIR=${CMAKE_CURRENT_BINARY_DIR} ${QDOC_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/doc/fluid.qdocconf)
66
67# Subdirectories
68add_subdirectory(controls)
69add_subdirectory(core)
70add_subdirectory(demo)
71add_subdirectory(effects)
72add_subdirectory(src)
73add_subdirectory(tests)
74add_subdirectory(material)
75
76# Install icons
77if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/icons")
78 install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/icons"
79 DESTINATION ${QML_INSTALL_DIR}/Fluid/Controls
80 PATTERN "icons/icons.qrc" EXCLUDE)
81endif()
82
83# Display feature summary
84feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
diff --git a/LICENSE.MPL2 b/LICENSE.MPL2
new file mode 100644
index 0000000..14e2f77
--- /dev/null
+++ b/LICENSE.MPL2
@@ -0,0 +1,373 @@
1Mozilla Public License Version 2.0
2==================================
3
41. Definitions
5--------------
6
71.1. "Contributor"
8 means each individual or legal entity that creates, contributes to
9 the creation of, or owns Covered Software.
10
111.2. "Contributor Version"
12 means the combination of the Contributions of others (if any) used
13 by a Contributor and that particular Contributor's Contribution.
14
151.3. "Contribution"
16 means Covered Software of a particular Contributor.
17
181.4. "Covered Software"
19 means Source Code Form to which the initial Contributor has attached
20 the notice in Exhibit A, the Executable Form of such Source Code
21 Form, and Modifications of such Source Code Form, in each case
22 including portions thereof.
23
241.5. "Incompatible With Secondary Licenses"
25 means
26
27 (a) that the initial Contributor has attached the notice described
28 in Exhibit B to the Covered Software; or
29
30 (b) that the Covered Software was made available under the terms of
31 version 1.1 or earlier of the License, but not also under the
32 terms of a Secondary License.
33
341.6. "Executable Form"
35 means any form of the work other than Source Code Form.
36
371.7. "Larger Work"
38 means a work that combines Covered Software with other material, in
39 a separate file or files, that is not Covered Software.
40
411.8. "License"
42 means this document.
43
441.9. "Licensable"
45 means having the right to grant, to the maximum extent possible,
46 whether at the time of the initial grant or subsequently, any and
47 all of the rights conveyed by this License.
48
491.10. "Modifications"
50 means any of the following:
51
52 (a) any file in Source Code Form that results from an addition to,
53 deletion from, or modification of the contents of Covered
54 Software; or
55
56 (b) any new file in Source Code Form that contains any Covered
57 Software.
58
591.11. "Patent Claims" of a Contributor
60 means any patent claim(s), including without limitation, method,
61 process, and apparatus claims, in any patent Licensable by such
62 Contributor that would be infringed, but for the grant of the
63 License, by the making, using, selling, offering for sale, having
64 made, import, or transfer of either its Contributions or its
65 Contributor Version.
66
671.12. "Secondary License"
68 means either the GNU General Public License, Version 2.0, the GNU
69 Lesser General Public License, Version 2.1, the GNU Affero General
70 Public License, Version 3.0, or any later versions of those
71 licenses.
72
731.13. "Source Code Form"
74 means the form of the work preferred for making modifications.
75
761.14. "You" (or "Your")
77 means an individual or a legal entity exercising rights under this
78 License. For legal entities, "You" includes any entity that
79 controls, is controlled by, or is under common control with You. For
80 purposes of this definition, "control" means (a) the power, direct
81 or indirect, to cause the direction or management of such entity,
82 whether by contract or otherwise, or (b) ownership of more than
83 fifty percent (50%) of the outstanding shares or beneficial
84 ownership of such entity.
85
862. License Grants and Conditions
87--------------------------------
88
892.1. Grants
90
91Each Contributor hereby grants You a world-wide, royalty-free,
92non-exclusive license:
93
94(a) under intellectual property rights (other than patent or trademark)
95 Licensable by such Contributor to use, reproduce, make available,
96 modify, display, perform, distribute, and otherwise exploit its
97 Contributions, either on an unmodified basis, with Modifications, or
98 as part of a Larger Work; and
99
100(b) under Patent Claims of such Contributor to make, use, sell, offer
101 for sale, have made, import, and otherwise transfer either its
102 Contributions or its Contributor Version.
103
1042.2. Effective Date
105
106The licenses granted in Section 2.1 with respect to any Contribution
107become effective for each Contribution on the date the Contributor first
108distributes such Contribution.
109
1102.3. Limitations on Grant Scope
111
112The licenses granted in this Section 2 are the only rights granted under
113this License. No additional rights or licenses will be implied from the
114distribution or licensing of Covered Software under this License.
115Notwithstanding Section 2.1(b) above, no patent license is granted by a
116Contributor:
117
118(a) for any code that a Contributor has removed from Covered Software;
119 or
120
121(b) for infringements caused by: (i) Your and any other third party's
122 modifications of Covered Software, or (ii) the combination of its
123 Contributions with other software (except as part of its Contributor
124 Version); or
125
126(c) under Patent Claims infringed by Covered Software in the absence of
127 its Contributions.
128
129This License does not grant any rights in the trademarks, service marks,
130or logos of any Contributor (except as may be necessary to comply with
131the notice requirements in Section 3.4).
132
1332.4. Subsequent Licenses
134
135No Contributor makes additional grants as a result of Your choice to
136distribute the Covered Software under a subsequent version of this
137License (see Section 10.2) or under the terms of a Secondary License (if
138permitted under the terms of Section 3.3).
139
1402.5. Representation
141
142Each Contributor represents that the Contributor believes its
143Contributions are its original creation(s) or it has sufficient rights
144to grant the rights to its Contributions conveyed by this License.
145
1462.6. Fair Use
147
148This License is not intended to limit any rights You have under
149applicable copyright doctrines of fair use, fair dealing, or other
150equivalents.
151
1522.7. Conditions
153
154Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
155in Section 2.1.
156
1573. Responsibilities
158-------------------
159
1603.1. Distribution of Source Form
161
162All distribution of Covered Software in Source Code Form, including any
163Modifications that You create or to which You contribute, must be under
164the terms of this License. You must inform recipients that the Source
165Code Form of the Covered Software is governed by the terms of this
166License, and how they can obtain a copy of this License. You may not
167attempt to alter or restrict the recipients' rights in the Source Code
168Form.
169
1703.2. Distribution of Executable Form
171
172If You distribute Covered Software in Executable Form then:
173
174(a) such Covered Software must also be made available in Source Code
175 Form, as described in Section 3.1, and You must inform recipients of
176 the Executable Form how they can obtain a copy of such Source Code
177 Form by reasonable means in a timely manner, at a charge no more
178 than the cost of distribution to the recipient; and
179
180(b) You may distribute such Executable Form under the terms of this
181 License, or sublicense it under different terms, provided that the
182 license for the Executable Form does not attempt to limit or alter
183 the recipients' rights in the Source Code Form under this License.
184
1853.3. Distribution of a Larger Work
186
187You may create and distribute a Larger Work under terms of Your choice,
188provided that You also comply with the requirements of this License for
189the Covered Software. If the Larger Work is a combination of Covered
190Software with a work governed by one or more Secondary Licenses, and the
191Covered Software is not Incompatible With Secondary Licenses, this
192License permits You to additionally distribute such Covered Software
193under the terms of such Secondary License(s), so that the recipient of
194the Larger Work may, at their option, further distribute the Covered
195Software under the terms of either this License or such Secondary
196License(s).
197
1983.4. Notices
199
200You may not remove or alter the substance of any license notices
201(including copyright notices, patent notices, disclaimers of warranty,
202or limitations of liability) contained within the Source Code Form of
203the Covered Software, except that You may alter any license notices to
204the extent required to remedy known factual inaccuracies.
205
2063.5. Application of Additional Terms
207
208You may choose to offer, and to charge a fee for, warranty, support,
209indemnity or liability obligations to one or more recipients of Covered
210Software. However, You may do so only on Your own behalf, and not on
211behalf of any Contributor. You must make it absolutely clear that any
212such warranty, support, indemnity, or liability obligation is offered by
213You alone, and You hereby agree to indemnify every Contributor for any
214liability incurred by such Contributor as a result of warranty, support,
215indemnity or liability terms You offer. You may include additional
216disclaimers of warranty and limitations of liability specific to any
217jurisdiction.
218
2194. Inability to Comply Due to Statute or Regulation
220---------------------------------------------------
221
222If it is impossible for You to comply with any of the terms of this
223License with respect to some or all of the Covered Software due to
224statute, judicial order, or regulation then You must: (a) comply with
225the terms of this License to the maximum extent possible; and (b)
226describe the limitations and the code they affect. Such description must
227be placed in a text file included with all distributions of the Covered
228Software under this License. Except to the extent prohibited by statute
229or regulation, such description must be sufficiently detailed for a
230recipient of ordinary skill to be able to understand it.
231
2325. Termination
233--------------
234
2355.1. The rights granted under this License will terminate automatically
236if You fail to comply with any of its terms. However, if You become
237compliant, then the rights granted under this License from a particular
238Contributor are reinstated (a) provisionally, unless and until such
239Contributor explicitly and finally terminates Your grants, and (b) on an
240ongoing basis, if such Contributor fails to notify You of the
241non-compliance by some reasonable means prior to 60 days after You have
242come back into compliance. Moreover, Your grants from a particular
243Contributor are reinstated on an ongoing basis if such Contributor
244notifies You of the non-compliance by some reasonable means, this is the
245first time You have received notice of non-compliance with this License
246from such Contributor, and You become compliant prior to 30 days after
247Your receipt of the notice.
248
2495.2. If You initiate litigation against any entity by asserting a patent
250infringement claim (excluding declaratory judgment actions,
251counter-claims, and cross-claims) alleging that a Contributor Version
252directly or indirectly infringes any patent, then the rights granted to
253You by any and all Contributors for the Covered Software under Section
2542.1 of this License shall terminate.
255
2565.3. In the event of termination under Sections 5.1 or 5.2 above, all
257end user license agreements (excluding distributors and resellers) which
258have been validly granted by You or Your distributors under this License
259prior to termination shall survive termination.
260
261************************************************************************
262* *
263* 6. Disclaimer of Warranty *
264* ------------------------- *
265* *
266* Covered Software is provided under this License on an "as is" *
267* basis, without warranty of any kind, either expressed, implied, or *
268* statutory, including, without limitation, warranties that the *
269* Covered Software is free of defects, merchantable, fit for a *
270* particular purpose or non-infringing. The entire risk as to the *
271* quality and performance of the Covered Software is with You. *
272* Should any Covered Software prove defective in any respect, You *
273* (not any Contributor) assume the cost of any necessary servicing, *
274* repair, or correction. This disclaimer of warranty constitutes an *
275* essential part of this License. No use of any Covered Software is *
276* authorized under this License except under this disclaimer. *
277* *
278************************************************************************
279
280************************************************************************
281* *
282* 7. Limitation of Liability *
283* -------------------------- *
284* *
285* Under no circumstances and under no legal theory, whether tort *
286* (including negligence), contract, or otherwise, shall any *
287* Contributor, or anyone who distributes Covered Software as *
288* permitted above, be liable to You for any direct, indirect, *
289* special, incidental, or consequential damages of any character *
290* including, without limitation, damages for lost profits, loss of *
291* goodwill, work stoppage, computer failure or malfunction, or any *
292* and all other commercial damages or losses, even if such party *
293* shall have been informed of the possibility of such damages. This *
294* limitation of liability shall not apply to liability for death or *
295* personal injury resulting from such party's negligence to the *
296* extent applicable law prohibits such limitation. Some *
297* jurisdictions do not allow the exclusion or limitation of *
298* incidental or consequential damages, so this exclusion and *
299* limitation may not apply to You. *
300* *
301************************************************************************
302
3038. Litigation
304-------------
305
306Any litigation relating to this License may be brought only in the
307courts of a jurisdiction where the defendant maintains its principal
308place of business and such litigation shall be governed by laws of that
309jurisdiction, without reference to its conflict-of-law provisions.
310Nothing in this Section shall prevent a party's ability to bring
311cross-claims or counter-claims.
312
3139. Miscellaneous
314----------------
315
316This License represents the complete agreement concerning the subject
317matter hereof. If any provision of this License is held to be
318unenforceable, such provision shall be reformed only to the extent
319necessary to make it enforceable. Any law or regulation which provides
320that the language of a contract shall be construed against the drafter
321shall not be used to construe this License against a Contributor.
322
32310. Versions of the License
324---------------------------
325
32610.1. New Versions
327
328Mozilla Foundation is the license steward. Except as provided in Section
32910.3, no one other than the license steward has the right to modify or
330publish new versions of this License. Each version will be given a
331distinguishing version number.
332
33310.2. Effect of New Versions
334
335You may distribute the Covered Software under the terms of the version
336of the License under which You originally received the Covered Software,
337or under the terms of any subsequent version published by the license
338steward.
339
34010.3. Modified Versions
341
342If you create software not governed by this License, and you want to
343create a new license for such software, you may create and use a
344modified version of this License if you rename the license and remove
345any references to the name of the license steward (except to note that
346such modified license differs from this License).
347
34810.4. Distributing Source Code Form that is Incompatible With Secondary
349Licenses
350
351If You choose to distribute Source Code Form that is Incompatible With
352Secondary Licenses under the terms of this version of the License, the
353notice described in Exhibit B of this License must be attached.
354
355Exhibit A - Source Code Form License Notice
356-------------------------------------------
357
358 This Source Code Form is subject to the terms of the Mozilla Public
359 License, v. 2.0. If a copy of the MPL was not distributed with this
360 file, You can obtain one at http://mozilla.org/MPL/2.0/.
361
362If it is not possible or desirable to put the notice in a particular
363file, then You may include the notice in a location (such as a LICENSE
364file in a relevant directory) where a recipient would be likely to look
365for such a notice.
366
367You may add additional accurate notices of copyright ownership.
368
369Exhibit B - "Incompatible With Secondary Licenses" Notice
370---------------------------------------------------------
371
372 This Source Code Form is "Incompatible With Secondary Licenses", as
373 defined by the Mozilla Public License, v. 2.0.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..70d04ba
--- /dev/null
+++ b/README.md
@@ -0,0 +1,77 @@
1Fluid
2=====
3
4[![ZenHub.io](https://img.shields.io/badge/supercharged%20by-zenhub.io-blue.svg)](https://zenhub.io)
5
6[![License](https://img.shields.io/badge/license-MPL2-blue.svg)](https://www.mozilla.org/en-US/MPL/2.0/)
7[![GitHub release](https://img.shields.io/github/release/lirios/fluid.svg)](https://github.com/lirios/fluid)
8[![Build Status](https://travis-ci.org/lirios/fluid.svg?branch=develop)](https://travis-ci.org/lirios/fluid)
9[![GitHub issues](https://img.shields.io/github/issues/lirios/fluid.svg)](https://github.com/lirios/fluid/issues)
10[![Maintained](https://img.shields.io/maintenance/yes/2017.svg)](https://github.com/lirios/fluid/commits/develop)
11
12Fluid is a collection of cross-platform QtQuick components for building fluid and dynamic applications.
13
14## Dependencies
15
16Qt >= 5.7.0 with at least the following modules is required:
17
18 * [qtbase](http://code.qt.io/cgit/qt/qtbase.git)
19 * [qtdeclarative](http://code.qt.io/cgit/qt/qtdeclarative.git)
20 * [qtquickcontrols2](http://code.qt.io/cgit/qt/qtquickcontrols2.git)
21 * [qtgraphicaleffects](http://code.qt.io/cgit/qt/qtgraphicaleffects.git)
22 * [qtsvg](http://code.qt.io/cgit/qt/qtsvg.git)
23
24## System-wide installation
25
26First, if you want to include the Material Design icons used with the `Icon` component, run:
27
28```sh
29./scripts/fetch_icons.sh
30```
31
32This will clone the Google repository holding the icons and copy the SVG icons into the `icons` directory.
33
34From the root of the repository, run:
35
36```sh
37mkdir build; cd build
38cmake .. -DKDE_INSTALL_USE_QT_SYS_PATHS=ON
39make
40make install # use sudo if necessary
41```
42
43On the `cmake` line, you can specify additional configuration parameters:
44
45 * `-DCMAKE_INSTALL_PREFIX=/path/to/install` (for example, `/opt/liri` or `/usr`)
46 * `-DCMAKE_BUILD_TYPE=<build_type>`, where `<build_type>` is one of:
47 * **Debug:** debug build
48 * **Release:** release build
49 * **RelWithDebInfo:** release build with debugging information
50
51## Per-project installation using QMake
52
53First, clone this repository.
54
55Run the icon script located here:
56
57```sh
58./scripts/fetch_icons.sh
59```
60
61In your project file, include the fluid.pri file:
62 `include(path/to/fluid.pri)`
63
64Then, in your `main.cpp` file or wherever you set up a `QQmlApplicationEngine`:
65* add this include directive :
66`#include "iconthemeimageprovider.h"`
67* add the resources files to your `QQmlApplicationEngine` import paths :
68`engine.addImportPath(QStringLiteral("qrc:/"));`
69* register fluid's image providers to the engine :
70`engine.addImageProvider(QLatin1String("fluidicons"), new IconsImageProvider());`
71`engine.addImageProvider(QLatin1String("fluidicontheme"), new IconThemeImageProvider());`
72* and after that you can load your qml file:
73`engine.load(QUrl(QStringLiteral("qrc:/main.qml")));`
74
75## Licensing
76
77Licensed under the terms of the Mozilla Public License version 2.0.
diff --git a/controls/+material/BaseListItem.qml b/controls/+material/BaseListItem.qml
new file mode 100644
index 0000000..2a956bc
--- /dev/null
+++ b/controls/+material/BaseListItem.qml
@@ -0,0 +1,45 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.4
16import QtQuick.Controls 2.0
17import Fluid.Material 1.0
18
19ListItemDelegate {
20 id: listItem
21
22 background: Rectangle {
23 color: listItem.highlighted ? Qt.rgba(0,0,0,0.05)
24 : ripple.containsMouse ? Qt.rgba(0,0,0,0.03)
25 : Qt.rgba(0,0,0,0)
26
27 Ripple {
28 id: ripple
29 width: parent.width
30 height: parent.height
31 enabled: interactive
32
33 control: listItem
34 }
35
36 ThinDivider {
37 x: dividerInset
38 y: parent.height - height
39
40 width: parent.width - x
41
42 visible: showDivider
43 }
44 }
45}
diff --git a/controls/+material/BodyLabel.qml b/controls/+material/BodyLabel.qml
new file mode 100644
index 0000000..9445a1e
--- /dev/null
+++ b/controls/+material/BodyLabel.qml
@@ -0,0 +1,30 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.4
16import QtQuick.Controls 2.0
17import Fluid.Core 1.0
18
19Label {
20 property int level: 1
21
22 font.pixelSize: Device.isMobile ? 14 : 13
23 font.weight: level == 1 ? Font.Normal : Font.Medium
24 lineHeight: level <= 1 ? 20.0 : 24.0
25 lineHeightMode: Text.FixedHeight
26 onLevelChanged: {
27 if (level < 1 || level > 2)
28 console.error("BodyLabel level must be either 1 or 2")
29 }
30}
diff --git a/controls/+material/CaptionLabel.qml b/controls/+material/CaptionLabel.qml
new file mode 100644
index 0000000..66d5638
--- /dev/null
+++ b/controls/+material/CaptionLabel.qml
@@ -0,0 +1,20 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.4
16import QtQuick.Controls 2.0
17
18Label {
19 font.pixelSize: 12
20}
diff --git a/controls/+material/DialogLabel.qml b/controls/+material/DialogLabel.qml
new file mode 100644
index 0000000..4230d4c
--- /dev/null
+++ b/controls/+material/DialogLabel.qml
@@ -0,0 +1,23 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls 2.0
17import QtQuick.Controls.Material 2.0
18import Fluid.Core 1.0 as FluidCore
19
20Label {
21 font.pixelSize: FluidCore.Device.isMobile ? 18 : 17
22 color: Material.secondaryTextColor
23}
diff --git a/controls/+material/DisplayLabel.qml b/controls/+material/DisplayLabel.qml
new file mode 100644
index 0000000..67b9e4b
--- /dev/null
+++ b/controls/+material/DisplayLabel.qml
@@ -0,0 +1,48 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.4
16import QtQuick.Controls 2.0
17import Fluid.Core 1.0
18
19Label {
20 property int level: 1
21
22 font.pixelSize: {
23 if (level <= 1)
24 return 34
25 else if (level == 2)
26 return 45
27 else if (level == 3)
28 return 56
29 return 112
30 }
31 lineHeight: {
32 if (level <= 1)
33 return 40.0
34 else if (level == 2)
35 return 48.0
36 return 1.0
37 }
38 lineHeightMode: {
39 if (level <= 2)
40 return Text.FixedHeight
41 return Text.ProportionalHeight
42 }
43 font.weight: level >= 4 ? Font.Light : Font.Normal
44 onLevelChanged: {
45 if (level < 1 || level > 4)
46 console.error("DisplayLabel level must be between 1 and 4")
47 }
48}
diff --git a/controls/+material/HeadlineLabel.qml b/controls/+material/HeadlineLabel.qml
new file mode 100644
index 0000000..b001aa9
--- /dev/null
+++ b/controls/+material/HeadlineLabel.qml
@@ -0,0 +1,22 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.4
16import QtQuick.Controls 2.0
17
18Label {
19 font.pixelSize: 24
20 lineHeight: 32.0
21 lineHeightMode: Text.FixedHeight
22}
diff --git a/controls/+material/SubheadingLabel.qml b/controls/+material/SubheadingLabel.qml
new file mode 100644
index 0000000..d7f23bf
--- /dev/null
+++ b/controls/+material/SubheadingLabel.qml
@@ -0,0 +1,29 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.4
16import QtQuick.Controls 2.0
17import Fluid.Core 1.0
18
19Label {
20 property int level: 1
21
22 font.pixelSize: Device.isMobile ? 16 : 15
23 lineHeight: level <= 1 ? 24.0 : 28.0
24 lineHeightMode: Text.FixedHeight
25 onLevelChanged: {
26 if (level < 1 || level > 2)
27 console.error("SubheadingLabel level must be either 1 or 2 with the Material style")
28 }
29}
diff --git a/controls/+material/ThinDivider.qml b/controls/+material/ThinDivider.qml
new file mode 100644
index 0000000..0b69ef5
--- /dev/null
+++ b/controls/+material/ThinDivider.qml
@@ -0,0 +1,22 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.4
16import QtQuick.Controls.Material 2.0
17
18Rectangle {
19 color: Material.dividerColor
20 width: parent.width
21 height: 1
22}
diff --git a/controls/+material/TitleLabel.qml b/controls/+material/TitleLabel.qml
new file mode 100644
index 0000000..486abff
--- /dev/null
+++ b/controls/+material/TitleLabel.qml
@@ -0,0 +1,21 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.4
16import QtQuick.Controls 2.0
17
18Label {
19 font.pixelSize: 20
20 font.weight: Font.Medium
21}
diff --git a/controls/Action.qml b/controls/Action.qml
new file mode 100644
index 0000000..582b945
--- /dev/null
+++ b/controls/Action.qml
@@ -0,0 +1,79 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
6 *
7 * $BEGIN_LICENSE:MPL2$
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
13 * $END_LICENSE$
14 */
15
16import QtQuick 2.5
17import Fluid.Core 1.0
18
19/*!
20 \qmltype Action
21 \inqmlmodule Fluid.Controls
22 \ingroup fluidcontrols
23
24 \brief Represents an action shown in an action bar, context menu, or list.
25
26 One of the most common uses of actions is displaying actions in the action bar of a page
27 using the \l Page::actions property. See the example for \l Page for more details.
28 */
29Object {
30 id: action
31
32 /*!
33 Set to \c false to disable the action in the UI.
34 */
35 property bool enabled: true
36
37 property string iconName
38
39 /*!
40 A URL pointing to an image to display as the icon. By default, this is
41 a special URL representing the icon named by \l iconName from the Material Design
42 icon collection or FontAwesome. The icon will be colorized using the specificed \l color,
43 unless you put ".color." in the filename, for example, "app-icon.color.svg".
44
45 \sa iconName
46 \sa Icon
47 */
48 property url iconSource: Utils.getSourceForIconName(iconName)
49
50 /*!
51 \qmlproperty keysequence shortcut
52
53 This property holds the shortcut bound to the action.
54 The keysequence can be a string or a standard key.
55 */
56 property alias shortcut: shortcutItem.sequence
57
58 /*!
59 The text displayed for the action.
60 */
61 property string text
62
63 /*!
64 The tooltip displayed for the action.
65 */
66 property string tooltip
67
68 /*!
69 Set to \c false to hide the action in the UI.
70 */
71 property bool visible: true
72
73 signal triggered(var source)
74
75 Shortcut {
76 id: shortcutItem
77 onActivated: action.triggered(shortcutItem)
78 }
79}
diff --git a/controls/AppBar.qml b/controls/AppBar.qml
new file mode 100644
index 0000000..822b258
--- /dev/null
+++ b/controls/AppBar.qml
@@ -0,0 +1,194 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls 2.0
17import QtQuick.Controls.Material 2.0
18import QtQuick.Layouts 1.0
19import Fluid.Core 1.0
20import Fluid.Controls 1.0
21import Fluid.Material 1.0 as FluidMaterial
22
23/*!
24 \qmltype AppBar
25 \inqmlmodule Fluid.Controls
26 \ingroup fluidcontrols
27
28 \brief Application tool bar.
29 */
30ToolBar {
31 id: appBar
32
33 Material.elevation: toolbar && !tabBar.visible ? 0 : elevation
34 Material.theme: toolbar ? toolbar.Material.theme : Material.Light
35
36 /*!
37 The back action to display to the left of the title in the action bar.
38 When used with a page, this will pick up the page's back action, which
39 by default is a back arrow when there is a page behind the current page
40 on the page stack. However, you can customize this, for example, to show
41 a navigation drawer at the root of your app.
42
43 When using an action bar in a page, set the \l Page::backAction instead of
44 directly setting this property.
45 */
46 property Action leftAction
47
48 /*!
49 A list of actions to show in the action bar. These actions will be shown
50 anchored to the right, and will overflow if there are more than the
51 maximum number of actions as defined in \l maxActionCount.
52
53 When used with a page, the actions will be set to the page's \l Page::actions
54 property, so set that instead of changing this directly.
55 */
56 property list<Action> actions
57
58 /*!
59 The elevation of the action bar. Set to 0 if you want have a header or some
60 other view below the action bar that you want to appear as part of the action bar.
61 */
62 property int elevation: 2
63
64 /*!
65 \internal
66 The size of the left icon and the action icons.
67 */
68 property int iconSize: Device.gridUnit <= 48 ? 20 : 24
69
70 property alias leftKeyline: titleLabel.x
71
72 /*!
73 The maximum number of actions that can be displayed before they spill over
74 into a drop-down menu. When using an action bar with a page, this inherits
75 from the global \l Toolbar::maxActionCount. If you are using an action bar
76 for custom purposes outside of a toolbar, this defaults to \c 3.
77 */
78 property int maxActionCount: toolbar ? toolbar.maxActionCount : 3
79
80 /*!
81 The title displayed in the action bar. When used in a page, the title will
82 be set to the title of the page, so set the \l Page::title property instead
83 of changing this directly.
84 */
85 property alias title: titleLabel.text
86
87 property alias tabs: tabBar.contentData
88
89 property alias currentTabIndex: tabBar.currentIndex
90
91 property AppToolBar toolbar
92
93 implicitHeight: background.implicitHeight
94
95 background: Rectangle {
96 color: appBar.Material.toolBarColor
97 height: implicitHeight
98 implicitHeight: Device.gridUnit + (tabBar.visible ? tabBar.implicitHeight : 0)
99
100 layer.enabled: appBar.Material.elevation > 0
101 layer.effect: FluidMaterial.ElevationEffect {
102 elevation: appBar.Material.elevation
103 fullWidth: true
104 }
105
106 ColumnLayout {
107 anchors.fill: parent
108 spacing: 0
109
110 RowLayout {
111 spacing: 0
112
113 Layout.preferredHeight: Device.gridUnit
114 Layout.fillWidth: true
115
116 IconButton {
117 id: leftButton
118
119 property bool showing: leftAction && leftAction.visible
120 property int margin: (width - 24)/2
121
122 Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
123 Layout.leftMargin: leftButton.showing ? 16 - leftButton.margin : -leftButton.width
124
125 iconSize: appBar.iconSize
126
127 iconSource: leftAction ? leftAction.iconSource : ""
128 visible: leftAction && leftAction.visible
129 enabled: leftAction && leftAction.enabled
130 onClicked: {
131 if (leftAction)
132 leftAction.triggered(leftButton)
133 }
134 }
135
136 TitleLabel {
137 id: titleLabel
138
139 Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
140 Layout.leftMargin: 16 + (leftButton.showing ? Device.gridUnit - leftButton.margin : 0)
141 Layout.rightMargin: 16
142
143 textFormat: Text.PlainText
144 color: Material.primaryTextColor
145 elide: Text.ElideRight
146 }
147
148 Item {
149 Layout.fillWidth: true
150 }
151
152 Row {
153 id: actionsRow
154
155 Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
156 Layout.rightMargin: 16 - leftButton.margin
157 Layout.preferredHeight: Device.gridUnit
158
159 spacing: 24 - 2 * leftButton.margin
160
161 Repeater {
162 model: appBar.actions
163 delegate: IconButton {
164 id: actionButton
165
166 anchors.verticalCenter: parent.verticalCenter
167
168 iconSize: appBar.iconSize
169
170 iconSource: modelData.iconSource
171 visible: modelData.visible
172 enabled: modelData.enabled
173 onClicked: modelData.triggered(actionButton)
174 }
175 }
176 }
177 }
178
179 TabBar {
180 id: tabBar
181
182 property bool fixed: true
183 property bool centered: false
184
185 Material.accent: appBar.Material.foreground
186
187 Layout.alignment: centered ? Qt.AlignHCenter : Qt.AlignLeft
188 Layout.leftMargin: centered ? 0 : leftKeyline - 12
189
190 visible: count > 0
191 }
192 }
193 }
194}
diff --git a/controls/AppToolBar.qml b/controls/AppToolBar.qml
new file mode 100644
index 0000000..1f81816
--- /dev/null
+++ b/controls/AppToolBar.qml
@@ -0,0 +1,62 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls 2.0
17import QtQuick.Controls.Material 2.0
18import Fluid.Core 1.0
19
20/*!
21 \qmltype AppToolBar
22 \inqmlmodule Fluid.Controls
23 \ingroup fluidcontrols
24
25 \brief Application tool bar.
26 */
27ToolBar {
28 id: toolbar
29
30 Material.elevation: page ? page.appBar.elevation : 2
31 Material.background: Material.primaryColor
32 Material.theme: Utils.lightDark(Material.background, Material.Light, Material.Dark)
33
34 property Page page
35 property int maxActionCount: 3
36
37 function pop(page) {
38 stack.pop(page.appBar)
39
40 toolbar.page = page
41 }
42
43 function push(page) {
44 stack.push(page.appBar)
45
46 page.appBar.toolbar = toolbar
47 toolbar.page = page
48 }
49
50 function replace(page) {
51 toolbar.page = page
52
53 stack.replace(page.appBar)
54 }
55
56 StackView {
57 id: stack
58
59 width: parent.width
60 height: parent.height
61 }
62}
diff --git a/controls/BaseListItem.qml b/controls/BaseListItem.qml
new file mode 100644
index 0000000..3a4d989
--- /dev/null
+++ b/controls/BaseListItem.qml
@@ -0,0 +1,43 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.4
16import QtQuick.Controls 2.0
17
18/*!
19 \qmltype BaseListItem
20 \inqmlmodule Fluid.Controls
21 \ingroup fluidcontrols
22
23 \brief The base class for list items.
24
25 Provides ripple effects, mouse/touch handling and tinting on mouse hover.
26 */
27ListItemDelegate {
28 id: listItem
29
30 background: Rectangle {
31 color: listItem.interactive && (listItem.highlighted || listItem.down)
32 ? Qt.rgba(0,0,0,0.05) : Qt.rgba(0,0,0,0)
33
34 ThinDivider {
35 x: dividerInset
36 y: parent.height - height
37
38 width: parent.width - x
39
40 visible: showDivider
41 }
42 }
43}
diff --git a/controls/BodyLabel.qml b/controls/BodyLabel.qml
new file mode 100644
index 0000000..ff63cec
--- /dev/null
+++ b/controls/BodyLabel.qml
@@ -0,0 +1,51 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Templates 2.0 as T
17
18/*!
19 \qmltype BodyLabel
20 \inqmlmodule Fluid.Controls
21 \ingroup fluidcontrols
22
23 \brief Text label with standard font and styling suitable to body text.
24
25 \code
26 BodyLabel {
27 text: qsTr("Body text")
28 }
29 \endcode
30*/
31T.Label {
32 /*!
33 \qmlproperty int level
34
35 This property holds the label level that controls
36 font style and size.
37
38 It can be either 1 or 2.
39
40 Default value is 1.
41 */
42 property int level: 1
43
44 font.pixelSize: 14
45 color: "#26282a"
46 linkColor: "#45a7d7"
47 onLevelChanged: {
48 if (level < 1 || level > 2)
49 console.error("BodyLabel level must be either 1 or 2")
50 }
51}
diff --git a/controls/CMakeLists.txt b/controls/CMakeLists.txt
new file mode 100644
index 0000000..0c190ab
--- /dev/null
+++ b/controls/CMakeLists.txt
@@ -0,0 +1,67 @@
1set(SOURCES
2 iconthemeimageprovider.cpp
3 plugin.cpp
4)
5
6set(QML_FILES
7 plugins.qmltypes
8 qmldir
9 Action.qml
10 AppBar.qml
11 AppToolBar.qml
12 BaseListItem.qml
13 BodyLabel.qml
14 CaptionLabel.qml
15 Card.qml
16 CircleImage.qml
17 Dialog.qml
18 DialogLabel.qml
19 DisplayLabel.qml
20 FluidStyle.qml
21 FluidWindow.qml
22 HeadlineLabel.qml
23 IconButton.qml
24 Icon.qml
25 InfoBar.qml
26 ListItemDelegate.qml
27 ListItem.qml
28 Loadable.qml
29 NavigationDrawer.qml
30 NoiseBackground.qml
31 Page.qml
32 PageStack.qml
33 Placeholder.qml
34 Showable.qml
35 Sidebar.qml
36 SmoothFadeImage.qml
37 SmoothFadeLoader.qml
38 Subheader.qml
39 SubheadingLabel.qml
40 Tab.qml
41 TabbedPage.qml
42 ThinDivider.qml
43 TitleLabel.qml
44 Units.qml
45)
46
47set(MATERIAL_FILES
48 +material/BaseListItem.qml
49 +material/BodyLabel.qml
50 +material/CaptionLabel.qml
51 +material/DialogLabel.qml
52 +material/DisplayLabel.qml
53 +material/HeadlineLabel.qml
54 +material/SubheadingLabel.qml
55 +material/ThinDivider.qml
56 +material/TitleLabel.qml
57)
58
59add_library(fluidcontrols SHARED ${SOURCES} ${QML_FILES} ${MATERIAL_FILES})
60target_link_libraries(fluidcontrols Qt5::Gui Qt5::Quick)
61
62install(TARGETS fluidcontrols LIBRARY
63 DESTINATION ${QML_INSTALL_DIR}/Fluid/Controls)
64install(FILES ${QML_FILES}
65 DESTINATION ${QML_INSTALL_DIR}/Fluid/Controls)
66install(FILES ${MATERIAL_FILES}
67 DESTINATION ${QML_INSTALL_DIR}/Fluid/Controls/+material)
diff --git a/controls/CaptionLabel.qml b/controls/CaptionLabel.qml
new file mode 100644
index 0000000..b62f1c2
--- /dev/null
+++ b/controls/CaptionLabel.qml
@@ -0,0 +1,35 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Templates 2.0 as T
17
18/*!
19 \qmltype CaptionLabel
20 \inqmlmodule Fluid.Controls
21 \ingroup fluidcontrols
22
23 \brief Text label with standard font and styling suitable to captions.
24
25 \code
26 Caption {
27 text: qsTr("A translatable caption")
28 }
29 \endcode
30*/
31T.Label {
32 font.pixelSize: 10
33 color: "#26282a"
34 linkColor: "#45a7d7"
35}
diff --git a/controls/Card.qml b/controls/Card.qml
new file mode 100644
index 0000000..4b4f666
--- /dev/null
+++ b/controls/Card.qml
@@ -0,0 +1,88 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick.Controls 2.0 as C
16import QtQuick.Controls.Material 2.0
17
18/*!
19 \qmltype Card
20 \inqmlmodule Fluid.Controls
21 \ingroup fluidcontrols
22
23 \brief Cards display content composed of different elements.
24
25 \code
26 Card {
27 anchors.centerIn: parent
28 width: 400
29 height: 400
30
31 Image {
32 id: picture
33 anchors {
34 left: parent.left
35 top: parent.top
36 right: parent.right
37 }
38 height: 200
39 source: "Yosemite.jpg"
40 }
41
42 Column {
43 id: column
44 anchors {
45 left: parent.left
46 top: picture.bottom
47 right: parent.right
48 margins: Units.smallSpacing * 2
49 }
50 spacing: Units.smallSpacing * 2
51
52 TitleLabel {
53 text: qsTr("Yosemite National Park")
54 }
55
56 BodyLabel {
57 text: qsTr("First protected in 1864, Yosemite National Park " +
58 "is best known for its waterfalls, but within its " +
59 "nearly 1,200 square miles, you can find deep " +
60 "valleys, grand meadows, ancient giant sequoias, " +
61 "a vast wilderness area, and much more.")
62 wrapMode: Text.WordWrap
63 width: parent.width
64 }
65
66 Row {
67 spacing: Units.smallSpacing
68
69 Button {
70 text: qsTr("Share")
71 flat: true
72 }
73
74 Button {
75 text: qsTr("Explore")
76 flat: true
77 }
78 }
79 }
80 }
81 \endcode
82*/
83C.Pane {
84 padding: 0
85
86 Material.background: "white"
87 Material.elevation: 1
88}
diff --git a/controls/CircleImage.qml b/controls/CircleImage.qml
new file mode 100644
index 0000000..c846109
--- /dev/null
+++ b/controls/CircleImage.qml
@@ -0,0 +1,49 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.4
16import QtGraphicalEffects 1.0
17import Fluid.Effects 1.0
18
19/*!
20 \qmltype CircleImage
21 \inqmlmodule Fluid.Controls
22 \ingroup fluidcontrols
23
24 \brief Circular image.
25*/
26Item {
27 id: item
28
29 property alias source: image.source
30 property alias status: image.status
31 property alias sourceSize: image.sourceSize
32 property alias asynchronous: image.asynchronous
33 property alias cache: image.cache
34 property alias fillMode: image.fillMode
35
36 width: image.implicitWidth
37 height: image.implicitHeight
38
39 Image {
40 id: image
41 anchors.fill: parent
42 visible: false
43 }
44
45 CircleMask {
46 anchors.fill: image
47 source: image
48 }
49}
diff --git a/controls/Dialog.qml b/controls/Dialog.qml
new file mode 100644
index 0000000..b9d1b77
--- /dev/null
+++ b/controls/Dialog.qml
@@ -0,0 +1,169 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
6 *
7 * $BEGIN_LICENSE:MPL2$
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
13 * $END_LICENSE$
14 */
15
16import QtQuick 2.0
17import QtQuick.Controls 2.0
18import QtQuick.Controls.Material 2.0
19import QtQuick.Layouts 1.0
20import Fluid.Core 1.0
21import Fluid.Controls 1.0
22
23/*!
24 \qmltype Dialog
25 \inqmlmodule Fluid.Controls
26 \ingroup fluidcontrols
27
28 \brief Dialog.
29*/
30Popup {
31 property alias title: titleLabel.text
32 property alias text: textLabel.text
33
34 property alias positiveButton: positiveButton
35 property alias negativeButton: negativeButton
36
37 property string positiveButtonText: qsTr("Ok")
38 property string negativeButtonText: qsTr("Cancel")
39
40 default property alias dialogContent: dialogContentItem.data
41
42 property bool __triggered
43
44 padding: 0
45 modal: true
46 focus: true
47
48 x: (parent.width - width)/2
49 y: (parent.height - height)/2
50
51 signal accepted
52 signal rejected
53 signal canceled
54
55 onOpened: __triggered = false
56
57 onAccepted: {
58 __triggered = true
59 close()
60 }
61
62 onRejected: {
63 __triggered = true
64 close()
65 }
66
67 onClosed: {
68 if (!__triggered)
69 canceled()
70 }
71
72 ColumnLayout {
73 width: parent.width
74 spacing: 0
75
76 Rectangle {
77 Layout.fillWidth: true
78 Layout.preferredWidth: column.implicitWidth + 48
79 Layout.preferredHeight: column.implicitHeight + 48
80 Layout.minimumWidth: Device.isMobile ? 280 : 300
81
82 ColumnLayout {
83 id: column
84
85 anchors.centerIn: parent
86 spacing: 0
87
88 width: parent.width - 48
89
90 TitleLabel {
91 id: titleLabel
92
93 Layout.fillWidth: true
94
95 wrapMode: Text.Wrap
96 visible: title != ""
97 }
98
99 Item {
100 Layout.fillWidth: true
101 Layout.preferredHeight: 20
102 visible: titleLabel.visible && textLabel.visible
103 }
104
105 Label {
106 id: textLabel
107
108 Layout.fillWidth: true
109
110 font: FluidStyle.dialogFont
111 wrapMode: Text.Wrap
112 color: Material.secondaryTextColor
113 visible: text != ""
114 }
115
116 Item {
117 Layout.fillWidth: true
118 Layout.preferredHeight: 20
119 visible: textLabel.visible
120 }
121
122 Item {
123 id: dialogContentItem
124 Layout.fillWidth: true
125 Layout.preferredHeight: childrenRect.height
126 }
127 }
128 }
129
130 RowLayout {
131 Layout.alignment: Qt.AlignRight
132 Layout.preferredHeight: 52
133
134 spacing: 0
135
136 Button {
137 id: negativeButton
138
139 Layout.alignment: Qt.AlignVCenter
140 Material.foreground: Material.primaryColor
141
142 text: negativeButtonText
143 flat: true
144
145 onClicked: rejected()
146 }
147
148 Item {
149 Layout.preferredWidth: 8
150 }
151
152 Button {
153 id: positiveButton
154
155 Layout.alignment: Qt.AlignVCenter
156 Material.foreground: Material.primaryColor
157
158 text: positiveButtonText
159 flat: true
160
161 onClicked: accepted()
162 }
163
164 Item {
165 Layout.preferredWidth: 8
166 }
167 }
168 }
169}
diff --git a/controls/DialogLabel.qml b/controls/DialogLabel.qml
new file mode 100644
index 0000000..2777027
--- /dev/null
+++ b/controls/DialogLabel.qml
@@ -0,0 +1,38 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Templates 2.0 as T
17
18/*!
19 \qmltype DialogLabel
20 \inqmlmodule Fluid.Controls
21 \ingroup fluidcontrols
22
23 \brief Text label with standard font and styling suitable to message box text.
24
25 \code
26 import QtQuick 2.0
27 import Fluid.Controls 1.0 as FluidControls
28
29 FluidControls.DialogLabel {
30 text: "Text to display"
31 }
32 \endcode
33*/
34T.Label {
35 font.pixelSize: 18
36 color: "#909090"
37 linkColor: "#45a7d7"
38}
diff --git a/controls/DisplayLabel.qml b/controls/DisplayLabel.qml
new file mode 100644
index 0000000..8f27f05
--- /dev/null
+++ b/controls/DisplayLabel.qml
@@ -0,0 +1,59 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Templates 2.0 as T
17
18/*!
19 \qmltype DisplayLabel
20 \inqmlmodule Fluid.Controls
21 \ingroup fluidcontrols
22
23 \brief Text label with standard font and styling suitable to display text.
24
25 \code
26 DisplayLabel {
27 text: qsTr("Display text")
28 }
29 \endcode
30*/
31T.Label {
32 /*!
33 \qmlproperty int level
34
35 This property holds the label level that controls
36 font style and size.
37
38 Only values between 1 and 4 are allowed.
39
40 Default value is 1.
41 */
42 property int level: 1
43
44 font.pixelSize: {
45 if (level <= 1)
46 return 30
47 else if (level == 2)
48 return 40
49 else if (level == 3)
50 return 50
51 return 100
52 }
53 color: "#26282a"
54 linkColor: "#45a7d7"
55 onLevelChanged: {
56 if (level < 1 || level > 4)
57 console.error("DisplayLabel level must be between 1 and 4")
58 }
59}
diff --git a/controls/FluidStyle.qml b/controls/FluidStyle.qml
new file mode 100644
index 0000000..4d3afea
--- /dev/null
+++ b/controls/FluidStyle.qml
@@ -0,0 +1,68 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import Fluid.Core 1.0
17
18pragma Singleton
19
20/*!
21 \qmltype FluidStyle
22 \inqmlmodule Fluid.Controls
23 \ingroup fluidcontrols
24
25 \brief Style.
26*/
27QtObject {
28 id: fluidStyle
29
30 readonly property color iconColorLight: Qt.rgba(0,0,0,0.54)
31 readonly property color iconColorDark: Qt.rgba(1,1,1)
32
33 readonly property font display4Font: Qt.font({ family: "Roboto", weight: Font.Light,
34 pixelSize: 112 })
35
36 readonly property font display3Font: Qt.font({ family: "Roboto", pixelSize: 56 })
37
38 readonly property font display2Font: Qt.font({ family: "Roboto", pixelSize: 45 })
39
40 readonly property font display1Font: Qt.font({ family: "Roboto", pixelSize: 34 })
41
42 readonly property font headlineFont: Qt.font({ family: "Roboto", pixelSize: 24 })
43
44 readonly property font titleFont: Qt.font({ family: "Roboto", weight: Font.DemiBold,
45 pixelSize: 20 })
46
47 readonly property font subheadingFont: Qt.font({ family: "Roboto",
48 pixelSize: Device.isMobile ? 16 : 15 })
49
50 readonly property font body2Font: Qt.font({ family: "Roboto", weight: Font.DemiBold,
51 pixelSize: Device.isMobile ? 14 : 13 })
52
53 readonly property font body1Font: Qt.font({ family: "Roboto",
54 pixelSize: Device.isMobile ? 14 : 13 })
55
56 readonly property font captionFont: Qt.font({ family: "Roboto", pixelSize: 12 })
57
58 readonly property font buttonFont: Qt.font({ family: "Roboto", weight: Font.DemiBold,
59 pixelSize: 14, capitalization: Font.AllUppercase })
60
61 /* Control fonts that don't fit into the standard font styles */
62
63 readonly property font subheaderFont: Qt.font({ family: "Roboto", weight: Font.DemiBold,
64 pixelSize: 14 })
65
66 readonly property font dialogFont: Qt.font({ family: "Roboto",
67 pixelSize: Device.isMobile ? 18 : 17 })
68}
diff --git a/controls/FluidWindow.qml b/controls/FluidWindow.qml
new file mode 100644
index 0000000..e7b0b67
--- /dev/null
+++ b/controls/FluidWindow.qml
@@ -0,0 +1,101 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.4
16import QtQuick.Controls 2.0
17import QtQuick.Controls.Material 2.0
18import Fluid.Core 1.0
19import Fluid.Controls 1.0 as FluidControls
20
21/*!
22 \qmltype FluidWindow
23 \inqmlmodule Fluid.Controls
24 \ingroup fluidcontrols
25
26 \brief A window that provides features commonly used for Material Design apps.
27
28 This is normally what you should use as your root component. It provides a \l Toolbar and
29 \l PageStack to provide access to standard features used by Material Design applications.
30
31 Here is a short working example of an application:
32
33 \qml
34 import QtQuick 2.4
35 import Fluid.Controls 1.0 as FluidControls
36
37 FluidControls.ApplicationWindow {
38 title: "Application Name"
39
40 initialPage: page
41
42 Page {
43 id: page
44 title: "Page Title"
45
46 Label {
47 anchors.centerIn: parent
48 text: "Hello World!"
49 }
50 }
51 }
52 \endqml
53*/
54ApplicationWindow {
55 id: window
56
57 /*!
58 \qmlproperty color decorationColor
59
60 The color of the status bar or window decorations, if the current
61 platform supports it.
62 */
63 property alias decorationColor: platformExtensions.decorationColor
64
65 property alias appBar: appBar
66
67 /*!
68 \qmlproperty Page initialPage
69
70 The initial page shown when the application starts.
71 */
72 property alias initialPage: pageStack.initialItem
73
74 /*!
75 \qmlproperty PageStack pageStack
76
77 The \l PageStack used for controlling pages and transitions between pages.
78 */
79 property alias pageStack: pageStack
80
81 header: FluidControls.AppToolBar {
82 id: appBar
83 }
84
85 FluidControls.PageStack {
86 id: pageStack
87
88 width: parent.width
89 height: parent.height
90
91 onPushed: appBar.push(page)
92 onPopped: appBar.pop(page)
93 onReplaced: appBar.replace(page)
94 }
95
96 PlatformExtensions {
97 id: platformExtensions
98 window: window
99 decorationColor: Material.shade(window.Material.primaryColor, Material.Shade700)
100 }
101}
diff --git a/controls/HeadlineLabel.qml b/controls/HeadlineLabel.qml
new file mode 100644
index 0000000..93d2bf6
--- /dev/null
+++ b/controls/HeadlineLabel.qml
@@ -0,0 +1,35 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Templates 2.0 as T
17
18/*!
19 \qmltype HeadlineLabel
20 \inqmlmodule Fluid.Controls
21 \ingroup fluidcontrols
22
23 \brief Text label with standard font and styling suitable to headlines.
24
25 \code
26 HeadlineLabel {
27 text: qsTr("A translatable headline")
28 }
29 \endcode
30*/
31T.Label {
32 font.pixelSize: 22
33 color: "#26282a"
34 linkColor: "#45a7d7"
35}
diff --git a/controls/Icon.qml b/controls/Icon.qml
new file mode 100644
index 0000000..3f0d4c5
--- /dev/null
+++ b/controls/Icon.qml
@@ -0,0 +1,173 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 * Copyright (C) 2015 Bogdan Cuza <bogdan.cuza@hotmail.com>
6 *
7 * $BEGIN_LICENSE:MPL2$
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
13 * $END_LICENSE$
14 */
15
16import QtQuick 2.4
17import QtQuick.Window 2.2
18import QtGraphicalEffects 1.0
19import QtQuick.Controls.Material 2.0
20import Fluid.Core 1.0
21import Fluid.Controls 1.0
22
23/*!
24 \qmltype Icon
25 \inqmlmodule Fluid.Controls
26 \ingroup fluidcontrols
27
28 \brief Displays an icon from the Material Design icon collection, the platform's icon theme,
29 or another (local or remote) location.
30
31 To use an icon from the \l{}{Material Design icon collection}, set the \c name property to the name of the icon in its group in the form of \c group/icon_name. For example:
32 \code
33 Icon {
34 name: "action/settings"
35 }
36 \endcode
37
38 This icon will by default use the light icon color from Material Design. To use the dark icon
39 color:
40 \code
41 Icon {
42 Material.theme: Material.Dark
43
44 name: "action/settings"
45 }
46 \endcode
47
48 In addition to using icons from Material Design, you can also use icons from the platform's
49 \l{http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html}{Freedesktop icon theme}. For example:
50
51 \code
52 Icon {
53 name: "gimp"
54 }
55 \endcode
56
57 By default, icons from the Freedesktop icon theme are not colorized unless they include the word "symbolic" in the icon name. For example, "gimp" would be full-colored by "edit-cut-symbolic" would be colored using the set \c color property (based off of \c Material.theme). If you need to colorize an icon manually, you can do so like this:
58
59 \code
60 Icon {
61 name: "gimp"
62 colorize: true
63 }
64 \endcode
65
66 You can also use custom icons like this:
67 \code
68 Icon {
69 source: Qt.resolvedUrl("icons/fun_icon.png")
70 }
71 \endcode
72 */
73Item {
74 id: icon
75
76 /*!
77 The color of the icon. Defaults to \c FluidStyle.iconColorLight. For dark backgrounds,
78 set \c Material.theme to Material.Dark or set this to \c FluidStyle.iconColorDark.
79 */
80 property color color: Material.theme == Material.Light ? FluidStyle.iconColorLight
81 : FluidStyle.iconColorDark
82
83 /*!
84 The size of the icon. Defaults to 24px.
85 */
86 property real size: 24
87
88 /*!
89 The name of the icon to display.
90
91 \sa source
92 */
93 property string name
94
95 /*!
96 \brief A URL pointing to an image to display as the icon.
97
98 By default, this is a special URL representing the icon named by \ref name from the Material
99 Design icon collection when using the form of "collection/icon_name", or in the case of a
100 single "icon_name", the platform's Freedesktop icon theme will be used.
101
102 By default, icons from the Material Design icons collection will be treated as symbolic icons and colored using the specified \ref color, while icons from the Freedesktop icon theme will
103 not be colorized. To override this, or set the behavior for your own custom icons, use
104 \ref colorize.
105
106 \sa name
107 */
108 property url source: Utils.getSourceForIconName(name)
109
110 /*!
111 \qmlproperty enumeration status
112 \list
113 \li Image.Null - no image has been set
114 \li Image.Ready - the image has been loaded
115 \li Image.Loading - the image is currently being loaded
116 \li Image.Error - an error occurred while loading the image
117 \endlist
118 */
119 property alias status: image.status
120
121 /*!
122 Specifies whether the image should be cached.
123 The default value is true.
124
125 Setting cache to false is useful when dealing with large images,
126 to make sure that they aren't cached at the expense of small
127 'ui element' images.
128 */
129 property alias cache: image.cache
130
131 /*!
132 \c true if the icon is valid and fully loaded.
133 */
134 readonly property bool valid: status == Image.Ready
135
136 /*!
137 Set to \c false if you want the icon to use the original image's colors and not be
138 colored using the specified \ref color.
139 */
140 property bool colorize: (String(icon.source).indexOf(".color.") === -1 &&
141 String(icon.source).indexOf("image://fluidicontheme/") === -1) ||
142 String(icon.source).indexOf("symbolic") !== -1
143
144 readonly property real sourceSize: String(icon.source).indexOf("image://fluidicontheme/") === 0 ? Units.roundToIconSize(size) : size
145
146 width: size
147 height: size
148
149 Image {
150 id: image
151
152 anchors.fill: parent
153 visible: !colorize
154
155 source: icon.source
156
157 sourceSize {
158 width: icon.sourceSize * Screen.devicePixelRatio
159 height: icon.sourceSize * Screen.devicePixelRatio
160 }
161 }
162
163 ColorOverlay {
164 id: overlay
165
166 anchors.fill: parent
167 source: image
168 color: Utils.alpha(icon.color, 1)
169 cached: true
170 visible: icon.valid && colorize
171 opacity: icon.color.a
172 }
173}
diff --git a/controls/IconButton.qml b/controls/IconButton.qml
new file mode 100644
index 0000000..7b74d53
--- /dev/null
+++ b/controls/IconButton.qml
@@ -0,0 +1,39 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls 2.0
17import QtQuick.Controls.Material 2.0
18
19/*!
20 \qmltype IconButton
21 \inqmlmodule Fluid.Controls
22 \ingroup fluidcontrols
23
24 \brief Tool button with an \l Icon.
25*/
26ToolButton {
27 id: iconButton
28
29 property alias iconName: icon.name
30 property alias iconSource: icon.source
31 property alias iconSize: icon.size
32 property alias iconColor: icon.color
33
34 indicator: Icon {
35 id: icon
36
37 anchors.centerIn: parent
38 }
39}
diff --git a/controls/InfoBar.qml b/controls/InfoBar.qml
new file mode 100644
index 0000000..27fbfcb
--- /dev/null
+++ b/controls/InfoBar.qml
@@ -0,0 +1,149 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 * Copyright (C) 2014-2016 Michael Spencer <sonrisesoftware@gmail.com>
6 * Copyright (C) 2014 Bogdan Cuza <bogdan.cuza@hotmail.com>
7 *
8 * $BEGIN_LICENSE:MPL2$
9 *
10 * This Source Code Form is subject to the terms of the Mozilla Public
11 * License, v. 2.0. If a copy of the MPL was not distributed with this
12 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
13 *
14 * $END_LICENSE$
15 */
16
17import QtQuick 2.4
18import QtQuick.Layouts 1.1
19import QtQuick.Controls 2.0
20import QtQuick.Controls.Material 2.0
21import Fluid.Core 1.0
22
23/*!
24 \qmltype InfoBar
25 \inqmlmodule Fluid.Controls
26 \ingroup fluidcontrols
27
28 \brief InfoBar provide lightweight feedback about an operation.
29
30 \code
31 Page {
32 title: qsTr("Send a message")
33
34 Button {
35 anchors.centerIn: parent
36 text: qsTr("Send Message")
37 onClicked: infoBar.open(qsTr("Message sent"))
38 }
39
40 InfoBar {
41 id: infoBar
42 }
43 }
44 \endcode
45*/
46Rectangle {
47 id: infoBar
48
49 property string buttonText
50 property color buttonColor: Material.accentColor
51 property string text
52 property bool opened
53 property int duration: 2000
54 property bool fullWidth: Device.type === Device.phone || Device.type === Device.phablet
55
56 signal clicked
57
58 function open(text) {
59 infoBar.text = text
60 opened = true
61 timer.restart()
62 }
63
64 anchors {
65 left: fullWidth ? parent.left : undefined
66 right: fullWidth ? parent.right : undefined
67 bottom: parent.bottom
68 bottomMargin: opened ? 0 : -infoBar.height
69 horizontalCenter: fullWidth ? undefined : parent.horizontalCenter
70
71 Behavior on bottomMargin {
72 NumberAnimation { duration: 300 }
73 }
74 }
75 radius: fullWidth ? 0 : 2
76 color: "#323232"
77 height: snackLayout.height
78 width: fullWidth ? undefined : snackLayout.width
79 opacity: opened ? 1 : 0
80
81 Timer {
82 id: timer
83
84 interval: infoBar.duration
85
86 onTriggered: {
87 if (!running)
88 infoBar.opened = false
89 }
90 }
91
92 RowLayout {
93 id: snackLayout
94
95 anchors {
96 verticalCenter: parent.verticalCenter
97 left: infoBar.fullWidth ? parent.left : undefined
98 right: infoBar.fullWidth ? parent.right : undefined
99 }
100
101 spacing: 0
102
103 Item {
104 width: 24
105 }
106
107 Label {
108 id: snackText
109 Layout.fillWidth: true
110 Layout.minimumWidth: infoBar.fullWidth ? -1 : 216 - snackButton.width
111 Layout.maximumWidth: infoBar.fullWidth ? -1 :
112 Math.min(496 - snackButton.width - middleSpacer.width - 48,
113 infoBar.parent.width - snackButton.width - middleSpacer.width - 48)
114
115 Layout.preferredHeight: lineCount == 2 ? 80 : 48
116 verticalAlignment: Text.AlignVCenter
117 maximumLineCount: 2
118 wrapMode: Text.Wrap
119 elide: Text.ElideRight
120 text: infoBar.text
121 color: "white"
122 }
123
124 Item {
125 id: middleSpacer
126 width: infoBar.buttonText == "" ? 0 : infoBar.fullWidth ? 24 : 48
127 }
128
129 Button {
130 id: snackButton
131 visible: infoBar.buttonText != ""
132 text: infoBar.buttonText
133 flat: true
134 width: visible ? implicitWidth : 0
135 font.bold: true
136 onClicked: infoBar.clicked()
137
138 Material.foreground: infoBar.buttonColor
139 }
140
141 Item {
142 width: 24
143 }
144 }
145
146 Behavior on opacity {
147 NumberAnimation { duration: 300 }
148 }
149}
diff --git a/controls/ListItem.qml b/controls/ListItem.qml
new file mode 100644
index 0000000..252e9fd
--- /dev/null
+++ b/controls/ListItem.qml
@@ -0,0 +1,155 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
6 *
7 * $BEGIN_LICENSE:MPL2$
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
13 * $END_LICENSE$
14 */
15
16import QtQuick 2.4
17import QtQuick.Controls 2.0
18import QtQuick.Controls.Material 2.0
19import QtQuick.Layouts 1.1
20import Fluid.Controls 1.0
21
22/*!
23 \qmltype BaseListItem
24 \inqmlmodule Fluid.Controls
25 \ingroup fluidcontrols
26
27 \brief A standard list item, with one or more lines of text and optional left and right items.
28 */
29BaseListItem {
30 id: listItem
31
32 implicitHeight: Math.max(subText != "" ? maximumLineCount == 2 ? 72 : 88
33 : secondaryItem.showing ? secondaryItem.childrenRect.height + Units.smallSpacing * 2 : 48,
34 leftItem.childrenRect.height + Units.smallSpacing * 2,
35 rightItem.childrenRect.height + Units.smallSpacing * 2)
36
37 dividerInset: leftItem.visible ? listItem.height : 0
38
39 property int maximumLineCount: 2
40
41 property alias subText: subLabel.text
42 property alias valueText: valueLabel.text
43
44 property alias iconName: icon.name
45 property alias iconSource: icon.source
46
47 property alias leftItem: leftItem.children
48 property alias rightItem: rightItem.children
49 property alias secondaryItem: secondaryItem.children
50
51 contentItem: RowLayout {
52 spacing: Units.smallSpacing * 2
53
54 Item {
55 id: leftItem
56 objectName: "leftItem"
57
58 Layout.preferredWidth: showing ? 40 : 0
59 Layout.preferredHeight: width
60 Layout.alignment: Qt.AlignCenter
61
62 property bool showing: visibleChildren.length > 0
63
64 Icon {
65 id: icon
66 objectName: "icon"
67
68 anchors {
69 verticalCenter: parent.verticalCenter
70 left: parent.left
71 }
72
73 visible: icon.valid
74 color: listItem.highlighted ? Material.primaryColor
75 : Material.theme == Material.Light ? FluidStyle.iconColorLight
76 : FluidStyle.iconColorDark
77 }
78 }
79
80 ColumnLayout {
81 Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
82 Layout.fillWidth: true
83
84 spacing: 0
85
86 RowLayout {
87 Layout.fillWidth: true
88
89 visible: label.text != "" || valueLabel.text != ""
90 spacing: Units.smallSpacing
91
92 SubheadingLabel {
93 id: label
94 objectName: "textLabel"
95
96 Layout.alignment: Qt.AlignVCenter
97 Layout.fillWidth: true
98
99 text: listItem.text
100 elide: Text.ElideRight
101 color: listItem.highlighted ? Material.primaryColor
102 : Material.primaryTextColor
103 visible: text != ""
104 }
105
106 BodyLabel {
107 id: valueLabel
108 objectName: "valueLabel"
109
110 Layout.alignment: Qt.AlignVCenter
111 Layout.preferredWidth: visible ? implicitWidth : 0
112
113 color: Material.secondaryTextColor
114 elide: Text.ElideRight
115
116 visible: text != ""
117 }
118 }
119
120 BodyLabel {
121 id: subLabel
122 objectName: "subTextLabel"
123
124 Layout.fillWidth: true
125 Layout.preferredHeight: implicitHeight * maximumLineCount/lineCount
126
127 color: Material.secondaryTextColor
128 elide: Text.ElideRight
129 wrapMode: Text.WordWrap
130
131 visible: text != "" && !contentItem.showing
132 maximumLineCount: listItem.maximumLineCount - 1
133 }
134
135 Item {
136 id: secondaryItem
137 objectName: "secondaryItem"
138
139 Layout.fillWidth: true
140 Layout.preferredHeight: showing ? childrenRect.height + Units.smallSpacing : 0
141
142 property bool showing: visibleChildren.length > 0
143 }
144 }
145
146 Item {
147 id: rightItem
148 objectName: "rightItem"
149 Layout.preferredWidth: showing ? childrenRect.width : 0
150 Layout.preferredHeight: parent.height
151
152 property bool showing: visibleChildren.length > 0
153 }
154 }
155}
diff --git a/controls/ListItemDelegate.qml b/controls/ListItemDelegate.qml
new file mode 100644
index 0000000..576f271
--- /dev/null
+++ b/controls/ListItemDelegate.qml
@@ -0,0 +1,42 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.4
16import QtQuick.Layouts 1.0
17import QtQuick.Controls 2.0
18import Fluid.Material 1.0
19
20/*!
21 \qmltype ListItemDelegate
22 \inqmlmodule Fluid.Controls
23 \ingroup fluidcontrols
24
25 \brief A delegate for list views.
26*/
27ItemDelegate {
28 Layout.fillWidth: true
29
30 property int dividerInset: 0
31 property bool showDivider: false
32 property bool interactive: true
33
34 width: parent ? parent.width : undefined
35
36 leftPadding: 16
37 rightPadding: 16
38 topPadding: 0
39 bottomPadding: 0
40
41 opacity: enabled ? 1 : 0.6
42}
diff --git a/controls/Loadable.qml b/controls/Loadable.qml
new file mode 100644
index 0000000..f1c9176
--- /dev/null
+++ b/controls/Loadable.qml
@@ -0,0 +1,70 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16
17/*!
18 \qmltype Loadable
19 \inqmlmodule Fluid.Controls
20 \ingroup fluidcontrols
21
22 \brief Loadable component.
23*/
24Item {
25 property Component component
26 property var showAnimation
27 property var hideAnimation
28 property alias asynchronous: loader.asynchronous
29 property alias item: loader.item
30
31 id: root
32 visible: false
33
34 Loader {
35 id: loader
36 anchors.fill: parent
37 asynchronous: true
38 onStatusChanged: {
39 if (status != Loader.Ready)
40 return;
41 if (item.showAnimation == undefined && root.showAnimation != undefined)
42 item.showAnimation = root.showAnimation;
43 if (item.hideAnimation == undefined && root.hideAnimation != undefined)
44 item.hideAnimation = root.hideAnimation;
45 root.visible = true;
46 if (item.show != undefined)
47 item.show();
48 }
49 }
50
51 Connections {
52 target: loader.item
53 onVisibleChanged: {
54 // Unload component as soon as it's hidden and hide this item as well
55 if (!loader.item.visible) {
56 loader.sourceComponent = undefined;
57 root.visible = false;
58 }
59 }
60 }
61
62 function show() {
63 loader.sourceComponent = root.component;
64 }
65
66 function hide() {
67 if (loader.item && loader.item.hide != undefined)
68 loader.item.hide();
69 }
70}
diff --git a/controls/NavigationDrawer.qml b/controls/NavigationDrawer.qml
new file mode 100644
index 0000000..36d3547
--- /dev/null
+++ b/controls/NavigationDrawer.qml
@@ -0,0 +1,195 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Layouts 1.0
17import QtQuick.Controls 2.0
18import QtQml 2.2
19import Fluid.Core 1.0
20import Fluid.Controls 1.0
21
22/*!
23 \qmltype NavigationDrawer
24 \inqmlmodule Fluid.Controls
25 \ingroup fluidcontrols
26
27 \brief The navigation drawer slides in from the left and is a common pattern in apps.
28
29 \code
30 import QtQuick.Window 2.2
31 import Fluid.Controls 2.0 as FluidControls
32
33 Window {
34 id: window
35 width: 400
36 height: 400
37 visible: true
38
39 Button {
40 text: "Open"
41 onClicked: drawer.open()
42 }
43
44 FluidControls.NavigationDrawer {
45 topContent: [
46 Button {
47 text: "Push me"
48 onClicked: console.log("Pushed")
49 }
50 ]
51
52 actions: [
53 Action {
54 text: "Action 1"
55 },
56 Action {
57 text: "Action 1"
58 }
59 ]
60 }
61 }
62 \endcode
63*/
64
65Drawer {
66 id: drawer
67
68 /*!
69 \qmlproperty list<Item> topContent
70
71 The items added to this list will be displayed on top of the
72 actions list.
73
74 \code
75 import QtQuick.Window 2.2
76 import Fluid.Controls 2.0 as FluidControls
77
78 Window {
79 id: window
80 width: 400
81 height: 400
82 visible: true
83
84 Button {
85 text: "Open"
86 onClicked: drawer.open()
87 }
88
89 FluidControls.NavigationDrawer {
90 topContent: [
91 Button {
92 text: "Push me"
93 onClicked: console.log("Pushed")
94 }
95 ]
96 }
97 }
98 \endcode
99 */
100 property alias topContent: topContent.data
101
102 /*!
103 \qmlproperty list<QtObject> actions
104
105 List of actions to be displayed by the drawer.
106
107 \code
108 import QtQuick.Window 2.2
109 import Fluid.Controls 2.0 as FluidControls
110
111 Window {
112 id: window
113 width: 400
114 height: 400
115 visible: true
116
117 Button {
118 text: "Open"
119 onClicked: drawer.open()
120 }
121
122 FluidControls.NavigationDrawer {
123 actions: [
124 Action {
125 text: "Action 1"
126 },
127 Action {
128 text: "Action 1"
129 }
130 ]
131 }
132 }
133 \endcode
134 */
135 property list<QtObject> actions
136
137 width: {
138 switch (Device.formFactor) {
139 case Device.Phone:
140 return 280
141 case Device.Tablet:
142 return 320
143 default:
144 break
145 }
146 return 56 * 4
147 }
148 height: ApplicationWindow.height
149
150 padding: 0
151
152 Pane {
153 id: pane
154
155 anchors.fill: parent
156 padding: 0
157
158 ColumnLayout {
159 anchors.fill: parent
160 spacing: 0
161
162 ColumnLayout {
163 id: topContent
164
165 height: childrenRect.height + 2 * drawer.padding
166
167 spacing: 0
168 visible: children.length > 0
169
170 Layout.margins: drawer.padding
171 Layout.fillWidth: true
172 }
173
174 ListView {
175 currentIndex: -1
176 spacing: 0
177
178 model: drawer.actions
179
180 delegate: ListItem {
181 iconName: modelData.iconName
182 text: modelData.text
183 onClicked: modelData.triggered(drawer)
184 }
185
186 visible: count > 0
187
188 Layout.fillWidth: true
189 Layout.fillHeight: true
190
191 ScrollBar.vertical: ScrollBar {}
192 }
193 }
194 }
195}
diff --git a/controls/NoiseBackground.qml b/controls/NoiseBackground.qml
new file mode 100644
index 0000000..e3513de
--- /dev/null
+++ b/controls/NoiseBackground.qml
@@ -0,0 +1,99 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15/****************************************************************************
16**
17** Copyright (C) 2017 The Qt Company Ltd.
18** Contact: https://www.qt.io/licensing/
19**
20** This file is part of Fluid and is derived from NoisyGradient.qml
21** from the Qt 5 launch demo.
22**
23** $QT_BEGIN_LICENSE:BSD$
24** You may use this file under the terms of the BSD license as follows:
25**
26** "Redistribution and use in source and binary forms, with or without
27** modification, are permitted provided that the following conditions are
28** met:
29** * Redistributions of source code must retain the above copyright
30** notice, this list of conditions and the following disclaimer.
31** * Redistributions in binary form must reproduce the above copyright
32** notice, this list of conditions and the following disclaimer in
33** the documentation and/or other materials provided with the
34** distribution.
35** * Neither the name of The Qt Company nor the names
36** of its contributors may be used to endorse or promote products derived
37** from this software without specific prior written permission.
38**
39**
40** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
43** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
44** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
46** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
50** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
51**
52** $QT_END_LICENSE$
53**
54****************************************************************************/
55
56import QtQuick 2.0
57
58/*!
59 \qmltype NoiseBackground
60 \inqmlmodule Fluid.Controls
61 \ingroup fluidcontrols
62
63 \brief Background with noise.
64*/
65ShaderEffect {
66 property alias gradient: rect.gradient
67 property alias color: rect.color
68
69 Rectangle {
70 id: rect
71 anchors.fill: parent
72 layer.enabled: true
73 layer.smooth: true
74 visible: false
75 }
76
77 readonly property variant source: rect
78
79 blending: false
80 fragmentShader: "
81 #ifdef GL_ES
82 precision lowp float;
83 #endif
84
85 uniform sampler2D source;
86 varying highp vec2 qt_TexCoord0;
87 uniform lowp float qt_Opacity;
88
89 // Noise function from: http://stackoverflow.com/questions/4200224/random-noise-functions-for-glsl
90 float rand(vec2 n) {
91 return 0.5 + 0.5 * fract(sin(dot(n.xy, vec2(12.9898, 78.233))) * 43758.5453);
92 }
93
94 void main() {
95 lowp float len = clamp(length(vec2(0.5, 0.0) - qt_TexCoord0), 0.0, 1.0);
96 gl_FragColor = texture2D(source, vec2(0, len)) * qt_Opacity + rand(qt_TexCoord0) * 0.05;
97 }
98 "
99}
diff --git a/controls/Page.qml b/controls/Page.qml
new file mode 100644
index 0000000..7cd93f5
--- /dev/null
+++ b/controls/Page.qml
@@ -0,0 +1,139 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
6 *
7 * $BEGIN_LICENSE:MPL2$
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
13 * $END_LICENSE$
14 */
15
16import QtQuick 2.4
17import QtQuick.Controls 2.0
18import Fluid.Controls 1.0 as FluidControls
19
20/*!
21 \qmltype Page
22 \inqmlmodule Fluid.Controls
23 \ingroup fluidcontrols
24
25 \brief Represents a page on the navigation page stack.
26
27 Example:
28
29 \qml
30 import QtQuick 2.4
31 import Fluid.Controls 1.0 as FluidControls
32
33 FluidControls.Page {
34 title: "Application Name"
35
36 actions: [
37 FluidControls.Action {
38 name: "Print"
39
40 // Icon name from the Google Material Design icon pack
41 iconName: "action/print"
42 }
43 ]
44 }
45 \endqml
46 */
47Page {
48 id: page
49
50 /*
51 \qmlproperty ActionBar actionBar
52
53 The action bar for this page. Use it as a group property to customize
54 this page's action bar. See the \l Page example for details on how to use
55 this property.
56 */
57 property alias appBar: appBar
58
59 /*!
60 The page's actions shown in the action bar.
61 */
62 property alias actions: appBar.actions
63
64 /*!
65 The action shown to the left of the title in the action bar. By default,
66 this is a back button which shows when there is a page behind the current
67 page in the page stack. However, you can replace it with your own action,
68 for example, an icon to open a navigation drawer when on your root page.
69 */
70 property alias leftAction: appBar.leftAction
71
72 /*!
73 \internal
74 Set by the page stack to true if there is a page behind this page on the
75 page stack.
76 */
77 property bool canGoBack: false
78
79 /*!
80 This signal is emitted when the back action is triggered or back key is released.
81
82 By default, the page will be popped from the page stack. To change the default
83 behavior, for example to show a confirmation dialog, listen for this signal using
84 \c onGoBack and set \c event.accepted to \c true. To dismiss the page from your
85 dialog without triggering this signal and re-showing the dialog, call
86 \c page.forcePop().
87 */
88 signal goBack(var event)
89
90 /*!
91 Pop this page from the page stack. This does nothing if this page is not
92 the current page on the page stack.
93
94 Use \c force to avoid calling the \l goBack signal. This is useful if you
95 use the \l goBack signal to show a confirmation dialog, and want to close
96 the page from your dialog without showing the dialog again. You can also
97 use \c forcePop() as a shortcut to this behavior.
98 */
99 function pop(event, force) {
100 if (StackView.view.currentItem !== page)
101 return false
102
103 if (!event)
104 event = {accepted: false}
105
106 if (!force)
107 goBack(event)
108
109 if (event.accepted) {
110 return true
111 } else {
112 return StackView.view.pop()
113 }
114 }
115
116 function forcePop() {
117 pop(null, true)
118 }
119
120 /*!
121 Push the specified component onto the page stack.
122 */
123 function push(component, properties) {
124 return StackView.view.push({item: component, properties: properties});
125 }
126
127 header: FluidControls.AppBar {
128 id: appBar
129
130 title: page.title
131
132 leftAction: FluidControls.Action {
133 text: "Back"
134 iconName: "navigation/arrow_back"
135 onTriggered: page.pop()
136 visible: page.canGoBack
137 }
138 }
139}
diff --git a/controls/PageStack.qml b/controls/PageStack.qml
new file mode 100644
index 0000000..4c948da
--- /dev/null
+++ b/controls/PageStack.qml
@@ -0,0 +1,51 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.4
16import QtQuick.Controls 2.0
17
18/*!
19 \qmltype PageStack
20 \inqmlmodule Fluid.Controls
21 \ingroup fluidcontrols
22
23 \brief Manages the page stack used for navigation.
24*/
25StackView {
26 id: stackView
27
28 signal pushed(Item page)
29 signal popped(Item page)
30 signal replaced(Item page)
31
32 property int __lastDepth: 0
33 property Item __oldItem: null
34
35 onCurrentItemChanged: {
36 if (stackView.currentItem) {
37 stackView.currentItem.canGoBack = stackView.depth > 1;
38 stackView.currentItem.forceActiveFocus()
39
40 if (__lastDepth > stackView.depth) {
41 popped(stackView.currentItem);
42 } else if (__lastDepth < stackView.depth) {
43 pushed(stackView.currentItem);
44 } else {
45 replaced(stackView.currentItem);
46 }
47 }
48
49 __lastDepth = stackView.depth;
50 }
51}
diff --git a/controls/Placeholder.qml b/controls/Placeholder.qml
new file mode 100644
index 0000000..f1e7996
--- /dev/null
+++ b/controls/Placeholder.qml
@@ -0,0 +1,66 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.2
16import QtQuick.Layouts 1.0
17import QtQuick.Controls 2.0
18import QtQuick.Controls.Material 2.0
19import Fluid.Controls 1.0
20
21/*!
22 \qmltype Placeholder
23 \inqmlmodule Fluid.Controls
24 \ingroup fluidcontrols
25
26 \brief Placeholder.
27*/
28Item {
29 property alias iconName: icon.name
30 property alias iconSource: icon.source
31 property alias text: textLabel.text
32 property alias subText: subTextLabel.text
33
34 ColumnLayout {
35 anchors.centerIn: parent
36
37 width: parent.width - 2 * Units.mediumSpacing
38
39 Icon {
40 id: icon
41 size: 96
42
43 Layout.alignment: Qt.AlignHCenter
44 }
45
46 Label {
47 id: textLabel
48 font: FluidStyle.titleFont
49 color: Material.secondaryTextColor
50 horizontalAlignment: Qt.AlignHCenter
51
52 Layout.fillWidth: true
53 }
54
55 Label {
56 id: subTextLabel
57 font: FluidStyle.subheadingFont
58 color: Material.secondaryTextColor
59 horizontalAlignment: Qt.AlignHCenter
60 wrapMode: Text.Wrap
61 visible: text !== ""
62
63 Layout.fillWidth: true
64 }
65 }
66}
diff --git a/controls/Showable.qml b/controls/Showable.qml
new file mode 100644
index 0000000..c7ceb9f
--- /dev/null
+++ b/controls/Showable.qml
@@ -0,0 +1,68 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16
17/*!
18 \qmltype Showable
19 \inqmlmodule Fluid.Controls
20 \ingroup fluidcontrols
21
22 \brief Showtable component.
23*/
24FocusScope {
25 property var showAnimation
26 property var hideAnimation
27
28 id: root
29 visible: false
30 onHideAnimationChanged: {
31 // Automatically set animation target when it's possible
32 if (showAnimation && showAnimation.target != undefined)
33 showAnimation.target = root;
34 if (hideAnimation && hideAnimation.target != undefined)
35 hideAnimation.target = root;
36
37 // Hide the item when the animation is over
38 if (hideAnimation) {
39 hideAnimation.runningChanged.connect(function() {
40 if (!hideAnimation.running)
41 root.visible = false;
42 });
43 }
44 }
45
46 function show() {
47 // Stop hide animation if it's still running
48 if (hideAnimation != undefined && hideAnimation.running)
49 hideAnimation.stop();
50
51 // Show the item otherwise we won't see the animation
52 visible = true;
53
54 // Restart show animation if available
55 if (showAnimation != undefined && !showAnimation.running)
56 showAnimation.restart();
57 }
58
59 function hide() {
60 // Stop show animation if it's still running
61 if (showAnimation != undefined && showAnimation.running)
62 showAnimation.stop();
63
64 // Restart hide animation if available
65 if (hideAnimation != undefined && !hideAnimation.running)
66 hideAnimation.restart();
67 }
68}
diff --git a/controls/Sidebar.qml b/controls/Sidebar.qml
new file mode 100644
index 0000000..8632a03
--- /dev/null
+++ b/controls/Sidebar.qml
@@ -0,0 +1,168 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
6 *
7 * $BEGIN_LICENSE:MPL2$
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
13 * $END_LICENSE$
14 */
15
16import QtQuick 2.0
17import QtQuick.Controls 2.0
18import QtQuick.Controls.Material 2.0
19import Fluid.Controls 1.0
20
21/*!
22 \qmltype Sidebar
23 \inqmlmodule Fluid.Controls
24 \ingroup fluidcontrols
25
26 \brief A sidebar component for use in adaptive layouts
27
28 To use, simply add an instance to your code, and anchor other components to it.
29
30 To show or hide, set the expanded property.
31
32 By default, the sidebar has a flickable built in, and whatever contents are added
33 will be placed in the flickable. When you want this disabled, or want to fill the
34 entire sidebar, set the autoFill property to false.
35
36 Examples:
37 \code
38 Item {
39 property bool wideAspect: width > Units.gu(80)
40
41 Sidebar {
42 expanded: wideAspect
43
44 // Anchoring is automatic
45 }
46 }
47 \endcode
48 */
49Pane {
50 id: sidebar
51
52 default property alias contents: contents.data
53
54 /*!
55 The text displayed for the action.
56 */
57 property int edge: Qt.LeftEdge
58
59 /*!
60 Show or hide the sidebar.
61 */
62 property bool expanded: true
63
64 /*!
65 Flick automatically.
66 */
67 property bool autoFlick: true
68
69 /*!
70 The text displayed as header.
71 */
72 property alias header: headerItem.text
73
74 Behavior on anchors.leftMargin {
75 NumberAnimation { duration: 200 }
76 }
77
78 Behavior on anchors.rightMargin {
79 NumberAnimation { duration: 200 }
80 }
81
82 Material.background: Material.theme === Material.Light ? "white" : "#333"
83 Material.elevation: 1
84
85 anchors {
86 left: edge === Qt.LeftEdge ? parent.left : undefined
87 top: parent.top
88 right: edge === Qt.RightEdge ? parent.right : undefined
89 bottom: parent.bottom
90 leftMargin: expanded ? 0 : -width
91 rightMargin: expanded ? 0 : -width
92 }
93
94 width: 250
95
96 padding: 0
97
98 Rectangle {
99 color: Material.dividerColor
100 width: 1
101
102 anchors {
103 left: edge === Qt.RightEdge ? parent.left : undefined
104 top: parent.top
105 right: edge === Qt.LeftEdge ? parent.right : undefined
106 bottom: parent.bottom
107 //rightMargin: -1
108 }
109 }
110
111 Item {
112 clip: true
113
114 anchors {
115 fill: parent
116 leftMargin: edge === Qt.RightEdge ? 1 : 0
117 rightMargin: edge === Qt.LeftEdge ? 1 : 0
118 }
119
120 Subheader {
121 id: headerItem
122
123 Material.elevation: flickable.atYBeginning ? 0 : 1
124
125 visible: text !== ""
126 z: 2
127 }
128
129 Flickable {
130 id: flickable
131
132 clip: true
133
134 ScrollBar.vertical: ScrollBar {}
135
136 anchors {
137 left: parent.left
138 top: headerItem.visible ? headerItem.bottom : parent.top
139 right: parent.right
140 bottom: parent.bottom
141 }
142
143 contentWidth: width
144 contentHeight: autoFlick ? contents.height : height
145 interactive: contentHeight > height
146
147 Item {
148 id: contents
149
150 width: flickable.width
151 height: autoFlick ? childrenRect.height : flickable.height
152 }
153
154 function getFlickableChild(item) {
155 if (item && item.hasOwnProperty("children")) {
156 for (var i = 0; i < item.children.length; i++) {
157 var child = item.children[i]
158 if (internal.isVerticalFlickable(child)) {
159 if (child.anchors.top === page.top || child.anchors.fill === page)
160 return item.children[i]
161 }
162 }
163 }
164 return null
165 }
166 }
167 }
168}
diff --git a/controls/SmoothFadeImage.qml b/controls/SmoothFadeImage.qml
new file mode 100644
index 0000000..fbd0a94
--- /dev/null
+++ b/controls/SmoothFadeImage.qml
@@ -0,0 +1,309 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16
17/*!
18 \qmltype SmoothFadeImage
19 \inqmlmodule Fluid.Controls
20 \ingroup fluidcontrols
21
22 \brief Displays an image and smoothly fade when the source is changed.
23
24 This component can be used in place of an Image when a smooth fade animation
25 between two sources is needed.
26
27 When the source is changed and the fade animation ends, the image loaded before
28 is unloaded; this means that only one image at a time is loaded.
29
30 Images are loaded asynchronously and are not cache, so unlike the Image
31 component the \c asynchronous and \c cache properties are not available.
32
33 Example of usage:
34 \code
35 import QtQuick 2.0
36 import Fluid.Controls 1.0
37
38 Item {
39 width: 128
40 height: 128
41
42 SmoothFadeImage {
43 anchors.fill: parent
44 source: "http://www.maui-project.org/images/logos/m.png"
45 fillMode: Image.PreserveAspectFit
46 smooth: true
47 fadeDuration: 400
48
49 MouseArea {
50 anchors.fill: parent
51 onClicked: parent.source = "http://www.maui-project.org/images/logos/qt.png"
52 }
53 }
54 }
55 \endcode
56*/
57Item {
58 id: root
59
60 /*!
61 The image being displayed.
62 SmoothFadeImage can handle any image format supported by Qt, loaded
63 from any URL scheme supported by Qt.
64
65 \sa Image::source
66 */
67 property url source
68
69 /*!
70 \qmlproperty enumeration fillMode
71
72 Set this property to define what happens when the source image has a
73 different size than the item.
74
75 \list
76 \li Image.Stretch - the image is scaled to fit (default)
77 \li Image.PreserveAspectFit - the image is scaled uniformly to fit without cropping
78 \li Image.PreserveAspectCrop - the image is scaled uniformly to fill, cropping if necessary
79 \li Image.Tile - the image is duplicated horizontally and vertically
80 \li Image.TileVertically - the image is stretched horizontally and tiled vertically
81 \li Image.TileHorizontally - the image is stretched vertically and tiled horizontally
82 \li Image.Pad - the image is not transformed
83 \endlist
84
85 Defaults to \c Image.Stretch.
86
87 Note that \c clip is false by default which means that the item might
88 paint outside its bounding rectangle even if the fillMode is set to PreserveAspectCrop.
89 */
90 property int fillMode : Image.Stretch
91
92 /*!
93 Set this to change the fade animation time (in milliseconds).
94 Default value is 250 ms.
95 */
96 property int fadeDuration: 250
97
98 /*!
99 This property holds whether the fade animation is running or not.
100 */
101 readonly property bool running: animation.running
102
103 /*!
104 Set this property to false to disable the fade animation.
105 If the animation is disable, SmoothFadeImage behaves like a normal Image.
106
107 The fade animation is enabled by default.
108 */
109 property bool animationEnabled: true
110
111 /*!
112 This property holds the actual width and height of the loaded image.
113
114 Unlike the \c width and \c height properties, which scale the painting of the
115 image, this property sets the actual number of pixels stored for the
116 loaded image so that large images do not use more memory than necessary.
117
118 For example, this ensures the image in memory is no larger than
119 1024x1024 pixels, regardless of the SmoothFadeImage's width and height values:
120
121 \code
122 Rectangle {
123 width: ...
124 height: ...
125
126 Image {
127 anchors.fill: parent
128 source: "reallyBigImage.jpg"
129 sourceSize.width: 1024
130 sourceSize.height: 1024
131 }
132 }
133 \endcode
134
135 If the image's actual size is larger than the sourceSize, the image is
136 scaled down. If only one dimension of the size is set to greater than 0,
137 the other dimension is set in proportion to preserve the source image's
138 aspect ratio. (The \c fillMode is independent of this.)
139
140 If both the sourceSize.width and sourceSize.height are set the image
141 will be scaled down to fit within the specified size, maintaining the
142 image's aspect ratio. The actual size of the image after scaling is
143 available via \c Item::implicitWidth and \c Item::implicitHeight.
144
145 If the source is an intrinsically scalable image (eg. SVG), this property
146 determines the size of the loaded image regardless of intrinsic size.
147 Avoid changing this property dynamically; rendering an SVG is slow compared
148 to an image.
149
150 If the source is a non-scalable image (eg. JPEG), the loaded image will be
151 no greater than this property specifies. For some formats (currently only
152 JPEG), the whole image will never actually be loaded into memory.
153
154 sourceSize can be cleared to the natural size of the image by setting
155 sourceSize to undefined.
156
157 Note: Changing this property dynamically causes the image source to be
158 reloaded, potentially even from the network, if it is not in the disk cache.
159 */
160 property alias sourceSize: __priv.sourceSize
161
162 /*!
163 \qmlproperty enumeration status
164
165 This property holds the status of image loading. It can be one of:
166
167 \list
168 \li Image.Null - no image has been set
169 \li Image.Ready - the image has been loaded
170 \li Image.Loading - the image is currently being loaded
171 \li Image.Error - an error occurred while loading the image
172 \endlist
173 */
174 readonly property int status: __priv.loadingImage ? __priv.loadingImage.status : Image.Null
175
176 /*!
177 This property holds whether the image is smoothly filtered when scaled or
178 transformed. Smooth filtering gives better visual quality, but it may be
179 slower on some hardware.
180
181 If the image is displayed at its natural size, this property has no
182 visual or performance effect.
183
184 By default, this property is set to \c true.
185 */
186 property bool smooth: true
187
188 /*!
189 This signal is emitted when the swap between the old source and the new
190 one has happened.
191 */
192 signal imageSwapped()
193
194 QtObject {
195 id: __priv
196
197 property size sourceSize: undefined
198
199 property Image currentImage: image1
200 property Image nextImage: image2
201 property Image loadingImage: currentImage
202
203 onSourceSizeChanged: {
204 // Change source size for both images
205 image1.sourceSize = sourceSize;
206 image2.sourceSize = sourceSize;
207 }
208
209 function swapImages() {
210 // Swap images stacking order and start fading animation
211 __priv.currentImage.z = 0;
212 __priv.nextImage.z = 1;
213 if (root.animationEnabled)
214 animation.start();
215
216 // Swap images pointers
217 var oldImage = __priv.currentImage;
218 __priv.currentImage = __priv.nextImage;
219 __priv.nextImage = oldImage;
220 }
221 }
222
223 onSourceChanged: {
224 // Set image pointers at creation time
225 if (__priv.currentImage === null) {
226 __priv.currentImage = image1;
227 __priv.nextImage = image2;
228 }
229
230 // Stop the animation if the source is changed while
231 // it's still running
232 animation.stop();
233
234 // Unload both images
235 if (root.source == "") {
236 __priv.currentImage.source = "";
237 __priv.nextImage.source = "";
238 __priv.loadingImage = null;
239 return;
240 }
241
242 if (__priv.currentImage.source == "") {
243 // Assign the source to the current image for the first time
244 __priv.currentImage.source = root.source;
245 __priv.loadingImage = __priv.currentImage;
246 } else {
247 // Image source is changed, make sure the animation is not running
248 animation.stop();
249
250 // Prepare the next image
251 __priv.nextImage.opacity = 0.0;
252 __priv.nextImage.source = root.source;
253 __priv.loadingImage = __priv.nextImage;
254
255 // If the next image is still cached the status will already be Ready
256 // otherwise it's not loaded, either way we need to swap
257 if (__priv.nextImage.status === Image.Ready || __priv.nextImage.source === "")
258 __priv.swapImages();
259 }
260 }
261
262 Connections {
263 target: __priv.nextImage
264 onOpacityChanged: {
265 if (__priv.nextImage.opacity == 1.0)
266 root.imageSwapped();
267 }
268 onStatusChanged: {
269 if (__priv.nextImage.status === Image.Ready)
270 __priv.swapImages();
271 }
272 }
273
274 Image {
275 id: image1
276 anchors.fill: parent
277 cache: false
278 asynchronous: true
279 fillMode: root.fillMode
280 smooth: root.smooth
281 clip: root.clip
282 z: 1
283 }
284
285 Image {
286 id: image2
287 anchors.fill: parent
288 cache: false
289 asynchronous: true
290 fillMode: root.fillMode
291 smooth: root.smooth
292 clip: root.clip
293 z: 0
294 }
295
296 NumberAnimation {
297 id: animation
298 target: __priv.nextImage
299 property: "opacity"
300 to: 1.0
301 duration: root.fadeDuration
302 onRunningChanged: {
303 // When the fade animation stops, we unload the second image in
304 // order to save some memory (only one image will be load at a time)
305 if (!running)
306 __priv.nextImage.source = "";
307 }
308 }
309}
diff --git a/controls/SmoothFadeLoader.qml b/controls/SmoothFadeLoader.qml
new file mode 100644
index 0000000..0c76a67
--- /dev/null
+++ b/controls/SmoothFadeLoader.qml
@@ -0,0 +1,137 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16
17/*!
18 \qmltype SmoothFadeLoader
19 \inqmlmodule Fluid.Controls
20 \ingroup fluidcontrols
21
22 \brief Displays an item and smoothly fade when the source is changed.
23
24 This component loads an item with a Loader and smoothly fade to another item when
25 the source URL is changed.
26
27 Items are loaded synchronously, also the item being hidden is not unloaded to
28 avoid an unpleasant "flash" after the transition.
29
30 Example of usage:
31 \code
32 import QtQuick 2.0
33 import Fluid.Controls 1.0
34
35 Item {
36 width: 640
37 height: 480
38
39 SmoothFadeLoader {
40 anchors.fill: parent
41 source: "MyComponent.qml"
42 fadeDuration: 400
43
44 MouseArea {
45 anchors.fill: parent
46 onClicked: parent.source = "AnotherComponent.qml"
47 }
48 }
49 }
50 \endcode
51*/
52Item {
53 /*!
54 The item being displayed.
55
56 \sa Loader::source
57 */
58 property url source
59
60 /*!
61 Set this to change the fade animation time (in milliseconds).
62 Default value is 250 ms.
63 */
64 property int fadeDuration: 250
65
66 /*!
67 This property holds whether the fade animation is running or not.
68 */
69 readonly property bool running: animation.running
70
71 id: root
72 onSourceChanged: {
73 animation.running = false;
74
75 if (__priv.currentLoader == loader1) {
76 __priv.currentLoader = loader2;
77 __priv.nextLoader = loader1;
78 } else {
79 __priv.currentLoader = loader1;
80 __priv.nextLoader = loader2;
81 }
82
83 __priv.currentLoader.source = sourceUrl;
84 __priv.currentLoader.opacity = 0;
85 __priv.currentLoader.z = 1;
86 __priv.nextLoader.z = 0;
87
88 if (__priv.firstTime) {
89 __priv.currentLoader.opacity = 1.0;
90 __priv.nextLoader.opacity = 0.0;
91 __priv.firstTime = false;
92 } else {
93 animation.running = true;
94 }
95 }
96
97 QtObject {
98 id: __priv
99
100 property bool firstTime: true
101 property Loader currentLoader: loader1
102 property Loader nextLoader: loader2
103 }
104
105 SequentialAnimation {
106 id: animation
107 running: false
108
109 NumberAnimation {
110 target: __priv.currentLoader
111 properties: "opacity"
112 from: 0.0
113 to: 1.0
114 duration: root.fadeDuration
115 easing.type: Easing.OutQuad
116 }
117
118 ScriptAction {
119 script: {
120 __priv.nextLoader.opacity = 0;
121 //__priv.nextLoader.source = "";
122 }
123 }
124 }
125
126 Loader {
127 id: loader1
128 anchors.fill: parent
129 z: 1
130 }
131
132 Loader {
133 id: loader2
134 anchors.fill: parent
135 z: 0
136 }
137}
diff --git a/controls/Subheader.qml b/controls/Subheader.qml
new file mode 100644
index 0000000..329d683
--- /dev/null
+++ b/controls/Subheader.qml
@@ -0,0 +1,45 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.4
16import QtQuick.Controls 2.0
17import QtQuick.Controls.Material 2.0
18import Fluid.Controls 1.0
19
20/*!
21 \qmltype Subheader
22 \inqmlmodule Fluid.Controls
23 \ingroup fluidcontrols
24
25 \brief Subheaders are special list tiles that delineate distinct sections of a list or grid list.
26 */
27BaseListItem {
28 id: listItem
29
30 implicitHeight: 48
31 interactive: false
32
33 property alias textColor: label.color
34
35 contentItem: Label {
36 id: label
37
38 font: FluidStyle.subheaderFont
39 text: listItem.text
40
41 verticalAlignment: Text.AlignVCenter
42
43 color: Material.secondaryTextColor
44 }
45}
diff --git a/controls/SubheadingLabel.qml b/controls/SubheadingLabel.qml
new file mode 100644
index 0000000..e43d1f5
--- /dev/null
+++ b/controls/SubheadingLabel.qml
@@ -0,0 +1,51 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Templates 2.0 as T
17
18/*!
19 \qmltype SubheadingLabel
20 \inqmlmodule Fluid.Controls
21 \ingroup fluidcontrols
22
23 \brief Text label with standard font and styling suitable to subheading.
24
25 \code
26 SubheadingLabel {
27 text: qsTr("A translatable subheading")
28 }
29 \endcode
30*/
31T.Label {
32 /*!
33 \qmlproperty int level
34
35 This property holds the label level that controls
36 font style and size.
37
38 Only values between 1 and 4 are allowed.
39
40 Default value is 1.
41 */
42 property int level: 1
43
44 font.pixelSize: 14
45 color: "#26282a"
46 linkColor: "#45a7d7"
47 onLevelChanged: {
48 if (level < 1 || level > 2)
49 console.error("BodyLabel level must be either 1 or 2")
50 }
51}
diff --git a/controls/Tab.qml b/controls/Tab.qml
new file mode 100644
index 0000000..80038d4
--- /dev/null
+++ b/controls/Tab.qml
@@ -0,0 +1,47 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.4
16import Fluid.Core 1.0
17
18Item {
19 id: tab
20
21 /*!
22 The title of this tab.
23 */
24 property string title
25
26 /*!
27 The icon displayed for this tab. This can be a Material Design icon or an icon from
28 FontAwesome. See \l Icon from more details.
29 */
30 property string iconName
31
32 /*!
33 A URL pointing to an image to display as the icon of this tab. By default, this is
34 a special URL representing the icon named by \l iconName from the Material Design
35 icon collection. The icon will be colorized using the specificed \l color,
36 unless you put ".color." in the filename, for example, "app-icon.color.svg".
37
38 \sa iconName
39 \sa Icon
40 */
41 property string iconSource: Utils.getSourceForIconName(iconName)
42
43 /*!
44 * Controls whether a close button will be shown for this tab.
45 */
46 property bool canRemove: false
47}
diff --git a/controls/TabbedPage.qml b/controls/TabbedPage.qml
new file mode 100644
index 0000000..bec0543
--- /dev/null
+++ b/controls/TabbedPage.qml
@@ -0,0 +1,90 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
6 *
7 * $BEGIN_LICENSE:MPL2$
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
13 * $END_LICENSE$
14 */
15
16import QtQuick 2.4
17import QtQuick.Controls 2.0
18import QtQuick.Controls.Material 2.0
19import Fluid.Core 1.0 as FluidCore
20import Fluid.Controls 1.0 as FluidControls
21
22FluidControls.Page {
23 id: page
24
25 default property alias contents: swipeView.contentChildren
26
27 property alias count: swipeView.count
28
29 readonly property int currentIndex: appBar.currentTabIndex
30
31 /*!
32 The currently selected tab.
33 */
34 readonly property Tab selectedTab: count > 0
35 ? swipeView.contentChildren[currentIndex] : null
36
37 onCurrentIndexChanged: swipeView.currentIndex = currentIndex
38
39 appBar.tabs: Repeater {
40 model: swipeView.contentChildren
41 delegate: TabButton {
42 text: modelData.title
43 width: parent.fixed ? parent.width / parent.count : implicitWidth
44
45 // Active color
46 Material.accent: appBar.Material.foreground
47
48 // Unfocused color
49 Material.foreground: FluidCore.Utils.alpha(appBar.Material.foreground, 0.7)
50
51 FluidControls.Icon {
52 id: tabIcon
53
54 anchors.left: parent.left
55 anchors.verticalCenter: parent.verticalCenter
56 anchors.leftMargin: FluidControls.Units.smallSpacing
57
58 name: modelData.iconName
59 source: modelData.iconSource
60 visible: status == Image.Ready
61 }
62
63 FluidControls.IconButton {
64 id: tabCloseButton
65
66 anchors.right: parent.right
67 anchors.verticalCenter: parent.verticalCenter
68 anchors.rightMargin: FluidControls.Units.smallSpacing
69
70 iconName: "navigation/close"
71 visible: modelData.canRemove
72
73 onClicked: swipeView.removeItem(swipeView.currentIndex)
74 }
75 }
76 }
77
78 SwipeView {
79 id: swipeView
80 anchors.fill: parent
81 currentIndex: appBar.currentTabIndex
82
83 onCurrentIndexChanged: appBar.currentTabIndex = currentIndex
84 }
85
86 function addTab(tab) {
87 swipeView.addItem(tab);
88 appBar.currentTabIndex = swipeView.count - 1;
89 }
90}
diff --git a/controls/ThinDivider.qml b/controls/ThinDivider.qml
new file mode 100644
index 0000000..7d2def5
--- /dev/null
+++ b/controls/ThinDivider.qml
@@ -0,0 +1,28 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.4
16
17/*!
18 \qmltype ThinDivider
19 \inqmlmodule Fluid.Controls
20 \ingroup fluidcontrols
21
22 \brief A 1px high divider for use in lists and other columns of content.
23 */
24Rectangle {
25 color: "#999"
26 width: parent.width
27 height: 1
28}
diff --git a/controls/TitleLabel.qml b/controls/TitleLabel.qml
new file mode 100644
index 0000000..8742d7e
--- /dev/null
+++ b/controls/TitleLabel.qml
@@ -0,0 +1,36 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Templates 2.0 as T
17
18/*!
19 \qmltype TitleLabel
20 \inqmlmodule Fluid.Controls
21 \ingroup fluidcontrols
22
23 \brief Text label with standard font and styling suitable to titles.
24
25 \code
26 Title {
27 text: qsTr("Translatable title")
28 }
29 \endcode
30*/
31T.Label {
32 font.pixelSize: 18
33 font.bold: true
34 color: "#26282a"
35 linkColor: "#45a7d7"
36}
diff --git a/controls/Units.qml b/controls/Units.qml
new file mode 100644
index 0000000..e702e33
--- /dev/null
+++ b/controls/Units.qml
@@ -0,0 +1,125 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15pragma Singleton
16
17import QtQuick 2.4
18import Fluid.Core 1.0
19
20/*!
21 \qmltype Units
22 \inqmlmodule Fluid.Controls
23 \ingroup fluidcontrols
24
25 \brief Units.
26*/
27Item {
28 /*
29 \qmlproperty int gridUnit
30 Fundamental unit of space for sizes depending on the current font.
31 It correspond to the capital letter M width in pixel.
32 */
33 readonly property int gridUnit: textMetrics.height
34
35 /*!
36 \qmlproperty real smallSpacing
37 The amount of spacing that should be used around smaller UI
38 elements. It can be used as margin around button box and
39 spacing between buttons.
40 */
41 readonly property real smallSpacing: 8
42
43 /*!
44 \qmlproperty real mediumSpacing
45 The amount of spacing that should be used inside medium UI
46 elements such as padding between title and body text in a dialog box.
47 */
48 readonly property real mediumSpacing: 20
49
50 /*!
51 \qmlproperty real largeSpacing
52 The amount of spacing that should be used inside bigger UI
53 elements such as padding in a dialog box.
54 */
55 readonly property real largeSpacing: 24
56
57 /*!
58 \qmlproperty int shortDuration
59 Duration for short animations to make UI events noticeable.
60 */
61 readonly property int shortDuration: 100
62
63 /*!
64 \qmlproperty int mediumDuration
65 Duration for medium length animations.
66 */
67 readonly property int mediumDuration: 200
68
69 /*!
70 \qmlproperty int longDuration
71 Duration for long animations such as windows opening or closing.
72 */
73 readonly property int longDuration: 400
74
75 /*!
76 \qmlproperty object iconSizes
77 Standard icon sizes.
78 */
79 readonly property QtObject iconSizes: QtObject {
80 readonly property int tiny: 8
81 readonly property int small: 16
82 readonly property int smallMedium: 22
83 readonly property int medium: 32
84 readonly property int large: 48
85 readonly property int huge: 64
86 readonly property int enormous: 128
87 }
88
89 TextMetrics {
90 id: textMetrics
91 text: "M"
92 }
93
94 /*!
95 Returns a round size in pixels multiplied by grid unit.
96 */
97 function gu(x) {
98 return Math.round(x * gridUnit);
99 }
100
101 /*!
102 Returns the size in pixel closes to the icon size.
103 */
104 function roundToIconSize(x) {
105 // Find the size closest to icon size
106 if (x <= 0)
107 return 0;
108 else if (x < 8)
109 return 8;
110 else if (x < 16)
111 return 16;
112 else if (x < 22)
113 return 22;
114 else if (x < 32)
115 return 32;
116 else if (x < 48)
117 return 48;
118 else if (x < 64)
119 return 64;
120 else if (x < 128)
121 return 128;
122
123 return x;
124 }
125}
diff --git a/controls/controls.pri b/controls/controls.pri
new file mode 100644
index 0000000..db09cef
--- /dev/null
+++ b/controls/controls.pri
@@ -0,0 +1,4 @@
1HEADERS += $$PWD/iconthemeimageprovider.h
2SOURCES += $$PWD/iconthemeimageprovider.cpp
3INCLUDEPATH += $$PWD
4RESOURCES += $$PWD/controls.qrc
diff --git a/controls/controls.qrc b/controls/controls.qrc
new file mode 100644
index 0000000..8f0c46c
--- /dev/null
+++ b/controls/controls.qrc
@@ -0,0 +1,46 @@
1<RCC>
2 <qresource prefix="/Fluid/Controls">
3 <file>Action.qml</file>
4 <file>AppBar.qml</file>
5 <file>AppToolBar.qml</file>
6 <file>BaseListItem.qml</file>
7 <file>BodyLabel.qml</file>
8 <file>CaptionLabel.qml</file>
9 <file>Card.qml</file>
10 <file>CircleImage.qml</file>
11 <file>Dialog.qml</file>
12 <file>DisplayLabel.qml</file>
13 <file>FluidStyle.qml</file>
14 <file>FluidWindow.qml</file>
15 <file>HeadlineLabel.qml</file>
16 <file>Icon.qml</file>
17 <file>IconButton.qml</file>
18 <file>InfoBar.qml</file>
19 <file>ListItem.qml</file>
20 <file>ListItemDelegate.qml</file>
21 <file>Loadable.qml</file>
22 <file>NavigationDrawer.qml</file>
23 <file>NoiseBackground.qml</file>
24 <file>Page.qml</file>
25 <file>PageStack.qml</file>
26 <file>Placeholder.qml</file>
27 <file>Showable.qml</file>
28 <file>Sidebar.qml</file>
29 <file>SmoothFadeImage.qml</file>
30 <file>SmoothFadeLoader.qml</file>
31 <file>Subheader.qml</file>
32 <file>SubheadingLabel.qml</file>
33 <file>ThinDivider.qml</file>
34 <file>TitleLabel.qml</file>
35 <file>Units.qml</file>
36 <file>+material/BaseListItem.qml</file>
37 <file>+material/BodyLabel.qml</file>
38 <file>+material/CaptionLabel.qml</file>
39 <file>+material/DisplayLabel.qml</file>
40 <file>+material/HeadlineLabel.qml</file>
41 <file>+material/SubheadingLabel.qml</file>
42 <file>+material/ThinDivider.qml</file>
43 <file>+material/TitleLabel.qml</file>
44 <file alias="qmldir">qmldir_noplugin</file>
45 </qresource>
46</RCC>
diff --git a/controls/iconthemeimageprovider.cpp b/controls/iconthemeimageprovider.cpp
new file mode 100644
index 0000000..8b1c77b
--- /dev/null
+++ b/controls/iconthemeimageprovider.cpp
@@ -0,0 +1,47 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15#include <QtGui/QIcon>
16
17#include "iconthemeimageprovider.h"
18
19IconThemeImageProvider::IconThemeImageProvider()
20 : QQuickImageProvider(QQuickImageProvider::Pixmap)
21{
22}
23
24QPixmap IconThemeImageProvider::requestPixmap(const QString &id, QSize *realSize,
25 const QSize &requestedSize)
26{
27 // Sanitize requested size
28 QSize size(requestedSize);
29 if (size.width() < 1)
30 size.setWidth(1);
31 if (size.height() < 1)
32 size.setHeight(1);
33
34 // Return real size
35 if (realSize)
36 *realSize = size;
37
38 // Is it a path?
39 if (id.startsWith('/'))
40 return QPixmap(id).scaled(size);
41
42 // Return icon from theme or fallback to a generic icon
43 QIcon icon = QIcon::fromTheme(id);
44 if (icon.isNull())
45 icon = QIcon::fromTheme(QLatin1String("application-x-executable"));
46 return icon.pixmap(size);
47}
diff --git a/controls/iconthemeimageprovider.h b/controls/iconthemeimageprovider.h
new file mode 100644
index 0000000..e50008f
--- /dev/null
+++ b/controls/iconthemeimageprovider.h
@@ -0,0 +1,25 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15#pragma once
16
17#include <QtQuick/QQuickImageProvider>
18
19class IconThemeImageProvider : public QQuickImageProvider
20{
21public:
22 IconThemeImageProvider();
23
24 QPixmap requestPixmap(const QString &id, QSize *realSize, const QSize &requestedSize);
25};
diff --git a/controls/plugin.cpp b/controls/plugin.cpp
new file mode 100644
index 0000000..661b234
--- /dev/null
+++ b/controls/plugin.cpp
@@ -0,0 +1,42 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15#include <QtQml>
16
17#include "iconthemeimageprovider.h"
18
19class FluidCorePlugin : public QQmlExtensionPlugin
20{
21 Q_OBJECT
22 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
23public:
24 void initializeEngine(QQmlEngine *engine, const char *uri);
25 void registerTypes(const char *uri);
26};
27
28void FluidCorePlugin::initializeEngine(QQmlEngine *engine, const char *uri)
29{
30 Q_ASSERT(QByteArray(uri) == QByteArrayLiteral("Fluid.Controls"));
31
32 engine->addImageProvider(QLatin1String("fluidicontheme"), new IconThemeImageProvider());
33}
34
35void FluidCorePlugin::registerTypes(const char *uri)
36{
37 Q_ASSERT(QByteArray(uri) == QByteArrayLiteral("Fluid.Controls"));
38
39 // @uri Fluid.Controls
40}
41
42#include "plugin.moc"
diff --git a/controls/plugins.qmltypes b/controls/plugins.qmltypes
new file mode 100644
index 0000000..29ef846
--- /dev/null
+++ b/controls/plugins.qmltypes
@@ -0,0 +1,569 @@
1import QtQuick.tooling 1.2
2
3// This file describes the plugin-supplied types contained in the library.
4// It is used for QML tooling purposes only.
5//
6// This file was auto-generated by:
7// 'qmlplugindump-qt5 -nonrelocatable Fluid.Controls 1.0'
8
9Module {
10 dependencies: [
11 "Fluid.Core 1.0",
12 "Fluid.Effects 1.0",
13 "Fluid.Material 1.0",
14 "QtGraphicalEffects 1.0",
15 "QtQml 2.2",
16 "QtQuick 2.7",
17 "QtQuick.Controls 2.0",
18 "QtQuick.Controls.Material 2.0",
19 "QtQuick.Controls.Material.impl 2.0",
20 "QtQuick.Controls.Universal 2.0",
21 "QtQuick.Controls.Universal.impl 2.0",
22 "QtQuick.Controls.impl 2.0",
23 "QtQuick.Layouts 1.1",
24 "QtQuick.Templates 2.0",
25 "QtQuick.Window 2.2"
26 ]
27 Component {
28 prototype: "QQuickApplicationWindow"
29 name: "QtQuick.Controls/ApplicationWindow 2.0"
30 exports: ["QtQuick.Controls/ApplicationWindow 2.0"]
31 exportMetaObjectRevisions: [0]
32 isComposite: true
33 defaultProperty: "data"
34 }
35 Component {
36 prototype: "QQuickItem"
37 name: "QtQuick.Controls.Material.impl/BoxShadow 2.0"
38 exports: ["QtQuick.Controls.Material.impl/BoxShadow 2.0"]
39 exportMetaObjectRevisions: [0]
40 isComposite: true
41 defaultProperty: "data"
42 Property { name: "offsetX"; type: "int" }
43 Property { name: "offsetY"; type: "int" }
44 Property { name: "blurRadius"; type: "int" }
45 Property { name: "spreadRadius"; type: "int" }
46 Property { name: "source"; type: "QQuickItem"; isPointer: true }
47 Property { name: "fullWidth"; type: "bool" }
48 Property { name: "fullHeight"; type: "bool" }
49 Property { name: "glowRadius"; type: "double" }
50 Property { name: "spread"; type: "double" }
51 Property { name: "color"; type: "QColor" }
52 Property { name: "cornerRadius"; type: "double" }
53 Property { name: "cached"; type: "bool" }
54 }
55 Component {
56 prototype: "QQuickBusyIndicator"
57 name: "QtQuick.Controls/BusyIndicator 2.0"
58 exports: ["QtQuick.Controls/BusyIndicator 2.0"]
59 exportMetaObjectRevisions: [0]
60 isComposite: true
61 defaultProperty: "data"
62 }
63 Component {
64 prototype: "QQuickButton"
65 name: "QtQuick.Controls/Button 2.0"
66 exports: ["QtQuick.Controls/Button 2.0"]
67 exportMetaObjectRevisions: [0]
68 isComposite: true
69 defaultProperty: "data"
70 }
71 Component {
72 prototype: "QQuickCheckBox"
73 name: "QtQuick.Controls/CheckBox 2.0"
74 exports: ["QtQuick.Controls/CheckBox 2.0"]
75 exportMetaObjectRevisions: [0]
76 isComposite: true
77 defaultProperty: "data"
78 }
79 Component {
80 prototype: "QQuickCheckDelegate"
81 name: "QtQuick.Controls/CheckDelegate 2.0"
82 exports: ["QtQuick.Controls/CheckDelegate 2.0"]
83 exportMetaObjectRevisions: [0]
84 isComposite: true
85 defaultProperty: "data"
86 }
87 Component {
88 prototype: "QQuickRectangle"
89 name: "QtQuick.Controls.Material.impl/CheckIndicator 2.0"
90 exports: ["QtQuick.Controls.Material.impl/CheckIndicator 2.0"]
91 exportMetaObjectRevisions: [0]
92 isComposite: true
93 defaultProperty: "data"
94 Property { name: "control"; type: "QQuickItem"; isPointer: true }
95 }
96 Component {
97 prototype: "QQuickRectangle"
98 name: "QtQuick.Controls.impl/CheckIndicator 2.0"
99 exports: ["QtQuick.Controls.impl/CheckIndicator 2.0"]
100 exportMetaObjectRevisions: [0]
101 isComposite: true
102 defaultProperty: "data"
103 Property { name: "control"; type: "QQuickItem"; isPointer: true }
104 }
105 Component {
106 prototype: "QQuickComboBox"
107 name: "QtQuick.Controls/ComboBox 2.0"
108 exports: ["QtQuick.Controls/ComboBox 2.0"]
109 exportMetaObjectRevisions: [0]
110 isComposite: true
111 defaultProperty: "data"
112 }
113 Component {
114 prototype: "QQuickDial"
115 name: "QtQuick.Controls/Dial 2.0"
116 exports: ["QtQuick.Controls/Dial 2.0"]
117 exportMetaObjectRevisions: [0]
118 isComposite: true
119 defaultProperty: "data"
120 }
121 Component {
122 prototype: "QQuickDrawer"
123 name: "QtQuick.Controls/Drawer 2.0"
124 exports: ["QtQuick.Controls/Drawer 2.0"]
125 exportMetaObjectRevisions: [0]
126 isComposite: true
127 defaultProperty: "contentData"
128 }
129 Component {
130 prototype: "QQuickItem"
131 name: "QtQuick.Controls.Material.impl/ElevationEffect 2.0"
132 exports: ["QtQuick.Controls.Material.impl/ElevationEffect 2.0"]
133 exportMetaObjectRevisions: [0]
134 isComposite: true
135 defaultProperty: "data"
136 Property { name: "source"; type: "QVariant" }
137 Property { name: "elevation"; type: "int" }
138 Property { name: "fullWidth"; type: "bool" }
139 Property { name: "fullHeight"; type: "bool" }
140 Property { name: "sourceItem"; type: "QQuickItem"; isReadonly: true; isPointer: true }
141 Property { name: "_shadows"; type: "QVariant"; isReadonly: true }
142 Property { name: "_shadow"; type: "QVariant"; isReadonly: true }
143 }
144 Component {
145 prototype: "QObject"
146 name: "FluidStyle 1.0"
147 exports: ["FluidStyle 1.0"]
148 exportMetaObjectRevisions: [0]
149 isComposite: true
150 isCreatable: false
151 isSingleton: true
152 Property { name: "iconColorLight"; type: "QColor"; isReadonly: true }
153 Property { name: "iconColorDark"; type: "QColor"; isReadonly: true }
154 Property { name: "display4Font"; type: "QFont"; isReadonly: true }
155 Property { name: "display3Font"; type: "QFont"; isReadonly: true }
156 Property { name: "display2Font"; type: "QFont"; isReadonly: true }
157 Property { name: "display1Font"; type: "QFont"; isReadonly: true }
158 Property { name: "headlineFont"; type: "QFont"; isReadonly: true }
159 Property { name: "titleFont"; type: "QFont"; isReadonly: true }
160 Property { name: "subheadingFont"; type: "QFont"; isReadonly: true }
161 Property { name: "body2Font"; type: "QFont"; isReadonly: true }
162 Property { name: "body1Font"; type: "QFont"; isReadonly: true }
163 Property { name: "captionFont"; type: "QFont"; isReadonly: true }
164 Property { name: "buttonFont"; type: "QFont"; isReadonly: true }
165 Property { name: "subheaderFont"; type: "QFont"; isReadonly: true }
166 Property { name: "dialogFont"; type: "QFont"; isReadonly: true }
167 }
168 Component {
169 prototype: "QQuickFrame"
170 name: "QtQuick.Controls/Frame 2.0"
171 exports: ["QtQuick.Controls/Frame 2.0"]
172 exportMetaObjectRevisions: [0]
173 isComposite: true
174 defaultProperty: "contentData"
175 }
176 Component {
177 prototype: "QQuickGroupBox"
178 name: "QtQuick.Controls/GroupBox 2.0"
179 exports: ["QtQuick.Controls/GroupBox 2.0"]
180 exportMetaObjectRevisions: [0]
181 isComposite: true
182 defaultProperty: "contentData"
183 }
184 Component {
185 prototype: "QQuickItemDelegate"
186 name: "QtQuick.Controls/ItemDelegate 2.0"
187 exports: ["QtQuick.Controls/ItemDelegate 2.0"]
188 exportMetaObjectRevisions: [0]
189 isComposite: true
190 defaultProperty: "data"
191 }
192 Component {
193 prototype: "QQuickLabel"
194 name: "QtQuick.Controls/Label 2.0"
195 exports: ["QtQuick.Controls/Label 2.0"]
196 exportMetaObjectRevisions: [0]
197 isComposite: true
198 defaultProperty: "data"
199 }
200 Component {
201 prototype: "QQuickMenu"
202 name: "QtQuick.Controls/Menu 2.0"
203 exports: ["QtQuick.Controls/Menu 2.0"]
204 exportMetaObjectRevisions: [0]
205 isComposite: true
206 defaultProperty: "contentData"
207 }
208 Component {
209 prototype: "QQuickMenuItem"
210 name: "QtQuick.Controls/MenuItem 2.0"
211 exports: ["QtQuick.Controls/MenuItem 2.0"]
212 exportMetaObjectRevisions: [0]
213 isComposite: true
214 defaultProperty: "data"
215 }
216 Component {
217 prototype: "QQuickPage"
218 name: "QtQuick.Controls/Page 2.0"
219 exports: ["QtQuick.Controls/Page 2.0"]
220 exportMetaObjectRevisions: [0]
221 isComposite: true
222 defaultProperty: "contentData"
223 }
224 Component {
225 prototype: "QQuickPageIndicator"
226 name: "QtQuick.Controls/PageIndicator 2.0"
227 exports: ["QtQuick.Controls/PageIndicator 2.0"]
228 exportMetaObjectRevisions: [0]
229 isComposite: true
230 defaultProperty: "data"
231 }
232 Component {
233 prototype: "QQuickPane"
234 name: "QtQuick.Controls/Pane 2.0"
235 exports: ["QtQuick.Controls/Pane 2.0"]
236 exportMetaObjectRevisions: [0]
237 isComposite: true
238 defaultProperty: "contentData"
239 }
240 Component {
241 prototype: "QQuickPopup"
242 name: "QtQuick.Controls/Popup 2.0"
243 exports: ["QtQuick.Controls/Popup 2.0"]
244 exportMetaObjectRevisions: [0]
245 isComposite: true
246 defaultProperty: "contentData"
247 }
248 Component {
249 prototype: "QQuickProgressBar"
250 name: "QtQuick.Controls/ProgressBar 2.0"
251 exports: ["QtQuick.Controls/ProgressBar 2.0"]
252 exportMetaObjectRevisions: [0]
253 isComposite: true
254 defaultProperty: "data"
255 }
256 Component {
257 prototype: "QQuickRadioButton"
258 name: "QtQuick.Controls/RadioButton 2.0"
259 exports: ["QtQuick.Controls/RadioButton 2.0"]
260 exportMetaObjectRevisions: [0]
261 isComposite: true
262 defaultProperty: "data"
263 }
264 Component {
265 prototype: "QQuickRadioDelegate"
266 name: "QtQuick.Controls/RadioDelegate 2.0"
267 exports: ["QtQuick.Controls/RadioDelegate 2.0"]
268 exportMetaObjectRevisions: [0]
269 isComposite: true
270 defaultProperty: "data"
271 }
272 Component {
273 prototype: "QQuickRectangle"
274 name: "QtQuick.Controls.impl/RadioIndicator 2.0"
275 exports: ["QtQuick.Controls.impl/RadioIndicator 2.0"]
276 exportMetaObjectRevisions: [0]
277 isComposite: true
278 defaultProperty: "data"
279 Property { name: "control"; type: "QQuickItem"; isPointer: true }
280 }
281 Component {
282 prototype: "QQuickRectangle"
283 name: "QtQuick.Controls.Universal.impl/RadioIndicator 2.0"
284 exports: ["QtQuick.Controls.Universal.impl/RadioIndicator 2.0"]
285 exportMetaObjectRevisions: [0]
286 isComposite: true
287 defaultProperty: "data"
288 Property { name: "control"; type: "QVariant" }
289 }
290 Component {
291 prototype: "QQuickRangeSlider"
292 name: "QtQuick.Controls/RangeSlider 2.0"
293 exports: ["QtQuick.Controls/RangeSlider 2.0"]
294 exportMetaObjectRevisions: [0]
295 isComposite: true
296 defaultProperty: "data"
297 }
298 Component {
299 prototype: "QQuickRectangle"
300 name: "QtQuick.Controls.Material.impl/Ripple 2.0"
301 exports: ["QtQuick.Controls.Material.impl/Ripple 2.0"]
302 exportMetaObjectRevisions: [0]
303 isComposite: true
304 defaultProperty: "data"
305 Property { name: "control"; type: "QQuickItem"; isPointer: true }
306 Property { name: "colored"; type: "bool" }
307 }
308 Component {
309 prototype: "QQuickScrollBar"
310 name: "QtQuick.Controls/ScrollBar 2.0"
311 exports: ["QtQuick.Controls/ScrollBar 2.0"]
312 exportMetaObjectRevisions: [0]
313 isComposite: true
314 defaultProperty: "data"
315 }
316 Component {
317 prototype: "QQuickScrollIndicator"
318 name: "QtQuick.Controls/ScrollIndicator 2.0"
319 exports: ["QtQuick.Controls/ScrollIndicator 2.0"]
320 exportMetaObjectRevisions: [0]
321 isComposite: true
322 defaultProperty: "data"
323 }
324 Component {
325 prototype: "QQuickSlider"
326 name: "QtQuick.Controls/Slider 2.0"
327 exports: ["QtQuick.Controls/Slider 2.0"]
328 exportMetaObjectRevisions: [0]
329 isComposite: true
330 defaultProperty: "data"
331 }
332 Component {
333 prototype: "QQuickItem"
334 name: "QtQuick.Controls.Material.impl/SliderHandle 2.0"
335 exports: ["QtQuick.Controls.Material.impl/SliderHandle 2.0"]
336 exportMetaObjectRevisions: [0]
337 isComposite: true
338 defaultProperty: "data"
339 Property { name: "value"; type: "double" }
340 Property { name: "handleHasFocus"; type: "bool" }
341 Property { name: "handlePressed"; type: "bool" }
342 Property { name: "initialSize"; type: "int"; isReadonly: true }
343 Property { name: "horizontal"; type: "bool"; isReadonly: true }
344 Property { name: "control"; type: "QVariant"; isReadonly: true }
345 }
346 Component {
347 prototype: "QQuickSpinBox"
348 name: "QtQuick.Controls/SpinBox 2.0"
349 exports: ["QtQuick.Controls/SpinBox 2.0"]
350 exportMetaObjectRevisions: [0]
351 isComposite: true
352 defaultProperty: "data"
353 }
354 Component {
355 prototype: "QQuickStackView"
356 name: "QtQuick.Controls/StackView 2.0"
357 exports: ["QtQuick.Controls/StackView 2.0"]
358 exportMetaObjectRevisions: [0]
359 isComposite: true
360 defaultProperty: "data"
361 }
362 Component {
363 prototype: "QQuickSwipeDelegate"
364 name: "QtQuick.Controls/SwipeDelegate 2.0"
365 exports: ["QtQuick.Controls/SwipeDelegate 2.0"]
366 exportMetaObjectRevisions: [0]
367 isComposite: true
368 defaultProperty: "data"
369 }
370 Component {
371 prototype: "QQuickSwipeView"
372 name: "QtQuick.Controls/SwipeView 2.0"
373 exports: ["QtQuick.Controls/SwipeView 2.0"]
374 exportMetaObjectRevisions: [0]
375 isComposite: true
376 defaultProperty: "contentData"
377 }
378 Component {
379 prototype: "QQuickSwitch"
380 name: "QtQuick.Controls/Switch 2.0"
381 exports: ["QtQuick.Controls/Switch 2.0"]
382 exportMetaObjectRevisions: [0]
383 isComposite: true
384 defaultProperty: "data"
385 }
386 Component {
387 prototype: "QQuickSwitchDelegate"
388 name: "QtQuick.Controls/SwitchDelegate 2.0"
389 exports: ["QtQuick.Controls/SwitchDelegate 2.0"]
390 exportMetaObjectRevisions: [0]
391 isComposite: true
392 defaultProperty: "data"
393 }
394 Component {
395 prototype: "QQuickRectangle"
396 name: "QtQuick.Controls.Universal.impl/SwitchIndicator 2.0"
397 exports: ["QtQuick.Controls.Universal.impl/SwitchIndicator 2.0"]
398 exportMetaObjectRevisions: [0]
399 isComposite: true
400 defaultProperty: "data"
401 Property { name: "control"; type: "QQuickItem"; isPointer: true }
402 }
403 Component {
404 prototype: "QQuickItem"
405 name: "QtQuick.Controls.impl/SwitchIndicator 2.0"
406 exports: ["QtQuick.Controls.impl/SwitchIndicator 2.0"]
407 exportMetaObjectRevisions: [0]
408 isComposite: true
409 defaultProperty: "data"
410 Property { name: "control"; type: "QQuickItem"; isPointer: true }
411 }
412 Component {
413 prototype: "QQuickItem"
414 name: "QtQuick.Controls.Material.impl/SwitchIndicator 2.0"
415 exports: ["QtQuick.Controls.Material.impl/SwitchIndicator 2.0"]
416 exportMetaObjectRevisions: [0]
417 isComposite: true
418 defaultProperty: "data"
419 Property { name: "control"; type: "QQuickItem"; isPointer: true }
420 }
421 Component {
422 prototype: "QQuickTabBar"
423 name: "QtQuick.Controls/TabBar 2.0"
424 exports: ["QtQuick.Controls/TabBar 2.0"]
425 exportMetaObjectRevisions: [0]
426 isComposite: true
427 defaultProperty: "contentData"
428 }
429 Component {
430 prototype: "QQuickTabButton"
431 name: "QtQuick.Controls/TabButton 2.0"
432 exports: ["QtQuick.Controls/TabButton 2.0"]
433 exportMetaObjectRevisions: [0]
434 isComposite: true
435 defaultProperty: "data"
436 }
437 Component {
438 prototype: "QQuickTextArea"
439 name: "QtQuick.Controls/TextArea 2.0"
440 exports: ["QtQuick.Controls/TextArea 2.0"]
441 exportMetaObjectRevisions: [0]
442 isComposite: true
443 defaultProperty: "data"
444 }
445 Component {
446 prototype: "QQuickTextField"
447 name: "QtQuick.Controls/TextField 2.0"
448 exports: ["QtQuick.Controls/TextField 2.0"]
449 exportMetaObjectRevisions: [0]
450 isComposite: true
451 defaultProperty: "data"
452 }
453 Component {
454 prototype: "QQuickToolBar"
455 name: "QtQuick.Controls/ToolBar 2.0"
456 exports: ["QtQuick.Controls/ToolBar 2.0"]
457 exportMetaObjectRevisions: [0]
458 isComposite: true
459 defaultProperty: "contentData"
460 }
461 Component {
462 prototype: "QQuickToolButton"
463 name: "QtQuick.Controls/ToolButton 2.0"
464 exports: ["QtQuick.Controls/ToolButton 2.0"]
465 exportMetaObjectRevisions: [0]
466 isComposite: true
467 defaultProperty: "data"
468 }
469 Component {
470 prototype: "QQuickToolTip"
471 name: "QtQuick.Controls/ToolTip 2.0"
472 exports: ["QtQuick.Controls/ToolTip 2.0"]
473 exportMetaObjectRevisions: [0]
474 isComposite: true
475 defaultProperty: "contentData"
476 }
477 Component {
478 prototype: "QQuickTumbler"
479 name: "QtQuick.Controls/Tumbler 2.0"
480 exports: ["QtQuick.Controls/Tumbler 2.0"]
481 exportMetaObjectRevisions: [0]
482 isComposite: true
483 defaultProperty: "data"
484 }
485 Component {
486 prototype: "QQuickItem"
487 name: "Units 1.0"
488 exports: ["Units 1.0"]
489 exportMetaObjectRevisions: [0]
490 isComposite: true
491 isCreatable: false
492 isSingleton: true
493 defaultProperty: "data"
494 Property { name: "gridUnit"; type: "int"; isReadonly: true }
495 Property { name: "smallSpacing"; type: "double"; isReadonly: true }
496 Property { name: "mediumSpacing"; type: "double"; isReadonly: true }
497 Property { name: "largeSpacing"; type: "double"; isReadonly: true }
498 Property { name: "shortDuration"; type: "int"; isReadonly: true }
499 Property { name: "mediumDuration"; type: "int"; isReadonly: true }
500 Property { name: "longDuration"; type: "int"; isReadonly: true }
501 Property { name: "iconSizes"; type: "QObject"; isReadonly: true; isPointer: true }
502 Method {
503 name: "gu"
504 type: "QVariant"
505 Parameter { name: "x"; type: "QVariant" }
506 }
507 Method {
508 name: "roundToIconSize"
509 type: "QVariant"
510 Parameter { name: "x"; type: "QVariant" }
511 }
512 }
513 Component {
514 prototype: "QObject"
515 name: "Utils 1.0"
516 exports: ["Utils 1.0"]
517 exportMetaObjectRevisions: [0]
518 isComposite: true
519 isCreatable: false
520 isSingleton: true
521 Method {
522 name: "asColor"
523 type: "QVariant"
524 Parameter { name: "color"; type: "QVariant" }
525 }
526 Method {
527 name: "alpha"
528 type: "QVariant"
529 Parameter { name: "color"; type: "QVariant" }
530 Parameter { name: "alpha"; type: "QVariant" }
531 }
532 Method {
533 name: "blendColors"
534 type: "QVariant"
535 Parameter { name: "color1"; type: "QVariant" }
536 Parameter { name: "color2"; type: "QVariant" }
537 Parameter { name: "a"; type: "QVariant" }
538 }
539 Method {
540 name: "luminance"
541 type: "QVariant"
542 Parameter { name: "color"; type: "QVariant" }
543 }
544 Method {
545 name: "lightDark"
546 type: "QVariant"
547 Parameter { name: "background"; type: "QVariant" }
548 Parameter { name: "lightColor"; type: "QVariant" }
549 Parameter { name: "darkColor"; type: "QVariant" }
550 }
551 Method {
552 name: "isDarkColor"
553 type: "QVariant"
554 Parameter { name: "color"; type: "QVariant" }
555 }
556 Method {
557 name: "getSourceForIconName"
558 type: "QVariant"
559 Parameter { name: "name"; type: "QVariant" }
560 }
561 Method {
562 name: "scale"
563 type: "QVariant"
564 Parameter { name: "percent"; type: "QVariant" }
565 Parameter { name: "start"; type: "QVariant" }
566 Parameter { name: "end"; type: "QVariant" }
567 }
568 }
569}
diff --git a/controls/qmldir b/controls/qmldir
new file mode 100644
index 0000000..1eb9813
--- /dev/null
+++ b/controls/qmldir
@@ -0,0 +1,41 @@
1module Fluid.Controls
2plugin fluidcontrols
3class FluidControlsPlugin
4typeinfo plugins.qmltypes
5
6Action 1.0 Action.qml
7AppBar 1.0 AppBar.qml
8AppToolBar 1.0 AppToolBar.qml
9BaseListItem 1.0 BaseListItem.qml
10BodyLabel 1.0 BodyLabel.qml
11CaptionLabel 1.0 CaptionLabel.qml
12Card 1.0 Card.qml
13CircleImage 1.0 CircleImage.qml
14Dialog 1.0 Dialog.qml
15DialogLabel 1.0 DialogLabel.qml
16DisplayLabel 1.0 DisplayLabel.qml
17FluidWindow 1.0 FluidWindow.qml
18HeadlineLabel 1.0 HeadlineLabel.qml
19IconButton 1.0 IconButton.qml
20Icon 1.0 Icon.qml
21InfoBar 1.0 InfoBar.qml
22ListItemDelegate 1.0 ListItemDelegate.qml
23ListItem 1.0 ListItem.qml
24Loadable 1.0 Loadable.qml
25NavigationDrawer 1.0 NavigationDrawer.qml
26NoiseBackground 1.0 NoiseBackground.qml
27Page 1.0 Page.qml
28PageStack 1.0 PageStack.qml
29Placeholder 1.0 Placeholder.qml
30Showable 1.0 Showable.qml
31Sidebar 1.0 Sidebar.qml
32SmoothFadeImage 1.0 SmoothFadeImage.qml
33SmoothFadeLoader 1.0 SmoothFadeLoader.qml
34Subheader 1.0 Subheader.qml
35SubheadingLabel 1.0 SubheadingLabel.qml
36Tab 1.0 Tab.qml
37TabbedPage 1.0 TabbedPage.qml
38ThinDivider 1.0 ThinDivider.qml
39TitleLabel 1.0 TitleLabel.qml
40singleton FluidStyle 1.0 FluidStyle.qml
41singleton Units 1.0 Units.qml
diff --git a/controls/qmldir_noplugin b/controls/qmldir_noplugin
new file mode 100644
index 0000000..07b7dcb
--- /dev/null
+++ b/controls/qmldir_noplugin
@@ -0,0 +1,39 @@
1module Fluid.Controls
2typeinfo plugins.qmltypes
3
4Action 1.0 Action.qml
5AppBar 1.0 AppBar.qml
6AppToolBar 1.0 AppToolBar.qml
7BaseListItem 1.0 BaseListItem.qml
8BodyLabel 1.0 BodyLabel.qml
9CaptionLabel 1.0 CaptionLabel.qml
10Card 1.0 Card.qml
11CircleImage 1.0 CircleImage.qml
12Dialog 1.0 Dialog.qml
13DialogLabel 1.0 DialogLabel.qml
14DisplayLabel 1.0 DisplayLabel.qml
15FluidWindow 1.0 FluidWindow.qml
16HeadlineLabel 1.0 HeadlineLabel.qml
17IconButton 1.0 IconButton.qml
18Icon 1.0 Icon.qml
19InfoBar 1.0 InfoBar.qml
20ListItemDelegate 1.0 ListItemDelegate.qml
21ListItem 1.0 ListItem.qml
22Loadable 1.0 Loadable.qml
23NavigationDrawer 1.0 NavigationDrawer.qml
24NoiseBackground 1.0 NoiseBackground.qml
25Page 1.0 Page.qml
26PageStack 1.0 PageStack.qml
27Placeholder 1.0 Placeholder.qml
28Showable 1.0 Showable.qml
29Sidebar 1.0 Sidebar.qml
30SmoothFadeImage 1.0 SmoothFadeImage.qml
31SmoothFadeLoader 1.0 SmoothFadeLoader.qml
32Subheader 1.0 Subheader.qml
33SubheadingLabel 1.0 SubheadingLabel.qml
34Tab 1.0 Tab.qml
35TabbedPage 1.0 TabbedPage.qml
36ThinDivider 1.0 ThinDivider.qml
37TitleLabel 1.0 TitleLabel.qml
38singleton FluidStyle 1.0 FluidStyle.qml
39singleton Units 1.0 Units.qml
diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt
new file mode 100644
index 0000000..21bd974
--- /dev/null
+++ b/core/CMakeLists.txt
@@ -0,0 +1,32 @@
1include_directories(
2 "${CMAKE_CURRENT_BINARY_DIR}/../src"
3 "${CMAKE_CURRENT_BINARY_DIR}/../src/Fluid"
4)
5
6add_definitions(-DQT_PLUGIN)
7
8set(SOURCES
9 plugin.cpp
10 clipboard.cpp
11 qmldateutils.cpp
12 device.cpp
13 iconsimageprovider.cpp
14 qqmlsortfilterproxymodel.cpp
15 standardpaths.cpp
16)
17
18add_library(fluidcore SHARED ${SOURCES})
19target_link_libraries(fluidcore Qt5::Svg Qt5::Gui Qt5::Quick Fluid)
20
21set(FILES
22 plugins.qmltypes
23 qmldir
24 Object.qml
25 PlatformExtensions.qml
26 Utils.qml
27)
28
29install(TARGETS fluidcore LIBRARY
30 DESTINATION ${QML_INSTALL_DIR}/Fluid/Core)
31install(FILES ${FILES}
32 DESTINATION ${QML_INSTALL_DIR}/Fluid/Core)
diff --git a/core/Object.qml b/core/Object.qml
new file mode 100644
index 0000000..abfcdde
--- /dev/null
+++ b/core/Object.qml
@@ -0,0 +1,38 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16
17/*!
18 \qmltype Object
19 \inqmlmodule Fluid.Core
20 \ingroup fluidcore
21
22 \brief A QtObject with children.
23
24 The \l Object type is a non-visual element that extends \l QtObject
25 with the ability to hold children objects.
26*/
27QtObject {
28 default property alias children: object.__children
29
30 /*!
31 \qmlproperty list<QtObject> Object::children
32
33 Children objects.
34 */
35 property list<QtObject> __children: [QtObject {}]
36
37 id: object
38}
diff --git a/core/PlatformExtensions.qml b/core/PlatformExtensions.qml
new file mode 100644
index 0000000..ba9dcdb
--- /dev/null
+++ b/core/PlatformExtensions.qml
@@ -0,0 +1,51 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2015-2016 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import Fluid.Core 1.0
17
18Object {
19 id: platform
20
21 property var platformExtensions
22
23 property color decorationColor
24 property var window: null
25
26 onDecorationColorChanged: {
27 if (platformExtensions && color != "#000000") {
28 platformExtensions.decorationColor = decorationColor
29 }
30 }
31
32 onWindowChanged: {
33 if (platformExtensions) {
34 platformExtensions.window = window
35 }
36 }
37
38 Component.onCompleted: {
39 try {
40 var code = 'import Liri.Platform 1.0; PlatformExtensions {}'
41 platformExtensions = Qt.createQmlObject(code, platform, "LiriExtensions");
42
43 platformExtensions.window = window
44 if (decorationColor != "#000000")
45 platformExtensions.decorationColor = decorationColor
46 } catch (error) {
47 // Ignore the error; it only means that the Papyros
48 // platform extensions are not available
49 }
50 }
51}
diff --git a/core/Utils.qml b/core/Utils.qml
new file mode 100644
index 0000000..7d3a480
--- /dev/null
+++ b/core/Utils.qml
@@ -0,0 +1,106 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
6 *
7 * $BEGIN_LICENSE:MPL2$
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
13 * $END_LICENSE$
14 */
15
16import QtQuick 2.0
17
18pragma Singleton
19
20/*!
21 \qmltype Utils
22 \inqmlmodule Fluid.Core
23 \ingroup fluidcore
24
25 \brief A collection of helpful utility methods.
26
27 Currently the only utility methods are for working with colors.
28*/
29QtObject {
30 /*!
31 Make sure we have a real \l color object to work with (versus a string like "#ccc")
32 */
33 function asColor(color) {
34 return Qt.darker(color, 1)
35 }
36
37 /*!
38 A utility method for changing the alpha on colors. Returns a new object, and does not
39 modify the original color at all.
40 */
41 function alpha(color, alpha) {
42 color = asColor(color)
43
44 color.a = alpha
45
46 return color
47 }
48
49 /*!
50 Blend \a color1 and \a color2 together and set alpha to \a a.
51 */
52 function blendColors(color1, color2, a) {
53 return alpha(Qt.tint(color1, color2), a)
54 }
55
56 /*!
57 Calculate luminance of \a color.
58 */
59 function luminance(color) {
60 color = asColor(color)
61 return (color.r * 0.2126) + (color.g * 0.7152) + (color.b * 0.0722)
62 }
63
64 /*!
65 Select a color depending on whether \a background color is light or dark.
66 Returns \a lightColor if \a background is a light color, otherwise
67 returns \a darkColor.
68 */
69 function lightDark(background, lightColor, darkColor) {
70 return isDarkColor(background) ? darkColor : lightColor
71 }
72
73 /*!
74 Returns \c true if \a color is dark and should have light content on top.
75 */
76 function isDarkColor(color) {
77 color = asColor(color)
78
79 var a = 1 - (0.299 * color.r + 0.587 * color.g + 0.114 * color.b)
80
81 return color.a > 0 && a >= 0.3
82 }
83
84 /*!
85 Returns a source suitable for an \l Image from an icon name.
86 If \a name is an URL it will be returned verbatim, instead if it
87 contains a slash character an icon relative to Fluid icons/ directory
88 will be returned, otherwise an image://fluidicontheme/\a name URL.
89 */
90 function getSourceForIconName(name) {
91 return name ? name.indexOf("/") === 0 || name.indexOf("file://") === 0 || name.indexOf("qrc") === 0
92 ? name
93 : name.indexOf("/") !== -1 ? "image://fluidicons/" + name
94 : "image://fluidicontheme/" + name
95 : ""
96 }
97
98 /*!
99 Scale \a percent in the range between \a start and \a end.
100 */
101 function scale(percent, start, end) {
102 var diff = end - start
103
104 return start + percent * diff
105 }
106}
diff --git a/core/clipboard.cpp b/core/clipboard.cpp
new file mode 100644
index 0000000..79280d3
--- /dev/null
+++ b/core/clipboard.cpp
@@ -0,0 +1,54 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
6 *
7 * $BEGIN_LICENSE:MPL2$
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
13 * $END_LICENSE$
14 */
15
16#include "clipboard.h"
17
18#include <QGuiApplication>
19
20/*!
21 \qmltype Clipboard
22 \inqmlmodule Fluid.Core
23 \ingroup fluidcore
24
25 \brief Clipboard.
26*/
27
28Clipboard::Clipboard(QObject *parent)
29 : QObject(parent)
30 , m_clipboard(QGuiApplication::clipboard())
31{
32 connect(m_clipboard, &QClipboard::dataChanged, this, &Clipboard::textChanged);
33}
34
35/*!
36 \qmlproperty string Clipboard::text
37
38 This property holds the clipboard text.
39*/
40
41QString Clipboard::text() const
42{
43 return m_clipboard->text();
44}
45
46void Clipboard::clear()
47{
48 m_clipboard->clear();
49}
50
51void Clipboard::setText(const QString &text)
52{
53 m_clipboard->setText(text);
54}
diff --git a/core/clipboard.h b/core/clipboard.h
new file mode 100644
index 0000000..72b19e7
--- /dev/null
+++ b/core/clipboard.h
@@ -0,0 +1,41 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15#pragma once
16
17#include <QObject>
18#include <QClipboard>
19
20class Clipboard : public QObject
21{
22 Q_OBJECT
23
24 Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
25
26public:
27 explicit Clipboard(QObject *parent = nullptr);
28
29 QString text() const;
30
31 Q_INVOKABLE void clear();
32
33public Q_SLOTS:
34 void setText(const QString &text);
35
36Q_SIGNALS:
37 void textChanged();
38
39private:
40 QClipboard *m_clipboard = nullptr;
41};
diff --git a/core/core.pri b/core/core.pri
new file mode 100644
index 0000000..16b7b9d
--- /dev/null
+++ b/core/core.pri
@@ -0,0 +1,19 @@
1HEADERS += \
2 $$PWD/clipboard.h \
3 $$PWD/device.h \
4 $$PWD/iconsimageprovider.h \
5 $$PWD/qmldateutils.h \
6 $$PWD/qqmlsortfilterproxymodel.h \
7 $$PWD/standardpaths.h
8
9SOURCES += \
10 $$PWD/clipboard.cpp \
11 $$PWD/device.cpp \
12 $$PWD/iconsimageprovider.cpp \
13 $$PWD/plugin.cpp \
14 $$PWD/qmldateutils.cpp \
15 $$PWD/qqmlsortfilterproxymodel.cpp \
16 $$PWD/standardpaths.cpp
17
18RESOURCES += \
19 $$PWD/core.qrc
diff --git a/core/core.qrc b/core/core.qrc
new file mode 100644
index 0000000..3b17685
--- /dev/null
+++ b/core/core.qrc
@@ -0,0 +1,8 @@
1<RCC>
2 <qresource prefix="/Fluid/Core">
3 <file>Object.qml</file>
4 <file>PlatformExtensions.qml</file>
5 <file>Utils.qml</file>
6 <file alias="qmldir">qmldir_noplugin</file>
7 </qresource>
8</RCC>
diff --git a/core/device.cpp b/core/device.cpp
new file mode 100644
index 0000000..07046b8
--- /dev/null
+++ b/core/device.cpp
@@ -0,0 +1,152 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15#include "device.h"
16
17Device::Device(QObject *parent)
18 : QObject(parent)
19{
20 m_screen = qGuiApp->primaryScreen();
21
22 connect(qGuiApp, &QGuiApplication::primaryScreenChanged, this, &Device::screenChanged);
23}
24
25Device::FormFactor Device::formFactor() const
26{
27 float diagonal = calculateDiagonal();
28
29 if (diagonal >= 3.5 && diagonal < 5) {
30 // iPhone 1st generation to phablet
31 return Device::Phone;
32 } else if (diagonal >= 5 && diagonal < 6.5) {
33 return Device::Phablet;
34 } else if (diagonal >= 6.5 && diagonal < 10.1) {
35 return Device::Tablet;
36 } else if (diagonal >= 10.1 && diagonal < 29) {
37 return Device::Computer;
38 } else if (diagonal >= 29 && diagonal < 92) {
39 return Device::TV;
40 } else {
41 return Device::Unknown;
42 }
43}
44
45QString Device::name() const
46{
47 switch (formFactor()) {
48 case Phone:
49 return tr("phone");
50 case Phablet:
51 return tr("phablet");
52 case Tablet:
53 return tr("tablet");
54 case Computer:
55 return tr("computer");
56 case TV:
57 return tr("TV");
58 case Unknown:
59 return tr("device");
60 default:
61 return tr("unknown");
62 }
63}
64
65QString Device::iconName() const
66{
67 switch (formFactor()) {
68 case Phone:
69 return "hardware/smartphone";
70 case Phablet:
71 return "hardware/tablet";
72 case Tablet:
73 return "hardware/tablet";
74 case Computer:
75 return "hardware/desktop_windows";
76 case TV:
77 return "hardware/tv";
78 case Unknown:
79 default:
80 return "hardware/computer";
81 }
82}
83
84bool Device::isPortrait() const
85{
86 return m_screen->physicalSize().height() > m_screen->physicalSize().width();
87}
88
89bool Device::hasTouchScreen() const
90{
91// QTBUG-36007
92#if defined(Q_OS_ANDROID)
93 return true;
94#else
95 const auto devices = QTouchDevice::devices();
96 foreach (const QTouchDevice *dev, devices) {
97 if (dev->type() == QTouchDevice::TouchScreen)
98 return true;
99 }
100 return false;
101#endif
102}
103
104bool Device::isMobile() const
105{
106#if defined(Q_OS_IOS) || defined(Q_OS_ANDROID) || defined(Q_OS_BLACKBERRY) || defined(Q_OS_QNX) \
107 || defined(Q_OS_WINRT)
108 return true;
109#else
110 if (qEnvironmentVariableIsSet("QT_QUICK_CONTROLS_MOBILE")) {
111 return true;
112 }
113 return false;
114#endif
115}
116
117bool Device::hoverEnabled() const
118{
119 return !isMobile() || !hasTouchScreen();
120}
121
122int Device::gridUnit() const
123{
124 Device::FormFactor formFactor = this->formFactor();
125
126 if (formFactor == Device::Phone || formFactor == Device::Phablet) {
127 return isPortrait() ? 56 : 48;
128 } else if (formFactor == Device::Tablet) {
129 return 64;
130 } else {
131 return hasTouchScreen() ? 64 : 48;
132 }
133}
134
135void Device::screenChanged()
136{
137 if (m_screen)
138 m_screen->disconnect(this);
139
140 m_screen = qGuiApp->primaryScreen();
141
142 connect(m_screen, &QScreen::geometryChanged, this, &Device::geometryChanged);
143
144 emit geometryChanged();
145}
146
147float Device::calculateDiagonal() const
148{
149 return sqrt(pow((m_screen->physicalSize().width()), 2)
150 + pow((m_screen->physicalSize().height()), 2))
151 * 0.039370;
152}
diff --git a/core/device.h b/core/device.h
new file mode 100644
index 0000000..113de03
--- /dev/null
+++ b/core/device.h
@@ -0,0 +1,67 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15#pragma once
16
17#include <QObject>
18
19#include <cmath>
20#include <QQmlEngine>
21#include <QGuiApplication>
22#include <QScreen>
23#include <QTouchDevice>
24
25class Device : public QObject
26{
27 Q_OBJECT
28
29 Q_PROPERTY(FormFactor formFactor READ formFactor NOTIFY geometryChanged)
30 Q_PROPERTY(QString name READ name NOTIFY geometryChanged)
31 Q_PROPERTY(QString iconName READ iconName NOTIFY geometryChanged)
32
33 Q_PROPERTY(bool isPortrait READ isPortrait NOTIFY geometryChanged)
34 Q_PROPERTY(bool isMobile READ isMobile CONSTANT)
35 Q_PROPERTY(bool hasTouchScreen READ hasTouchScreen CONSTANT)
36 Q_PROPERTY(bool hoverEnabled READ hoverEnabled CONSTANT)
37
38 Q_PROPERTY(int gridUnit READ gridUnit NOTIFY geometryChanged)
39
40public:
41 enum FormFactor { Phone, Phablet, Tablet, Computer, TV, Unknown };
42 Q_ENUM(FormFactor)
43
44 Device(QObject *parent = nullptr);
45
46 FormFactor formFactor() const;
47 QString name() const;
48 QString iconName() const;
49
50 bool isPortrait() const;
51 bool hasTouchScreen() const;
52 bool isMobile() const;
53 bool hoverEnabled() const;
54
55 int gridUnit() const;
56
57Q_SIGNALS:
58 void geometryChanged();
59
60private Q_SLOTS:
61 void screenChanged();
62
63private:
64 float calculateDiagonal() const;
65
66 QScreen *m_screen;
67};
diff --git a/core/doc/fluidcore.qdocconf b/core/doc/fluidcore.qdocconf
new file mode 100644
index 0000000..ffeb2b0
--- /dev/null
+++ b/core/doc/fluidcore.qdocconf
@@ -0,0 +1,47 @@
1include(../../doc/defaults.qdocconf)
2
3project = FluidCore
4description = Fluid Core Reference Documentation
5version = $FLUID_VERSION
6
7qhp.projects = FluidCore
8
9qhp.Fluid.file = fluidcore.qhp
10qhp.Fluid.namespace = io.liri.fluidcore.$FLUID_VERSION_TAG
11qhp.Fluid.virtualFolder = fluidcore
12qhp.Fluid.indexTitle = Fluid Core
13qhp.Fluid.indexRoot =
14
15qhp.Fluid.filterAttributes = fluidcore $FLUID_VERSION qtrefdoc
16qhp.Fluid.customFilters.Qt.name = FluidCore $FLUID_VERSION
17qhp.Fluid.customFilters.Qt.filterAttributes = fluidcore $FLUID_VERSION
18
19qhp.Fluid.subprojects = qmltypes classes examples
20qhp.Fluid.subprojects.qmltypes.title = QML Types
21qhp.Fluid.subprojects.qmltypes.indexTitle = Fluid Core QML Types
22qhp.Fluid.subprojects.qmltypes.selectors = qmlclass
23qhp.Fluid.subprojects.qmltypes.sortPages = true
24qhp.Fluid.subprojects.classes.title = C++ Classes
25qhp.Fluid.subprojects.classes.indexTitle = Fluid Core C++ Classes
26qhp.Fluid.subprojects.classes.selectors = class fake:headerfile
27qhp.Fluid.subprojects.classes.sortPages = true
28qhp.Fluid.subprojects.examples.title = Examples
29qhp.Fluid.subprojects.examples.indexTitle = Fluid Core Examples
30qhp.Fluid.subprojects.examples.selectors = fake:example
31
32# Specify the install path under QT_INSTALL_EXAMPLES
33# Note: paths passed to \example command must contain the parent directory, e.g.
34# \example controls/tabs
35#exampledirs += snippets
36
37#examplesinstallpath = fluid
38
39headerdirs += .
40
41sourcedirs += . src
42
43imagedirs += images
44
45navigation.landingpage = "Fluid Core"
46navigation.qmltypespage = "Fluid Core QML Types"
47navigation.cppclassespage = "Fluid Core C++ Classes"
diff --git a/core/iconsimageprovider.cpp b/core/iconsimageprovider.cpp
new file mode 100644
index 0000000..2ffbe10
--- /dev/null
+++ b/core/iconsimageprovider.cpp
@@ -0,0 +1,67 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15#include <QtCore/QDir>
16#include <QtSvg/QSvgRenderer>
17#include <QtGui/QPainter>
18#include <QtQml/QQmlEngine>
19
20#include "iconsimageprovider.h"
21
22IconsImageProvider::IconsImageProvider()
23 : QQuickImageProvider(QQuickImageProvider::Image)
24{
25}
26
27QImage IconsImageProvider::requestImage(const QString &id, QSize *realSize,
28 const QSize &requestedSize)
29{
30 // Sanitize requested size
31 QSize size(requestedSize);
32 if (size.width() < 1)
33 size.setWidth(1);
34 if (size.height() < 1)
35 size.setHeight(1);
36
37 // Return real size
38 if (realSize)
39 *realSize = size;
40
41#ifdef FLUID_LOCAL
42 QSvgRenderer renderer(QLatin1String("qrc:/Fluid/Controls/") + id + QLatin1String(".svg"));
43 QImage image(size, QImage::Format_ARGB32);
44 image.fill(Qt::transparent);
45 QPainter painter(&image);
46 renderer.render(&painter);
47 return image;
48#else
49 const QString targetPath = QStringLiteral("Fluid/Controls/icons");
50 const QStringList importPaths = QQmlEngine().importPathList();
51
52 for (const QString &importPath: importPaths) {
53 QDir dir(importPath);
54 if (dir.exists(targetPath)) {
55 QDir targetDir(dir.absoluteFilePath(targetPath));
56 QSvgRenderer renderer(targetDir.absoluteFilePath(id + QLatin1String(".svg")));
57 QImage image(size, QImage::Format_ARGB32);
58 image.fill(Qt::transparent);
59 QPainter painter(&image);
60 renderer.render(&painter);
61 return image;
62 }
63 }
64
65 return QImage();
66#endif
67}
diff --git a/core/iconsimageprovider.h b/core/iconsimageprovider.h
new file mode 100644
index 0000000..f30a705
--- /dev/null
+++ b/core/iconsimageprovider.h
@@ -0,0 +1,25 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15#pragma once
16
17#include <QtQuick/QQuickImageProvider>
18
19class IconsImageProvider : public QQuickImageProvider
20{
21public:
22 IconsImageProvider();
23
24 QImage requestImage(const QString &id, QSize *realSize, const QSize &requestedSize);
25};
diff --git a/core/plugin.cpp b/core/plugin.cpp
new file mode 100644
index 0000000..511b439
--- /dev/null
+++ b/core/plugin.cpp
@@ -0,0 +1,90 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15#include <QtQml/QQmlExtensionPlugin>
16#include <QtQml/qqml.h>
17
18#include "clipboard.h"
19#include "device.h"
20#include "iconsimageprovider.h"
21#include "qmldateutils.h"
22#include "qqmlsortfilterproxymodel.h"
23#include "standardpaths.h"
24
25static QObject *dateUtilsProvider(QQmlEngine *engine, QJSEngine *jsEngine)
26{
27 Q_UNUSED(engine);
28 Q_UNUSED(jsEngine);
29
30 return new DateUtils();
31}
32
33static QObject *deviceProvider(QQmlEngine *engine, QJSEngine *jsEngine)
34{
35 Q_UNUSED(engine);
36 Q_UNUSED(jsEngine);
37
38 return new Device();
39}
40
41static QObject *standardPathsProvider(QQmlEngine *engine, QJSEngine *jsEngine)
42{
43 Q_UNUSED(engine);
44 Q_UNUSED(jsEngine);
45
46 return new StandardPaths();
47}
48
49class FluidCorePlugin : public QQmlExtensionPlugin
50{
51 Q_OBJECT
52 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
53public:
54 void initializeEngine(QQmlEngine *engine, const char *uri);
55 void registerTypes(const char *uri);
56};
57
58void FluidCorePlugin::initializeEngine(QQmlEngine *engine, const char *uri)
59{
60 Q_ASSERT(QByteArray(uri) == QByteArrayLiteral("Fluid.Core"));
61
62 engine->addImageProvider(QLatin1String("fluidicons"), new IconsImageProvider());
63}
64
65void FluidCorePlugin::registerTypes(const char *uri)
66{
67 Q_ASSERT(QByteArray("Fluid.Core") == QByteArray(uri));
68
69 // @uri Fluid.Core
70
71 qmlRegisterType<Clipboard>(uri, 1, 0, "Clipboard");
72
73 qmlRegisterType<QAbstractItemModel>();
74 qmlRegisterType<QQmlSortFilterProxyModel>(uri, 1, 0, "SortFilterProxyModel");
75
76 qmlRegisterSingletonType<DateUtils>(uri, 1, 0, "DateUtils", dateUtilsProvider);
77 qmlRegisterSingletonType<Device>(uri, 1, 0, "Device", deviceProvider);
78 qmlRegisterSingletonType<StandardPaths>(uri, 1, 0, "StandardPaths", standardPathsProvider);
79}
80
81#ifdef FLUID_LOCAL
82static void registerFluidCoreTypes() {
83 FluidCorePlugin fluidCore;
84 fluidCore.registerTypes("Fluid.Core");
85}
86
87Q_COREAPP_STARTUP_FUNCTION(registerFluidCoreTypes)
88#endif
89
90#include "plugin.moc"
diff --git a/core/plugins.qmltypes b/core/plugins.qmltypes
new file mode 100644
index 0000000..f8f71ef
--- /dev/null
+++ b/core/plugins.qmltypes
@@ -0,0 +1,268 @@
1import QtQuick.tooling 1.2
2
3// This file describes the plugin-supplied types contained in the library.
4// It is used for QML tooling purposes only.
5//
6// This file was auto-generated by:
7// 'qmlplugindump-qt5 -nonrelocatable Fluid.Core 1.0'
8
9Module {
10 dependencies: ["QtQuick 2.0"]
11 Component {
12 name: "Clipboard"
13 prototype: "QObject"
14 exports: ["Fluid.Core/Clipboard 1.0"]
15 exportMetaObjectRevisions: [0]
16 Property { name: "text"; type: "string" }
17 Method {
18 name: "setText"
19 Parameter { name: "text"; type: "string" }
20 }
21 Method { name: "clear" }
22 }
23 Component {
24 name: "DateUtils"
25 prototype: "QObject"
26 exports: ["Fluid.Core/DateUtils 1.0"]
27 isCreatable: false
28 isSingleton: true
29 exportMetaObjectRevisions: [0]
30 Enum {
31 name: "DurationFormat"
32 values: {
33 "Long": 0,
34 "Short": 1
35 }
36 }
37 Enum {
38 name: "DurationType"
39 values: {
40 "Seconds": 0,
41 "Minutes": 1,
42 "Hours": 2,
43 "Any": 3
44 }
45 }
46 Method {
47 name: "formatDuration"
48 type: "string"
49 Parameter { name: "duration"; type: "qlonglong" }
50 Parameter { name: "format"; type: "DurationFormat" }
51 Parameter { name: "type"; type: "DurationType" }
52 }
53 Method {
54 name: "formatDuration"
55 type: "string"
56 Parameter { name: "duration"; type: "qlonglong" }
57 Parameter { name: "format"; type: "DurationFormat" }
58 }
59 Method {
60 name: "formatDuration"
61 type: "string"
62 Parameter { name: "duration"; type: "qlonglong" }
63 }
64 }
65 Component {
66 name: "Device"
67 prototype: "QObject"
68 exports: ["Fluid.Core/Device 1.0"]
69 isCreatable: false
70 isSingleton: true
71 exportMetaObjectRevisions: [0]
72 Enum {
73 name: "FormFactor"
74 values: {
75 "Phone": 0,
76 "Phablet": 1,
77 "Tablet": 2,
78 "Computer": 3,
79 "TV": 4,
80 "Unknown": 5
81 }
82 }
83 Property { name: "formFactor"; type: "FormFactor"; isReadonly: true }
84 Property { name: "name"; type: "string"; isReadonly: true }
85 Property { name: "iconName"; type: "string"; isReadonly: true }
86 Property { name: "isPortrait"; type: "bool"; isReadonly: true }
87 Property { name: "isMobile"; type: "bool"; isReadonly: true }
88 Property { name: "hasTouchScreen"; type: "bool"; isReadonly: true }
89 Property { name: "hoverEnabled"; type: "bool"; isReadonly: true }
90 Property { name: "gridUnit"; type: "int"; isReadonly: true }
91 Signal { name: "geometryChanged" }
92 }
93 Component {
94 name: "QAbstractProxyModel"
95 prototype: "QAbstractItemModel"
96 Property { name: "sourceModel"; type: "QAbstractItemModel"; isPointer: true }
97 Method {
98 name: "mapToSource"
99 type: "QModelIndex"
100 Parameter { name: "proxyIndex"; type: "QModelIndex" }
101 }
102 Method {
103 name: "mapFromSource"
104 type: "QModelIndex"
105 Parameter { name: "sourceIndex"; type: "QModelIndex" }
106 }
107 Method {
108 name: "mapSelectionToSource"
109 type: "QItemSelection"
110 Parameter { name: "selection"; type: "QItemSelection" }
111 }
112 Method {
113 name: "mapSelectionFromSource"
114 type: "QItemSelection"
115 Parameter { name: "selection"; type: "QItemSelection" }
116 }
117 }
118 Component {
119 name: "QQmlSortFilterProxyModel"
120 prototype: "QSortFilterProxyModel"
121 exports: ["Fluid.Core/SortFilterProxyModel 1.0"]
122 exportMetaObjectRevisions: [0]
123 Enum {
124 name: "PatternSyntax"
125 values: {
126 "RegExp": 0,
127 "Wildcard": 1,
128 "FixedString": 2,
129 "RegExp2": 3,
130 "WildcardUnix": 4,
131 "W3CXmlSchema11": 5
132 }
133 }
134 Property { name: "count"; type: "int"; isReadonly: true }
135 Property { name: "filterRoleName"; type: "string" }
136 Property { name: "filterPattern"; type: "string" }
137 Property { name: "filterPatternSyntax"; type: "PatternSyntax" }
138 Property { name: "filterValue"; type: "QVariant" }
139 Property { name: "filterExpression"; type: "QQmlScriptString" }
140 Property { name: "sortRoleName"; type: "string" }
141 Property { name: "sortOrder"; type: "Qt::SortOrder" }
142 Property { name: "sortExpression"; type: "QQmlScriptString" }
143 }
144 Component {
145 name: "QSortFilterProxyModel"
146 prototype: "QAbstractProxyModel"
147 Property { name: "filterRegExp"; type: "QRegExp" }
148 Property { name: "filterKeyColumn"; type: "int" }
149 Property { name: "dynamicSortFilter"; type: "bool" }
150 Property { name: "filterCaseSensitivity"; type: "Qt::CaseSensitivity" }
151 Property { name: "sortCaseSensitivity"; type: "Qt::CaseSensitivity" }
152 Property { name: "isSortLocaleAware"; type: "bool" }
153 Property { name: "sortRole"; type: "int" }
154 Property { name: "filterRole"; type: "int" }
155 Method {
156 name: "setFilterRegExp"
157 Parameter { name: "pattern"; type: "string" }
158 }
159 Method {
160 name: "setFilterWildcard"
161 Parameter { name: "pattern"; type: "string" }
162 }
163 Method {
164 name: "setFilterFixedString"
165 Parameter { name: "pattern"; type: "string" }
166 }
167 Method { name: "clear" }
168 Method { name: "invalidate" }
169 }
170 Component {
171 name: "StandardPaths"
172 prototype: "QObject"
173 exports: ["Fluid.Core/StandardPaths 1.0"]
174 isCreatable: false
175 isSingleton: true
176 exportMetaObjectRevisions: [0]
177 Enum {
178 name: "StandardLocation"
179 values: {
180 "DesktopLocation": 0,
181 "DocumentsLocation": 1,
182 "FontsLocation": 2,
183 "ApplicationsLocation": 3,
184 "MusicLocation": 4,
185 "MoviesLocation": 5,
186 "PicturesLocation": 6,
187 "TempLocation": 7,
188 "HomeLocation": 8,
189 "DataLocation": 9,
190 "CacheLocation": 10,
191 "GenericDataLocation": 11,
192 "RuntimeLocation": 12,
193 "ConfigLocation": 13,
194 "DownloadLocation": 14,
195 "GenericCacheLocation": 15,
196 "GenericConfigLocation": 16
197 }
198 }
199 Method {
200 name: "locateFile"
201 type: "string"
202 Parameter { name: "type"; type: "StandardLocation" }
203 Parameter { name: "fileName"; type: "string" }
204 }
205 Method {
206 name: "locateDirectory"
207 type: "string"
208 Parameter { name: "type"; type: "StandardLocation" }
209 Parameter { name: "dirName"; type: "string" }
210 }
211 }
212 Component {
213 prototype: "QObject"
214 name: "Utils 1.0"
215 exports: ["Utils 1.0"]
216 exportMetaObjectRevisions: [0]
217 isComposite: true
218 isCreatable: false
219 isSingleton: true
220 Method {
221 name: "asColor"
222 type: "QVariant"
223 Parameter { name: "color"; type: "QVariant" }
224 }
225 Method {
226 name: "alpha"
227 type: "QVariant"
228 Parameter { name: "color"; type: "QVariant" }
229 Parameter { name: "alpha"; type: "QVariant" }
230 }
231 Method {
232 name: "blendColors"
233 type: "QVariant"
234 Parameter { name: "color1"; type: "QVariant" }
235 Parameter { name: "color2"; type: "QVariant" }
236 Parameter { name: "a"; type: "QVariant" }
237 }
238 Method {
239 name: "luminance"
240 type: "QVariant"
241 Parameter { name: "color"; type: "QVariant" }
242 }
243 Method {
244 name: "lightDark"
245 type: "QVariant"
246 Parameter { name: "background"; type: "QVariant" }
247 Parameter { name: "lightColor"; type: "QVariant" }
248 Parameter { name: "darkColor"; type: "QVariant" }
249 }
250 Method {
251 name: "isDarkColor"
252 type: "QVariant"
253 Parameter { name: "color"; type: "QVariant" }
254 }
255 Method {
256 name: "getSourceForIconName"
257 type: "QVariant"
258 Parameter { name: "name"; type: "QVariant" }
259 }
260 Method {
261 name: "scale"
262 type: "QVariant"
263 Parameter { name: "percent"; type: "QVariant" }
264 Parameter { name: "start"; type: "QVariant" }
265 Parameter { name: "end"; type: "QVariant" }
266 }
267 }
268}
diff --git a/core/qmldateutils.cpp b/core/qmldateutils.cpp
new file mode 100644
index 0000000..a060f26
--- /dev/null
+++ b/core/qmldateutils.cpp
@@ -0,0 +1,34 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
6 *
7 * $BEGIN_LICENSE:MPL2$
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
13 * $END_LICENSE$
14 */
15
16#include "qmldateutils.h"
17
18DateUtils::DateUtils(QObject *parent)
19 : QObject(parent)
20{
21}
22
23QString DateUtils::formatDuration(qlonglong duration, DurationFormat format,
24 DurationType type) const
25{
26 return Fluid::DateUtils::formatDuration(duration,
27 static_cast<Fluid::DateUtils::DurationFormat>(format),
28 static_cast<Fluid::DateUtils::DurationType>(type));
29}
30
31QString DateUtils::friendlyTime(const QDateTime &time, bool standalone) const
32{
33 return Fluid::DateUtils::friendlyTime(time, standalone);
34}
diff --git a/core/qmldateutils.h b/core/qmldateutils.h
new file mode 100644
index 0000000..29fffbe
--- /dev/null
+++ b/core/qmldateutils.h
@@ -0,0 +1,42 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
6 *
7 * $BEGIN_LICENSE:MPL2$
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
13 * $END_LICENSE$
14 */
15
16#pragma once
17
18#ifdef FLUID_LOCAL
19 #include "../src/dateutils.h"
20#else
21 #include <Fluid/DateUtils>
22#endif
23#include <QtCore/QObject>
24
25class DateUtils : public QObject
26{
27 Q_OBJECT
28
29public:
30 enum DurationFormat { Long, Short };
31 Q_ENUM(DurationFormat)
32
33 enum DurationType { Seconds, Minutes, Hours, Any };
34 Q_ENUM(DurationType)
35
36 DateUtils(QObject *parent = nullptr);
37
38 Q_INVOKABLE QString formatDuration(qlonglong duration,
39 DurationFormat format = DurationFormat::Short,
40 DurationType type = DurationType::Any) const;
41 Q_INVOKABLE QString friendlyTime(const QDateTime &time, bool standalone) const;
42};
diff --git a/core/qmldir b/core/qmldir
new file mode 100644
index 0000000..07b5022
--- /dev/null
+++ b/core/qmldir
@@ -0,0 +1,8 @@
1module Fluid.Core
2plugin fluidcore
3class FluidCorePlugin
4typeinfo plugins.qmltypes
5
6Object 1.0 Object.qml
7PlatformExtensions 1.0 PlatformExtensions.qml
8singleton Utils 1.0 Utils.qml
diff --git a/core/qmldir_noplugin b/core/qmldir_noplugin
new file mode 100644
index 0000000..c22216e
--- /dev/null
+++ b/core/qmldir_noplugin
@@ -0,0 +1,5 @@
1module Fluid.Core
2typeinfo plugins.qmltypes
3
4Object 1.0 Object.qml
5singleton Utils 1.0 Utils.qml
diff --git a/core/qqmlsortfilterproxymodel.cpp b/core/qqmlsortfilterproxymodel.cpp
new file mode 100644
index 0000000..0f88cc0
--- /dev/null
+++ b/core/qqmlsortfilterproxymodel.cpp
@@ -0,0 +1,283 @@
1/****************************************************************************
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pierre-Yves Siret
5 *
6 * $BEGIN_LICENSE:MIT$
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 *
26 * $END_LICENSE$
27 ***************************************************************************/
28
29#include "qqmlsortfilterproxymodel.h"
30#include <QtQml>
31
32QQmlSortFilterProxyModel::QQmlSortFilterProxyModel(QObject *parent)
33 : QSortFilterProxyModel(parent)
34 , m_filterExpression(0)
35 , m_compareExpression(0)
36{
37 connect(this, &QAbstractProxyModel::sourceModelChanged, this,
38 &QQmlSortFilterProxyModel::updateRoles);
39 connect(this, &QAbstractItemModel::modelReset, this, &QQmlSortFilterProxyModel::updateRoles);
40 connect(this, &QAbstractItemModel::rowsInserted, this, &QQmlSortFilterProxyModel::countChanged);
41 connect(this, &QAbstractItemModel::rowsRemoved, this, &QQmlSortFilterProxyModel::countChanged);
42 connect(this, &QAbstractItemModel::modelReset, this, &QQmlSortFilterProxyModel::countChanged);
43 connect(this, &QAbstractItemModel::layoutChanged, this,
44 &QQmlSortFilterProxyModel::countChanged);
45 setDynamicSortFilter(true);
46}
47
48int QQmlSortFilterProxyModel::count() const
49{
50 return rowCount();
51}
52
53const QString &QQmlSortFilterProxyModel::filterRoleName() const
54{
55 return m_filterRoleName;
56}
57
58void QQmlSortFilterProxyModel::setFilterRoleName(const QString &filterRoleName)
59{
60 if (m_filterRoleName == filterRoleName)
61 return;
62
63 m_filterRoleName = filterRoleName;
64 updateFilterRole();
65 emit filterRoleNameChanged();
66}
67
68QString QQmlSortFilterProxyModel::filterPattern() const
69{
70 return filterRegExp().pattern();
71}
72
73void QQmlSortFilterProxyModel::setFilterPattern(const QString &filterPattern)
74{
75 QRegExp regExp = filterRegExp();
76 if (regExp.pattern() == filterPattern)
77 return;
78
79 regExp.setPattern(filterPattern);
80 QSortFilterProxyModel::setFilterRegExp(regExp);
81 emit filterPatternChanged();
82}
83
84QQmlSortFilterProxyModel::PatternSyntax QQmlSortFilterProxyModel::filterPatternSyntax() const
85{
86 return static_cast<PatternSyntax>(filterRegExp().patternSyntax());
87}
88
89void QQmlSortFilterProxyModel::setFilterPatternSyntax(
90 QQmlSortFilterProxyModel::PatternSyntax patternSyntax)
91{
92 QRegExp regExp = filterRegExp();
93 QRegExp::PatternSyntax patternSyntaxTmp = static_cast<QRegExp::PatternSyntax>(patternSyntax);
94 if (regExp.patternSyntax() == patternSyntaxTmp)
95 return;
96
97 regExp.setPatternSyntax(patternSyntaxTmp);
98 QSortFilterProxyModel::setFilterRegExp(regExp);
99 emit filterPatternSyntaxChanged();
100}
101
102const QVariant &QQmlSortFilterProxyModel::filterValue() const
103{
104 return m_filterValue;
105}
106
107void QQmlSortFilterProxyModel::setFilterValue(const QVariant &filterValue)
108{
109 if (m_filterValue == filterValue)
110 return;
111
112 m_filterValue = filterValue;
113 invalidateFilter();
114 emit filterValueChanged();
115}
116
117const QQmlScriptString &QQmlSortFilterProxyModel::filterExpression() const
118{
119 return m_filterScriptString;
120}
121
122void QQmlSortFilterProxyModel::setFilterExpression(const QQmlScriptString &filterScriptString)
123{
124 if (m_filterScriptString == filterScriptString)
125 return;
126
127 m_filterScriptString = filterScriptString;
128 QQmlContext *context = new QQmlContext(qmlContext(this));
129
130 QVariantMap map;
131 Q_FOREACH (const QByteArray &roleName, roleNames().values())
132 map.insert(roleName, QVariant());
133
134 context->setContextProperty("model", map);
135 context->setContextProperty("index", -1);
136
137 delete (m_filterExpression);
138 m_filterExpression = new QQmlExpression(m_filterScriptString, context, 0, this);
139 connect(m_filterExpression, &QQmlExpression::valueChanged, this,
140 &QQmlSortFilterProxyModel::invalidateFilter);
141 m_filterExpression->setNotifyOnValueChanged(true);
142 m_filterExpression->evaluate();
143
144 emit filterExpressionChanged();
145}
146
147const QString &QQmlSortFilterProxyModel::sortRoleName() const
148{
149 return m_sortRoleName;
150}
151
152void QQmlSortFilterProxyModel::setSortRoleName(const QString &sortRoleName)
153{
154 if (m_sortRoleName == sortRoleName)
155 return;
156
157 m_sortRoleName = sortRoleName;
158 updateSortRole();
159 emit sortRoleNameChanged();
160}
161
162void QQmlSortFilterProxyModel::setSortOrder(Qt::SortOrder sortOrder)
163{
164 if (!m_sortRoleName.isEmpty())
165 sort(0, sortOrder);
166}
167
168const QQmlScriptString &QQmlSortFilterProxyModel::sortExpression() const
169{
170 return m_compareScriptString;
171}
172
173void QQmlSortFilterProxyModel::setSortExpression(const QQmlScriptString &compareScriptString)
174{
175 if (m_compareScriptString == compareScriptString)
176 return;
177
178 m_compareScriptString = compareScriptString;
179 QQmlContext *context = new QQmlContext(qmlContext(this));
180
181 QVariantMap map;
182 Q_FOREACH (const QByteArray &roleName, roleNames().values())
183 map.insert(roleName, QVariant());
184
185 context->setContextProperty("modelLeft", map);
186 context->setContextProperty("indexLeft", -1);
187 context->setContextProperty("modelRight", map);
188 context->setContextProperty("indexRight", -1);
189
190 delete (m_compareExpression);
191 m_compareExpression = new QQmlExpression(m_compareScriptString, context, 0, this);
192 connect(m_compareExpression, &QQmlExpression::valueChanged, this,
193 &QQmlSortFilterProxyModel::invalidate);
194 m_compareExpression->setNotifyOnValueChanged(true);
195 m_compareExpression->evaluate();
196
197 emit sortExpressionChanged();
198}
199
200bool QQmlSortFilterProxyModel::filterAcceptsRow(int source_row,
201 const QModelIndex &source_parent) const
202{
203 QModelIndex modelIndex = sourceModel()->index(source_row, 0, source_parent);
204 bool valueAccepted = !m_filterValue.isValid()
205 || (m_filterValue == sourceModel()->data(modelIndex, filterRole()));
206 bool baseAcceptsRow =
207 valueAccepted && QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
208 if (baseAcceptsRow && !m_filterScriptString.isEmpty()) {
209 QVariantMap map = modelDataMap(modelIndex);
210
211 QQmlContext context(qmlContext(this));
212 context.setContextProperty("model", map);
213 context.setContextProperty("index", source_row);
214 QQmlExpression expression(m_filterScriptString, &context, 0);
215 QVariant result = expression.evaluate();
216
217 if (!expression.hasError())
218 return result.toBool();
219 else
220 qWarning() << expression.error();
221 }
222 return baseAcceptsRow;
223}
224
225bool QQmlSortFilterProxyModel::lessThan(const QModelIndex &source_left,
226 const QModelIndex &source_right) const
227{
228 if (!m_compareScriptString.isEmpty()) {
229 QQmlContext context(qmlContext(this));
230 context.setContextProperty("modelLeft", modelDataMap(source_left));
231 context.setContextProperty("indexLeft", source_left.row());
232 context.setContextProperty("modelRight", modelDataMap(source_right));
233 context.setContextProperty("indexRight", source_right.row());
234
235 QQmlExpression expression(m_compareScriptString, &context, 0);
236 QVariant result = expression.evaluate();
237
238 if (!expression.hasError())
239 return result.toBool();
240 else
241 qWarning() << expression.error();
242 }
243 return QSortFilterProxyModel::lessThan(source_left, source_right);
244}
245
246void QQmlSortFilterProxyModel::invalidateFilter()
247{
248 QSortFilterProxyModel::invalidateFilter();
249}
250
251void QQmlSortFilterProxyModel::updateFilterRole()
252{
253 QList<int> filterRoles = roleNames().keys(m_filterRoleName.toUtf8());
254 if (!filterRoles.empty()) {
255 setFilterRole(filterRoles.first());
256 }
257}
258
259void QQmlSortFilterProxyModel::updateSortRole()
260{
261 QList<int> sortRoles = roleNames().keys(m_sortRoleName.toUtf8());
262 if (!sortRoles.empty()) {
263 setSortRole(sortRoles.first());
264 sort(0, sortOrder());
265 }
266}
267
268void QQmlSortFilterProxyModel::updateRoles()
269{
270 updateFilterRole();
271 updateSortRole();
272}
273
274QVariantMap QQmlSortFilterProxyModel::modelDataMap(const QModelIndex &modelIndex) const
275{
276 QVariantMap map;
277 QHash<int, QByteArray> roles = roleNames();
278 for (QHash<int, QByteArray>::const_iterator it = roles.begin(); it != roles.end(); ++it)
279 map.insert(it.value(), sourceModel()->data(modelIndex, it.key()));
280 return map;
281}
282
283#include "moc_qqmlsortfilterproxymodel.cpp"
diff --git a/core/qqmlsortfilterproxymodel.h b/core/qqmlsortfilterproxymodel.h
new file mode 100644
index 0000000..58f09e7
--- /dev/null
+++ b/core/qqmlsortfilterproxymodel.h
@@ -0,0 +1,129 @@
1/****************************************************************************
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pierre-Yves Siret
5 *
6 * $BEGIN_LICENSE:MIT$
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 *
26 * $END_LICENSE$
27 ***************************************************************************/
28
29#ifndef QQMLSORTFILTERPROXYMODEL_H
30#define QQMLSORTFILTERPROXYMODEL_H
31
32#include <QSortFilterProxyModel>
33#include <QQmlExpression>
34
35class QQmlSortFilterProxyModel : public QSortFilterProxyModel
36{
37 Q_OBJECT
38 Q_PROPERTY(int count READ count NOTIFY countChanged)
39 Q_PROPERTY(QString filterRoleName READ filterRoleName WRITE setFilterRoleName NOTIFY
40 filterRoleNameChanged)
41 Q_PROPERTY(
42 QString filterPattern READ filterPattern WRITE setFilterPattern NOTIFY filterPatternChanged)
43 Q_PROPERTY(PatternSyntax filterPatternSyntax READ filterPatternSyntax WRITE
44 setFilterPatternSyntax NOTIFY filterPatternSyntaxChanged)
45 Q_PROPERTY(QVariant filterValue READ filterValue WRITE setFilterValue NOTIFY filterValueChanged)
46 Q_PROPERTY(QQmlScriptString filterExpression READ filterExpression WRITE setFilterExpression
47 NOTIFY filterExpressionChanged)
48
49 Q_PROPERTY(
50 QString sortRoleName READ sortRoleName WRITE setSortRoleName NOTIFY sortRoleNameChanged)
51 Q_PROPERTY(Qt::SortOrder sortOrder READ sortOrder WRITE setSortOrder)
52 Q_PROPERTY(QQmlScriptString sortExpression READ sortExpression WRITE setSortExpression NOTIFY
53 sortExpressionChanged)
54
55public:
56 enum PatternSyntax {
57 RegExp = QRegExp::RegExp,
58 Wildcard = QRegExp::Wildcard,
59 FixedString = QRegExp::FixedString,
60 RegExp2 = QRegExp::RegExp2,
61 WildcardUnix = QRegExp::WildcardUnix,
62 W3CXmlSchema11 = QRegExp::W3CXmlSchema11
63 };
64 Q_ENUM(PatternSyntax)
65
66 QQmlSortFilterProxyModel(QObject *parent = 0);
67
68 int count() const;
69
70 const QString &filterRoleName() const;
71 void setFilterRoleName(const QString &filterRoleName);
72
73 QString filterPattern() const;
74 void setFilterPattern(const QString &filterPattern);
75
76 PatternSyntax filterPatternSyntax() const;
77 void setFilterPatternSyntax(PatternSyntax patternSyntax);
78
79 const QVariant &filterValue() const;
80 void setFilterValue(const QVariant &filterValue);
81
82 const QQmlScriptString &filterExpression() const;
83 void setFilterExpression(const QQmlScriptString &filterScriptString);
84
85 const QString &sortRoleName() const;
86 void setSortRoleName(const QString &sortRoleName);
87
88 void setSortOrder(Qt::SortOrder sortOrder);
89
90 const QQmlScriptString &sortExpression() const;
91 void setSortExpression(const QQmlScriptString &compareScriptString);
92
93signals:
94 void countChanged();
95
96 void filterRoleNameChanged();
97 void filterPatternSyntaxChanged();
98 void filterPatternChanged();
99 void filterValueChanged();
100 void filterExpressionChanged();
101
102 void sortRoleNameChanged();
103 void sortExpressionChanged();
104
105protected:
106 bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
107 bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const;
108
109private slots:
110 void invalidateFilter();
111 void updateFilterRole();
112 void updateSortRole();
113 void updateRoles();
114
115private:
116 QVariantMap modelDataMap(const QModelIndex &modelIndex) const;
117
118 QString m_filterRoleName;
119 QString m_sortRoleName;
120
121 QQmlScriptString m_filterScriptString;
122 QQmlExpression *m_filterExpression;
123
124 QQmlScriptString m_compareScriptString;
125 QQmlExpression *m_compareExpression;
126 QVariant m_filterValue;
127};
128
129#endif // QQMLSORTFILTERPROXYMODEL_H
diff --git a/core/standardpaths.cpp b/core/standardpaths.cpp
new file mode 100644
index 0000000..ec67683
--- /dev/null
+++ b/core/standardpaths.cpp
@@ -0,0 +1,36 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15#include <QtCore/QStandardPaths>
16
17#include "standardpaths.h"
18
19StandardPaths::StandardPaths(QObject *parent)
20 : QObject(parent)
21{
22}
23
24QString StandardPaths::locateFile(StandardLocation type, const QString &fileName)
25{
26 QStandardPaths::StandardLocation qtype = static_cast<QStandardPaths::StandardLocation>(type);
27 return QStandardPaths::locate(qtype, fileName);
28}
29
30QString StandardPaths::locateDirectory(StandardLocation type, const QString &dirName)
31{
32 QStandardPaths::StandardLocation qtype = static_cast<QStandardPaths::StandardLocation>(type);
33 return QStandardPaths::locate(qtype, dirName, QStandardPaths::LocateDirectory);
34}
35
36#include "moc_standardpaths.cpp"
diff --git a/core/standardpaths.h b/core/standardpaths.h
new file mode 100644
index 0000000..6f3d0bc
--- /dev/null
+++ b/core/standardpaths.h
@@ -0,0 +1,51 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15#ifndef STANDARDPATHS_H
16#define STANDARDPATHS_H
17
18#include <QtCore/QObject>
19
20class StandardPaths : public QObject
21{
22 Q_OBJECT
23public:
24 enum StandardLocation {
25 DesktopLocation,
26 DocumentsLocation,
27 FontsLocation,
28 ApplicationsLocation,
29 MusicLocation,
30 MoviesLocation,
31 PicturesLocation,
32 TempLocation,
33 HomeLocation,
34 DataLocation,
35 CacheLocation,
36 GenericDataLocation,
37 RuntimeLocation,
38 ConfigLocation,
39 DownloadLocation,
40 GenericCacheLocation,
41 GenericConfigLocation
42 };
43 Q_ENUM(StandardLocation)
44
45 StandardPaths(QObject *parent = 0);
46
47 Q_INVOKABLE QString locateFile(StandardLocation type, const QString &fileName);
48 Q_INVOKABLE QString locateDirectory(StandardLocation type, const QString &dirName);
49};
50
51#endif // STANDARDPATHS_H
diff --git a/demo/+material/StyledRectangle.qml b/demo/+material/StyledRectangle.qml
new file mode 100644
index 0000000..7da64ab
--- /dev/null
+++ b/demo/+material/StyledRectangle.qml
@@ -0,0 +1,22 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls.Material 2.0
17
18Rectangle {
19 color: Material.background
20
21 Material.theme: index == 0 ? Material.Light : Material.Dark
22}
diff --git a/demo/+universal/StyledRectangle.qml b/demo/+universal/StyledRectangle.qml
new file mode 100644
index 0000000..ca1999b
--- /dev/null
+++ b/demo/+universal/StyledRectangle.qml
@@ -0,0 +1,22 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls.Universal 2.0
17
18Rectangle {
19 color: Universal.background
20
21 Universal.theme: index == 0 ? Universal.Light : Universal.Dark
22}
diff --git a/demo/BasicComponents.qml b/demo/BasicComponents.qml
new file mode 100644
index 0000000..a46f083
--- /dev/null
+++ b/demo/BasicComponents.qml
@@ -0,0 +1,80 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls 2.0
17import QtQuick.Controls.Material 2.0
18import QtQuick.Controls.Universal 2.0
19import Fluid.Controls 1.0
20import "Pages/Basic"
21
22Tab {
23 title: qsTr("Basic")
24
25 Pane {
26 id: listPane
27 anchors {
28 left: parent.left
29 top: parent.top
30 bottom: parent.bottom
31 }
32 width: 200
33 padding: 0
34 z: 2
35
36 Material.background: "white"
37 Material.elevation: 1
38
39 Universal.background: Universal.accent
40
41 ListView {
42 id: listView
43 anchors.fill: parent
44 currentIndex: 0
45 model: ListModel {
46 ListElement { title: qsTr("Button"); source: "qrc:/Pages/Basic/ButtonPage.qml" }
47 ListElement { title: qsTr("CheckBox"); source: "qrc:/Pages/Basic/CheckBoxPage.qml" }
48 ListElement { title: qsTr("RadioButton"); source: "qrc:/Pages/Basic/RadioButtonPage.qml" }
49 ListElement { title: qsTr("Switch"); source: "qrc:/Pages/Basic/SwitchPage.qml" }
50 ListElement { title: qsTr("ProgressBar"); source: "qrc:/Pages/Basic/ProgressBarPage.qml" }
51 ListElement { title: qsTr("BusyIndicator"); source: "qrc:/Pages/Basic/BusyIndicatorPage.qml" }
52 ListElement { title: qsTr("Slider"); source: "qrc:/Pages/Basic/SliderPage.qml" }
53 }
54 header: Subheader {
55 text: qsTr("Demos")
56 }
57 delegate: ListItem {
58 text: model.title
59 highlighted: ListView.isCurrentItem
60 onClicked: {
61 listView.currentIndex = index
62 stackView.push(model.source)
63 }
64 }
65
66 ScrollBar.vertical: ScrollBar {}
67 }
68 }
69
70 StackView {
71 id: stackView
72 anchors {
73 left: listPane.right
74 top: parent.top
75 right: parent.right
76 bottom: parent.bottom
77 }
78 initialItem: ButtonPage {}
79 }
80}
diff --git a/demo/CMakeLists.txt b/demo/CMakeLists.txt
new file mode 100644
index 0000000..a4f9ab6
--- /dev/null
+++ b/demo/CMakeLists.txt
@@ -0,0 +1,10 @@
1set(SOURCES main.cpp demo.qrc)
2file(GLOB_RECURSE QML_SOURCES
3 RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.qml")
4
5add_executable(fluid-demo ${SOURCES} ${QML_SOURCES})
6target_link_libraries(fluid-demo Qt5::Gui Qt5::Qml Qt5::QuickControls2)
7
8install(TARGETS fluid-demo
9 BUNDLE DESTINATION .
10 RUNTIME DESTINATION ${BIN_INSTALL_DIR})
diff --git a/demo/CompoundComponents.qml b/demo/CompoundComponents.qml
new file mode 100644
index 0000000..2de7bd2
--- /dev/null
+++ b/demo/CompoundComponents.qml
@@ -0,0 +1,76 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls 2.0
17import QtQuick.Controls.Material 2.0
18import QtQuick.Controls.Universal 2.0
19import Fluid.Controls 1.0
20import "Pages/Compound"
21
22Tab {
23 title: qsTr("Compound")
24
25 Pane {
26 id: listPane
27 anchors {
28 left: parent.left
29 top: parent.top
30 bottom: parent.bottom
31 }
32 width: 200
33 padding: 0
34 z: 2
35
36 Material.background: "white"
37 Material.elevation: 1
38
39 Universal.background: Universal.accent
40
41 ListView {
42 id: listView
43 anchors.fill: parent
44 currentIndex: 0
45 model: ListModel {
46 ListElement { title: qsTr("ListItem"); source: "qrc:/Pages/Compound/ListItemPage.qml" }
47 ListElement { title: qsTr("Card"); source: "qrc:/Pages/Compound/CardPage.qml" }
48 ListElement { title: qsTr("InfoBar"); source: "qrc:/Pages/Compound/InfoBarPage.qml" }
49 }
50 header: Subheader {
51 text: qsTr("Demos")
52 }
53 delegate: ListItem {
54 text: model.title
55 highlighted: ListView.isCurrentItem
56 onClicked: {
57 listView.currentIndex = index
58 stackView.push(model.source)
59 }
60 }
61
62 ScrollBar.vertical: ScrollBar {}
63 }
64 }
65
66 StackView {
67 id: stackView
68 anchors {
69 left: listPane.right
70 top: parent.top
71 right: parent.right
72 bottom: parent.bottom
73 }
74 initialItem: ListItemPage {}
75 }
76}
diff --git a/demo/MaterialComponents.qml b/demo/MaterialComponents.qml
new file mode 100644
index 0000000..444b049
--- /dev/null
+++ b/demo/MaterialComponents.qml
@@ -0,0 +1,74 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls 2.0
17import QtQuick.Controls.Material 2.0
18import QtQuick.Controls.Universal 2.0
19import Fluid.Controls 1.0
20import "Pages/Material"
21
22Tab {
23 title: qsTr("Material")
24
25 Pane {
26 id: listPane
27 anchors {
28 left: parent.left
29 top: parent.top
30 bottom: parent.bottom
31 }
32 width: 200
33 padding: 0
34 z: 2
35
36 Material.background: "white"
37 Material.elevation: 1
38
39 Universal.background: Universal.accent
40
41 ListView {
42 id: listView
43 anchors.fill: parent
44 currentIndex: 0
45 model: ListModel {
46 ListElement { title: qsTr("ActionButton"); source: "qrc:/Pages/Material/ActionButtonPage.qml" }
47 }
48 header: Subheader {
49 text: qsTr("Demos")
50 }
51 delegate: ListItem {
52 text: model.title
53 highlighted: ListView.isCurrentItem
54 onClicked: {
55 listView.currentIndex = index
56 stackView.push(model.source)
57 }
58 }
59
60 ScrollBar.vertical: ScrollBar {}
61 }
62 }
63
64 StackView {
65 id: stackView
66 anchors {
67 left: listPane.right
68 top: parent.top
69 right: parent.right
70 bottom: parent.bottom
71 }
72 initialItem: ActionButtonPage {}
73 }
74}
diff --git a/demo/NavigationComponents.qml b/demo/NavigationComponents.qml
new file mode 100644
index 0000000..ce0a2fd
--- /dev/null
+++ b/demo/NavigationComponents.qml
@@ -0,0 +1,74 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls 2.0
17import QtQuick.Controls.Material 2.0
18import QtQuick.Controls.Universal 2.0
19import Fluid.Controls 1.0
20import "Pages/Navigation"
21
22Tab {
23 title: qsTr("Navigation")
24
25 Pane {
26 id: listPane
27 anchors {
28 left: parent.left
29 top: parent.top
30 bottom: parent.bottom
31 }
32 width: 200
33 padding: 0
34 z: 2
35
36 Material.background: "white"
37 Material.elevation: 1
38
39 Universal.background: Universal.accent
40
41 ListView {
42 id: listView
43 anchors.fill: parent
44 currentIndex: 0
45 model: ListModel {
46 ListElement { title: qsTr("NavigationDrawer"); source: "qrc:/Pages/Navigation/NavDrawerPage.qml" }
47 }
48 header: Subheader {
49 text: qsTr("Demos")
50 }
51 delegate: ListItem {
52 text: model.title
53 highlighted: ListView.isCurrentItem
54 onClicked: {
55 listView.currentIndex = index
56 stackView.push(model.source)
57 }
58 }
59
60 ScrollBar.vertical: ScrollBar {}
61 }
62 }
63
64 StackView {
65 id: stackView
66 anchors {
67 left: listPane.right
68 top: parent.top
69 right: parent.right
70 bottom: parent.bottom
71 }
72 initialItem: NavDrawerPage {}
73 }
74}
diff --git a/demo/Pages/Basic/BusyIndicatorPage.qml b/demo/Pages/Basic/BusyIndicatorPage.qml
new file mode 100644
index 0000000..1a6341e
--- /dev/null
+++ b/demo/Pages/Basic/BusyIndicatorPage.qml
@@ -0,0 +1,44 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls 2.0
17import QtQuick.Layouts 1.0
18import "../.."
19
20Flickable {
21 clip: true
22 contentHeight: Math.max(layout.implicitHeight, height)
23
24 ScrollBar.vertical: ScrollBar {}
25
26 ColumnLayout {
27 id: layout
28 anchors.fill: parent
29
30 Repeater {
31 model: 2
32
33 StyledRectangle {
34 Layout.fillWidth: true
35 Layout.fillHeight: true
36
37 BusyIndicator {
38 anchors.centerIn: parent
39 running: true
40 }
41 }
42 }
43 }
44}
diff --git a/demo/Pages/Basic/ButtonPage.qml b/demo/Pages/Basic/ButtonPage.qml
new file mode 100644
index 0000000..6cf94fe
--- /dev/null
+++ b/demo/Pages/Basic/ButtonPage.qml
@@ -0,0 +1,115 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls 2.0
17import QtQuick.Layouts 1.0
18import Fluid.Controls 1.0
19import "../.."
20
21Flickable {
22 clip: true
23 contentHeight: Math.max(layout.implicitHeight, height)
24
25 ScrollBar.vertical: ScrollBar {}
26
27 ColumnLayout {
28 id: layout
29 anchors.fill: parent
30
31 Repeater {
32 model: 2
33
34 StyledRectangle {
35 Layout.fillWidth: true
36 Layout.fillHeight: true
37 Layout.minimumWidth: grid.width + 80
38 Layout.minimumHeight: grid.height + 80
39
40 GridLayout {
41 id: grid
42 anchors.centerIn: parent
43 columns: 2
44 rows: 4
45
46 // Row 1
47
48 TitleLabel {
49 text: qsTr("Enabled")
50
51 Layout.alignment: Qt.AlignHCenter
52 }
53
54 TitleLabel {
55 text: qsTr("Disabled")
56
57 Layout.alignment: Qt.AlignHCenter
58 }
59
60 // Row 2
61
62 Button {
63 text: qsTr("Button")
64 }
65
66 Button {
67 text: qsTr("Button")
68 enabled: false
69 }
70
71 // Row 3
72
73 Button {
74 text: qsTr("Checked")
75 checkable: false
76 checked: true
77 }
78
79 Button {
80 text: qsTr("Checked")
81 checkable: false
82 checked: true
83 enabled: false
84 }
85
86 // Row 4
87
88 Button {
89 text: qsTr("Flat")
90 flat: true
91 }
92
93 Button {
94 text: qsTr("Flat")
95 flat: true
96 enabled: false
97 }
98
99 // Row 5
100
101 Button {
102 text: qsTr("Highlighted")
103 highlighted: true
104 }
105
106 Button {
107 text: qsTr("Highlighted")
108 highlighted: true
109 enabled: false
110 }
111 }
112 }
113 }
114 }
115}
diff --git a/demo/Pages/Basic/CheckBoxPage.qml b/demo/Pages/Basic/CheckBoxPage.qml
new file mode 100644
index 0000000..6e53e73
--- /dev/null
+++ b/demo/Pages/Basic/CheckBoxPage.qml
@@ -0,0 +1,101 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
6 *
7 * $BEGIN_LICENSE:MPL2$
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
13 * $END_LICENSE$
14 */
15
16import QtQuick 2.0
17import QtQuick.Controls 2.0
18import QtQuick.Layouts 1.0
19import Fluid.Controls 1.0
20import "../.."
21
22Flickable {
23 clip: true
24 contentHeight: Math.max(layout.implicitHeight, height)
25
26 ScrollBar.vertical: ScrollBar {}
27
28 ColumnLayout {
29 id: layout
30 anchors.fill: parent
31
32 Repeater {
33 model: 2
34
35 StyledRectangle {
36 Layout.fillWidth: true
37 Layout.fillHeight: true
38 Layout.minimumWidth: grid.width + 80
39 Layout.minimumHeight: grid.height + 80
40
41 GridLayout {
42 id: grid
43 anchors.centerIn: parent
44 columns: 3
45 rows: 3
46
47 // Row 1
48
49 Item {
50 width: 1
51 height: 1
52 }
53
54 TitleLabel {
55 text: qsTr("Enabled")
56
57 Layout.alignment: Qt.AlignHCenter
58 }
59
60 TitleLabel {
61 text: qsTr("Disabled")
62
63 Layout.alignment: Qt.AlignHCenter
64 }
65
66 // Row 2
67
68 Label {
69 text: qsTr("On")
70 }
71
72 CheckBox {
73 checked: true
74 text: qsTr("CheckBox")
75 }
76
77 CheckBox {
78 checked: true
79 enabled: false
80 text: qsTr("CheckBox")
81 }
82
83 // Row 3
84
85 Label {
86 text: qsTr("Off")
87 }
88
89 CheckBox {
90 text: qsTr("CheckBox")
91 }
92
93 CheckBox {
94 text: qsTr("CheckBox")
95 enabled: false
96 }
97 }
98 }
99 }
100 }
101}
diff --git a/demo/Pages/Basic/ProgressBarPage.qml b/demo/Pages/Basic/ProgressBarPage.qml
new file mode 100644
index 0000000..440db51
--- /dev/null
+++ b/demo/Pages/Basic/ProgressBarPage.qml
@@ -0,0 +1,127 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls 2.0
17import QtQuick.Layouts 1.0
18import Fluid.Controls 1.0
19import "../.."
20
21Flickable {
22 clip: true
23 contentHeight: Math.max(layout.implicitHeight, height)
24
25 ScrollBar.vertical: ScrollBar {}
26
27 ColumnLayout {
28 id: layout
29 anchors.fill: parent
30
31 Repeater {
32 model: 2
33
34 StyledRectangle {
35 Layout.fillWidth: true
36 Layout.fillHeight: true
37 Layout.minimumWidth: grid.width + 80
38 Layout.minimumHeight: grid.height + 80
39
40 GridLayout {
41 id: grid
42 anchors.centerIn: parent
43 columns: 3
44
45 // Row 1
46
47 Item {
48 width: 1
49 height: 1
50 }
51
52 TitleLabel {
53 text: qsTr("Determinate")
54
55 Layout.alignment: Qt.AlignHCenter
56 }
57
58 TitleLabel {
59 text: qsTr("Indeterminate")
60
61 Layout.alignment: Qt.AlignHCenter
62 }
63
64 // Row 2
65
66 Label {
67 text: qsTr("Static")
68 }
69
70 ProgressBar {
71 from: 0.0
72 to: 1.0
73 value: 0.5
74 indeterminate: false
75 }
76
77 ProgressBar {
78 from: 0.0
79 to: 1.0
80 value: 0.5
81 indeterminate: true
82 }
83
84 // Row 3
85
86 Label {
87 text: qsTr("Animated")
88 }
89
90 ProgressBar {
91 from: 0.0
92 to: 1.0
93 indeterminate: false
94
95 SequentialAnimation on value {
96 running: true
97 loops: NumberAnimation.Infinite
98
99 NumberAnimation {
100 from: 0.0
101 to: 1.0
102 duration: 3000
103 }
104 }
105 }
106
107 ProgressBar {
108 from: 0.0
109 to: 1.0
110 indeterminate: true
111
112 SequentialAnimation on value {
113 running: true
114 loops: NumberAnimation.Infinite
115
116 NumberAnimation {
117 from: 0.0
118 to: 1.0
119 duration: 3000
120 }
121 }
122 }
123 }
124 }
125 }
126 }
127}
diff --git a/demo/Pages/Basic/RadioButtonPage.qml b/demo/Pages/Basic/RadioButtonPage.qml
new file mode 100644
index 0000000..80c98d5
--- /dev/null
+++ b/demo/Pages/Basic/RadioButtonPage.qml
@@ -0,0 +1,100 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls 2.0
17import QtQuick.Layouts 1.0
18import Fluid.Controls 1.0
19import "../.."
20
21Flickable {
22 clip: true
23 contentHeight: Math.max(layout.implicitHeight, height)
24
25 ScrollBar.vertical: ScrollBar {}
26
27 ColumnLayout {
28 id: layout
29 anchors.fill: parent
30
31 Repeater {
32 model: 2
33
34 StyledRectangle {
35 Layout.fillWidth: true
36 Layout.fillHeight: true
37 Layout.minimumWidth: grid.width + 80
38 Layout.minimumHeight: grid.height + 80
39
40 GridLayout {
41 id: grid
42 anchors.centerIn: parent
43 columns: 3
44 rows: 3
45
46 // Row 1
47
48 Item {
49 width: 1
50 height: 1
51 }
52
53 TitleLabel {
54 text: qsTr("Enabled")
55
56 Layout.alignment: Qt.AlignHCenter
57 }
58
59 TitleLabel {
60 text: qsTr("Disabled")
61
62 Layout.alignment: Qt.AlignHCenter
63 }
64
65 // Row 2
66
67 Label {
68 text: qsTr("On")
69 }
70
71 RadioButton {
72 checked: true
73 text: qsTr("RadioButton")
74 }
75
76 RadioButton {
77 checked: true
78 enabled: false
79 text: qsTr("RadioButton")
80 }
81
82 // Row 3
83
84 Label {
85 text: qsTr("Off")
86 }
87
88 RadioButton {
89 text: qsTr("RadioButton")
90 }
91
92 RadioButton {
93 text: qsTr("RadioButton")
94 enabled: false
95 }
96 }
97 }
98 }
99 }
100}
diff --git a/demo/Pages/Basic/SliderPage.qml b/demo/Pages/Basic/SliderPage.qml
new file mode 100644
index 0000000..72d9c11
--- /dev/null
+++ b/demo/Pages/Basic/SliderPage.qml
@@ -0,0 +1,152 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls 2.0
17import QtQuick.Layouts 1.0
18import Fluid.Controls 1.0
19import "../.."
20
21Flickable {
22 clip: true
23 contentHeight: Math.max(layout.implicitHeight, height)
24
25 ScrollBar.vertical: ScrollBar {}
26
27 ColumnLayout {
28 id: layout
29 anchors.fill: parent
30
31 Repeater {
32 model: 2
33
34 StyledRectangle {
35 Layout.fillWidth: true
36 Layout.fillHeight: true
37 Layout.minimumWidth: grid.width + 80
38 Layout.minimumHeight: grid.height + 80
39
40 GridLayout {
41 id: grid
42 anchors.centerIn: parent
43 columns: 3
44 rows: 3
45
46 // Row 1
47
48 Item {
49 width: 1
50 height: 1
51 }
52
53 TitleLabel {
54 text: qsTr("Enabled")
55
56 Layout.alignment: Qt.AlignHCenter
57 }
58
59 TitleLabel {
60 text: qsTr("Disabled")
61
62 Layout.alignment: Qt.AlignHCenter
63 }
64
65 // Row 2
66
67 Label {
68 text: qsTr("Horizontal / Single")
69 }
70
71 Slider {
72 from: 0.0
73 to: 1.0
74 value: 0.5
75 }
76
77 Slider {
78 from: 0.0
79 to: 1.0
80 value: 0.5
81 enabled: false
82 }
83
84 // Row 3
85
86 Label {
87 text: qsTr("Horizontal / Range")
88 }
89
90 RangeSlider {
91 from: 0.0
92 to: 1.0
93 first.value: 0.4
94 second.value: 0.6
95 }
96
97 RangeSlider {
98 from: 0.0
99 to: 1.0
100 first.value: 0.4
101 second.value: 0.6
102 enabled: false
103 }
104
105 // Row 4
106
107 Label {
108 text: qsTr("Vertical / Single")
109 }
110
111 Slider {
112 from: 0.0
113 to: 1.0
114 value: 0.5
115 orientation: Qt.Vertical
116 }
117
118 Slider {
119 from: 0.0
120 to: 1.0
121 value: 0.5
122 enabled: false
123 orientation: Qt.Vertical
124 }
125
126 // Row 5
127
128 Label {
129 text: qsTr("Vertical / Range")
130 }
131
132 RangeSlider {
133 from: 0.0
134 to: 1.0
135 first.value: 0.4
136 second.value: 0.6
137 orientation: Qt.Vertical
138 }
139
140 RangeSlider {
141 from: 0.0
142 to: 1.0
143 first.value: 0.4
144 second.value: 0.6
145 enabled: false
146 orientation: Qt.Vertical
147 }
148 }
149 }
150 }
151 }
152}
diff --git a/demo/Pages/Basic/SwitchPage.qml b/demo/Pages/Basic/SwitchPage.qml
new file mode 100644
index 0000000..15c679b
--- /dev/null
+++ b/demo/Pages/Basic/SwitchPage.qml
@@ -0,0 +1,100 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls 2.0
17import QtQuick.Layouts 1.0
18import Fluid.Controls 1.0
19import "../.."
20
21Flickable {
22 clip: true
23 contentHeight: Math.max(layout.implicitHeight, height)
24
25 ScrollBar.vertical: ScrollBar {}
26
27 ColumnLayout {
28 id: layout
29 anchors.fill: parent
30
31 Repeater {
32 model: 2
33
34 StyledRectangle {
35 Layout.fillWidth: true
36 Layout.fillHeight: true
37 Layout.minimumWidth: grid.width + 80
38 Layout.minimumHeight: grid.height + 80
39
40 GridLayout {
41 id: grid
42 anchors.centerIn: parent
43 columns: 3
44 rows: 3
45
46 // Row 1
47
48 Item {
49 width: 1
50 height: 1
51 }
52
53 TitleLabel {
54 text: qsTr("Enabled")
55
56 Layout.alignment: Qt.AlignHCenter
57 }
58
59 TitleLabel {
60 text: qsTr("Disabled")
61
62 Layout.alignment: Qt.AlignHCenter
63 }
64
65 // Row 2
66
67 Label {
68 text: qsTr("On")
69 }
70
71 Switch {
72 checked: true
73 text: qsTr("Switch")
74 }
75
76 Switch {
77 checked: true
78 enabled: false
79 text: qsTr("Switch")
80 }
81
82 // Row 3
83
84 Label {
85 text: qsTr("Off")
86 }
87
88 Switch {
89 text: qsTr("Switch")
90 }
91
92 Switch {
93 text: qsTr("Switch")
94 enabled: false
95 }
96 }
97 }
98 }
99 }
100}
diff --git a/demo/Pages/Compound/CardPage.qml b/demo/Pages/Compound/CardPage.qml
new file mode 100644
index 0000000..ec33a3e
--- /dev/null
+++ b/demo/Pages/Compound/CardPage.qml
@@ -0,0 +1,76 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls 2.0
17import Fluid.Controls 1.0
18
19Item {
20 Card {
21 id: card
22 anchors.centerIn: parent
23 width: 400
24 height: 400
25
26 Image {
27 id: picture
28 anchors {
29 left: parent.left
30 top: parent.top
31 right: parent.right
32 }
33 height: 200
34 source: "https://www.nps.gov/yose/planyourvisit/images/glacier-point-people-960web.jpg"
35 }
36
37 Column {
38 id: column
39 anchors {
40 left: parent.left
41 top: picture.bottom
42 right: parent.right
43 margins: Units.smallSpacing * 2
44 }
45 spacing: Units.smallSpacing * 2
46
47 TitleLabel {
48 text: qsTr("Yosemite National Park")
49 }
50
51 BodyLabel {
52 text: qsTr("First protected in 1864, Yosemite National Park " +
53 "is best known for its waterfalls, but within its " +
54 "nearly 1,200 square miles, you can find deep " +
55 "valleys, grand meadows, ancient giant sequoias, " +
56 "a vast wilderness area, and much more.")
57 wrapMode: Text.WordWrap
58 width: parent.width
59 }
60
61 Row {
62 spacing: Units.smallSpacing
63
64 Button {
65 text: qsTr("Share")
66 flat: true
67 }
68
69 Button {
70 text: qsTr("Explore")
71 flat: true
72 }
73 }
74 }
75 }
76}
diff --git a/demo/Pages/Compound/InfoBarPage.qml b/demo/Pages/Compound/InfoBarPage.qml
new file mode 100644
index 0000000..1830e39
--- /dev/null
+++ b/demo/Pages/Compound/InfoBarPage.qml
@@ -0,0 +1,30 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls 2.0
17import Fluid.Controls 1.0
18
19Item {
20 Button {
21 anchors.centerIn: parent
22 text: qsTr("Open")
23 onClicked: infoBar.open(qsTr("Message sent"))
24 }
25
26 InfoBar {
27 id: infoBar
28 buttonText: qsTr("OK")
29 }
30}
diff --git a/demo/Pages/Compound/ListItemPage.qml b/demo/Pages/Compound/ListItemPage.qml
new file mode 100644
index 0000000..f86f81b
--- /dev/null
+++ b/demo/Pages/Compound/ListItemPage.qml
@@ -0,0 +1,40 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls 2.0
17import Fluid.Controls 1.0
18import "../.."
19
20Page {
21 ListView {
22 anchors.fill: parent
23 model: ListModel {
24 ListElement { title: "List Item 1"; source: "qrc:/Pages/Compound/SubPage.qml" }
25 ListElement { title: "List Item 2"; source: "qrc:/Pages/Compound/SubPage.qml" }
26 ListElement { title: "List Item 3"; source: "qrc:/Pages/Compound/SubPage.qml" }
27 ListElement { title: "List Item 4"; source: "qrc:/Pages/Compound/SubPage.qml" }
28 ListElement { title: "List Item 5"; source: "qrc:/Pages/Compound/SubPage.qml" }
29 }
30 header: Subheader {
31 text: "Header"
32 }
33 delegate: ListItem {
34 text: model.title
35 onClicked: pageStack.push(model.source)
36 }
37
38 ScrollIndicator.vertical: ScrollIndicator {}
39 }
40}
diff --git a/demo/Pages/Compound/SubPage.qml b/demo/Pages/Compound/SubPage.qml
new file mode 100644
index 0000000..8a86a28
--- /dev/null
+++ b/demo/Pages/Compound/SubPage.qml
@@ -0,0 +1,31 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick.Controls 2.0
16import Fluid.Controls 1.0
17
18Page {
19 title: "Sub page demo"
20
21 actions: [
22 Action {
23 iconName: "action/settings"
24 }
25 ]
26
27 Label {
28 anchors.centerIn: parent
29 text: "Testing"
30 }
31}
diff --git a/demo/Pages/Material/ActionButtonPage.qml b/demo/Pages/Material/ActionButtonPage.qml
new file mode 100644
index 0000000..1fcf516
--- /dev/null
+++ b/demo/Pages/Material/ActionButtonPage.qml
@@ -0,0 +1,68 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls 2.0
17import QtQuick.Controls.Material 2.0
18import Fluid.Material 1.0
19import "../.."
20
21Flickable {
22 clip: true
23 contentHeight: Math.max(layout.implicitHeight, height)
24
25 ScrollBar.vertical: ScrollBar {}
26
27 Column {
28 id: layout
29 anchors.fill: parent
30
31 Repeater {
32 model: 2
33
34 StyledRectangle {
35 //y: height * index
36 width: parent.width
37 height: parent.height / 2
38
39 Column {
40 anchors.centerIn: parent
41
42 ActionButton {
43 iconName: "device/airplanemode_active"
44 }
45
46 ActionButton {
47 iconName: "navigation/check"
48
49 Material.elevation: 1
50 }
51
52 ActionButton {
53 iconName: "device/airplanemode_active"
54
55 Material.background: Material.primaryColor
56 }
57
58 ActionButton {
59 iconName: "navigation/check"
60
61 Material.elevation: 1
62 Material.background: Material.primaryColor
63 }
64 }
65 }
66 }
67 }
68}
diff --git a/demo/Pages/Material/WavePage.qml b/demo/Pages/Material/WavePage.qml
new file mode 100644
index 0000000..58cae01
--- /dev/null
+++ b/demo/Pages/Material/WavePage.qml
@@ -0,0 +1,41 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls 2.0
17import QtQuick.Controls.Material 2.0
18import Fluid.Controls 1.0
19import Fluid.Material 1.0
20import "../.."
21
22Item {
23 Wave {
24 id: wave
25 initialX: parent.width - size
26 initialY: parent.height - size
27 size: 48
28 color: Material.accentColor
29 }
30
31 Button {
32 anchors.centerIn: parent
33 text: qsTr("Toggle")
34 onClicked: {
35 if (wave.opened)
36 wave.close(parent.width - wave.size, parent.height - wave.size)
37 else
38 wave.open(0, 0)
39 }
40 }
41}
diff --git a/demo/Pages/Navigation/NavDrawerPage.qml b/demo/Pages/Navigation/NavDrawerPage.qml
new file mode 100644
index 0000000..4c7dd21
--- /dev/null
+++ b/demo/Pages/Navigation/NavDrawerPage.qml
@@ -0,0 +1,26 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls 2.0
17import Fluid.Controls 1.0
18import "../.."
19
20Item {
21 Button {
22 anchors.centerIn: parent
23 text: qsTr("Open")
24 onClicked: navDrawer.open()
25 }
26}
diff --git a/demo/Pages/Style/PalettePage.qml b/demo/Pages/Style/PalettePage.qml
new file mode 100644
index 0000000..bc34dab
--- /dev/null
+++ b/demo/Pages/Style/PalettePage.qml
@@ -0,0 +1,135 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls 2.0
17import QtQuick.Controls.Material 2.0
18import QtQuick.Layouts 1.0
19import Fluid.Core 1.0
20import Fluid.Controls 1.0
21import "../.."
22
23Flickable {
24 clip: true
25 contentHeight: Math.max(grid.implicitHeight, height)
26
27 ScrollBar.vertical: ScrollBar {}
28
29 property color whiteColor: Qt.rgba(255, 255, 255, 1)
30 property color blackColor: Qt.rgba(0, 0, 0, 1)
31
32 GridLayout {
33 id: grid
34
35 anchors {
36 top: parent.top
37 bottom: parent.bottom
38 horizontalCenter: parent.horizontalCenter
39 topMargin: Units.largeSpacing
40 }
41
42 width: parent.width * 0.8
43
44 columns: width / 300
45 rowSpacing: Units.smallSpacing
46 columnSpacing: Units.smallSpacing
47
48 Repeater {
49 model: ListModel {
50 ListElement {
51 paletteIndex: Material.Red
52 name: "Red"
53 }
54 ListElement {
55 paletteIndex: Material.Pink
56 name: "Pink"
57 }
58 ListElement {
59 paletteIndex: Material.Purple
60 name: "Purple"
61 }
62 ListElement {
63 paletteIndex: Material.DeepPurple
64 name: "DeepPurple"
65 }
66 ListElement {
67 paletteIndex: Material.Indigo
68 name: "Indigo"
69 }
70 ListElement {
71 paletteIndex: Material.Blue
72 name: "Blue"
73 }
74 ListElement {
75 paletteIndex: Material.LightBlue
76 name: "LightBlue"
77 }
78 ListElement {
79 paletteIndex: Material.Cyan
80 name: "Cyan"
81 }
82 ListElement {
83 paletteIndex: Material.Teal
84 name: "Teal"
85 }
86 ListElement {
87 paletteIndex: Material.Green
88 name: "Green"
89 }
90 ListElement {
91 paletteIndex: Material.LightGreen
92 name: "LightGreen"
93 }
94 ListElement {
95 paletteIndex: Material.Lime
96 name: "Lime"
97 }
98 ListElement {
99 paletteIndex: Material.Yellow
100 name: "Yellow"
101 }
102 ListElement {
103 paletteIndex: Material.Amber
104 name: "Amber"
105 }
106 ListElement {
107 paletteIndex: Material.Orange
108 name: "Orange"
109 }
110 ListElement {
111 paletteIndex: Material.DeepOrange
112 name: "DeepOrange"
113 }
114 ListElement {
115 paletteIndex: Material.Grey
116 name: "Grey"
117 }
118 ListElement {
119 paletteIndex: Material.BlueGrey
120 name: "BlueGrey"
121 }
122 ListElement {
123 paletteIndex: Material.Brown
124 name: "Brown"
125 }
126 }
127
128 PaletteSwatch {
129 paletteIndex: model.paletteIndex
130 paletteName: model.name
131 paletteColor: Material.color(model.paletteIndex, Material.Shade500)
132 }
133 }
134 }
135}
diff --git a/demo/Pages/Style/PaletteSwatch.qml b/demo/Pages/Style/PaletteSwatch.qml
new file mode 100644
index 0000000..ac5c9b3
--- /dev/null
+++ b/demo/Pages/Style/PaletteSwatch.qml
@@ -0,0 +1,173 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls 2.0
17import QtQuick.Controls.Material 2.0
18import Fluid.Core 1.0
19import Fluid.Controls 1.0
20import "../.."
21
22Column {
23 id: mainLayout
24
25 property int paletteIndex
26 property string paletteName
27 property color paletteColor
28
29 spacing: 0
30
31 Rectangle {
32 width: 300
33 height: 80
34 color: paletteColor
35
36 Label {
37 anchors {
38 top: parent.top
39 left: parent.left
40 margins: Units.smallSpacing * 2
41 }
42 font.bold: true
43 color: Utils.lightDark(parent.color, blackColor, whiteColor)
44 text: paletteName
45 }
46 }
47
48 Column {
49 spacing: 0
50
51 Repeater {
52 model: ListModel {
53 ListElement {
54 shadeIndex: Material.Shade100
55 name: "100"
56 }
57 ListElement {
58 shadeIndex: Material.Shade200
59 name: "200"
60 }
61 ListElement {
62 shadeIndex: Material.Shade300
63 name: "300"
64 }
65 ListElement {
66 shadeIndex: Material.Shade400
67 name: "400"
68 }
69 ListElement {
70 shadeIndex: Material.Shade500
71 name: "500"
72 }
73 ListElement {
74 shadeIndex: Material.Shade600
75 name: "600"
76 }
77 ListElement {
78 shadeIndex: Material.Shade700
79 name: "700"
80 }
81 ListElement {
82 shadeIndex: Material.Shade800
83 name: "800"
84 }
85 ListElement {
86 shadeIndex: Material.Shade900
87 name: "900"
88 }
89 }
90
91 Rectangle {
92 width: 300
93 height: 40
94 color: Material.color(paletteIndex, model.shadeIndex)
95
96 Label {
97 anchors {
98 left: parent.left
99 verticalCenter: parent.verticalCenter
100 margins: Units.smallSpacing * 2
101 }
102 font.bold: true
103 color: Utils.lightDark(parent.color, blackColor, whiteColor)
104 text: model.name
105 }
106
107 Label {
108 anchors {
109 right: parent.right
110 verticalCenter: parent.verticalCenter
111 margins: Units.smallSpacing * 2
112 }
113 font.bold: true
114 color: Utils.lightDark(parent.color, blackColor, whiteColor)
115 text: parent.color
116 }
117 }
118 }
119 }
120
121 Column {
122 spacing: 0
123
124 Repeater {
125 model: ListModel {
126 ListElement {
127 shadeIndex: Material.ShadeA100
128 name: "A100"
129 }
130 ListElement {
131 shadeIndex: Material.ShadeA200
132 name: "A200"
133 }
134 ListElement {
135 shadeIndex: Material.ShadeA400
136 name: "A400"
137 }
138 ListElement {
139 shadeIndex: Material.ShadeA700
140 name: "A700"
141 }
142 }
143
144 Rectangle {
145 width: 300
146 height: 40
147 color: Material.color(paletteIndex, model.shadeIndex)
148
149 Label {
150 anchors {
151 left: parent.left
152 verticalCenter: parent.verticalCenter
153 margins: Units.smallSpacing * 2
154 }
155 font.bold: true
156 color: Utils.lightDark(parent.color, blackColor, whiteColor)
157 text: model.name
158 }
159
160 Label {
161 anchors {
162 right: parent.right
163 verticalCenter: parent.verticalCenter
164 margins: Units.smallSpacing * 2
165 }
166 font.bold: true
167 color: Utils.lightDark(parent.color, blackColor, whiteColor)
168 text: parent.color
169 }
170 }
171 }
172 }
173}
diff --git a/demo/Pages/Style/TypographyPage.qml b/demo/Pages/Style/TypographyPage.qml
new file mode 100644
index 0000000..d87d00c
--- /dev/null
+++ b/demo/Pages/Style/TypographyPage.qml
@@ -0,0 +1,87 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Layouts 1.0
17import QtQuick.Controls 2.0
18import Fluid.Controls 1.0
19import "../.."
20
21Flickable {
22 clip: true
23 contentHeight: Math.max(layout.implicitHeight, height)
24
25 ScrollBar.vertical: ScrollBar {}
26
27 ColumnLayout {
28 id: layout
29 anchors.fill: parent
30 anchors.margins: Units.mediumSpacing
31 spacing: Units.smallSpacing
32
33 DisplayLabel {
34 level: 4
35 text: "Display 4"
36 }
37
38 DisplayLabel {
39 level: 3
40 text: "Display 3"
41 }
42
43 DisplayLabel {
44 level: 2
45 text: "Display 2"
46 }
47
48 DisplayLabel {
49 level: 1
50 text: "Display 1"
51 }
52
53 HeadlineLabel {
54 text: "Headline"
55 }
56
57 TitleLabel {
58 text: "Title"
59 }
60
61 SubheadingLabel {
62 text: "Subheading"
63 }
64
65 BodyLabel {
66 level: 2
67 text: "Body 2"
68 }
69
70 BodyLabel {
71 level: 1
72 text: "Body 1"
73 }
74
75 CaptionLabel {
76 text: "Caption"
77 }
78
79 Label {
80 text: "Label"
81 }
82
83 Item {
84 Layout.fillHeight: true
85 }
86 }
87}
diff --git a/demo/Style.qml b/demo/Style.qml
new file mode 100644
index 0000000..9f997bd
--- /dev/null
+++ b/demo/Style.qml
@@ -0,0 +1,75 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtQuick.Controls 2.0
17import QtQuick.Controls.Material 2.0
18import QtQuick.Controls.Universal 2.0
19import Fluid.Controls 1.0
20import "Pages/Style"
21
22Tab {
23 title: qsTr("Style")
24
25 Pane {
26 id: listPane
27 anchors {
28 left: parent.left
29 top: parent.top
30 bottom: parent.bottom
31 }
32 width: 200
33 padding: 0
34 z: 2
35
36 Material.background: "white"
37 Material.elevation: 1
38
39 Universal.background: Universal.accent
40
41 ListView {
42 id: listView
43 anchors.fill: parent
44 currentIndex: 0
45 model: ListModel {
46 ListElement { title: qsTr("Palette"); source: "qrc:/Pages/Style/PalettePage.qml" }
47 ListElement { title: qsTr("Typography"); source: "qrc:/Pages/Style/TypographyPage.qml" }
48 }
49 header: Subheader {
50 text: qsTr("Demos")
51 }
52 delegate: ListItem {
53 text: model.title
54 highlighted: ListView.isCurrentItem
55 onClicked: {
56 listView.currentIndex = index
57 stackView.push(model.source)
58 }
59 }
60
61 ScrollBar.vertical: ScrollBar {}
62 }
63 }
64
65 StackView {
66 id: stackView
67 anchors {
68 left: listPane.right
69 top: parent.top
70 right: parent.right
71 bottom: parent.bottom
72 }
73 initialItem: PalettePage {}
74 }
75}
diff --git a/demo/StyledRectangle.qml b/demo/StyledRectangle.qml
new file mode 100644
index 0000000..3af12dd
--- /dev/null
+++ b/demo/StyledRectangle.qml
@@ -0,0 +1,21 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16
17Rectangle {
18 // Default styled rectangle is red to spot errors
19 // related to how styles are loaded
20 color: "red"
21}
diff --git a/demo/demo.pro b/demo/demo.pro
new file mode 100644
index 0000000..7f6c2ba
--- /dev/null
+++ b/demo/demo.pro
@@ -0,0 +1,9 @@
1TEMPLATE = app
2
3QT += qml quick quickcontrols2
4CONFIG += c++11
5
6SOURCES += main.cpp
7RESOURCES += demo.qrc
8
9include(../fluid.pri)
diff --git a/demo/demo.qrc b/demo/demo.qrc
new file mode 100644
index 0000000..b447c47
--- /dev/null
+++ b/demo/demo.qrc
@@ -0,0 +1,30 @@
1<RCC>
2 <qresource prefix="/">
3 <file>main.qml</file>
4 <file>BasicComponents.qml</file>
5 <file>CompoundComponents.qml</file>
6 <file>MaterialComponents.qml</file>
7 <file>NavigationComponents.qml</file>
8 <file>Style.qml</file>
9 <file>StyledRectangle.qml</file>
10 <file>+material/StyledRectangle.qml</file>
11 <file>+universal/StyledRectangle.qml</file>
12 <file>Pages/Basic/BusyIndicatorPage.qml</file>
13 <file>Pages/Basic/ButtonPage.qml</file>
14 <file>Pages/Basic/CheckBoxPage.qml</file>
15 <file>Pages/Basic/ProgressBarPage.qml</file>
16 <file>Pages/Basic/RadioButtonPage.qml</file>
17 <file>Pages/Basic/SliderPage.qml</file>
18 <file>Pages/Basic/SwitchPage.qml</file>
19 <file>Pages/Compound/ListItemPage.qml</file>
20 <file>Pages/Compound/SubPage.qml</file>
21 <file>Pages/Compound/CardPage.qml</file>
22 <file>Pages/Compound/InfoBarPage.qml</file>
23 <file>Pages/Style/PalettePage.qml</file>
24 <file>Pages/Style/PaletteSwatch.qml</file>
25 <file>Pages/Style/TypographyPage.qml</file>
26 <file>Pages/Material/ActionButtonPage.qml</file>
27 <file>Pages/Material/WavePage.qml</file>
28 <file>Pages/Navigation/NavDrawerPage.qml</file>
29 </qresource>
30</RCC>
diff --git a/demo/main.cpp b/demo/main.cpp
new file mode 100644
index 0000000..055d695
--- /dev/null
+++ b/demo/main.cpp
@@ -0,0 +1,37 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
6 *
7 * $BEGIN_LICENSE:MPL2$
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
13 * $END_LICENSE$
14 */
15
16#include <QGuiApplication>
17#include <QQmlApplicationEngine>
18#include <QQuickStyle>
19#include <QQmlContext>
20
21int main(int argc, char *argv[])
22{
23 QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
24
25 QGuiApplication app(argc, argv);
26
27 if (QQuickStyle::name().isEmpty())
28 QQuickStyle::setStyle("Material");
29
30 QQmlApplicationEngine engine;
31#ifdef FLUID_LOCAL
32 engine.addImportPath(QStringLiteral("qrc:/"));
33#endif
34 engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
35
36 return app.exec();
37}
diff --git a/demo/main.qml b/demo/main.qml
new file mode 100644
index 0000000..37b0077
--- /dev/null
+++ b/demo/main.qml
@@ -0,0 +1,104 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
6 *
7 * $BEGIN_LICENSE:MPL2$
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
13 * $END_LICENSE$
14 */
15
16import QtQuick 2.6
17import QtQuick.Controls 2.0
18import QtQuick.Controls.Material 2.0
19import QtQuick.Controls.Universal 2.0
20import QtQuick.Layouts 1.3
21import Fluid.Controls 1.0
22
23FluidWindow {
24 id: window
25
26 visible: true
27
28 width: 1024
29 height: 800
30
31 title: qsTr("Fluid Demo")
32
33 Material.primary: Material.LightBlue
34 Material.accent: Material.Blue
35
36 Universal.accent: Universal.Cobalt
37
38 NavigationDrawer {
39 id: navDrawer
40
41 //width: Math.min(window.width, window.height) / 3 * 2
42 height: window.height
43
44 topContent: [
45 Rectangle {
46 color: Material.primary
47 height: 48
48
49 Label {
50 anchors.centerIn: parent
51 text: qsTr("Top Content")
52 }
53
54 Layout.fillWidth: true
55 }
56 ]
57
58 actions: [
59 Action {
60 text: qsTr("Action 1")
61 iconName: "action/info"
62 onTriggered: console.log("action1 triggered")
63 },
64 Action {
65 text: qsTr("Action 2")
66 iconName: "action/info"
67 onTriggered: console.log("action2 triggered")
68 },
69 Action {
70 text: qsTr("Action 3")
71 iconName: "action/info"
72 onTriggered: console.log("action3 triggered")
73 }
74 ]
75 }
76
77 initialPage: TabbedPage {
78 title: window.title
79
80 actions: [
81 Action {
82 text: qsTr("Dummy error")
83 iconName: "alert/warning"
84 onTriggered: console.log("Dummy error")
85 },
86 Action {
87 text: qsTr("Colors")
88 iconName: "image/color_lens"
89 onTriggered: console.log("Colors")
90 },
91 Action {
92 text: qsTr("Settings")
93 iconName: "action/settings"
94 onTriggered: console.log("Settings clicked")
95 }
96 ]
97
98 BasicComponents {}
99 CompoundComponents {}
100 MaterialComponents {}
101 NavigationComponents {}
102 Style {}
103 }
104}
diff --git a/doc/defaults.qdocconf b/doc/defaults.qdocconf
new file mode 100644
index 0000000..39c8491
--- /dev/null
+++ b/doc/defaults.qdocconf
@@ -0,0 +1,23 @@
1include($QT_INSTALL_DOCS/global/macros.qdocconf)
2include($QT_INSTALL_DOCS/global/qt-cpp-defines.qdocconf)
3include($QT_INSTALL_DOCS/global/compat.qdocconf)
4include($QT_INSTALL_DOCS/global/fileextensions.qdocconf)
5include($QT_INSTALL_DOCS/global/qt-html-templates-offline.qdocconf)
6include(html-footer-offline.qdocconf)
7
8outputdir = $FLUID_BUILD_DIR/doc/html
9
10dist.metadata.default.author = Fluid
11dist.metadata.default.permissions = all
12dist.metadata.default.publisher = Fluid
13dist.metadata.default.copyryear = 2016
14dist.metadata.default.copyrholder = Fluid
15dist.metadata.default.audience = programmer
16
17navigation.homepage = "Fluid $FLUID_VERSION"
18
19#sourcedirs += includes
20
21url = http://doc.liri.io/sdk
22
23buildversion = "Fluid $FLUID_VERSION Reference Documentation"
diff --git a/doc/fluid.qdocconf b/doc/fluid.qdocconf
new file mode 100644
index 0000000..1fee46d
--- /dev/null
+++ b/doc/fluid.qdocconf
@@ -0,0 +1,59 @@
1include(defaults.qdocconf)
2
3project = Fluid
4description = Fluid Reference Documentation
5version = $FLUID_VERSION
6
7qhp.projects = Fluid
8
9qhp.Fluid.file = fluid.qhp
10qhp.Fluid.namespace = io.liri.fluid.$FLUID_VERSION_TAG
11qhp.Fluid.virtualFolder = fluid
12qhp.Fluid.indexTitle = Fluid $FLUID_VERSION Reference Documentation
13qhp.Fluid.indexRoot =
14
15qhp.Fluid.filterAttributes = fluid $FLUID_VERSION qtrefdoc
16qhp.Fluid.customFilters.Qt.name = Fluid $FLUID_VERSION
17qhp.Fluid.customFilters.Qt.filterAttributes = fluid $FLUID_VERSION
18
19qhp.Fluid.subprojects = fluidcore fluidcontrols fluideffects fluidmaterial
20qhp.Fluid.subproject.fluidcore.title = Fluid Core
21qhp.Fluid.subproject.fluidcore.indexTitle = Fluid Core QML Types
22qhp.Fluid.subprojects.fluidcore.selectors = qmlclass
23qhp.Fluid.subprojects.fluidcore.sortPages = true
24qhp.Fluid.subproject.fluidcontrols.title = Fluid Controls
25qhp.Fluid.subproject.fluidcontrols.indexTitle = Fluid Controls QML Types
26qhp.Fluid.subprojects.fluidcontrols.selectors = qmlclass
27qhp.Fluid.subprojects.fluidcontrols.sortPages = true
28qhp.Fluid.subproject.fluideffects.title = Fluid Controls
29qhp.Fluid.subproject.fluideffects.indexTitle = Fluid Effects QML Types
30qhp.Fluid.subprojects.fluideffects.selectors = qmlclass
31qhp.Fluid.subprojects.fluideffects.sortPages = true
32qhp.Fluid.subproject.fluidmaterial.title = Fluid Controls
33qhp.Fluid.subproject.fluidmaterial.indexTitle = Fluid Controls QML Types
34qhp.Fluid.subprojects.fluidmaterial.selectors = qmlclass
35qhp.Fluid.subprojects.fluidmaterial.sortPages = true
36
37indexes += $QT_INSTALL_DOCS/qtcore/qtcore.index
38indexes += $QT_INSTALL_DOCS/qtgui/qtgui.index
39indexes += $QT_INSTALL_DOCS/qtqml/qtqml.index
40indexes += $QT_INSTALL_DOCS/qtquick/qtquick.index
41indexes += $QT_INSTALL_DOCS/qtquickcontrols2/qtquickcontrols2.index
42
43depends += qtcore qtgui qtqml qtquick qtquickcontrols2
44
45# Specify the install path under QT_INSTALL_EXAMPLES
46# Note: paths passed to \example command must contain the parent directory, e.g.
47# \example controls/tabs
48#exampledirs += snippets
49
50#examplesinstallpath = fluid
51
52sourcedirs += ../core ../controls ../effects ../material src
53
54headerdirs += ../core ../controls ../effects ../material src
55
56imagedirs += images
57
58navigation.landingpage = "Fluid"
59navigation.homepage = "Fluid Documentation"
diff --git a/doc/html-footer-offline.qdocconf b/doc/html-footer-offline.qdocconf
new file mode 100644
index 0000000..26f4557
--- /dev/null
+++ b/doc/html-footer-offline.qdocconf
@@ -0,0 +1,18 @@
1HTML.footer = \
2 " </div>\n" \
3 " </div>\n" \
4 " </div>\n" \
5 " </div>\n" \
6 "</div>\n" \
7 "<div class=\"footer\">\n" \
8 " <p>\n" \
9 " <acronym title=\"Copyright\">&copy;</acronym> 2016 Liri.\n" \
10 " Documentation contributions included herein are the copyrights of\n" \
11 " their respective owners.<br>" \
12 " The documentation provided herein is licensed under the terms of the" \
13 " <a href=\"http://www.gnu.org/licenses/fdl.html\">GNU Free Documentation" \
14 " License version 1.3</a> as published by the Free Software Foundation.<br>" \
15 " Qt and respective logos are trademarks of The Qt Company Ltd. " \
16 " in Finland and/or other countries worldwide. All other trademarks are property\n" \
17 " of their respective owners. </p>\n" \
18 "</div>\n" \
diff --git a/doc/src/fluidcontrols.qdoc b/doc/src/fluidcontrols.qdoc
new file mode 100644
index 0000000..cde0ed5
--- /dev/null
+++ b/doc/src/fluidcontrols.qdoc
@@ -0,0 +1,25 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15/*!
16 \qmlmodule Fluid.Controls 1.0
17 \title Fluid Controls QML Types
18 \ingroup fluidcontrols
19
20 \brief Provides additional controls to extend Qt Quick Controls 2.
21
22 \section1 References
23
24 Fluid Controls extends \l[QtQuickControls2]{Qt Quick Controls 2}.
25*/
diff --git a/doc/src/fluidcore.qdoc b/doc/src/fluidcore.qdoc
new file mode 100644
index 0000000..82294bd
--- /dev/null
+++ b/doc/src/fluidcore.qdoc
@@ -0,0 +1,30 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15/*!
16 \qmlmodule Fluid.Core 1.0
17 \title Fluid Core QML Types
18 \ingroup fluidcore
19
20 \brief Provides basic QML types for Qt applications.
21
22 Basic QML types for Qt applications.
23
24 The Fluid Core QML Types can be imported into your application
25 using the following import statement:
26
27 \code
28 import Fluid.Core 1.0
29 \endcode
30*/
diff --git a/doc/src/fluideffects.qdoc b/doc/src/fluideffects.qdoc
new file mode 100644
index 0000000..751be11
--- /dev/null
+++ b/doc/src/fluideffects.qdoc
@@ -0,0 +1,21 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15/*!
16 \qmlmodule Fluid.Effects 1.0
17 \title Fluid Effects QML Types
18 \ingroup fluideffects
19
20 \brief Provides effects for Qt applications.
21*/
diff --git a/doc/src/fluidmaterial.qdoc b/doc/src/fluidmaterial.qdoc
new file mode 100644
index 0000000..4423b7b
--- /dev/null
+++ b/doc/src/fluidmaterial.qdoc
@@ -0,0 +1,21 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15/*!
16 \qmlmodule Fluid.Material 1.0
17 \title Fluid Material QML Types
18 \ingroup fluidmaterial
19
20 \brief Provides QML types specific to Material Design.
21*/
diff --git a/doc/src/index.qdoc b/doc/src/index.qdoc
new file mode 100644
index 0000000..0d87196
--- /dev/null
+++ b/doc/src/index.qdoc
@@ -0,0 +1,31 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15/*!
16 \page index.html
17 \keyword Fluid Reference Documentation
18
19 A collection of cross-platform QtQuick components for building fluid and dynamic applications.
20
21 \section1 QML Modules
22
23 Fluid is comprised of several QML modules.
24
25 \list
26 \li \l[FluidCore]{Fluid Core QML Types}
27 \li \l[FluidControls]{Fluid Controls QML Types}
28 \li \l[FluidEffects]{Fluid Effects QML Types}
29 \li \l[FluidMaterial]{Fluid Material QML Types}
30 \endlist
31*/
diff --git a/effects/BoxShadow.qml b/effects/BoxShadow.qml
new file mode 100644
index 0000000..2fb3616
--- /dev/null
+++ b/effects/BoxShadow.qml
@@ -0,0 +1,53 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16import QtGraphicalEffects 1.0
17
18/*!
19 \qmltype BoxShadow
20 \inqmlmodule Fluid.Effects
21 \ingroup fluideffects
22
23 \brief A implementation of CSS's box-shadow.
24
25 A implementation of CSS's box-shadow, used by ElevationEffect for a Material Design
26 elevation shadow effect.
27*/
28RectangularGlow {
29 // The 4 properties from CSS box-shadow, plus the inherited color property
30 property int offsetX
31 property int offsetY
32 property int blurRadius
33 property int spreadRadius
34
35 // The source item the shadow is being applied to, used for correctly
36 // calculating the corner radius
37 property Item source
38
39 property bool fullWidth
40 property bool fullHeight
41
42 x: (parent.width - width)/2 + offsetX
43 y: (parent.height - height)/2 + offsetY
44
45 implicitWidth: source ? source.width : parent.width
46 implicitHeight: source ? source.height : parent.height
47
48 width: implicitWidth + 2 * spreadRadius + (fullWidth ? 2 * cornerRadius : 0)
49 height: implicitHeight + 2 * spreadRadius + (fullHeight ? 2 * cornerRadius : 0)
50 glowRadius: blurRadius/2
51 spread: 0.05
52 cornerRadius: blurRadius + (source && source.radius || 0)
53}
diff --git a/effects/CMakeLists.txt b/effects/CMakeLists.txt
new file mode 100644
index 0000000..86ab09d
--- /dev/null
+++ b/effects/CMakeLists.txt
@@ -0,0 +1,10 @@
1set(FILES
2 plugins.qmltypes
3 qmldir
4 BoxShadow.qml
5 CircleMask.qml
6 Vignette.qml
7)
8
9install(FILES ${FILES}
10 DESTINATION ${QML_INSTALL_DIR}/Fluid/Effects)
diff --git a/effects/CircleMask.qml b/effects/CircleMask.qml
new file mode 100644
index 0000000..0a70c44
--- /dev/null
+++ b/effects/CircleMask.qml
@@ -0,0 +1,51 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
6 *
7 * $BEGIN_LICENSE:MPL2$
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
13 * $END_LICENSE$
14 */
15
16import QtQuick 2.4
17import QtGraphicalEffects 1.0
18
19/*!
20 \qmltype CircleMask
21 \inqmlmodule Fluid.Effects
22 \ingroup fluideffects
23
24 \brief Circular mask.
25*/
26Item {
27 id: item
28
29 property alias source: mask.source
30
31 Rectangle {
32 id: circleMask
33
34 width: parent.width
35 height: parent.height
36
37 smooth: true
38 visible: false
39
40 radius: Math.max(width/2, height/2)
41 }
42
43 OpacityMask {
44 id: mask
45
46 width: parent.width
47 height: parent.height
48
49 maskSource: circleMask
50 }
51}
diff --git a/effects/Vignette.qml b/effects/Vignette.qml
new file mode 100644
index 0000000..2258190
--- /dev/null
+++ b/effects/Vignette.qml
@@ -0,0 +1,77 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.0
16
17/*!
18 \qmltype Vignette
19 \inqmlmodule Fluid.Effects
20 \ingroup fluideffects
21
22 \brief Vignette effect.
23*/
24Item {
25 id: root
26
27 /*!
28 This property defines the source item that is going to be used as source
29 for the generated effect.
30 */
31 property variant source
32
33 /*!
34 This property defines the vignette radius.
35 */
36 property alias radius: effect.radius
37
38 /*!
39 This property defines how much brightness will be used.
40 */
41 property alias brightness: effect.brightness
42
43 ShaderEffect {
44 id: effect
45 anchors.fill: parent
46
47 property variant source: ShaderEffectSource {
48 sourceItem: root.source
49 sourceRect: Qt.rect(0, 0, 0, 0)
50 hideSource: false
51 smooth: true
52 visible: false
53 }
54
55 property real radius: 16
56 property real brightness: 0.1
57
58 fragmentShader: "
59 varying highp vec2 qt_TexCoord0;
60 uniform highp float qt_Opacity;
61 uniform highp float radius;
62 uniform highp float brightness;
63 uniform lowp sampler2D source;
64
65 void main() {
66 highp vec2 uv = qt_TexCoord0.xy;
67 highp vec2 coord = qt_TexCoord0 - 0.5;
68 lowp vec4 orig = texture2D(source, uv);
69
70 highp float vignette = 1.0 - dot(coord, coord);
71
72 lowp vec3 col = orig.rgb * clamp(pow(vignette, radius) + brightness, 0.0, 1.0);
73
74 gl_FragColor = vec4(col, 1.0);
75 }"
76 }
77}
diff --git a/effects/effects.pri b/effects/effects.pri
new file mode 100644
index 0000000..afb9022
--- /dev/null
+++ b/effects/effects.pri
@@ -0,0 +1 @@
RESOURCES += $$PWD/effects.qrc
diff --git a/effects/effects.qrc b/effects/effects.qrc
new file mode 100644
index 0000000..1331e4f
--- /dev/null
+++ b/effects/effects.qrc
@@ -0,0 +1,9 @@
1<RCC>
2 <qresource prefix="/Fluid/Effects">
3 <file>BoxShadow.qml</file>
4 <file>CircleMask.qml</file>
5 <file>plugins.qmltypes</file>
6 <file>qmldir</file>
7 <file>Vignette.qml</file>
8 </qresource>
9</RCC>
diff --git a/effects/plugins.qmltypes b/effects/plugins.qmltypes
new file mode 100644
index 0000000..85c0289
--- /dev/null
+++ b/effects/plugins.qmltypes
@@ -0,0 +1,15 @@
1import QtQuick.tooling 1.2
2
3// This file describes the plugin-supplied types contained in the library.
4// It is used for QML tooling purposes only.
5//
6// This file was auto-generated by:
7// 'qmlplugindump-qt5 -nonrelocatable Fluid.Effects 1.0'
8
9Module {
10 dependencies: [
11 "QtGraphicalEffects 1.0",
12 "QtQuick 2.4",
13 "QtQuick.Window 2.1"
14 ]
15}
diff --git a/effects/qmldir b/effects/qmldir
new file mode 100644
index 0000000..225a435
--- /dev/null
+++ b/effects/qmldir
@@ -0,0 +1,6 @@
1module Fluid.Effects
2typeinfo plugins.qmltypes
3
4BoxShadow 1.0 BoxShadow.qml
5CircleMask 1.0 CircleMask.qml
6Vignette 1.0 Vignette.qml
diff --git a/fluid.pri b/fluid.pri
new file mode 100644
index 0000000..af7e52a
--- /dev/null
+++ b/fluid.pri
@@ -0,0 +1,8 @@
1DEFINES += FLUID_LOCAL
2include(src/src.pri)
3include(core/core.pri)
4include(controls/controls.pri)
5include(effects/effects.pri)
6include(material/material.pri)
7
8RESOURCES += $$PWD/icons/icons.qrc
diff --git a/material/ActionButton.qml b/material/ActionButton.qml
new file mode 100644
index 0000000..e6cdcfc
--- /dev/null
+++ b/material/ActionButton.qml
@@ -0,0 +1,106 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
6 *
7 * $BEGIN_LICENSE:MPL2$
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
13 * $END_LICENSE$
14 */
15
16import QtQuick 2.4
17import QtQuick.Controls 2.0
18import QtQuick.Controls.Material 2.0
19import Fluid.Core 1.0
20import Fluid.Controls 1.0
21import QtGraphicalEffects 1.0
22
23/*!
24 \qmltype ActionButton
25 \inqmlmodule Fluid.Material
26
27 \brief A floating action button.
28
29 An ActionButton is a floating action button that provides a primary action
30 on the current page.
31 */
32Button {
33 id: button
34
35 /*!
36 The name of the icon to display in the action button, selected from the Material
37 Design icon collection by Google.
38 */
39 property alias iconName: icon.name
40
41 /*!
42 Floating action buttons come in two sizes:
43
44 \list
45 \li \b {Default size} - for most use cases
46 \li \b {Mini size} - only used to create visual continuity with other screen elements
47 \endlist
48 */
49 property bool isMiniSize: false
50
51 padding: 0
52
53 width: 76
54 height: 76
55
56 contentItem: Item {
57 implicitHeight: isMiniSize ? 40 : 56
58 implicitWidth: implicitHeight
59
60 Icon {
61 id: icon
62
63 anchors.centerIn: parent
64 color: Utils.lightDark(button.Material.background, "black", "white")
65 size: 24
66 }
67 }
68
69 background: Rectangle {
70 implicitWidth: 64
71 implicitHeight: 64
72
73 x: 6
74 y: 6
75
76 width: parent.width - 12
77 height: parent.height - 12
78
79 radius: width/2
80
81 color: button.Material.background
82
83 RectangularGlow {
84 anchors.centerIn: parent
85 anchors.verticalCenterOffset: button.Material.elevation === 1 ? 1.5 : 1
86
87 width: parent.width
88 height: parent.height
89
90 z: -1
91
92 glowRadius: button.Material.elevation === 1 ? 0.75 : 0.3
93 opacity: button.Material.elevation === 1 ? 0.6 : 0.3
94 spread: button.Material.elevation === 1 ? 0.7 : 0.85
95 color: "black"
96 cornerRadius: height/2
97 }
98
99 Ripple {
100 anchors.fill: parent
101 control: button
102
103 circular: true
104 }
105 }
106}
diff --git a/material/CMakeLists.txt b/material/CMakeLists.txt
new file mode 100644
index 0000000..04be30a
--- /dev/null
+++ b/material/CMakeLists.txt
@@ -0,0 +1,11 @@
1set(FLUID_FILES
2 plugins.qmltypes
3 qmldir
4 ActionButton.qml
5 ElevationEffect.qml
6 Ripple.qml
7 Wave.qml
8)
9
10install(FILES ${FLUID_FILES}
11 DESTINATION ${QML_INSTALL_DIR}/Fluid/Material)
diff --git a/material/ElevationEffect.qml b/material/ElevationEffect.qml
new file mode 100644
index 0000000..e72d517
--- /dev/null
+++ b/material/ElevationEffect.qml
@@ -0,0 +1,251 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.6
16import Fluid.Effects 1.0
17
18/*!
19 An effect for standard Material Design elevation shadows. Useful for using as \c layer.effect.
20 */
21Item {
22 id: effect
23
24 /*!
25 The source the effect is applied to.
26 */
27 property var source
28
29 /*!
30 The elevation of the \l source Item.
31 */
32 property int elevation: 0
33
34 /*!
35 Set to \c true if the \l source Item is the same width as its parent and the shadow
36 should be full width instead of rounding around the corner of the Item.
37 \sa fullHeight
38 */
39 property bool fullWidth: false
40
41 /*!
42 Set to \c true if the \l source Item is the same height as its parent and the shadow
43 should be full height instead of rounding around the corner of the Item.
44 \sa fullWidth
45 */
46 property bool fullHeight: false
47
48 /*!
49 \internal
50 The actual source Item the effect is applied to.
51 */
52 readonly property Item sourceItem: source.sourceItem
53
54 /*
55 * The following shadow values are taken from Angular Material
56 *
57 * The MIT License (MIT)
58 *
59 * Copyright (c) 2014-2016 Google, Inc. http://angularjs.org
60 *
61 * Permission is hereby granted, free of charge, to any person obtaining a copy
62 * of this software and associated documentation files (the "Software"), to deal
63 * in the Software without restriction, including without limitation the rights
64 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
65 * copies of the Software, and to permit persons to whom the Software is
66 * furnished to do so, subject to the following conditions:
67 *
68 * The above copyright notice and this permission notice shall be included in all
69 * copies or substantial portions of the Software.
70 *
71 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
72 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
73 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
74 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
75 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
76 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
77 * SOFTWARE.
78 */
79 /*!
80 \internal
81 The shadows to use for each possible elevation. There are three shadows that when combined
82 make up the elevation.
83 */
84 readonly property var _shadows: [
85 [{offset: 0, blur: 0, spread: 0},
86 {offset: 0, blur: 0, spread: 0},
87 {offset: 0, blur: 0, spread: 0}],
88
89 [{offset: 1, blur: 3, spread: 0},
90 {offset: 1, blur: 1, spread: 0},
91 {offset: 2, blur: 1, spread: -1}],
92
93 [{offset: 1, blur: 5, spread: 0},
94 {offset: 2, blur: 2, spread: 0},
95 {offset: 3, blur: 1, spread: -2}],
96
97 [{offset: 1, blur: 8, spread: 0},
98 {offset: 3, blur: 4, spread: 0},
99 {offset: 3, blur: 3, spread: -2}],
100
101 [{offset: 2, blur: 4, spread: -1},
102 {offset: 4, blur: 5, spread: 0},
103 {offset: 1, blur: 10, spread: 0}],
104
105 [{offset: 3, blur: 5, spread: -1},
106 {offset: 5, blur: 8, spread: 0},
107 {offset: 1, blur: 14, spread: 0}],
108
109 [{offset: 3, blur: 5, spread: -1},
110 {offset: 6, blur: 10, spread: 0},
111 {offset: 1, blur: 18, spread: 0}],
112
113 [{offset: 4, blur: 5, spread: -2},
114 {offset: 7, blur: 10, spread: 1},
115 {offset: 2, blur: 16, spread: 1}],
116
117 [{offset: 5, blur: 5, spread: -3},
118 {offset: 8, blur: 10, spread: 1},
119 {offset: 3, blur: 14, spread: 2}],
120
121 [{offset: 5, blur: 6, spread: -3},
122 {offset: 9, blur: 12, spread: 1},
123 {offset: 3, blur: 16, spread: 2}],
124
125 [{offset: 6, blur: 6, spread: -3},
126 {offset: 10, blur: 14, spread: 1},
127 {offset: 4, blur: 18, spread: 3}],
128
129 [{offset: 6, blur: 7, spread: -4},
130 {offset: 11, blur: 15, spread: 1},
131 {offset: 4, blur: 20, spread: 3}],
132
133 [{offset: 7, blur: 8, spread: -4},
134 {offset: 12, blur: 17, spread: 2},
135 {offset: 5, blur: 22, spread: 4}],
136
137 [{offset: 7, blur: 8, spread: -4},
138 {offset: 13, blur: 19, spread: 2},
139 {offset: 5, blur: 24, spread: 4}],
140
141 [{offset: 7, blur: 9, spread: -4},
142 {offset: 14, blur: 21, spread: 2},
143 {offset: 5, blur: 26, spread: 4}],
144
145 [{offset: 8, blur: 9, spread: -5},
146 {offset: 15, blur: 22, spread: 2},
147 {offset: 6, blur: 28, spread: 5}],
148
149 [{offset: 8, blur: 10, spread: -5},
150 {offset: 16, blur: 24, spread: 2},
151 {offset: 6, blur: 30, spread: 5}],
152
153 [{offset: 8, blur: 11, spread: -5},
154 {offset: 17, blur: 26, spread: 2},
155 {offset: 6, blur: 32, spread: 5}],
156
157 [{offset: 9, blur: 11, spread: -5},
158 {offset: 18, blur: 28, spread: 2},
159 {offset: 7, blur: 34, spread: 6}],
160
161 [{offset: 9, blur: 12, spread: -6},
162 {offset: 19, blur: 29, spread: 2},
163 {offset: 7, blur: 36, spread: 6}],
164
165 [{offset: 10, blur: 13, spread: -6},
166 {offset: 20, blur: 31, spread: 3},
167 {offset: 8, blur: 38, spread: 7}],
168
169 [{offset: 10, blur: 13, spread: -6},
170 {offset: 21, blur: 33, spread: 3},
171 {offset: 8, blur: 40, spread: 7}],
172
173 [{offset: 10, blur: 14, spread: -6},
174 {offset: 22, blur: 35, spread: 3},
175 {offset: 8, blur: 42, spread: 7}],
176
177 [{offset: 11, blur: 14, spread: -7},
178 {offset: 23, blur: 36, spread: 3},
179 {offset: 9, blur: 44, spread: 8}],
180
181 [{offset: 11, blur: 15, spread: -7},
182 {offset: 24, blur: 38, spread: 3},
183 {offset: 9, blur: 46, spread: 8}]
184 ]
185
186 /*!
187 \internal
188 The current shadow based on the elevation.
189 */
190 readonly property var _shadow: _shadows[elevation]
191
192 // Nest the shadows and source view in two items rendered as a layer
193 // so the shadow is not clipped by the bounds of the source view
194 Item {
195 property int margin: -100
196
197 x: margin
198 y: margin
199 width: parent.width - 2 * margin
200 height: parent.height - 2 * margin
201
202 // By rendering as a layer, the shadow will never show through the source item,
203 // even when the source item's opacity is less than 1
204 layer.enabled: true
205
206 // The box shadows automatically pick up the size of the source Item and not
207 // the size of the parent, so we don't need to worry about the extra padding
208 // in the parent Item
209 BoxShadow {
210 offsetY: _shadow[0].offset
211 blurRadius: _shadow[0].blur
212 spreadRadius: _shadow[0].spread
213 color: Qt.rgba(0,0,0, 0.2)
214
215 fullWidth: effect.fullWidth
216 fullHeight: effect.fullHeight
217 source: effect.sourceItem
218 }
219
220 BoxShadow {
221 offsetY: _shadow[1].offset
222 blurRadius: _shadow[1].blur
223 spreadRadius: _shadow[1].spread
224 color: Qt.rgba(0,0,0, 0.14)
225
226 fullWidth: effect.fullWidth
227 fullHeight: effect.fullHeight
228 source: effect.sourceItem
229 }
230
231 BoxShadow {
232 offsetY: _shadow[2].offset
233 blurRadius: _shadow[2].blur
234 spreadRadius: _shadow[2].spread
235 color: Qt.rgba(0,0,0, 0.12)
236
237 fullWidth: effect.fullWidth
238 fullHeight: effect.fullHeight
239 source: effect.sourceItem
240 }
241
242 ShaderEffect {
243 property alias source: effect.source
244
245 x: (parent.width - width)/2
246 y: (parent.height - height)/2
247 width: sourceItem.width
248 height: sourceItem.height
249 }
250 }
251}
diff --git a/material/Ripple.qml b/material/Ripple.qml
new file mode 100644
index 0000000..b99a46a
--- /dev/null
+++ b/material/Ripple.qml
@@ -0,0 +1,290 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
6 *
7 * $BEGIN_LICENSE:MPL2$
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
13 * $END_LICENSE$
14 */
15
16import QtQuick 2.4
17import Fluid.Core 1.0
18import Fluid.Effects 1.0
19
20/*!
21 \qmltype Ripple
22 \inqmlmodule Fluid.UI 1.0
23 \brief Represents a Material Design ripple ink animation used in various touchable components.
24
25 This component is useful for including in Material Design-specific components, which should be implemented using the +material file selector. Eventually this should be upstreamed to QtQuick
26 Controls 2.
27 */
28MouseArea {
29 id: ripple
30
31 /*!
32 The color of the ripple. Defaults to black with 12% opacity.
33 */
34 property color color: Qt.rgba(0,0,0,0.12)
35
36 /*!
37 Set to \c true if the ripple is used on a circular component, such as a button in an
38 action bar or a floating action button.
39 */
40 property bool circular: false
41
42 /*!
43 Set to \c true if the ripple should be centered regardless of where the mouse/touch
44 input came from.
45 */
46 property bool centered: false
47
48 /*!
49 Set to \c true if the component is focused and should display a focus ripple.
50 */
51 property bool focused
52
53 /*!
54 The color of the focus ripple. Also used to determine the color of the focus background
55 behind the ripple.
56 \sa focused
57 */
58 property color focusColor: "transparent"
59
60 /*!
61 The width of the focus ripple.
62 \sa focused
63 */
64 property int focusWidth: width - 32
65
66 property Item control
67
68 clip: true
69 hoverEnabled: Device.hoverEnabled
70
71 Connections {
72 target: control
73
74 onPressedChanged: {
75 if (!control.pressed)
76 __private.removeLastCircle()
77 }
78 }
79
80 onPressed: {
81 __private.createTapCircle(mouse.x, mouse.y)
82
83 if (control)
84 mouse.accepted = false
85 }
86
87 onReleased: __private.removeLastCircle()
88 onCanceled: __private.removeLastCircle()
89
90 QtObject {
91 id: __private
92
93 property int startRadius: circular ? width/10 : width/6
94 property int endRadius
95 property bool showFocus: true
96
97 property Item lastCircle
98
99 function createTapCircle(x, y) {
100 endRadius = centered ? width/2 : radius(x, y) + 5
101 showFocus = false
102
103 lastCircle = tapCircle.createObject(ripple, {
104 "circleX": centered ? width/2 : x,
105 "circleY": centered ? height/2 : y
106 })
107 }
108
109 function removeLastCircle() {
110 if (lastCircle)
111 lastCircle.removeCircle()
112 }
113
114 function radius(x, y) {
115 var dist1 = Math.max(dist(x, y, 0, 0), dist(x, y, width, height))
116 var dist2 = Math.max(dist(x, y, width, 0), dist(x, y, 0, height))
117
118 return Math.max(dist1, dist2)
119 }
120
121 function dist(x1, y1, x2, y2) {
122 var distX = x2 - x1
123 var distY = y2 - y1
124
125 return Math.sqrt(distX * distX + distY * distY)
126 }
127 }
128
129 Rectangle {
130 id: focusBackground
131 objectName: "focusBackground"
132
133 width: parent.width
134 height: parent.height
135
136 color: Utils.isDarkColor(focusColor) && focusColor.a > 0
137 ? Qt.rgba(0,0,0,0.2) : Qt.rgba(0,0,0,0.1)
138
139 opacity: __private.showFocus && focused ? 1 : 0
140
141 Behavior on opacity {
142 NumberAnimation { duration: 500; easing.type: Easing.InOutQuad }
143 }
144 }
145
146 Rectangle {
147 id: focusCircle
148 objectName: "focusRipple"
149
150 property bool focusedState
151
152 x: (parent.width - width)/2
153 y: (parent.height - height)/2
154
155 width: focused
156 ? focusedState ? focusWidth
157 : Math.min(parent.width - 8, focusWidth + 12)
158 : parent.width/5
159 height: width
160
161 radius: width/2
162
163 opacity: __private.showFocus && focused ? 1 : 0
164
165 color: focusColor.a === 0 ? Qt.rgba(1,1,1,0.4) : focusColor
166
167 Behavior on opacity {
168 NumberAnimation { duration: 500; easing.type: Easing.InOutQuad }
169 }
170
171 Behavior on width {
172 NumberAnimation { duration: focusTimer.interval; }
173 }
174
175 Timer {
176 id: focusTimer
177 running: focused
178 repeat: true
179 interval: 800
180
181 onTriggered: focusCircle.focusedState = !focusCircle.focusedState
182 }
183 }
184
185 Component {
186 id: tapCircle
187
188 Item {
189 id: circleItem
190 objectName: "tapRipple"
191
192 property bool done
193
194 property real circleX
195 property real circleY
196
197 property bool closed
198
199 width: parent.width
200 height: parent.height
201
202 function removeCircle() {
203 done = true
204
205 if (fillSizeAnimation.running) {
206 fillOpacityAnimation.stop()
207 closeAnimation.start()
208
209 circleItem.destroy(500);
210 } else {
211 __private.showFocus = true
212 fadeAnimation.start();
213
214 circleItem.destroy(300);
215 }
216 }
217
218 Item {
219 id: circleParent
220
221 width: parent.width
222 height: parent.height
223
224 visible: !circular
225
226 Rectangle {
227 id: circleRectangle
228
229 x: circleItem.circleX - radius
230 y: circleItem.circleY - radius
231
232 width: radius * 2
233 height: radius * 2
234
235 opacity: 0
236 color: ripple.color
237
238 NumberAnimation {
239 id: fillSizeAnimation
240 running: true
241
242 target: circleRectangle; property: "radius"; duration: 500;
243 from: __private.startRadius; to: __private.endRadius;
244 easing.type: Easing.InOutQuad
245
246 onStopped: {
247 if (done)
248 __private.showFocus = true
249 }
250 }
251
252 NumberAnimation {
253 id: fillOpacityAnimation
254 running: true
255
256 target: circleRectangle; property: "opacity"; duration: 300;
257 from: 0; to: 1; easing.type: Easing.InOutQuad
258 }
259
260 NumberAnimation {
261 id: fadeAnimation
262
263 target: circleRectangle; property: "opacity"; duration: 300;
264 from: 1; to: 0; easing.type: Easing.InOutQuad
265 }
266
267 SequentialAnimation {
268 id: closeAnimation
269
270 NumberAnimation {
271 target: circleRectangle; property: "opacity"; duration: 250;
272 to: 1; easing.type: Easing.InOutQuad
273 }
274
275 NumberAnimation {
276 target: circleRectangle; property: "opacity"; duration: 250;
277 from: 1; to: 0; easing.type: Easing.InOutQuad
278 }
279 }
280 }
281 }
282
283 CircleMask {
284 anchors.fill: parent
285 source: circleParent
286 visible: circular
287 }
288 }
289 }
290}
diff --git a/material/Wave.qml b/material/Wave.qml
new file mode 100644
index 0000000..50ea8ae
--- /dev/null
+++ b/material/Wave.qml
@@ -0,0 +1,80 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 * Copyright (C) 2014 Bogdan Cuza <bogdan.cuza@hotmail.com>
6 *
7 * $BEGIN_LICENSE:MPL2$
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
13 * $END_LICENSE$
14 */
15
16import QtQuick 2.4
17
18/*!
19 \qmltype Wave
20 \inqmlmodule Fluid.Material 1.0
21 \brief Provides a wave animation for transitioning between views of content.
22 */
23Rectangle {
24 id: wave
25
26 property bool opened
27 property real size
28 property real initialX
29 property real initialY
30 property real abstractWidth: parent.width
31 property real abstractHeight: parent.height
32 property real diameter: 2 * Math.sqrt(Math.pow(Math.max(initialX, abstractWidth - initialX), 2)
33 + Math.pow(Math.max(initialY, abstractHeight - initialY), 2))
34
35 signal finished(bool opened)
36
37 function open(x, y) {
38 wave.initialX = x || parent.width/2;
39 wave.initialY = y || parent.height/2;
40 wave.opened = true;
41 }
42
43 function close(x, y) {
44 wave.initialX = x || parent.width/2;
45 wave.initialY = y || parent.height/2;
46 wave.opened = false;
47 }
48
49 width: size
50 height: size
51 radius: size/2
52 x: initialX - size/2
53 y: initialY - size/2
54
55 states: State {
56 name: "opened"
57 when: wave.opened
58
59 PropertyChanges {
60 target: wave
61 size: wave.diameter
62 }
63 }
64
65 transitions: Transition {
66 from: ""
67 to: "opened"
68 reversible: true
69
70 SequentialAnimation {
71 NumberAnimation {
72 property: "size"
73 easing.type: Easing.OutCubic
74 }
75 ScriptAction {
76 script: wave.finished(wave.opened)
77 }
78 }
79 }
80}
diff --git a/material/material.pri b/material/material.pri
new file mode 100644
index 0000000..6016f5f
--- /dev/null
+++ b/material/material.pri
@@ -0,0 +1,2 @@
1RESOURCES += \
2 $$PWD/material.qrc
diff --git a/material/material.qrc b/material/material.qrc
new file mode 100644
index 0000000..7ea8ecb
--- /dev/null
+++ b/material/material.qrc
@@ -0,0 +1,10 @@
1<RCC>
2 <qresource prefix="/Fluid/Material">
3 <file>ActionButton.qml</file>
4 <file>ElevationEffect.qml</file>
5 <file>plugins.qmltypes</file>
6 <file>qmldir</file>
7 <file>Ripple.qml</file>
8 <file>Wave.qml</file>
9 </qresource>
10</RCC>
diff --git a/material/plugins.qmltypes b/material/plugins.qmltypes
new file mode 100644
index 0000000..238ccfe
--- /dev/null
+++ b/material/plugins.qmltypes
@@ -0,0 +1,569 @@
1import QtQuick.tooling 1.2
2
3// This file describes the plugin-supplied types contained in the library.
4// It is used for QML tooling purposes only.
5//
6// This file was auto-generated by:
7// 'qmlplugindump-qt5 -nonrelocatable Fluid.Material 1.0'
8
9Module {
10 dependencies: [
11 "Fluid.Controls 1.0",
12 "Fluid.Core 1.0",
13 "Fluid.Effects 1.0",
14 "QtGraphicalEffects 1.0",
15 "QtQml 2.2",
16 "QtQuick 2.7",
17 "QtQuick.Controls 2.0",
18 "QtQuick.Controls.Material 2.0",
19 "QtQuick.Controls.Material.impl 2.0",
20 "QtQuick.Controls.Universal 2.0",
21 "QtQuick.Controls.Universal.impl 2.0",
22 "QtQuick.Controls.impl 2.0",
23 "QtQuick.Layouts 1.1",
24 "QtQuick.Templates 2.0",
25 "QtQuick.Window 2.2"
26 ]
27 Component {
28 prototype: "QQuickApplicationWindow"
29 name: "QtQuick.Controls/ApplicationWindow 2.0"
30 exports: ["QtQuick.Controls/ApplicationWindow 2.0"]
31 exportMetaObjectRevisions: [0]
32 isComposite: true
33 defaultProperty: "data"
34 }
35 Component {
36 prototype: "QQuickItem"
37 name: "QtQuick.Controls.Material.impl/BoxShadow 2.0"
38 exports: ["QtQuick.Controls.Material.impl/BoxShadow 2.0"]
39 exportMetaObjectRevisions: [0]
40 isComposite: true
41 defaultProperty: "data"
42 Property { name: "offsetX"; type: "int" }
43 Property { name: "offsetY"; type: "int" }
44 Property { name: "blurRadius"; type: "int" }
45 Property { name: "spreadRadius"; type: "int" }
46 Property { name: "source"; type: "QQuickItem"; isPointer: true }
47 Property { name: "fullWidth"; type: "bool" }
48 Property { name: "fullHeight"; type: "bool" }
49 Property { name: "glowRadius"; type: "double" }
50 Property { name: "spread"; type: "double" }
51 Property { name: "color"; type: "QColor" }
52 Property { name: "cornerRadius"; type: "double" }
53 Property { name: "cached"; type: "bool" }
54 }
55 Component {
56 prototype: "QQuickBusyIndicator"
57 name: "QtQuick.Controls/BusyIndicator 2.0"
58 exports: ["QtQuick.Controls/BusyIndicator 2.0"]
59 exportMetaObjectRevisions: [0]
60 isComposite: true
61 defaultProperty: "data"
62 }
63 Component {
64 prototype: "QQuickButton"
65 name: "QtQuick.Controls/Button 2.0"
66 exports: ["QtQuick.Controls/Button 2.0"]
67 exportMetaObjectRevisions: [0]
68 isComposite: true
69 defaultProperty: "data"
70 }
71 Component {
72 prototype: "QQuickCheckBox"
73 name: "QtQuick.Controls/CheckBox 2.0"
74 exports: ["QtQuick.Controls/CheckBox 2.0"]
75 exportMetaObjectRevisions: [0]
76 isComposite: true
77 defaultProperty: "data"
78 }
79 Component {
80 prototype: "QQuickCheckDelegate"
81 name: "QtQuick.Controls/CheckDelegate 2.0"
82 exports: ["QtQuick.Controls/CheckDelegate 2.0"]
83 exportMetaObjectRevisions: [0]
84 isComposite: true
85 defaultProperty: "data"
86 }
87 Component {
88 prototype: "QQuickRectangle"
89 name: "QtQuick.Controls.Material.impl/CheckIndicator 2.0"
90 exports: ["QtQuick.Controls.Material.impl/CheckIndicator 2.0"]
91 exportMetaObjectRevisions: [0]
92 isComposite: true
93 defaultProperty: "data"
94 Property { name: "control"; type: "QQuickItem"; isPointer: true }
95 }
96 Component {
97 prototype: "QQuickRectangle"
98 name: "QtQuick.Controls.impl/CheckIndicator 2.0"
99 exports: ["QtQuick.Controls.impl/CheckIndicator 2.0"]
100 exportMetaObjectRevisions: [0]
101 isComposite: true
102 defaultProperty: "data"
103 Property { name: "control"; type: "QQuickItem"; isPointer: true }
104 }
105 Component {
106 prototype: "QQuickComboBox"
107 name: "QtQuick.Controls/ComboBox 2.0"
108 exports: ["QtQuick.Controls/ComboBox 2.0"]
109 exportMetaObjectRevisions: [0]
110 isComposite: true
111 defaultProperty: "data"
112 }
113 Component {
114 prototype: "QQuickDial"
115 name: "QtQuick.Controls/Dial 2.0"
116 exports: ["QtQuick.Controls/Dial 2.0"]
117 exportMetaObjectRevisions: [0]
118 isComposite: true
119 defaultProperty: "data"
120 }
121 Component {
122 prototype: "QQuickDrawer"
123 name: "QtQuick.Controls/Drawer 2.0"
124 exports: ["QtQuick.Controls/Drawer 2.0"]
125 exportMetaObjectRevisions: [0]
126 isComposite: true
127 defaultProperty: "contentData"
128 }
129 Component {
130 prototype: "QQuickItem"
131 name: "QtQuick.Controls.Material.impl/ElevationEffect 2.0"
132 exports: ["QtQuick.Controls.Material.impl/ElevationEffect 2.0"]
133 exportMetaObjectRevisions: [0]
134 isComposite: true
135 defaultProperty: "data"
136 Property { name: "source"; type: "QVariant" }
137 Property { name: "elevation"; type: "int" }
138 Property { name: "fullWidth"; type: "bool" }
139 Property { name: "fullHeight"; type: "bool" }
140 Property { name: "sourceItem"; type: "QQuickItem"; isReadonly: true; isPointer: true }
141 Property { name: "_shadows"; type: "QVariant"; isReadonly: true }
142 Property { name: "_shadow"; type: "QVariant"; isReadonly: true }
143 }
144 Component {
145 prototype: "QObject"
146 name: "FluidStyle 1.0"
147 exports: ["FluidStyle 1.0"]
148 exportMetaObjectRevisions: [0]
149 isComposite: true
150 isCreatable: false
151 isSingleton: true
152 Property { name: "iconColorLight"; type: "QColor"; isReadonly: true }
153 Property { name: "iconColorDark"; type: "QColor"; isReadonly: true }
154 Property { name: "display4Font"; type: "QFont"; isReadonly: true }
155 Property { name: "display3Font"; type: "QFont"; isReadonly: true }
156 Property { name: "display2Font"; type: "QFont"; isReadonly: true }
157 Property { name: "display1Font"; type: "QFont"; isReadonly: true }
158 Property { name: "headlineFont"; type: "QFont"; isReadonly: true }
159 Property { name: "titleFont"; type: "QFont"; isReadonly: true }
160 Property { name: "subheadingFont"; type: "QFont"; isReadonly: true }
161 Property { name: "body2Font"; type: "QFont"; isReadonly: true }
162 Property { name: "body1Font"; type: "QFont"; isReadonly: true }
163 Property { name: "captionFont"; type: "QFont"; isReadonly: true }
164 Property { name: "buttonFont"; type: "QFont"; isReadonly: true }
165 Property { name: "subheaderFont"; type: "QFont"; isReadonly: true }
166 Property { name: "dialogFont"; type: "QFont"; isReadonly: true }
167 }
168 Component {
169 prototype: "QQuickFrame"
170 name: "QtQuick.Controls/Frame 2.0"
171 exports: ["QtQuick.Controls/Frame 2.0"]
172 exportMetaObjectRevisions: [0]
173 isComposite: true
174 defaultProperty: "contentData"
175 }
176 Component {
177 prototype: "QQuickGroupBox"
178 name: "QtQuick.Controls/GroupBox 2.0"
179 exports: ["QtQuick.Controls/GroupBox 2.0"]
180 exportMetaObjectRevisions: [0]
181 isComposite: true
182 defaultProperty: "contentData"
183 }
184 Component {
185 prototype: "QQuickItemDelegate"
186 name: "QtQuick.Controls/ItemDelegate 2.0"
187 exports: ["QtQuick.Controls/ItemDelegate 2.0"]
188 exportMetaObjectRevisions: [0]
189 isComposite: true
190 defaultProperty: "data"
191 }
192 Component {
193 prototype: "QQuickLabel"
194 name: "QtQuick.Controls/Label 2.0"
195 exports: ["QtQuick.Controls/Label 2.0"]
196 exportMetaObjectRevisions: [0]
197 isComposite: true
198 defaultProperty: "data"
199 }
200 Component {
201 prototype: "QQuickMenu"
202 name: "QtQuick.Controls/Menu 2.0"
203 exports: ["QtQuick.Controls/Menu 2.0"]
204 exportMetaObjectRevisions: [0]
205 isComposite: true
206 defaultProperty: "contentData"
207 }
208 Component {
209 prototype: "QQuickMenuItem"
210 name: "QtQuick.Controls/MenuItem 2.0"
211 exports: ["QtQuick.Controls/MenuItem 2.0"]
212 exportMetaObjectRevisions: [0]
213 isComposite: true
214 defaultProperty: "data"
215 }
216 Component {
217 prototype: "QQuickPage"
218 name: "QtQuick.Controls/Page 2.0"
219 exports: ["QtQuick.Controls/Page 2.0"]
220 exportMetaObjectRevisions: [0]
221 isComposite: true
222 defaultProperty: "contentData"
223 }
224 Component {
225 prototype: "QQuickPageIndicator"
226 name: "QtQuick.Controls/PageIndicator 2.0"
227 exports: ["QtQuick.Controls/PageIndicator 2.0"]
228 exportMetaObjectRevisions: [0]
229 isComposite: true
230 defaultProperty: "data"
231 }
232 Component {
233 prototype: "QQuickPane"
234 name: "QtQuick.Controls/Pane 2.0"
235 exports: ["QtQuick.Controls/Pane 2.0"]
236 exportMetaObjectRevisions: [0]
237 isComposite: true
238 defaultProperty: "contentData"
239 }
240 Component {
241 prototype: "QQuickPopup"
242 name: "QtQuick.Controls/Popup 2.0"
243 exports: ["QtQuick.Controls/Popup 2.0"]
244 exportMetaObjectRevisions: [0]
245 isComposite: true
246 defaultProperty: "contentData"
247 }
248 Component {
249 prototype: "QQuickProgressBar"
250 name: "QtQuick.Controls/ProgressBar 2.0"
251 exports: ["QtQuick.Controls/ProgressBar 2.0"]
252 exportMetaObjectRevisions: [0]
253 isComposite: true
254 defaultProperty: "data"
255 }
256 Component {
257 prototype: "QQuickRadioButton"
258 name: "QtQuick.Controls/RadioButton 2.0"
259 exports: ["QtQuick.Controls/RadioButton 2.0"]
260 exportMetaObjectRevisions: [0]
261 isComposite: true
262 defaultProperty: "data"
263 }
264 Component {
265 prototype: "QQuickRadioDelegate"
266 name: "QtQuick.Controls/RadioDelegate 2.0"
267 exports: ["QtQuick.Controls/RadioDelegate 2.0"]
268 exportMetaObjectRevisions: [0]
269 isComposite: true
270 defaultProperty: "data"
271 }
272 Component {
273 prototype: "QQuickRectangle"
274 name: "QtQuick.Controls.impl/RadioIndicator 2.0"
275 exports: ["QtQuick.Controls.impl/RadioIndicator 2.0"]
276 exportMetaObjectRevisions: [0]
277 isComposite: true
278 defaultProperty: "data"
279 Property { name: "control"; type: "QQuickItem"; isPointer: true }
280 }
281 Component {
282 prototype: "QQuickRectangle"
283 name: "QtQuick.Controls.Universal.impl/RadioIndicator 2.0"
284 exports: ["QtQuick.Controls.Universal.impl/RadioIndicator 2.0"]
285 exportMetaObjectRevisions: [0]
286 isComposite: true
287 defaultProperty: "data"
288 Property { name: "control"; type: "QVariant" }
289 }
290 Component {
291 prototype: "QQuickRangeSlider"
292 name: "QtQuick.Controls/RangeSlider 2.0"
293 exports: ["QtQuick.Controls/RangeSlider 2.0"]
294 exportMetaObjectRevisions: [0]
295 isComposite: true
296 defaultProperty: "data"
297 }
298 Component {
299 prototype: "QQuickRectangle"
300 name: "QtQuick.Controls.Material.impl/Ripple 2.0"
301 exports: ["QtQuick.Controls.Material.impl/Ripple 2.0"]
302 exportMetaObjectRevisions: [0]
303 isComposite: true
304 defaultProperty: "data"
305 Property { name: "control"; type: "QQuickItem"; isPointer: true }
306 Property { name: "colored"; type: "bool" }
307 }
308 Component {
309 prototype: "QQuickScrollBar"
310 name: "QtQuick.Controls/ScrollBar 2.0"
311 exports: ["QtQuick.Controls/ScrollBar 2.0"]
312 exportMetaObjectRevisions: [0]
313 isComposite: true
314 defaultProperty: "data"
315 }
316 Component {
317 prototype: "QQuickScrollIndicator"
318 name: "QtQuick.Controls/ScrollIndicator 2.0"
319 exports: ["QtQuick.Controls/ScrollIndicator 2.0"]
320 exportMetaObjectRevisions: [0]
321 isComposite: true
322 defaultProperty: "data"
323 }
324 Component {
325 prototype: "QQuickSlider"
326 name: "QtQuick.Controls/Slider 2.0"
327 exports: ["QtQuick.Controls/Slider 2.0"]
328 exportMetaObjectRevisions: [0]
329 isComposite: true
330 defaultProperty: "data"
331 }
332 Component {
333 prototype: "QQuickItem"
334 name: "QtQuick.Controls.Material.impl/SliderHandle 2.0"
335 exports: ["QtQuick.Controls.Material.impl/SliderHandle 2.0"]
336 exportMetaObjectRevisions: [0]
337 isComposite: true
338 defaultProperty: "data"
339 Property { name: "value"; type: "double" }
340 Property { name: "handleHasFocus"; type: "bool" }
341 Property { name: "handlePressed"; type: "bool" }
342 Property { name: "initialSize"; type: "int"; isReadonly: true }
343 Property { name: "horizontal"; type: "bool"; isReadonly: true }
344 Property { name: "control"; type: "QVariant"; isReadonly: true }
345 }
346 Component {
347 prototype: "QQuickSpinBox"
348 name: "QtQuick.Controls/SpinBox 2.0"
349 exports: ["QtQuick.Controls/SpinBox 2.0"]
350 exportMetaObjectRevisions: [0]
351 isComposite: true
352 defaultProperty: "data"
353 }
354 Component {
355 prototype: "QQuickStackView"
356 name: "QtQuick.Controls/StackView 2.0"
357 exports: ["QtQuick.Controls/StackView 2.0"]
358 exportMetaObjectRevisions: [0]
359 isComposite: true
360 defaultProperty: "data"
361 }
362 Component {
363 prototype: "QQuickSwipeDelegate"
364 name: "QtQuick.Controls/SwipeDelegate 2.0"
365 exports: ["QtQuick.Controls/SwipeDelegate 2.0"]
366 exportMetaObjectRevisions: [0]
367 isComposite: true
368 defaultProperty: "data"
369 }
370 Component {
371 prototype: "QQuickSwipeView"
372 name: "QtQuick.Controls/SwipeView 2.0"
373 exports: ["QtQuick.Controls/SwipeView 2.0"]
374 exportMetaObjectRevisions: [0]
375 isComposite: true
376 defaultProperty: "contentData"
377 }
378 Component {
379 prototype: "QQuickSwitch"
380 name: "QtQuick.Controls/Switch 2.0"
381 exports: ["QtQuick.Controls/Switch 2.0"]
382 exportMetaObjectRevisions: [0]
383 isComposite: true
384 defaultProperty: "data"
385 }
386 Component {
387 prototype: "QQuickSwitchDelegate"
388 name: "QtQuick.Controls/SwitchDelegate 2.0"
389 exports: ["QtQuick.Controls/SwitchDelegate 2.0"]
390 exportMetaObjectRevisions: [0]
391 isComposite: true
392 defaultProperty: "data"
393 }
394 Component {
395 prototype: "QQuickRectangle"
396 name: "QtQuick.Controls.Universal.impl/SwitchIndicator 2.0"
397 exports: ["QtQuick.Controls.Universal.impl/SwitchIndicator 2.0"]
398 exportMetaObjectRevisions: [0]
399 isComposite: true
400 defaultProperty: "data"
401 Property { name: "control"; type: "QQuickItem"; isPointer: true }
402 }
403 Component {
404 prototype: "QQuickItem"
405 name: "QtQuick.Controls.impl/SwitchIndicator 2.0"
406 exports: ["QtQuick.Controls.impl/SwitchIndicator 2.0"]
407 exportMetaObjectRevisions: [0]
408 isComposite: true
409 defaultProperty: "data"
410 Property { name: "control"; type: "QQuickItem"; isPointer: true }
411 }
412 Component {
413 prototype: "QQuickItem"
414 name: "QtQuick.Controls.Material.impl/SwitchIndicator 2.0"
415 exports: ["QtQuick.Controls.Material.impl/SwitchIndicator 2.0"]
416 exportMetaObjectRevisions: [0]
417 isComposite: true
418 defaultProperty: "data"
419 Property { name: "control"; type: "QQuickItem"; isPointer: true }
420 }
421 Component {
422 prototype: "QQuickTabBar"
423 name: "QtQuick.Controls/TabBar 2.0"
424 exports: ["QtQuick.Controls/TabBar 2.0"]
425 exportMetaObjectRevisions: [0]
426 isComposite: true
427 defaultProperty: "contentData"
428 }
429 Component {
430 prototype: "QQuickTabButton"
431 name: "QtQuick.Controls/TabButton 2.0"
432 exports: ["QtQuick.Controls/TabButton 2.0"]
433 exportMetaObjectRevisions: [0]
434 isComposite: true
435 defaultProperty: "data"
436 }
437 Component {
438 prototype: "QQuickTextArea"
439 name: "QtQuick.Controls/TextArea 2.0"
440 exports: ["QtQuick.Controls/TextArea 2.0"]
441 exportMetaObjectRevisions: [0]
442 isComposite: true
443 defaultProperty: "data"
444 }
445 Component {
446 prototype: "QQuickTextField"
447 name: "QtQuick.Controls/TextField 2.0"
448 exports: ["QtQuick.Controls/TextField 2.0"]
449 exportMetaObjectRevisions: [0]
450 isComposite: true
451 defaultProperty: "data"
452 }
453 Component {
454 prototype: "QQuickToolBar"
455 name: "QtQuick.Controls/ToolBar 2.0"
456 exports: ["QtQuick.Controls/ToolBar 2.0"]
457 exportMetaObjectRevisions: [0]
458 isComposite: true
459 defaultProperty: "contentData"
460 }
461 Component {
462 prototype: "QQuickToolButton"
463 name: "QtQuick.Controls/ToolButton 2.0"
464 exports: ["QtQuick.Controls/ToolButton 2.0"]
465 exportMetaObjectRevisions: [0]
466 isComposite: true
467 defaultProperty: "data"
468 }
469 Component {
470 prototype: "QQuickToolTip"
471 name: "QtQuick.Controls/ToolTip 2.0"
472 exports: ["QtQuick.Controls/ToolTip 2.0"]
473 exportMetaObjectRevisions: [0]
474 isComposite: true
475 defaultProperty: "contentData"
476 }
477 Component {
478 prototype: "QQuickTumbler"
479 name: "QtQuick.Controls/Tumbler 2.0"
480 exports: ["QtQuick.Controls/Tumbler 2.0"]
481 exportMetaObjectRevisions: [0]
482 isComposite: true
483 defaultProperty: "data"
484 }
485 Component {
486 prototype: "QQuickItem"
487 name: "Units 1.0"
488 exports: ["Units 1.0"]
489 exportMetaObjectRevisions: [0]
490 isComposite: true
491 isCreatable: false
492 isSingleton: true
493 defaultProperty: "data"
494 Property { name: "gridUnit"; type: "int"; isReadonly: true }
495 Property { name: "smallSpacing"; type: "double"; isReadonly: true }
496 Property { name: "mediumSpacing"; type: "double"; isReadonly: true }
497 Property { name: "largeSpacing"; type: "double"; isReadonly: true }
498 Property { name: "shortDuration"; type: "int"; isReadonly: true }
499 Property { name: "mediumDuration"; type: "int"; isReadonly: true }
500 Property { name: "longDuration"; type: "int"; isReadonly: true }
501 Property { name: "iconSizes"; type: "QObject"; isReadonly: true; isPointer: true }
502 Method {
503 name: "gu"
504 type: "QVariant"
505 Parameter { name: "x"; type: "QVariant" }
506 }
507 Method {
508 name: "roundToIconSize"
509 type: "QVariant"
510 Parameter { name: "x"; type: "QVariant" }
511 }
512 }
513 Component {
514 prototype: "QObject"
515 name: "Utils 1.0"
516 exports: ["Utils 1.0"]
517 exportMetaObjectRevisions: [0]
518 isComposite: true
519 isCreatable: false
520 isSingleton: true
521 Method {
522 name: "asColor"
523 type: "QVariant"
524 Parameter { name: "color"; type: "QVariant" }
525 }
526 Method {
527 name: "alpha"
528 type: "QVariant"
529 Parameter { name: "color"; type: "QVariant" }
530 Parameter { name: "alpha"; type: "QVariant" }
531 }
532 Method {
533 name: "blendColors"
534 type: "QVariant"
535 Parameter { name: "color1"; type: "QVariant" }
536 Parameter { name: "color2"; type: "QVariant" }
537 Parameter { name: "a"; type: "QVariant" }
538 }
539 Method {
540 name: "luminance"
541 type: "QVariant"
542 Parameter { name: "color"; type: "QVariant" }
543 }
544 Method {
545 name: "lightDark"
546 type: "QVariant"
547 Parameter { name: "background"; type: "QVariant" }
548 Parameter { name: "lightColor"; type: "QVariant" }
549 Parameter { name: "darkColor"; type: "QVariant" }
550 }
551 Method {
552 name: "isDarkColor"
553 type: "QVariant"
554 Parameter { name: "color"; type: "QVariant" }
555 }
556 Method {
557 name: "getSourceForIconName"
558 type: "QVariant"
559 Parameter { name: "name"; type: "QVariant" }
560 }
561 Method {
562 name: "scale"
563 type: "QVariant"
564 Parameter { name: "percent"; type: "QVariant" }
565 Parameter { name: "start"; type: "QVariant" }
566 Parameter { name: "end"; type: "QVariant" }
567 }
568 }
569}
diff --git a/material/qmldir b/material/qmldir
new file mode 100644
index 0000000..6aff2c1
--- /dev/null
+++ b/material/qmldir
@@ -0,0 +1,7 @@
1module Fluid.Material
2typeinfo plugins.qmltypes
3
4ActionButton 1.0 ActionButton.qml
5ElevationEffect 1.0 ElevationEffect.qml
6Ripple 1.0 Ripple.qml
7Wave 1.0 Wave.qml
diff --git a/scripts/fetch_icons.sh b/scripts/fetch_icons.sh
new file mode 100755
index 0000000..9c452db
--- /dev/null
+++ b/scripts/fetch_icons.sh
@@ -0,0 +1,39 @@
1#! /bin/bash
2
3GIT_DIR=material-design-icons
4TARGET_DIR=icons
5QRC_FILE=$TARGET_DIR/icons.qrc
6
7CATEGORIES=(action av communication device file image maps notification social toggle alert content editor hardware navigation)
8
9if [ -d $GIT_DIR ]; then
10 pushd $GIT_DIR; git pull; popd
11else
12 git clone https://github.com/google/material-design-icons.git $GIT_DIR
13fi
14
15mkdir -p $TARGET_DIR
16
17echo "<RCC>
18 <qresource prefix=\"/Fluid/Controls/\">" > $QRC_FILE
19for CATEGORY in ${CATEGORIES[*]}; do
20 if [ -d $TARGET_DIR/$CATEGORY ]; then
21 rm -r $TARGET_DIR/$CATEGORY
22 fi
23
24 mkdir $TARGET_DIR/$CATEGORY
25
26 ICONS=$(ls $GIT_DIR/$CATEGORY/svg/production/*48px*)
27
28
29 for FILE in $ICONS; do
30 ICON=$(basename $FILE)
31 NEW_NAME=$(echo $ICON | sed -E 's/ic_(.*)_48px.svg/\1.svg/')
32 cp $FILE $TARGET_DIR/$CATEGORY/$NEW_NAME
33 echo " <file>$CATEGORY/$NEW_NAME</file>" >> $QRC_FILE
34 done
35done
36
37echo " </qresource>
38</RCC>
39" >> $QRC_FILE \ No newline at end of file
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..dacd2e0
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,79 @@
1include(GenerateExportHeader)
2include(CMakePackageConfigHelpers)
3include(ECMSetupVersion)
4include(ECMGenerateHeaders)
5
6ecm_setup_version(${PROJECT_VERSION} VARIABLE_PREFIX FLUID
7 VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/Fluid/fluid/fluidversion.h"
8 PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/FluidConfigVersion.cmake"
9 SOVERSION ${PROJECT_SOVERSION})
10
11set(FLUID_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}/Fluid")
12
13set(CMAKECONFIG_INSTALL_DIR "${CMAKECONFIG_INSTALL_PREFIX}/Fluid")
14
15configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/FluidConfig.cmake.in"
16 "${CMAKE_CURRENT_BINARY_DIR}/FluidConfig.cmake"
17 INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR})
18
19install(FILES "${CMAKE_CURRENT_BINARY_DIR}/FluidConfig.cmake"
20 "${CMAKE_CURRENT_BINARY_DIR}/FluidConfigVersion.cmake"
21 DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
22 COMPONENT Devel)
23install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Fluid/fluid/fluidversion.h
24 DESTINATION ${FLUID_INCLUDEDIR}/fluid COMPONENT Devel)
25
26###################################
27
28add_definitions(-DQT_NO_KEYWORDS)
29
30set(SOURCES
31 dateutils.cpp
32)
33
34add_library(Fluid SHARED ${SOURCES})
35
36target_link_libraries(Fluid
37 PUBLIC
38 Qt5::Core
39)
40
41##################################################
42
43generate_export_header(Fluid EXPORT_FILE_NAME ${CMAKE_CURRENT_BINARY_DIR}/Fluid/fluid/fluid_export.h)
44
45target_include_directories(Fluid INTERFACE "$<INSTALL_INTERFACE:${FLUID_INCLUDEDIR}>")
46
47set_target_properties(Fluid PROPERTIES
48 VERSION ${PROJECT_VERSION}
49 SOVERSION ${PROJECT_SOVERSION})
50
51ecm_generate_headers(Fluid_CamelCase_HEADERS
52 HEADER_NAMES
53 DateUtils
54 REQUIRED_HEADERS
55 Fluid_HEADERS
56 PREFIX
57 Fluid
58 OUTPUT_DIR
59 ${CMAKE_CURRENT_BINARY_DIR}/Fluid
60)
61install(FILES ${Fluid_CamelCase_HEADERS}
62 DESTINATION ${FLUID_INCLUDEDIR}/Fluid
63 COMPONENT Devel)
64
65install(TARGETS Fluid EXPORT FluidTargets ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
66
67install(
68 FILES
69 ${CMAKE_CURRENT_BINARY_DIR}/Fluid/fluid/fluid_export.h
70 dateutils.h
71 DESTINATION
72 ${FLUID_INCLUDEDIR}/fluid
73 COMPONENT
74 Devel
75)
76
77install(EXPORT FluidTargets
78 DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
79 FILE FluidTargets.cmake NAMESPACE Fluid::)
diff --git a/src/FluidConfig.cmake.in b/src/FluidConfig.cmake.in
new file mode 100644
index 0000000..8cbfe85
--- /dev/null
+++ b/src/FluidConfig.cmake.in
@@ -0,0 +1,11 @@
1@PACKAGE_INIT@
2
3find_dependency(Qt5Core @REQUIRED_QT_VERSION@)
4find_dependency(Qt5Gui @REQUIRED_QT_VERSION@)
5find_dependency(Qt5Qml @REQUIRED_QT_VERSION@)
6find_dependency(Qt5Quick @REQUIRED_QT_VERSION@)
7find_dependency(Qt5QuickControls2 @REQUIRED_QT_VERSION@)
8
9set(FLUID_CMAKE_MODULES_DIR "${CMAKE_CURRENT_LIST_DIR}")
10
11include("${FLUID_CMAKE_MODULES_DIR}/FluidTargets.cmake")
diff --git a/src/dateutils.cpp b/src/dateutils.cpp
new file mode 100644
index 0000000..62e6903
--- /dev/null
+++ b/src/dateutils.cpp
@@ -0,0 +1,82 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
6 *
7 * $BEGIN_LICENSE:MPL2$
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
13 * $END_LICENSE$
14 */
15
16#include "dateutils.h"
17
18using namespace Fluid;
19
20QString DateUtils::formatDuration(qlonglong duration, DurationFormat format, DurationType type)
21{
22 int hours = duration / (1000 * 60 * 60);
23 int minutes = duration / (1000 * 60) - 60 * hours;
24 int seconds = duration / 1000 - 60 * minutes - 60 * 60 * hours;
25
26 QString string;
27
28 if (type == Any || type == Seconds) {
29 if (format == Short)
30 string = QStringLiteral("%1").arg(seconds, 2, 10, QChar('0'));
31 else
32 string = QStringLiteral("%1s").arg(seconds);
33 }
34
35 if (type == Seconds || type == Minutes || (type == Any && (minutes >= 1 || hours >= 1))) {
36 if (format == Short) {
37 if (string.length() > 0)
38 string = QStringLiteral("%1:%2").arg(minutes, 2, 10, QChar('0')).arg(string);
39 else
40 string = QStringLiteral("%1").arg(minutes, 2, 10, QChar('0'));
41 } else {
42 string = QStringLiteral("%1m %2").arg(minutes).arg(string);
43 }
44 }
45
46 if (type == Seconds || type == Minutes || type == Hours || (type == Any && (hours >= 1))) {
47 if (format == Short) {
48 if (string.length() > 0)
49 string = QStringLiteral("%1:%2").arg(hours).arg(string);
50 else
51 string = QStringLiteral("%1").arg(hours);
52 } else {
53 string = QStringLiteral("%1h %2").arg(hours).arg(string);
54 }
55 }
56
57 return string.trimmed();
58}
59
60QString DateUtils::friendlyTime(const QDateTime &time, bool standalone)
61{
62 QDateTime now = QDateTime::currentDateTime();
63 qint64 minutes = qRound64(time.secsTo(now) / 60.0f);
64 if (minutes < 1)
65 return standalone ? tr("Now") : "now";
66 else if (minutes == 1)
67 return tr("1 minute ago");
68 else if (minutes < 60)
69 return tr("%1 minutes ago").arg(minutes);
70 qint64 hours = qRound64(minutes / 60.0f);
71 if (hours == 1)
72 return tr("1 hour ago");
73 else if (hours < 24)
74 return tr("%1 hours ago").arg(hours);
75 qint64 days = qRound64(hours / 24.0f);
76 if (days == 1)
77 return tr("1 day ago");
78 else if (days <= 10)
79 return tr("%1 days ago").arg(days);
80 QString string = time.toString();
81 return standalone ? string : tr("on %1").arg(string);
82}
diff --git a/src/dateutils.h b/src/dateutils.h
new file mode 100644
index 0000000..e49cbac
--- /dev/null
+++ b/src/dateutils.h
@@ -0,0 +1,44 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
6 *
7 * $BEGIN_LICENSE:MPL2$
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
13 * $END_LICENSE$
14 */
15
16#pragma once
17
18#ifdef FLUID_LOCAL
19 #define FLUID_EXPORT
20#else
21 #include <Fluid/fluid/fluid_export.h>
22#endif
23#include <QtCore/QObject>
24#include <QtCore/QDateTime>
25
26namespace Fluid {
27
28class FLUID_EXPORT DateUtils : public QObject
29{
30 Q_OBJECT
31
32public:
33 enum DurationFormat { Long, Short };
34 Q_ENUM(DurationFormat)
35
36 enum DurationType { Seconds, Minutes, Hours, Any };
37 Q_ENUM(DurationType)
38
39 static QString formatDuration(qlonglong duration, DurationFormat format = Short,
40 DurationType type = Any);
41 static QString friendlyTime(const QDateTime &time, bool standalone);
42};
43
44} // namespace Fluid
diff --git a/src/src.pri b/src/src.pri
new file mode 100644
index 0000000..6b73833
--- /dev/null
+++ b/src/src.pri
@@ -0,0 +1,5 @@
1HEADERS += \
2 $$PWD/dateutils.h
3
4SOURCES += \
5 $$PWD/dateutils.cpp
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644
index 0000000..0653827
--- /dev/null
+++ b/tests/CMakeLists.txt
@@ -0,0 +1 @@
add_subdirectory(auto)
diff --git a/tests/auto/CMakeLists.txt b/tests/auto/CMakeLists.txt
new file mode 100644
index 0000000..27e47a2
--- /dev/null
+++ b/tests/auto/CMakeLists.txt
@@ -0,0 +1,7 @@
1if(NOT USE_SUPERBUILD)
2 add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} -VV)
3endif()
4
5add_subdirectory(controls)
6add_subdirectory(core)
7add_subdirectory(material)
diff --git a/tests/auto/controls/CMakeLists.txt b/tests/auto/controls/CMakeLists.txt
new file mode 100644
index 0000000..ee473f8
--- /dev/null
+++ b/tests/auto/controls/CMakeLists.txt
@@ -0,0 +1,10 @@
1set(SOURCES controls.cpp)
2
3set(CMAKE_MACOSX_BUNDLE FALSE)
4
5add_definitions(-DQUICK_TEST_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
6
7add_executable(tst_controls ${SOURCES})
8target_link_libraries(tst_controls Qt5::Qml Qt5::Test Qt5::QuickTest)
9add_test(tst_controls tst_controls)
10add_dependencies(check tst_controls)
diff --git a/tests/auto/controls/controls.cpp b/tests/auto/controls/controls.cpp
new file mode 100644
index 0000000..1d14afc
--- /dev/null
+++ b/tests/auto/controls/controls.cpp
@@ -0,0 +1,16 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15#include <QtQuickTest/QtQuickTest>
16QUICK_TEST_MAIN(tst_controls)
diff --git a/tests/auto/controls/tst_icon.qml b/tests/auto/controls/tst_icon.qml
new file mode 100644
index 0000000..6d3fc26
--- /dev/null
+++ b/tests/auto/controls/tst_icon.qml
@@ -0,0 +1,83 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.4
16import QtTest 1.0
17import Fluid.Controls 1.0
18import QtQuick.Controls.Material 2.0
19
20Icon {
21 id: icon
22
23 TestCase {
24 name: "IconTests"
25 when: windowShown
26
27 function test_source_should_use_desktop_provider_for_freedesktop_icon() {
28 icon.name = 'edit-cut-symbolic'
29
30 compare(icon.source, 'image://fluidicontheme/edit-cut-symbolic')
31 }
32
33 function test_source_should_use_icon_prefix_for_material_icon() {
34 icon.name = 'action/settings'
35
36 compare(icon.source, 'image://fluidicons/action/settings')
37 }
38
39 function test_source_should_use_file_url_for_file_name() {
40 icon.name = '/path/to/icon.png'
41
42 compare(icon.source, 'file:///path/to/icon.png')
43 }
44
45 function test_source_should_use_file_url_for_file_url() {
46 icon.name = 'file:///path/to/icon.png'
47
48 compare(icon.source, 'file:///path/to/icon.png')
49 }
50
51 function test_colorize_should_be_true_for_material_icon() {
52 icon.name = 'action/settings'
53
54 compare(icon.colorize, true)
55 }
56
57 function test_colorize_should_be_true_for_symbolic_icon() {
58 icon.name = 'edit-cut-symbolic'
59
60 compare(icon.colorize, true)
61 }
62
63 function test_colorize_should_be_false_for_regular_icon() {
64 icon.name = 'gimp'
65
66 compare(icon.colorize, false)
67 }
68
69 function test_color_should_be_light_icon_color_for_light_theme() {
70 icon.Material.theme = Material.Light
71
72 // Colors must be converted to strings for compare to work
73 compare(String(icon.color), String(FluidStyle.iconColorLight))
74 }
75
76 function test_color_should_be_dark_icon_color_for_dark_theme() {
77 icon.Material.theme = Material.Dark
78
79 // Colors must be converted to strings for compare to work
80 compare(String(icon.color), String(FluidStyle.iconColorDark))
81 }
82 }
83}
diff --git a/tests/auto/controls/tst_listitem.qml b/tests/auto/controls/tst_listitem.qml
new file mode 100644
index 0000000..1f10ee1
--- /dev/null
+++ b/tests/auto/controls/tst_listitem.qml
@@ -0,0 +1,123 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.4
16import QtQuick.Controls 2.0
17import QtTest 1.0
18import Fluid.Controls 1.0
19
20Item {
21 width: 400
22 height: 400
23
24 Column {
25 anchors.fill: parent
26
27 ListItem {
28 id: listItem
29
30 width: 200
31
32 SignalSpy {
33 id: clickedSpy
34 target: listItem
35 signalName: "clicked"
36 }
37 }
38
39 ListItem {
40 id: listItemWithSubtext1
41
42 maximumLineCount: 2
43 subText: "Random Text"
44 }
45
46 ListItem {
47 id: listItemWithSubtext2
48
49 maximumLineCount: 3
50 subText: "Random Text"
51 }
52
53 ListItem {
54 id: listItemWithSecondaryItem
55
56 secondaryItem: Button {}
57 }
58
59 ListItem {
60 id: listItemWithoutSecondaryItem
61 }
62
63 ListItem {
64 id: listItemWithLeftItem
65
66 iconName: "action/settings"
67 }
68
69 ListItem {
70 id: listItemWithRightItem
71
72 text: "Random Text"
73 rightItem: ComboBox {
74 anchors.centerIn: parent
75 textRole: "text"
76 model: ListModel {
77 ListElement { text: "One"; value: 1 }
78 ListElement { text: "Two"; value: 2 }
79 }
80 }
81 }
82 }
83
84 TestCase {
85 name: "ListItemTests"
86 when: windowShown
87
88 function test_leftItem_shows_when_iconName_is_set() {
89 var leftItem = findChild(listItem, "leftItem")
90
91 compare(leftItem.showing, false)
92
93 listItem.iconName = "action/settings"
94
95 compare(leftItem.showing, true)
96 }
97
98 function test_click_isnt_eaten_by_ripple() {
99 clickedSpy.clear()
100
101 mouseClick(listItem)
102
103 compare(clickedSpy.count, 1)
104 }
105
106 function test_implicit_height() {
107 compare(listItemWithSubtext1.implicitHeight, 72)
108
109 compare(listItemWithSubtext2.implicitHeight, 88)
110
111 var secondaryItem = findChild(listItemWithSecondaryItem, "secondaryItem")
112 compare(listItemWithSecondaryItem.implicitHeight, secondaryItem.childrenRect.height + Units.smallSpacing * 2)
113
114 compare(listItemWithoutSecondaryItem.implicitHeight, 48)
115
116 var leftItem = findChild(listItemWithLeftItem, "leftItem")
117 compare(listItemWithLeftItem.implicitHeight, 48)
118
119 var rightItem = findChild(listItemWithRightItem, "rightItem")
120 compare(listItemWithRightItem.implicitHeight, rightItem.childrenRect.height + Units.smallSpacing * 2)
121 }
122 }
123}
diff --git a/tests/auto/core/CMakeLists.txt b/tests/auto/core/CMakeLists.txt
new file mode 100644
index 0000000..dbe79a9
--- /dev/null
+++ b/tests/auto/core/CMakeLists.txt
@@ -0,0 +1,10 @@
1set(SOURCES core.cpp)
2
3set(CMAKE_MACOSX_BUNDLE FALSE)
4
5add_definitions(-DQUICK_TEST_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
6
7add_executable(tst_core ${SOURCES})
8target_link_libraries(tst_core Qt5::Qml Qt5::Test Qt5::QuickTest)
9add_test(tst_core tst_core)
10add_dependencies(check tst_core)
diff --git a/tests/auto/core/core.cpp b/tests/auto/core/core.cpp
new file mode 100644
index 0000000..7983d3e
--- /dev/null
+++ b/tests/auto/core/core.cpp
@@ -0,0 +1,16 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15#include <QtQuickTest/QtQuickTest>
16QUICK_TEST_MAIN(tst_core)
diff --git a/tests/auto/core/tst_clipboard.qml b/tests/auto/core/tst_clipboard.qml
new file mode 100644
index 0000000..9c99cd6
--- /dev/null
+++ b/tests/auto/core/tst_clipboard.qml
@@ -0,0 +1,59 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.4
16import QtTest 1.0
17import Fluid.Core 1.0
18
19TestCase {
20 name: "ClipboardTests"
21
22 Clipboard {
23 id: clipboard
24 }
25
26 SignalSpy {
27 id: textChangedSpy
28 target: clipboard
29 signalName: "textChanged"
30 }
31
32 function test_clipboard_works() {
33 var text = "Hello World"
34
35 clipboard.text = text
36
37 compare(clipboard.text, text)
38 }
39
40 function tests_setting_text_should_fire_textChanged() {
41 clipboard.text = ""
42
43 textChangedSpy.clear()
44
45 clipboard.text = "Random Text"
46
47 compare(textChangedSpy.count, 1)
48 }
49
50 function test_clear_should_fire_textChanged() {
51 clipboard.text = "Non empty text"
52
53 textChangedSpy.clear()
54
55 clipboard.clear()
56
57 compare(textChangedSpy.count, 1)
58 }
59}
diff --git a/tests/auto/core/tst_utils.qml b/tests/auto/core/tst_utils.qml
new file mode 100644
index 0000000..9d977a9
--- /dev/null
+++ b/tests/auto/core/tst_utils.qml
@@ -0,0 +1,38 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
6 *
7 * $BEGIN_LICENSE:MPL2$
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
13 * $END_LICENSE$
14 */
15
16import QtQuick 2.4
17import QtTest 1.0
18import Fluid.Core 1.0
19
20TestCase {
21 name: "UtilsTests"
22
23 function test_blendColors() {
24 compare(Utils.blendColors("lightsteelblue", "#10FF0000", 0.5), "#80b5b8d0")
25 }
26
27 function test_luminance() {
28 compare(Utils.luminance("lightsteelblue"), 0.7593254230563821)
29 }
30
31 function test_isDarkColor_should_return_true_for_dark_color() {
32 compare(Utils.isDarkColor("#455A64"), true)
33 }
34
35 function test_isDarkColor_should_return_false_for_light_color() {
36 compare(Utils.isDarkColor("#B0BEC5"), false)
37 }
38}
diff --git a/tests/auto/material/CMakeLists.txt b/tests/auto/material/CMakeLists.txt
new file mode 100644
index 0000000..78db8aa
--- /dev/null
+++ b/tests/auto/material/CMakeLists.txt
@@ -0,0 +1,12 @@
1set(SOURCES material.cpp)
2
3set(CMAKE_MACOSX_BUNDLE FALSE)
4
5add_definitions(-DQUICK_TEST_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
6
7qt5_add_resources(RESOURCES material.qrc)
8
9add_executable(tst_material ${SOURCES} ${RESOURCES})
10target_link_libraries(tst_material Qt5::Qml Qt5::QuickControls2 Qt5::Test Qt5::QuickTest)
11add_test(tst_material tst_material)
12add_dependencies(check tst_material)
diff --git a/tests/auto/material/material.cpp b/tests/auto/material/material.cpp
new file mode 100644
index 0000000..0d0bd81
--- /dev/null
+++ b/tests/auto/material/material.cpp
@@ -0,0 +1,16 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15#include <QtQuickTest/QtQuickTest>
16QUICK_TEST_MAIN(tst_material)
diff --git a/tests/auto/material/material.qrc b/tests/auto/material/material.qrc
new file mode 100644
index 0000000..e313f5e
--- /dev/null
+++ b/tests/auto/material/material.qrc
@@ -0,0 +1,5 @@
1<!DOCTYPE RCC><RCC version="1.0">
2<qresource prefix="/">
3 <file>qtquickcontrols2.conf</file>
4</qresource>
5</RCC>
diff --git a/tests/auto/material/qtquickcontrols2.conf b/tests/auto/material/qtquickcontrols2.conf
new file mode 100644
index 0000000..b6c7c87
--- /dev/null
+++ b/tests/auto/material/qtquickcontrols2.conf
@@ -0,0 +1,2 @@
1[Controls]
2Style=Material
diff --git a/tests/auto/material/tst_ripple.qml b/tests/auto/material/tst_ripple.qml
new file mode 100644
index 0000000..b79b18e
--- /dev/null
+++ b/tests/auto/material/tst_ripple.qml
@@ -0,0 +1,88 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Michael Spencer <sonrisesoftware@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.4
16import QtTest 1.0
17import Fluid.Material 1.0
18
19Ripple {
20 id: ripple
21
22 width: 100
23 height: 100
24
25 TestCase {
26 name: "RippleTests"
27 when: windowShown
28
29 function test_mouse_press_shows_ripple() {
30 compare(getRipples().length, 0)
31 mousePress(ripple)
32 compare(getRipples().length, 1)
33 mouseRelease(ripple)
34 wait(1000)
35 }
36
37 function test_mouse_up_hides_ripple() {
38 mouseClick(ripple)
39 compare(getRipples().length, 1)
40 wait(1000)
41 compare(getRipples().length, 0)
42 }
43
44 function test_focused_ripple_shows_focus_background() {
45 var focusBackground = findChild(ripple, "focusBackground")
46 compare(focusBackground.opacity, 0)
47
48 ripple.focused = true
49 wait(1000)
50
51 compare(focusBackground.opacity, 1)
52
53 ripple.focused = false
54 wait(1000)
55 }
56
57 function test_focused_ripple_shows_focus_ripple() {
58 var focusRipple = findChild(ripple, "focusRipple")
59 compare(focusRipple.opacity, 0)
60
61 ripple.focused = true
62 wait(1000)
63
64 compare(focusRipple.opacity, 1)
65
66 ripple.focused = false
67 wait(1000)
68 }
69
70 function getRipples() {
71 return filteredChildren("tapRipple")
72 }
73
74 function filteredChildren(objectName) {
75 var filtered = []
76
77 for (var i = 0; i < ripple.children.length; i++) {
78 var child = ripple.children[i]
79
80 if (child.objectName == objectName) {
81 filtered.push(child)
82 }
83 }
84
85 return filtered
86 }
87 }
88}
diff --git a/tests/auto/material/tst_typography.qml b/tests/auto/material/tst_typography.qml
new file mode 100644
index 0000000..3a328fb
--- /dev/null
+++ b/tests/auto/material/tst_typography.qml
@@ -0,0 +1,166 @@
1/*
2 * This file is part of Fluid.
3 *
4 * Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
5 *
6 * $BEGIN_LICENSE:MPL2$
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 *
12 * $END_LICENSE$
13 */
14
15import QtQuick 2.4
16import QtTest 1.0
17import Fluid.Core 1.0
18import Fluid.Controls 1.0
19import QtQuick.Controls 2.0
20
21TestCase {
22 id: testCase
23 name: "TypographyTests"
24 width: 200
25 height: 200
26 visible: true
27 when: windowShown
28
29 Component {
30 id: displayLabelComponent
31 DisplayLabel {}
32 }
33
34 Component {
35 id: bodyLabelComponent
36 BodyLabel {}
37 }
38
39 Component {
40 id: captionLabelComponent
41 CaptionLabel {}
42 }
43
44 Component {
45 id: headlineLabelComponent
46 HeadlineLabel {}
47 }
48
49 Component {
50 id: subheadingLabelComponent
51 SubheadingLabel {}
52 }
53
54 Component {
55 id: titleLabelComponent
56 TitleLabel {}
57 }
58
59 function test_display_label() {
60 var displayLabel = displayLabelComponent.createObject(testCase)
61 verify(displayLabel)
62
63 // FIXME: We can't apparently access +material from tests,
64 // hence these test will fail
65 return
66
67 displayLabel.level = 1
68 compare(displayLabel.font.pixelSize, 34)
69 compare(displayLabel.font.weight, Font.Normal)
70 displayLabel.level = 2
71 compare(displayLabel.font.pixelSize, 45)
72 compare(displayLabel.font.weight, Font.Normal)
73 displayLabel.level = 3
74 compare(displayLabel.font.pixelSize, 56)
75 compare(displayLabel.font.weight, Font.Normal)
76 displayLabel.level = 4
77 compare(displayLabel.font.pixelSize, 112)
78 compare(displayLabel.font.weight, Font.Light)
79 }
80
81 function test_body_label() {
82 var bodyLabel = bodyLabelComponent.createObject(testCase)
83 verify(bodyLabel)
84
85 // FIXME: We can't apparently access +material from tests,
86 // hence these test will fail
87 return
88
89 bodyLabel.level = 1
90 if (Device.isMobile)
91 compare(bodyLabel.font.pixelSize, 14)
92 else
93 compare(bodyLabel.font.pixelSize, 13)
94 compare(bodyLabel.lineHeight, 20.0)
95 compare(bodyLabel.lineHeightMode, Text.FixedHeight)
96
97 bodyLabel.level = 2
98 if (Device.isMobile)
99 compare(bodyLabel.font.pixelSize, 14)
100 else
101 compare(bodyLabel.font.pixelSize, 13)
102 compare(bodyLabel.lineHeight, 24.0)
103 compare(bodyLabel.lineHeightMode, Text.FixedHeight)
104 }
105
106 function test_caption_label() {
107 var captionLabel = captionLabelComponent.createObject(testCase)
108 verify(captionLabel)
109
110 // FIXME: We can't apparently access +material from tests,
111 // hence these test will fail
112 return
113
114 compare(captionLabel.font.pixelSize, 12)
115 }
116
117 function test_headline_label() {
118 var headlineLabel = headlineLabelComponent.createObject(testCase)
119 verify(headlineLabel)
120
121 // FIXME: We can't apparently access +material from tests,
122 // hence these test will fail
123 return
124
125 compare(headlineLabel.font.pixelSize, 24)
126 compare(headlineLabel.lineHeight, 32.0)
127 compare(headlineLabel.lineHeightMode, Text.FixedHeight)
128 }
129
130 function test_subheading_label() {
131 var subheadingLabel = subheadingLabelComponent.createObject(testCase)
132 verify(subheadingLabel)
133
134 // FIXME: We can't apparently access +material from tests,
135 // hence these test will fail
136 return
137
138 subheadingLabel.level = 1
139 if (Device.isMobile)
140 compare(subheadingLabel.font.pixelSize, 16)
141 else
142 compare(subheadingLabel.font.pixelSize, 15)
143 compare(subheadingLabel.lineHeight, 24.0)
144 compare(subheadingLabel.lineHeightMode, Text.FixedHeight)
145
146 subheadingLabel.level = 2
147 if (Device.isMobile)
148 compare(subheadingLabel.font.pixelSize, 16)
149 else
150 compare(subheadingLabel.font.pixelSize, 15)
151 compare(subheadingLabel.lineHeight, 28.0)
152 compare(subheadingLabel.lineHeightMode, Text.FixedHeight)
153 }
154
155 function test_title_label() {
156 var titleLabel = titleLabelComponent.createObject(testCase)
157 verify(titleLabel)
158
159 // FIXME: We can't apparently access +material from tests,
160 // hence these test will fail
161 return
162
163 compare(titleLabel.font.pixelSize, 20)
164 compare(titleLabel.font.weight, Font.Medium)
165 }
166}