diff options
Diffstat (limited to 'controls')
54 files changed, 4493 insertions, 0 deletions
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 | |||
15 | import QtQuick 2.4 | ||
16 | import QtQuick.Controls 2.0 | ||
17 | import Fluid.Material 1.0 | ||
18 | |||
19 | ListItemDelegate { | ||
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 | |||
15 | import QtQuick 2.4 | ||
16 | import QtQuick.Controls 2.0 | ||
17 | import Fluid.Core 1.0 | ||
18 | |||
19 | Label { | ||
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 | |||
15 | import QtQuick 2.4 | ||
16 | import QtQuick.Controls 2.0 | ||
17 | |||
18 | Label { | ||
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 | |||
15 | import QtQuick 2.0 | ||
16 | import QtQuick.Controls 2.0 | ||
17 | import QtQuick.Controls.Material 2.0 | ||
18 | import Fluid.Core 1.0 as FluidCore | ||
19 | |||
20 | Label { | ||
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 | |||
15 | import QtQuick 2.4 | ||
16 | import QtQuick.Controls 2.0 | ||
17 | import Fluid.Core 1.0 | ||
18 | |||
19 | Label { | ||
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 | |||
15 | import QtQuick 2.4 | ||
16 | import QtQuick.Controls 2.0 | ||
17 | |||
18 | Label { | ||
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 | |||
15 | import QtQuick 2.4 | ||
16 | import QtQuick.Controls 2.0 | ||
17 | import Fluid.Core 1.0 | ||
18 | |||
19 | Label { | ||
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 | |||
15 | import QtQuick 2.4 | ||
16 | import QtQuick.Controls.Material 2.0 | ||
17 | |||
18 | Rectangle { | ||
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 | |||
15 | import QtQuick 2.4 | ||
16 | import QtQuick.Controls 2.0 | ||
17 | |||
18 | Label { | ||
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 | |||
16 | import QtQuick 2.5 | ||
17 | import 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 | */ | ||
29 | Object { | ||
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 | |||
15 | import QtQuick 2.0 | ||
16 | import QtQuick.Controls 2.0 | ||
17 | import QtQuick.Controls.Material 2.0 | ||
18 | import QtQuick.Layouts 1.0 | ||
19 | import Fluid.Core 1.0 | ||
20 | import Fluid.Controls 1.0 | ||
21 | import 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 | */ | ||
30 | ToolBar { | ||
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 | |||
15 | import QtQuick 2.0 | ||
16 | import QtQuick.Controls 2.0 | ||
17 | import QtQuick.Controls.Material 2.0 | ||
18 | import Fluid.Core 1.0 | ||
19 | |||
20 | /*! | ||
21 | \qmltype AppToolBar | ||
22 | \inqmlmodule Fluid.Controls | ||
23 | \ingroup fluidcontrols | ||
24 | |||
25 | \brief Application tool bar. | ||
26 | */ | ||
27 | ToolBar { | ||
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 | |||
15 | import QtQuick 2.4 | ||
16 | import 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 | */ | ||
27 | ListItemDelegate { | ||
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 | |||
15 | import QtQuick 2.0 | ||
16 | import 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 | */ | ||
31 | T.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 @@ | |||
1 | set(SOURCES | ||
2 | iconthemeimageprovider.cpp | ||
3 | plugin.cpp | ||
4 | ) | ||
5 | |||
6 | set(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 | |||
47 | set(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 | |||
59 | add_library(fluidcontrols SHARED ${SOURCES} ${QML_FILES} ${MATERIAL_FILES}) | ||
60 | target_link_libraries(fluidcontrols Qt5::Gui Qt5::Quick) | ||
61 | |||
62 | install(TARGETS fluidcontrols LIBRARY | ||
63 | DESTINATION ${QML_INSTALL_DIR}/Fluid/Controls) | ||
64 | install(FILES ${QML_FILES} | ||
65 | DESTINATION ${QML_INSTALL_DIR}/Fluid/Controls) | ||
66 | install(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 | |||
15 | import QtQuick 2.0 | ||
16 | import 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 | */ | ||
31 | T.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 | |||
15 | import QtQuick.Controls 2.0 as C | ||
16 | import 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 | */ | ||
83 | C.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 | |||
15 | import QtQuick 2.4 | ||
16 | import QtGraphicalEffects 1.0 | ||
17 | import Fluid.Effects 1.0 | ||
18 | |||
19 | /*! | ||
20 | \qmltype CircleImage | ||
21 | \inqmlmodule Fluid.Controls | ||
22 | \ingroup fluidcontrols | ||
23 | |||
24 | \brief Circular image. | ||
25 | */ | ||
26 | Item { | ||
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 | |||
16 | import QtQuick 2.0 | ||
17 | import QtQuick.Controls 2.0 | ||
18 | import QtQuick.Controls.Material 2.0 | ||
19 | import QtQuick.Layouts 1.0 | ||
20 | import Fluid.Core 1.0 | ||
21 | import Fluid.Controls 1.0 | ||
22 | |||
23 | /*! | ||
24 | \qmltype Dialog | ||
25 | \inqmlmodule Fluid.Controls | ||
26 | \ingroup fluidcontrols | ||
27 | |||
28 | \brief Dialog. | ||
29 | */ | ||
30 | Popup { | ||
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 | |||
15 | import QtQuick 2.0 | ||
16 | import 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 | */ | ||
34 | T.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 | |||
15 | import QtQuick 2.0 | ||
16 | import 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 | */ | ||
31 | T.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 | |||
15 | import QtQuick 2.0 | ||
16 | import Fluid.Core 1.0 | ||
17 | |||
18 | pragma Singleton | ||
19 | |||
20 | /*! | ||
21 | \qmltype FluidStyle | ||
22 | \inqmlmodule Fluid.Controls | ||
23 | \ingroup fluidcontrols | ||
24 | |||
25 | \brief Style. | ||
26 | */ | ||
27 | QtObject { | ||
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 | |||
15 | import QtQuick 2.4 | ||
16 | import QtQuick.Controls 2.0 | ||
17 | import QtQuick.Controls.Material 2.0 | ||
18 | import Fluid.Core 1.0 | ||
19 | import 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 | */ | ||
54 | ApplicationWindow { | ||
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 | |||
15 | import QtQuick 2.0 | ||
16 | import 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 | */ | ||
31 | T.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 | |||
16 | import QtQuick 2.4 | ||
17 | import QtQuick.Window 2.2 | ||
18 | import QtGraphicalEffects 1.0 | ||
19 | import QtQuick.Controls.Material 2.0 | ||
20 | import Fluid.Core 1.0 | ||
21 | import 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 | */ | ||
73 | Item { | ||
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 | |||
15 | import QtQuick 2.0 | ||
16 | import QtQuick.Controls 2.0 | ||
17 | import 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 | */ | ||
26 | ToolButton { | ||
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 | |||
17 | import QtQuick 2.4 | ||
18 | import QtQuick.Layouts 1.1 | ||
19 | import QtQuick.Controls 2.0 | ||
20 | import QtQuick.Controls.Material 2.0 | ||
21 | import 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 | */ | ||
46 | Rectangle { | ||
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 | |||
16 | import QtQuick 2.4 | ||
17 | import QtQuick.Controls 2.0 | ||
18 | import QtQuick.Controls.Material 2.0 | ||
19 | import QtQuick.Layouts 1.1 | ||
20 | import 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 | */ | ||
29 | BaseListItem { | ||
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 | |||
15 | import QtQuick 2.4 | ||
16 | import QtQuick.Layouts 1.0 | ||
17 | import QtQuick.Controls 2.0 | ||
18 | import 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 | */ | ||
27 | ItemDelegate { | ||
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 | |||
15 | import QtQuick 2.0 | ||
16 | |||
17 | /*! | ||
18 | \qmltype Loadable | ||
19 | \inqmlmodule Fluid.Controls | ||
20 | \ingroup fluidcontrols | ||
21 | |||
22 | \brief Loadable component. | ||
23 | */ | ||
24 | Item { | ||
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 | |||
15 | import QtQuick 2.0 | ||
16 | import QtQuick.Layouts 1.0 | ||
17 | import QtQuick.Controls 2.0 | ||
18 | import QtQml 2.2 | ||
19 | import Fluid.Core 1.0 | ||
20 | import 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 | |||
65 | Drawer { | ||
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 | |||
56 | import QtQuick 2.0 | ||
57 | |||
58 | /*! | ||
59 | \qmltype NoiseBackground | ||
60 | \inqmlmodule Fluid.Controls | ||
61 | \ingroup fluidcontrols | ||
62 | |||
63 | \brief Background with noise. | ||
64 | */ | ||
65 | ShaderEffect { | ||
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 | |||
16 | import QtQuick 2.4 | ||
17 | import QtQuick.Controls 2.0 | ||
18 | import 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 | */ | ||
47 | Page { | ||
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 | |||
15 | import QtQuick 2.4 | ||
16 | import 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 | */ | ||
25 | StackView { | ||
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 | |||
15 | import QtQuick 2.2 | ||
16 | import QtQuick.Layouts 1.0 | ||
17 | import QtQuick.Controls 2.0 | ||
18 | import QtQuick.Controls.Material 2.0 | ||
19 | import Fluid.Controls 1.0 | ||
20 | |||
21 | /*! | ||
22 | \qmltype Placeholder | ||
23 | \inqmlmodule Fluid.Controls | ||
24 | \ingroup fluidcontrols | ||
25 | |||
26 | \brief Placeholder. | ||
27 | */ | ||
28 | Item { | ||
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 | |||
15 | import QtQuick 2.0 | ||
16 | |||
17 | /*! | ||
18 | \qmltype Showable | ||
19 | \inqmlmodule Fluid.Controls | ||
20 | \ingroup fluidcontrols | ||
21 | |||
22 | \brief Showtable component. | ||
23 | */ | ||
24 | FocusScope { | ||
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 | |||
16 | import QtQuick 2.0 | ||
17 | import QtQuick.Controls 2.0 | ||
18 | import QtQuick.Controls.Material 2.0 | ||
19 | import 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 | */ | ||
49 | Pane { | ||
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 | |||
15 | import 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 | */ | ||
57 | Item { | ||
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 | |||
15 | import 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 | */ | ||
52 | Item { | ||
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 | |||
15 | import QtQuick 2.4 | ||
16 | import QtQuick.Controls 2.0 | ||
17 | import QtQuick.Controls.Material 2.0 | ||
18 | import 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 | */ | ||
27 | BaseListItem { | ||
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 | |||
15 | import QtQuick 2.0 | ||
16 | import 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 | */ | ||
31 | T.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 | |||
15 | import QtQuick 2.4 | ||
16 | import Fluid.Core 1.0 | ||
17 | |||
18 | Item { | ||
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 | |||
16 | import QtQuick 2.4 | ||
17 | import QtQuick.Controls 2.0 | ||
18 | import QtQuick.Controls.Material 2.0 | ||
19 | import Fluid.Core 1.0 as FluidCore | ||
20 | import Fluid.Controls 1.0 as FluidControls | ||
21 | |||
22 | FluidControls.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 | |||
15 | import 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 | */ | ||
24 | Rectangle { | ||
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 | |||
15 | import QtQuick 2.0 | ||
16 | import 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 | */ | ||
31 | T.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 | |||
15 | pragma Singleton | ||
16 | |||
17 | import QtQuick 2.4 | ||
18 | import Fluid.Core 1.0 | ||
19 | |||
20 | /*! | ||
21 | \qmltype Units | ||
22 | \inqmlmodule Fluid.Controls | ||
23 | \ingroup fluidcontrols | ||
24 | |||
25 | \brief Units. | ||
26 | */ | ||
27 | Item { | ||
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 @@ | |||
1 | HEADERS += $$PWD/iconthemeimageprovider.h | ||
2 | SOURCES += $$PWD/iconthemeimageprovider.cpp | ||
3 | INCLUDEPATH += $$PWD | ||
4 | RESOURCES += $$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 | |||
19 | IconThemeImageProvider::IconThemeImageProvider() | ||
20 | : QQuickImageProvider(QQuickImageProvider::Pixmap) | ||
21 | { | ||
22 | } | ||
23 | |||
24 | QPixmap 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 | |||
19 | class IconThemeImageProvider : public QQuickImageProvider | ||
20 | { | ||
21 | public: | ||
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 | |||
19 | class FluidCorePlugin : public QQmlExtensionPlugin | ||
20 | { | ||
21 | Q_OBJECT | ||
22 | Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") | ||
23 | public: | ||
24 | void initializeEngine(QQmlEngine *engine, const char *uri); | ||
25 | void registerTypes(const char *uri); | ||
26 | }; | ||
27 | |||
28 | void 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 | |||
35 | void 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 @@ | |||
1 | import 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 | |||
9 | Module { | ||
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 @@ | |||
1 | module Fluid.Controls | ||
2 | plugin fluidcontrols | ||
3 | class FluidControlsPlugin | ||
4 | typeinfo plugins.qmltypes | ||
5 | |||
6 | Action 1.0 Action.qml | ||
7 | AppBar 1.0 AppBar.qml | ||
8 | AppToolBar 1.0 AppToolBar.qml | ||
9 | BaseListItem 1.0 BaseListItem.qml | ||
10 | BodyLabel 1.0 BodyLabel.qml | ||
11 | CaptionLabel 1.0 CaptionLabel.qml | ||
12 | Card 1.0 Card.qml | ||
13 | CircleImage 1.0 CircleImage.qml | ||
14 | Dialog 1.0 Dialog.qml | ||
15 | DialogLabel 1.0 DialogLabel.qml | ||
16 | DisplayLabel 1.0 DisplayLabel.qml | ||
17 | FluidWindow 1.0 FluidWindow.qml | ||
18 | HeadlineLabel 1.0 HeadlineLabel.qml | ||
19 | IconButton 1.0 IconButton.qml | ||
20 | Icon 1.0 Icon.qml | ||
21 | InfoBar 1.0 InfoBar.qml | ||
22 | ListItemDelegate 1.0 ListItemDelegate.qml | ||
23 | ListItem 1.0 ListItem.qml | ||
24 | Loadable 1.0 Loadable.qml | ||
25 | NavigationDrawer 1.0 NavigationDrawer.qml | ||
26 | NoiseBackground 1.0 NoiseBackground.qml | ||
27 | Page 1.0 Page.qml | ||
28 | PageStack 1.0 PageStack.qml | ||
29 | Placeholder 1.0 Placeholder.qml | ||
30 | Showable 1.0 Showable.qml | ||
31 | Sidebar 1.0 Sidebar.qml | ||
32 | SmoothFadeImage 1.0 SmoothFadeImage.qml | ||
33 | SmoothFadeLoader 1.0 SmoothFadeLoader.qml | ||
34 | Subheader 1.0 Subheader.qml | ||
35 | SubheadingLabel 1.0 SubheadingLabel.qml | ||
36 | Tab 1.0 Tab.qml | ||
37 | TabbedPage 1.0 TabbedPage.qml | ||
38 | ThinDivider 1.0 ThinDivider.qml | ||
39 | TitleLabel 1.0 TitleLabel.qml | ||
40 | singleton FluidStyle 1.0 FluidStyle.qml | ||
41 | singleton 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 @@ | |||
1 | module Fluid.Controls | ||
2 | typeinfo plugins.qmltypes | ||
3 | |||
4 | Action 1.0 Action.qml | ||
5 | AppBar 1.0 AppBar.qml | ||
6 | AppToolBar 1.0 AppToolBar.qml | ||
7 | BaseListItem 1.0 BaseListItem.qml | ||
8 | BodyLabel 1.0 BodyLabel.qml | ||
9 | CaptionLabel 1.0 CaptionLabel.qml | ||
10 | Card 1.0 Card.qml | ||
11 | CircleImage 1.0 CircleImage.qml | ||
12 | Dialog 1.0 Dialog.qml | ||
13 | DialogLabel 1.0 DialogLabel.qml | ||
14 | DisplayLabel 1.0 DisplayLabel.qml | ||
15 | FluidWindow 1.0 FluidWindow.qml | ||
16 | HeadlineLabel 1.0 HeadlineLabel.qml | ||
17 | IconButton 1.0 IconButton.qml | ||
18 | Icon 1.0 Icon.qml | ||
19 | InfoBar 1.0 InfoBar.qml | ||
20 | ListItemDelegate 1.0 ListItemDelegate.qml | ||
21 | ListItem 1.0 ListItem.qml | ||
22 | Loadable 1.0 Loadable.qml | ||
23 | NavigationDrawer 1.0 NavigationDrawer.qml | ||
24 | NoiseBackground 1.0 NoiseBackground.qml | ||
25 | Page 1.0 Page.qml | ||
26 | PageStack 1.0 PageStack.qml | ||
27 | Placeholder 1.0 Placeholder.qml | ||
28 | Showable 1.0 Showable.qml | ||
29 | Sidebar 1.0 Sidebar.qml | ||
30 | SmoothFadeImage 1.0 SmoothFadeImage.qml | ||
31 | SmoothFadeLoader 1.0 SmoothFadeLoader.qml | ||
32 | Subheader 1.0 Subheader.qml | ||
33 | SubheadingLabel 1.0 SubheadingLabel.qml | ||
34 | Tab 1.0 Tab.qml | ||
35 | TabbedPage 1.0 TabbedPage.qml | ||
36 | ThinDivider 1.0 ThinDivider.qml | ||
37 | TitleLabel 1.0 TitleLabel.qml | ||
38 | singleton FluidStyle 1.0 FluidStyle.qml | ||
39 | singleton Units 1.0 Units.qml | ||